diff --git a/HJGL_DS/BLL/HJGL/JoinMarking/DrawingInfoService.cs b/HJGL_DS/BLL/HJGL/JoinMarking/DrawingInfoService.cs index f502731..d2c27c4 100644 --- a/HJGL_DS/BLL/HJGL/JoinMarking/DrawingInfoService.cs +++ b/HJGL_DS/BLL/HJGL/JoinMarking/DrawingInfoService.cs @@ -1,5 +1,10 @@ using System; +using System.Collections.Generic; +using System.Globalization; using System.Linq; +using System.Text.RegularExpressions; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace BLL { @@ -8,6 +13,10 @@ namespace BLL /// public static class DrawingInfoService { + private static readonly Regex JointNoRegex = new Regex( + @"^(?[^0-9]*)(?[0-9]+(?:\.[0-9]+)?)(?.*)$", + RegexOptions.Compiled); + /// /// 根据附件文件标识获取图纸 JSON。 /// @@ -24,6 +33,136 @@ namespace BLL .FirstOrDefault(); } + /// + /// 同步管线图纸中的焊口标注,数据由调用方统一提交。 + /// + public static void UpdateJointAnnotation(Model.SGGLDB db, string isoId, string oldJointNo, string newJointNo) + { + if (db == null || string.IsNullOrWhiteSpace(isoId) + || string.IsNullOrWhiteSpace(oldJointNo) || string.IsNullOrWhiteSpace(newJointNo) + || string.Equals(oldJointNo, newJointNo, StringComparison.Ordinal)) + { + return; + } + + Model.AttachFile attachFile = db.AttachFile.FirstOrDefault(x => + x.ToKeyId == isoId && x.MenuId == Const.HJGL_PipelineManageMenuId); + if (attachFile == null || string.IsNullOrWhiteSpace(attachFile.AttachSource)) + { + return; + } + + List attachFileIds; + try + { + attachFileIds = JArray.Parse(attachFile.AttachSource) + .OfType() + .Select(x => x.Value("id")) + .Where(x => !string.IsNullOrWhiteSpace(x)) + .Distinct() + .ToList(); + } + catch (JsonException) + { + return; + } + + var drawingInfos = db.HJGL_DrawingInfo + .Where(x => attachFileIds.Contains(x.AttachFileId)) + .ToList(); + + foreach (Model.HJGL_DrawingInfo drawingInfo in drawingInfos) + { + if (string.IsNullOrWhiteSpace(drawingInfo.DrawingJson)) + { + continue; + } + + try + { + string drawingJson = UpdateDrawingJson(drawingInfo.DrawingJson, oldJointNo, newJointNo); + if (drawingJson != null) + { + drawingInfo.DrawingJson = drawingJson; + } + } + catch (JsonException) + { + // 单张图纸 JSON 异常时跳过,不影响焊口信息更新。 + } + } + } + + private static string UpdateDrawingJson(string drawingJson, string oldJointNo, string newJointNo) + { + JObject drawing = JsonConvert.DeserializeObject(drawingJson); + JObject annotations = drawing == null ? null : drawing["annotations"] as JObject; + if (annotations == null) + { + return null; + } + + JointNoParts jointNoParts = JointNoParts.Parse(newJointNo); + List matchedAnnotations = annotations.Properties() + .SelectMany(x => x.Value.OfType()) + .Where(x => string.Equals(x.Value("label"), oldJointNo, StringComparison.Ordinal)) + .ToList(); + + foreach (JObject annotation in matchedAnnotations) + { + annotation["label"] = newJointNo; + annotation["displayValue"] = JToken.FromObject(jointNoParts.DisplayValue); + + JObject settings = annotation["settings"] as JObject ?? new JObject(); + settings["prefix"] = jointNoParts.Prefix; + settings["suffix"] = jointNoParts.Suffix; + annotation["settings"] = settings; + } + + return matchedAnnotations.Count > 0 ? JsonConvert.SerializeObject(drawing) : null; + } + + private sealed class JointNoParts + { + public string Prefix { get; private set; } + + public object DisplayValue { get; private set; } + + public string Suffix { get; private set; } + + public static JointNoParts Parse(string jointNo) + { + Match match = JointNoRegex.Match(jointNo); + if (!match.Success) + { + return new JointNoParts { Prefix = string.Empty, DisplayValue = jointNo, Suffix = string.Empty }; + } + + string number = match.Groups["number"].Value; + string integerPart = number.Split('.')[0]; + long numberValue; + decimal decimalValue; + bool hasLeadingZero = integerPart.Length > 1 && integerPart.StartsWith("0"); + object displayValue = number; + if (!hasLeadingZero && long.TryParse(number, out numberValue)) + { + displayValue = numberValue; + } + else if (!hasLeadingZero && decimal.TryParse(number, NumberStyles.AllowDecimalPoint, + CultureInfo.InvariantCulture, out decimalValue)) + { + displayValue = decimalValue; + } + + return new JointNoParts + { + Prefix = match.Groups["prefix"].Value, + DisplayValue = displayValue, + Suffix = match.Groups["suffix"].Value + }; + } + } + /// /// 新增或更新图纸标注信息,同一 AttachFileId 只保留一条记录。 /// diff --git a/HJGL_DS/BLL/HJGL/WeldingManage/HJGL_PW_JointInfoService.cs b/HJGL_DS/BLL/HJGL/WeldingManage/HJGL_PW_JointInfoService.cs index 25f999f..c13814a 100644 --- a/HJGL_DS/BLL/HJGL/WeldingManage/HJGL_PW_JointInfoService.cs +++ b/HJGL_DS/BLL/HJGL/WeldingManage/HJGL_PW_JointInfoService.cs @@ -96,6 +96,9 @@ namespace BLL Model.HJGL_PW_JointInfo newJointInfo = db.HJGL_PW_JointInfo.FirstOrDefault(e => e.JOT_ID == jointInfo.JOT_ID); if (newJointInfo != null) { + Model.HJGL_PW_JointInfo originalJointInfo = db.HJGL_PW_JointInfo.GetOriginalEntityState(newJointInfo); + string oldJointNo = originalJointInfo == null ? newJointInfo.JOT_JointNo : originalJointInfo.JOT_JointNo; + string drawingIsoId = originalJointInfo == null ? newJointInfo.ISO_ID : originalJointInfo.ISO_ID; newJointInfo.JOT_JointNo = jointInfo.JOT_JointNo; newJointInfo.DReportID = jointInfo.DReportID; newJointInfo.ISO_ID = jointInfo.ISO_ID; @@ -138,6 +141,7 @@ namespace BLL newJointInfo.PressureTestPackageNo = jointInfo.PressureTestPackageNo; newJointInfo.IsGold = jointInfo.IsGold; + DrawingInfoService.UpdateJointAnnotation(db, drawingIsoId, oldJointNo, newJointInfo.JOT_JointNo); db.SubmitChanges(); } } @@ -501,15 +505,24 @@ namespace BLL if (operateState == Const.Delete || jointAttribute != "固定") { Model.HJGL_PW_JointInfo deleteJointInfo = db.HJGL_PW_JointInfo.FirstOrDefault(e => e.JOT_ID == jotId); - if (deleteJointInfo.JOT_JointNo.Last() == 'G') + if (deleteJointInfo != null && !string.IsNullOrEmpty(deleteJointInfo.JOT_JointNo) + && deleteJointInfo.JOT_JointNo.Last() == 'G') { + string oldJointNo = deleteJointInfo.JOT_JointNo; deleteJointInfo.JOT_JointNo = deleteJointInfo.JOT_JointNo.Substring(0, deleteJointInfo.JOT_JointNo.Length - 1); + DrawingInfoService.UpdateJointAnnotation(db, deleteJointInfo.ISO_ID, oldJointNo, deleteJointInfo.JOT_JointNo); db.SubmitChanges(); } } else { Model.HJGL_PW_JointInfo addJointInfo = db.HJGL_PW_JointInfo.FirstOrDefault(e => e.JOT_ID == jotId); + if (addJointInfo == null || string.IsNullOrEmpty(addJointInfo.JOT_JointNo)) + { + return; + } + + string oldJointNo = addJointInfo.JOT_JointNo; if (addJointInfo.JOT_JointNo.Last() != 'G') { addJointInfo.JOT_JointNo += "G"; @@ -518,6 +531,7 @@ namespace BLL { addJointInfo.JOT_JointNo += "H"; } + DrawingInfoService.UpdateJointAnnotation(db, addJointInfo.ISO_ID, oldJointNo, addJointInfo.JOT_JointNo); db.SubmitChanges(); } } diff --git a/HJGL_DS/FineUIPro.Web/HJGL/JoinMarking/PDFShow.aspx b/HJGL_DS/FineUIPro.Web/HJGL/JoinMarking/PDFShow.aspx index 51e8e6a..191461e 100644 --- a/HJGL_DS/FineUIPro.Web/HJGL/JoinMarking/PDFShow.aspx +++ b/HJGL_DS/FineUIPro.Web/HJGL/JoinMarking/PDFShow.aspx @@ -6,12 +6,12 @@ - + - +
diff --git a/HJGL_DS/FineUIPro.Web/HJGL/JoinMarking/assets/viewer-C4q9fMuF.js b/HJGL_DS/FineUIPro.Web/HJGL/JoinMarking/assets/viewer-C4q9fMuF.js deleted file mode 100644 index 8f9e0a8..0000000 --- a/HJGL_DS/FineUIPro.Web/HJGL/JoinMarking/assets/viewer-C4q9fMuF.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as e,r as t,m as a,p as l,E as n,c as o,o as i,b as r,d as s,n as u,t as c,e as d,l as v,v as f,f as y,q as p,P as m,u as g,x as b,C as h,D as x}from"./styles-G88NglGL.js";import"./pdfjs-DXqArq6h.js";import"./pdf-lib-AfLQbX6n.js";const S={class:"viewer-container"},w={class:"viewer-main"},k={class:"controls"},_=["disabled"],D={style:{"min-width":"54px","text-align":"center"}},T=["max"],J={style:{"margin-left":"4px"}},P={key:0,style:{display:"flex","align-items":"center",gap:"12px","margin-left":"8px","font-size":"12px",color:"#6b7280"}},z={class:"viewer"};x(e({__name:"ViewerApp",setup(e){const x=t(null),C=t(null),F=t(0),I=t(1),O=t(1),R=t(null),A=t(""),E=t({}),N=t(!1);let L=null;const M=t({startNumber:1,increment:1,prefix:"",suffix:"",fontSize:10,borderStyle:"none",annotationStyle:"circle-outline"});let B=null;const H=t({show:!1,message:"",type:"success"});let U=null;function W(e,t="success"){H.value={show:!0,message:e,type:t},clearTimeout(U),U=setTimeout(()=>{H.value.show=!1},2500)}const j=t(null),V=t(100),$=t(1),Y=a(()=>{const e=null!==j.value?j.value:$.value;return Math.round(100*e)});function Z(e){C.value=e.pdf,F.value=e.numPages,I.value=1,O.value=1,ie&&R.value&&h(()=>{R.value.setAnnotations(ie),h(()=>{R.value&&R.value.renderPage&&R.value.renderPage(I.value)}),W("标注数据已加载"),ie=null})}function q(e){$.value=e}function G(e){j.value=e,V.value=Math.round(100*e)}function K(){j.value=+V.value/100}async function Q(e){if(e&&e.trim())try{const t=await fetch(e);if(!t.ok)throw new Error(`获取失败: ${t.status}`);const a=await t.blob(),l=new FileReader;l.onload=e=>{const t=e.target.result;R.value?(R.value.setTemporaryImage(t,400),W("点击PDF上要放置图片的位置, 按ESC取消")):W("请先加载PDF","error")},l.onerror=()=>{W("读取图片数据失败","error")},l.readAsDataURL(a)}catch(t){console.error("导入图片错误:",t),W("导入图片失败: "+t.message,"error")}else W("图片URL为空","error")}async function X(){const e=document.getElementById("imgurl1"),t=e?.value?.trim();t?await Q(t):W("未找到图片地址1","error")}async function ee(){const e=document.getElementById("imgurl2"),t=e?.value?.trim();t?await Q(t):W("未找到图片地址2","error")}function te(){if(!R.value||!C.value)return void W("请先加载PDF","error");const e=document.getElementById("annotionData");if(!e||!e.value||!e.value.trim())return void W("未找到焊口数据","error");let t;try{const a=JSON.parse(e.value);t=Array.isArray(a)?a:a?.annotations&&"object"==typeof a.annotations?Object.entries(a.annotations).flatMap(([e,t])=>Array.isArray(t)?t.map(t=>({...t,page:t.page??Number(e)})):[]):null}catch(a){return void W("焊口数据格式错误","error")}if(t&&0!==t.length)try{const e=function(e){const t=document.createElement("canvas"),a=t.getContext("2d"),l=[{key:"index",label:"序号",width:50},{key:"JOT_JointNo",label:"焊口编号",width:100},{key:"WED_Code",label:"焊工代号",width:90},{key:"JOT_Location",label:"焊接位置",width:80},{key:"JOT_WeldDate",label:"焊接日期",width:100},{key:"DetectionTypeCode",label:"检测类型",width:80},{key:"IsRepair",label:"是否返修",width:70},{key:"IsHotProcess",label:"是否热处理",width:80},{key:"JOT_JointStatus",label:"焊口状态",width:80}],n=32,o=36,i=l.reduce((e,t)=>e+t.width,0)+16,r=o+n*e.length+16;t.width=2*i,t.height=2*r,t.style.width=i+"px",t.style.height=r+"px",a.scale(2,2),a.fillStyle="#ffffff",a.fillRect(0,0,i,r);const s=i-16;a.fillStyle="#e8edf2",a.fillRect(8,8,s,o),a.fillStyle="#1e3a5f",a.font='bold 14px "Microsoft YaHei", "SimHei", sans-serif',a.textAlign="center",a.textBaseline="middle";let u=8;for(const c of l)a.fillText(c.label,u+c.width/2,26),u+=c.width;a.font='13px "Microsoft YaHei", "SimHei", sans-serif';for(let c=0;cn&&i.length>1;)i=i.slice(0,-1);i!==l&&(i+="…"),a.fillText(i,u+e.width/2,o+16),u+=e.width}}a.strokeStyle="#c0c8d4",a.lineWidth=1,a.strokeRect(8,8,s,o+n*e.length);for(let c=0;c<=e.length;c++){const e=44+c*n;a.beginPath(),a.moveTo(8,e),a.lineTo(8+s,e),a.stroke()}u=8;for(let c=0;ce+t,0),o=36;t.width=2*n,t.height=232,t.style.width=n+"px",t.style.height="116px",a.scale(2,2),a.clearRect(0,0,n,116),a.strokeStyle="#000000",a.lineWidth=1.5,a.strokeRect(0,0,n,o),a.fillStyle="#000000",a.font='bold 14px "Microsoft YaHei", "SimHei", sans-serif',a.textAlign="center",a.textBaseline="middle",a.fillText(e,n/2,18);const i=["编制人","审核人","日期"];let r=0;for(let s=0;s<3;s++)a.strokeRect(r,36,l[s],o),a.fillStyle="#000000",a.font='bold 14px "Microsoft YaHei", "SimHei", sans-serif',a.textAlign="center",a.textBaseline="middle",a.fillText(i[s],r+l[s]/2,54),r+=l[s];r=0;for(let s=0;s<3;s++)a.strokeRect(r,72,l[s],44),r+=l[s];return t.toDataURL("image/png")}(t);R.value.setTemporaryImage(e,360),W("点击PDF上要放置签名的位置, 按ESC取消")}catch(a){console.error("生成签名表格失败:",a),W("生成签名表格失败: "+a.message,"error")}}function le(e){const t=I.value;E.value[t]||(E.value[t]=[]),E.value[t].push(e),R.value&&R.value.setImages(E.value),W("图片已放置")}function ne(){W("已取消图片放置")}function oe(e){E.value[e.page]=e.images,W("图片已删除")}let ie=null;function re(e,t="circle-outline"){const a={};for(const l in e||{}){const n=Array.isArray(e[l])?e[l]:[];a[l]=n.map(e=>{const a=e?.borderStyle??e?.settings?.borderStyle??"none",l=e?.fontSize??e?.settings?.fontSize??10,n=e?.annotationStyle??e?.settings?.annotationStyle??t;return{...e,displayValue:e?.displayValue??e?.label??"",style:e?.style??a,borderStyle:a,annotationStyle:n,fontSize:l,settings:{...e?.settings,prefix:e?.settings?.prefix??"",suffix:e?.settings?.suffix??"",fontSize:l,borderStyle:a,annotationStyle:n}}})}return a}function se(e){if(e&&e.trim())try{const t=JSON.parse(e);let a={};if(Array.isArray(t)){const e=t.map((e,t)=>{const a=e.page||"1",l=e.borderStyle||e.border_style||M.value.borderStyle||"none",n=e.fontSize??e.font_size??M.value.fontSize??10,o=e.annotationStyle||e.annotation_style||M.value.annotationStyle||"circle-outline";return{page:a,annotation:{x:parseFloat(e.x)||0,y:parseFloat(e.y)||0,x2:parseFloat(e.x2)||0,y2:parseFloat(e.y2)||0,displayValue:e.JOT_JointNo||t+1,label:e.JOT_JointNo||"",text:e.JOT_JointNo||"",style:l,borderStyle:l,fontSize:n,annotationStyle:o,JOT_ID:e.JOT_ID||"",JOT_JointNo:e.JOT_JointNo||"",WED_Code:e.WED_Code||null,JOT_Location:e.JOT_Location||"",JOT_WeldDate:e.JOT_WeldDate||null,DetectionTypeCode:e.DetectionTypeCode||"/",IsRepair:e.IsRepair||"/",IsHotProcess:e.IsHotProcess||"/",JOT_JointStatus:e.JOT_JointStatus||"",settings:{prefix:"",suffix:"",fontSize:n,borderStyle:l,annotationStyle:o}}}});for(const t of e)a[t.page]||(a[t.page]=[]),a[t.page].push(t.annotation);if(t.length>0&&t[0].JOT_JointNo){const e=t[0].JOT_JointNo.match(/^([A-Za-z]*)([0-9]+)([A-Za-z]*)$/);e&&(M.value.prefix=e[1],M.value.suffix=e[3])}}else{if(!t.annotations)return void console.warn("annotionData: 无法识别的数据格式");{const e=t.globalSettings?.annotationStyle||M.value.annotationStyle||"circle-outline";if(a=re(t.annotations,e),t.globalSettings){const e=t.globalSettings;M.value={startNumber:e.startNumber??1,increment:e.increment??1,prefix:e.prefix??"",suffix:e.suffix??"",fontSize:e.fontSize??e.font_size??10,borderStyle:e.borderStyle??e.border_style??"none",annotationStyle:e.annotationStyle??e.annotation_style??"circle-outline"}}else(t.fontSize||t.borderStyle||t.annotationStyle)&&(M.value={...M.value,fontSize:t.fontSize??t.font_size??M.value.fontSize??10,borderStyle:t.borderStyle??t.border_style??M.value.borderStyle??"none",annotationStyle:t.annotationStyle??t.annotation_style??M.value.annotationStyle??"circle-outline"})}}if(R.value&&C.value){const e=re(a,M.value.annotationStyle||"circle-outline");R.value.setAnnotations(e),h(()=>{R.value&&R.value.renderPage&&R.value.renderPage(I.value)}),W("标注数据已加载")}else ie=re(a,M.value.annotationStyle||"circle-outline");console.log("annotionData 解析成功,页面数:",Object.keys(a).length)}catch(t){console.error("annotionData 解析失败:",t)}}return l(()=>{const e=document.getElementById("hdpdfurl");let t=null;e&&e.value&&e.value.trim()&&(t=e.value.trim());const a=new URLSearchParams(window.location.search).get("url");a&&(t=a),t&&async function(e){if(e){W("正在加载PDF...");try{const a=await fetch(e);if(!a.ok)throw new Error(`加载失败: ${a.status} ${a.statusText}`);const l=await a.arrayBuffer(),n=new Blob([l],{type:"application/pdf"});L=l;let o="online.pdf";try{const t=new URL(e).pathname.split("/"),a=t[t.length-1];a&&a.includes(".pdf")&&(o=decodeURIComponent(a))}catch(t){}const i=new File([n],o,{type:"application/pdf"});x.value=i,A.value=o,I.value=1,O.value=1,j.value=1,V.value=100,W("PDF加载成功")}catch(a){console.error("Failed to load PDF from URL:",a),W("加载PDF失败: "+a.message,"error")}}}(t),function(){const e=document.getElementById("annotionData");e&&(e.value&&e.value.trim()&&se(e.value),B=new MutationObserver(t=>{for(const a of t)"attributes"===a.type&&"value"===a.attributeName&&se(e.getAttribute("value"))}),B.observe(e,{attributes:!0,attributeFilter:["value"]}),e.addEventListener("input",()=>se(e.value)),e.addEventListener("change",()=>se(e.value)))}()}),n(()=>{B&&(B.disconnect(),B=null)}),(e,t)=>(i(),o("div",S,[H.value.show?(i(),o("div",{key:0,style:u({position:"fixed",top:"20px",right:"20px",padding:"12px 16px",background:"success"===H.value.type?"#d1fae5":"#fee2e2",color:"success"===H.value.type?"#065f46":"#991b1b",borderRadius:"4px",boxShadow:"0 4px 12px rgba(0,0,0,0.15)",zIndex:9999,animation:"slideIn 0.3s ease-out",fontSize:"14px",fontWeight:"500"})},c(H.value.message),5)):r("",!0),s("div",w,[s("div",k,[s("div",{class:"btn btn-secondary",onClick:X},"图片导入1"),s("div",{class:"btn btn-secondary",onClick:ee},"图片导入2"),s("div",{class:"btn btn-primary",onClick:te},"焊口表格"),s("div",{class:"btn btn-primary",onClick:ae},"添加签名"),s("div",{class:v(["btn",{"btn-primary":N.value,"btn-secondary":!N.value,disabled:!C.value}]),onClick:t[0]||(t[0]=e=>!C.value||(N.value=!N.value,void W(N.value?"已显示所有焊口数据":"已隐藏焊口数据"))),style:{display:"none"}},c(N.value?"隐藏焊口数据":"焊口数据展示"),3),s("div",{class:v(["btn btn-success",{disabled:!C.value}]),onClick:t[1]||(t[1]=e=>!C.value||async function(){if(L&&R.value)try{const e=R.value.getAnnotations(),t=R.value.getPageRotations(),a=await g(L,e,E.value,{startNumber:M.value.startNumber,increment:M.value.increment,prefix:M.value.prefix,suffix:M.value.suffix,fontSize:M.value.fontSize,borderStyle:M.value.borderStyle,annotationStyle:M.value.annotationStyle},t),l=(A.value||`annotated_${Date.now()}`).replace(/\.[^.]+$/,"");b(a,`${l}.pdf`),W("PDF已生成并下载")}catch(e){console.error("Failed to generate PDF:",e),W("生成PDF失败: "+e.message,"error")}else W("请先打开PDF文件","error")}())},"保存PDF",2),t[10]||(t[10]=s("div",{style:{width:"1px",background:"#e5e7eb",height:"24px",margin:"0 8px"}},null,-1)),s("div",{class:v(["btn",{disabled:!C.value||I.value<=1}]),onClick:t[2]||(t[2]=e=>!(!C.value||I.value<=1)&&void(I.value>1&&(I.value--,O.value=I.value)))},"上一页",2),s("div",{class:v(["btn",{disabled:!C.value||I.value>=F.value}]),onClick:t[3]||(t[3]=e=>!(!C.value||I.value>=F.value)&&void(I.value!C.value||(null===j.value&&(j.value=$.value),j.value=Math.max(.5,+(j.value/1.2).toFixed(2)),void(V.value=Math.round(100*j.value))))},"-",2),s("div",{class:v(["btn",{disabled:!C.value}]),onClick:t[5]||(t[5]=e=>!C.value||(null===j.value&&(j.value=$.value),j.value=Math.min(3,+(1.2*j.value).toFixed(2)),void(V.value=Math.round(100*j.value))))},"+",2),d(s("input",{"onUpdate:modelValue":t[6]||(t[6]=e=>V.value=e),onInput:K,type:"range",min:"50",max:"300",style:{width:"140px"},disabled:!C.value},null,40,_),[[f,V.value,void 0,{number:!0}]]),s("div",D,c(Y.value)+"%",1),t[12]||(t[12]=s("div",{style:{width:"1px",background:"#e5e7eb",height:"24px",margin:"0 8px"}},null,-1)),t[13]||(t[13]=s("div",{style:{"margin-left":"8px"}},"第",-1)),d(s("input",{type:"number","onUpdate:modelValue":t[7]||(t[7]=e=>O.value=e),min:1,max:F.value,style:{width:"80px","margin-left":"4px"}},null,8,T),[[f,O.value,void 0,{number:!0}]]),s("div",{class:v(["btn",{disabled:!C.value}]),onClick:t[8]||(t[8]=e=>!C.value||void(O.value>=1&&O.value<=F.value&&(I.value=O.value)))},"跳转",2),s("div",J,"/ "+c(F.value||0)+" 页",1),t[14]||(t[14]=s("div",{style:{width:"1px",background:"#e5e7eb",height:"24px",margin:"0 8px"}},null,-1)),A.value?(i(),o("div",P,[s("div",null,[t[9]||(t[9]=s("strong",null,"文件:",-1)),y(" "+c(A.value),1)])])):r("",!0),t[15]||(t[15]=s("div",{style:{flex:"1"}},null,-1))]),s("div",z,[p(m,{file:x.value,page:I.value,scale:j.value,"annotation-mode":!1,"read-only":!0,"border-style":M.value.borderStyle,"annotation-style":M.value.annotationStyle,"start-number":M.value.startNumber,increment:M.value.increment,prefix:M.value.prefix,suffix:M.value.suffix,"font-size":M.value.fontSize,"show-all-weld-info":N.value,ref_key:"pdfViewerRef",ref:R,onLoaded:Z,onScaleChanged:q,onWheelZoom:G,onPlaceImage:le,onImagePlacingCancelled:ne,onImageDeleted:oe},null,8,["file","page","scale","border-style","annotation-style","start-number","increment","prefix","suffix","font-size","show-all-weld-info"])])])]))}},[["__scopeId","data-v-7710504d"]])).mount("#app"); diff --git a/HJGL_DS/FineUIPro.Web/HJGL/JoinMarking/assets/viewer-D3iNrO9k.js b/HJGL_DS/FineUIPro.Web/HJGL/JoinMarking/assets/viewer-D3iNrO9k.js new file mode 100644 index 0000000..db82a4d --- /dev/null +++ b/HJGL_DS/FineUIPro.Web/HJGL/JoinMarking/assets/viewer-D3iNrO9k.js @@ -0,0 +1 @@ +import{_ as e,r as t,m as l,p as a,E as n,c as o,o as i,b as s,d as r,n as u,t as c,e as v,l as d,v as f,f as y,q as p,P as g,u as m,x as b,C as x,D as h}from"./styles-G88NglGL.js";import"./pdfjs-DXqArq6h.js";import"./pdf-lib-AfLQbX6n.js";const S={class:"viewer-container"},w={class:"viewer-main"},k={class:"controls"},_=["disabled"],T={style:{"min-width":"54px","text-align":"center"}},D=["max"],J={style:{"margin-left":"4px"}},z={key:0,style:{display:"flex","align-items":"center",gap:"12px","margin-left":"8px","font-size":"12px",color:"#6b7280"}},P={class:"viewer"};h(e({__name:"ViewerApp",setup(e){const h=t(null),O=t(null),C=t(0),F=t(1),I=t(1),R=t(null),A=t(""),N=t({}),E=t(!1);let M=null;const H=t({startNumber:1,increment:1,prefix:"",suffix:"",fontSize:10,borderStyle:"none",annotationStyle:"circle-outline"});let L=null;const W=t({show:!1,message:"",type:"success"});let B=null;function U(e,t="success"){W.value={show:!0,message:e,type:t},clearTimeout(B),B=setTimeout(()=>{W.value.show=!1},2500)}const j=t(null),V=t(100),$=t(1),Y=l(()=>{const e=null!==j.value?j.value:$.value;return Math.round(100*e)});function Z(e){O.value=e.pdf,C.value=e.numPages,F.value=1,I.value=1,ae&&R.value&&x(()=>{R.value.setAnnotations(ae),x(()=>{R.value&&R.value.renderPage&&R.value.renderPage(F.value)}),U("标注数据已加载"),ae=null})}function q(e){$.value=e}function G(e){j.value=e,V.value=Math.round(100*e)}function K(){j.value=+V.value/100}function Q(){if(!R.value||!O.value)return void U("请先加载PDF","error");const e=document.getElementById("annotionData");if(!e||!e.value||!e.value.trim())return void U("未找到焊口数据","error");let t;try{const l=JSON.parse(e.value);t=Array.isArray(l)?l:l?.annotations&&"object"==typeof l.annotations?Object.entries(l.annotations).flatMap(([e,t])=>Array.isArray(t)?t.map(t=>({...t,page:t.page??Number(e)})):[]):null}catch(l){return void U("焊口数据格式错误","error")}if(t&&0!==t.length)try{const e=function(e){const t=document.createElement("canvas"),l=t.getContext("2d"),a=[{key:"index",label:"序号",width:50},{key:"JOT_JointNo",label:"焊口编号",width:100},{key:"WED_Code",label:"焊工代号",width:90},{key:"JOT_Location",label:"焊接位置",width:80},{key:"JOT_WeldDate",label:"焊接日期",width:100},{key:"DetectionTypeCode",label:"检测类型",width:80},{key:"IsRepair",label:"是否返修",width:70},{key:"IsHotProcess",label:"是否热处理",width:80},{key:"JOT_JointStatus",label:"焊口状态",width:80}],n=32,o=36,i=a.reduce((e,t)=>e+t.width,0)+16,s=o+n*e.length+16;t.width=2*i,t.height=2*s,t.style.width=i+"px",t.style.height=s+"px",l.scale(2,2),l.fillStyle="#ffffff",l.fillRect(0,0,i,s);const r=i-16;l.fillStyle="#e8edf2",l.fillRect(8,8,r,o),l.fillStyle="#1e3a5f",l.font='bold 14px "Microsoft YaHei", "SimHei", sans-serif',l.textAlign="center",l.textBaseline="middle";let u=8;for(const c of a)l.fillText(c.label,u+c.width/2,26),u+=c.width;l.font='13px "Microsoft YaHei", "SimHei", sans-serif';for(let c=0;cn&&i.length>1;)i=i.slice(0,-1);i!==a&&(i+="…"),l.fillText(i,u+e.width/2,o+16),u+=e.width}}l.strokeStyle="#c0c8d4",l.lineWidth=1,l.strokeRect(8,8,r,o+n*e.length);for(let c=0;c<=e.length;c++){const e=44+c*n;l.beginPath(),l.moveTo(8,e),l.lineTo(8+r,e),l.stroke()}u=8;for(let c=0;ce+t,0),o=36;t.width=2*n,t.height=232,t.style.width=n+"px",t.style.height="116px",l.scale(2,2),l.clearRect(0,0,n,116),l.strokeStyle="#000000",l.lineWidth=1.5,l.strokeRect(0,0,n,o),l.fillStyle="#000000",l.font='bold 14px "Microsoft YaHei", "SimHei", sans-serif',l.textAlign="center",l.textBaseline="middle",l.fillText(e,n/2,18);const i=["编制人","审核人","日期"];let s=0;for(let r=0;r<3;r++)l.strokeRect(s,36,a[r],o),l.fillStyle="#000000",l.font='bold 14px "Microsoft YaHei", "SimHei", sans-serif',l.textAlign="center",l.textBaseline="middle",l.fillText(i[r],s+a[r]/2,54),s+=a[r];s=0;for(let r=0;r<3;r++)l.strokeRect(s,72,a[r],44),s+=a[r];return t.toDataURL("image/png")}(t);R.value.setTemporaryImage(e,360),U("点击PDF上要放置签名的位置, 按ESC取消")}catch(l){console.error("生成签名表格失败:",l),U("生成签名表格失败: "+l.message,"error")}}function ee(e){const t=F.value;N.value[t]||(N.value[t]=[]),N.value[t].push(e),R.value&&R.value.setImages(N.value),U("图片已放置")}function te(){U("已取消图片放置")}function le(e){N.value[e.page]=e.images,U("图片已删除")}let ae=null;function ne(e,t="circle-outline"){const l={};for(const a in e||{}){const n=Array.isArray(e[a])?e[a]:[];l[a]=n.map(e=>{const l=e?.borderStyle??e?.settings?.borderStyle??"none",a=e?.fontSize??e?.settings?.fontSize??10,n=e?.annotationStyle??e?.settings?.annotationStyle??t;return{...e,displayValue:e?.displayValue??e?.label??"",style:e?.style??l,borderStyle:l,annotationStyle:n,fontSize:a,settings:{...e?.settings,prefix:e?.settings?.prefix??"",suffix:e?.settings?.suffix??"",fontSize:a,borderStyle:l,annotationStyle:n}}})}return l}function oe(e){if(e&&e.trim())try{const t=JSON.parse(e);let l={};if(Array.isArray(t)){const e=t.map((e,t)=>{const l=e.page||"1",a=e.borderStyle||e.border_style||H.value.borderStyle||"none",n=e.fontSize??e.font_size??H.value.fontSize??10,o=e.annotationStyle||e.annotation_style||H.value.annotationStyle||"circle-outline";return{page:l,annotation:{x:parseFloat(e.x)||0,y:parseFloat(e.y)||0,x2:parseFloat(e.x2)||0,y2:parseFloat(e.y2)||0,displayValue:e.JOT_JointNo||t+1,label:e.JOT_JointNo||"",text:e.JOT_JointNo||"",style:a,borderStyle:a,fontSize:n,annotationStyle:o,JOT_ID:e.JOT_ID||"",JOT_JointNo:e.JOT_JointNo||"",WED_Code:e.WED_Code||null,JOT_Location:e.JOT_Location||"",JOT_WeldDate:e.JOT_WeldDate||null,DetectionTypeCode:e.DetectionTypeCode||"/",IsRepair:e.IsRepair||"/",IsHotProcess:e.IsHotProcess||"/",JOT_JointStatus:e.JOT_JointStatus||"",settings:{prefix:"",suffix:"",fontSize:n,borderStyle:a,annotationStyle:o}}}});for(const t of e)l[t.page]||(l[t.page]=[]),l[t.page].push(t.annotation);if(t.length>0&&t[0].JOT_JointNo){const e=t[0].JOT_JointNo.match(/^([A-Za-z]*)([0-9]+)([A-Za-z]*)$/);e&&(H.value.prefix=e[1],H.value.suffix=e[3])}}else{if(!t.annotations)return void console.warn("annotionData: 无法识别的数据格式");{const e=t.globalSettings?.annotationStyle||H.value.annotationStyle||"circle-outline";if(l=ne(t.annotations,e),t.globalSettings){const e=t.globalSettings;H.value={startNumber:e.startNumber??1,increment:e.increment??1,prefix:e.prefix??"",suffix:e.suffix??"",fontSize:e.fontSize??e.font_size??10,borderStyle:e.borderStyle??e.border_style??"none",annotationStyle:e.annotationStyle??e.annotation_style??"circle-outline"}}else(t.fontSize||t.borderStyle||t.annotationStyle)&&(H.value={...H.value,fontSize:t.fontSize??t.font_size??H.value.fontSize??10,borderStyle:t.borderStyle??t.border_style??H.value.borderStyle??"none",annotationStyle:t.annotationStyle??t.annotation_style??H.value.annotationStyle??"circle-outline"})}}if(R.value&&O.value){const e=ne(l,H.value.annotationStyle||"circle-outline");R.value.setAnnotations(e),x(()=>{R.value&&R.value.renderPage&&R.value.renderPage(F.value)}),U("标注数据已加载")}else ae=ne(l,H.value.annotationStyle||"circle-outline");console.log("annotionData 解析成功,页面数:",Object.keys(l).length)}catch(t){console.error("annotionData 解析失败:",t)}}return a(()=>{const e=document.getElementById("hdpdfurl");let t=null;e&&e.value&&e.value.trim()&&(t=e.value.trim());const l=new URLSearchParams(window.location.search).get("url");l&&(t=l),t&&async function(e){if(e){U("正在加载PDF...");try{const l=await fetch(e);if(!l.ok)throw new Error(`加载失败: ${l.status} ${l.statusText}`);const a=await l.arrayBuffer(),n=new Blob([a],{type:"application/pdf"});M=a;let o="online.pdf";try{const t=new URL(e).pathname.split("/"),l=t[t.length-1];l&&l.includes(".pdf")&&(o=decodeURIComponent(l))}catch(t){}const i=new File([n],o,{type:"application/pdf"});h.value=i,A.value=o,F.value=1,I.value=1,j.value=1,V.value=100,U("PDF加载成功")}catch(l){console.error("Failed to load PDF from URL:",l),U("加载PDF失败: "+l.message,"error")}}}(t),function(){const e=document.getElementById("annotionData");e&&(e.value&&e.value.trim()&&oe(e.value),L=new MutationObserver(t=>{for(const l of t)"attributes"===l.type&&"value"===l.attributeName&&oe(e.getAttribute("value"))}),L.observe(e,{attributes:!0,attributeFilter:["value"]}),e.addEventListener("input",()=>oe(e.value)),e.addEventListener("change",()=>oe(e.value)))}()}),n(()=>{L&&(L.disconnect(),L=null)}),(e,t)=>(i(),o("div",S,[W.value.show?(i(),o("div",{key:0,style:u({position:"fixed",top:"20px",right:"20px",padding:"12px 16px",background:"success"===W.value.type?"#d1fae5":"#fee2e2",color:"success"===W.value.type?"#065f46":"#991b1b",borderRadius:"4px",boxShadow:"0 4px 12px rgba(0,0,0,0.15)",zIndex:9999,animation:"slideIn 0.3s ease-out",fontSize:"14px",fontWeight:"500"})},c(W.value.message),5)):s("",!0),r("div",w,[r("div",k,[r("div",{class:"btn btn-primary",onClick:Q},"焊口表格"),r("div",{class:"btn btn-primary",onClick:X},"添加签名"),r("div",{class:d(["btn",{"btn-primary":E.value,"btn-secondary":!E.value,disabled:!O.value}]),onClick:t[0]||(t[0]=e=>!O.value||(E.value=!E.value,void U(E.value?"已显示所有焊口数据":"已隐藏焊口数据"))),style:{display:"none"}},c(E.value?"隐藏焊口数据":"焊口数据展示"),3),r("div",{class:d(["btn btn-success",{disabled:!O.value}]),onClick:t[1]||(t[1]=e=>!O.value||async function(){if(M&&R.value)try{const e=R.value.getAnnotations(),t=R.value.getPageRotations(),l=await m(M,e,N.value,{startNumber:H.value.startNumber,increment:H.value.increment,prefix:H.value.prefix,suffix:H.value.suffix,fontSize:H.value.fontSize,borderStyle:H.value.borderStyle,annotationStyle:H.value.annotationStyle},t),a=(A.value||`annotated_${Date.now()}`).replace(/\.[^.]+$/,"");b(l,`${a}.pdf`),U("PDF已生成并下载")}catch(e){console.error("Failed to generate PDF:",e),U("生成PDF失败: "+e.message,"error")}else U("请先打开PDF文件","error")}())},"保存PDF",2),t[10]||(t[10]=r("div",{style:{width:"1px",background:"#e5e7eb",height:"24px",margin:"0 8px"}},null,-1)),r("div",{class:d(["btn",{disabled:!O.value||F.value<=1}]),onClick:t[2]||(t[2]=e=>!(!O.value||F.value<=1)&&void(F.value>1&&(F.value--,I.value=F.value)))},"上一页",2),r("div",{class:d(["btn",{disabled:!O.value||F.value>=C.value}]),onClick:t[3]||(t[3]=e=>!(!O.value||F.value>=C.value)&&void(F.value!O.value||(null===j.value&&(j.value=$.value),j.value=Math.max(.5,+(j.value/1.2).toFixed(2)),void(V.value=Math.round(100*j.value))))},"-",2),r("div",{class:d(["btn",{disabled:!O.value}]),onClick:t[5]||(t[5]=e=>!O.value||(null===j.value&&(j.value=$.value),j.value=Math.min(3,+(1.2*j.value).toFixed(2)),void(V.value=Math.round(100*j.value))))},"+",2),v(r("input",{"onUpdate:modelValue":t[6]||(t[6]=e=>V.value=e),onInput:K,type:"range",min:"50",max:"300",style:{width:"140px"},disabled:!O.value},null,40,_),[[f,V.value,void 0,{number:!0}]]),r("div",T,c(Y.value)+"%",1),t[12]||(t[12]=r("div",{style:{width:"1px",background:"#e5e7eb",height:"24px",margin:"0 8px"}},null,-1)),t[13]||(t[13]=r("div",{style:{"margin-left":"8px"}},"第",-1)),v(r("input",{type:"number","onUpdate:modelValue":t[7]||(t[7]=e=>I.value=e),min:1,max:C.value,style:{width:"80px","margin-left":"4px"}},null,8,D),[[f,I.value,void 0,{number:!0}]]),r("div",{class:d(["btn",{disabled:!O.value}]),onClick:t[8]||(t[8]=e=>!O.value||void(I.value>=1&&I.value<=C.value&&(F.value=I.value)))},"跳转",2),r("div",J,"/ "+c(C.value||0)+" 页",1),t[14]||(t[14]=r("div",{style:{width:"1px",background:"#e5e7eb",height:"24px",margin:"0 8px"}},null,-1)),A.value?(i(),o("div",z,[r("div",null,[t[9]||(t[9]=r("strong",null,"文件:",-1)),y(" "+c(A.value),1)])])):s("",!0),t[15]||(t[15]=r("div",{style:{flex:"1"}},null,-1))]),r("div",P,[p(g,{file:h.value,page:F.value,scale:j.value,"annotation-mode":!1,"read-only":!0,"border-style":H.value.borderStyle,"annotation-style":H.value.annotationStyle,"start-number":H.value.startNumber,increment:H.value.increment,prefix:H.value.prefix,suffix:H.value.suffix,"font-size":H.value.fontSize,"show-all-weld-info":E.value,ref_key:"pdfViewerRef",ref:R,onLoaded:Z,onScaleChanged:q,onWheelZoom:G,onPlaceImage:ee,onImagePlacingCancelled:te,onImageDeleted:le},null,8,["file","page","scale","border-style","annotation-style","start-number","increment","prefix","suffix","font-size","show-all-weld-info"])])])]))}},[["__scopeId","data-v-b1adea8b"]])).mount("#app"); diff --git a/HJGL_DS/FineUIPro.Web/HJGL/JoinMarking/assets/viewer-ieFmb7PT.css b/HJGL_DS/FineUIPro.Web/HJGL/JoinMarking/assets/viewer-ieFmb7PT.css deleted file mode 100644 index 2946c47..0000000 --- a/HJGL_DS/FineUIPro.Web/HJGL/JoinMarking/assets/viewer-ieFmb7PT.css +++ /dev/null @@ -1 +0,0 @@ -.viewer-container[data-v-7710504d]{display:flex;height:100vh;padding:12px;box-sizing:border-box}.viewer-main[data-v-7710504d]{flex:1;min-width:0;display:flex;flex-direction:column;border:1px solid var(--border);border-radius:10px;background:var(--panel);box-shadow:0 10px 30px -18px #00000059;padding:8px;box-sizing:border-box}.controls[data-v-7710504d]{flex-wrap:wrap;overflow:visible}.controls[data-v-7710504d]>*{flex-shrink:0} diff --git a/HJGL_DS/FineUIPro.Web/HJGL/JoinMarking/assets/viewer-u37LBwT8.css b/HJGL_DS/FineUIPro.Web/HJGL/JoinMarking/assets/viewer-u37LBwT8.css new file mode 100644 index 0000000..21b935d --- /dev/null +++ b/HJGL_DS/FineUIPro.Web/HJGL/JoinMarking/assets/viewer-u37LBwT8.css @@ -0,0 +1 @@ +.viewer-container[data-v-b1adea8b]{display:flex;height:100vh;padding:12px;box-sizing:border-box}.viewer-main[data-v-b1adea8b]{flex:1;min-width:0;display:flex;flex-direction:column;border:1px solid var(--border);border-radius:10px;background:var(--panel);box-shadow:0 10px 30px -18px #00000059;padding:8px;box-sizing:border-box}.controls[data-v-b1adea8b]{flex-wrap:wrap;overflow:visible}.controls[data-v-b1adea8b]>*{flex-shrink:0} diff --git a/HJGL_DS/FineUIPro.Web/HJGL/JoinMarking/viewer.html b/HJGL_DS/FineUIPro.Web/HJGL/JoinMarking/viewer.html index a6098df..79ea227 100644 --- a/HJGL_DS/FineUIPro.Web/HJGL/JoinMarking/viewer.html +++ b/HJGL_DS/FineUIPro.Web/HJGL/JoinMarking/viewer.html @@ -4,12 +4,12 @@ PDF 预览 - + - +