commit 8938e09ab7b3f0367bb1ea01232f3e4038b660f0 Author: lijh Date: Tue Mar 10 15:44:21 2026 +0800 first commit diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9491a2f --- /dev/null +++ b/.gitignore @@ -0,0 +1,363 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Oo]ut/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd \ No newline at end of file diff --git a/2018/1Interop.ZwmPicViewLib.DLL b/2018/1Interop.ZwmPicViewLib.DLL new file mode 100644 index 0000000..63110b7 Binary files /dev/null and b/2018/1Interop.ZwmPicViewLib.DLL differ diff --git a/2018/Interop.ADODB.dll b/2018/Interop.ADODB.dll new file mode 100644 index 0000000..175069b Binary files /dev/null and b/2018/Interop.ADODB.dll differ diff --git a/2018/Interop.ADOX.dll b/2018/Interop.ADOX.dll new file mode 100644 index 0000000..002f7d5 Binary files /dev/null and b/2018/Interop.ADOX.dll differ diff --git a/2018/Interop.ZWBASCALCLib.DLL b/2018/Interop.ZWBASCALCLib.DLL new file mode 100644 index 0000000..08d3de0 Binary files /dev/null and b/2018/Interop.ZWBASCALCLib.DLL differ diff --git a/2018/Interop.ZWCAD.dll b/2018/Interop.ZWCAD.dll new file mode 100644 index 0000000..5359204 Binary files /dev/null and b/2018/Interop.ZWCAD.dll differ diff --git a/2018/Interop.ZwmToolKitLib.dll b/2018/Interop.ZwmToolKitLib.dll new file mode 100644 index 0000000..7135797 Binary files /dev/null and b/2018/Interop.ZwmToolKitLib.dll differ diff --git a/2018/Office Client.zip b/2018/Office Client.zip new file mode 100644 index 0000000..62efd53 Binary files /dev/null and b/2018/Office Client.zip differ diff --git a/2018/Office Client2312.zip b/2018/Office Client2312.zip new file mode 100644 index 0000000..62efd53 Binary files /dev/null and b/2018/Office Client2312.zip differ diff --git a/2018/TcLogging.dll b/2018/TcLogging.dll new file mode 100644 index 0000000..7c41835 Binary files /dev/null and b/2018/TcLogging.dll differ diff --git a/2018/TcMemBindingv170.dll b/2018/TcMemBindingv170.dll new file mode 100644 index 0000000..69d984b Binary files /dev/null and b/2018/TcMemBindingv170.dll differ diff --git a/2018/TcMemBindingv17064.dll b/2018/TcMemBindingv17064.dll new file mode 100644 index 0000000..1a9e154 Binary files /dev/null and b/2018/TcMemBindingv17064.dll differ diff --git a/2018/TcMemNetBindingInterface.dll b/2018/TcMemNetBindingInterface.dll new file mode 100644 index 0000000..08fc512 Binary files /dev/null and b/2018/TcMemNetBindingInterface.dll differ diff --git a/2018/TcServerNetBinding.dll b/2018/TcServerNetBinding.dll new file mode 100644 index 0000000..1ca6aaf Binary files /dev/null and b/2018/TcServerNetBinding.dll differ diff --git a/2018/TcServerNetBindingInterface.dll b/2018/TcServerNetBindingInterface.dll new file mode 100644 index 0000000..078cc96 Binary files /dev/null and b/2018/TcServerNetBindingInterface.dll differ diff --git a/2018/TcSoaAdministrationLoose.dll b/2018/TcSoaAdministrationLoose.dll new file mode 100644 index 0000000..141c6a3 Binary files /dev/null and b/2018/TcSoaAdministrationLoose.dll differ diff --git a/2018/TcSoaCadLoose.dll b/2018/TcSoaCadLoose.dll new file mode 100644 index 0000000..b3dbf27 Binary files /dev/null and b/2018/TcSoaCadLoose.dll differ diff --git a/2018/TcSoaClient.dll b/2018/TcSoaClient.dll new file mode 100644 index 0000000..1edc5ae Binary files /dev/null and b/2018/TcSoaClient.dll differ diff --git a/2018/TcSoaCommon.dll b/2018/TcSoaCommon.dll new file mode 100644 index 0000000..9294178 Binary files /dev/null and b/2018/TcSoaCommon.dll differ diff --git a/2018/TcSoaCoreStrong.dll b/2018/TcSoaCoreStrong.dll new file mode 100644 index 0000000..b021d6a Binary files /dev/null and b/2018/TcSoaCoreStrong.dll differ diff --git a/2018/TcSoaFMS.dll b/2018/TcSoaFMS.dll new file mode 100644 index 0000000..dfb952c Binary files /dev/null and b/2018/TcSoaFMS.dll differ diff --git a/2018/TcSoaQueryStrong.dll b/2018/TcSoaQueryStrong.dll new file mode 100644 index 0000000..74009a8 Binary files /dev/null and b/2018/TcSoaQueryStrong.dll differ diff --git a/2018/TcSoaStrongModel.dll b/2018/TcSoaStrongModel.dll new file mode 100644 index 0000000..2e99b6b Binary files /dev/null and b/2018/TcSoaStrongModel.dll differ diff --git a/2018/ZwDatabaseMgd.dll b/2018/ZwDatabaseMgd.dll new file mode 100644 index 0000000..9881c3b Binary files /dev/null and b/2018/ZwDatabaseMgd.dll differ diff --git a/2018/ZwManaged.dll b/2018/ZwManaged.dll new file mode 100644 index 0000000..9c97c6a Binary files /dev/null and b/2018/ZwManaged.dll differ diff --git a/2018/rac_login_background13.png b/2018/rac_login_background13.png new file mode 100644 index 0000000..12c348b Binary files /dev/null and b/2018/rac_login_background13.png differ diff --git a/README.MD b/README.MD new file mode 100644 index 0000000..c8ae3aa --- /dev/null +++ b/README.MD @@ -0,0 +1,238 @@ +# 中望CAD集成配置 + +## 1. 安装 + +1. 复制集成文件夹 `Connor` 到中望CAD目录(复制整个文件夹,不是里面的内容) +2. 将`cn.net.connor.zwcadm_1.0.0.jar`复制到tc的`plugins`目录,并进行注册 +3. 将`connor_zwcad_itk.dll`复制到服务器tc的`bin`目录,并添加到首选项 + +**自动加载:** + +> 注意事项: +> +> 增加的行中所包含的命令会在图纸打开时运行,服务器上运行的CAD建议不要做自动加载的配置 + +```text +修改CAD目录下Zwcadm文件夹中的ZWCADM2020.lsp文件 +1. 自动加载dll +增加行:(command "NETLOAD" "Connor/connor_zwcadm.dll" ) +2. 从文件提取信息 +增加行:(command "KReadInfo") +KReadInfo命令,是读取图纸文件夹中info.txt文件中的标题栏信息并进行同步,用于从tc打开时同步数据 + +示例: +======================================== +(vl-load-com) + +(load "ZWCAD2020doc.lsp") +(command "NETLOAD" "Connor/connor_zwcadm.dll" ) +(command "KReadInfo") +(princ) +======================================== +``` + +**从TC打开图纸时同步属性** + +> 通过cn.net.connor.zwcadm_1.0.0.jar包将属性信息提取到中间文件,然后通过KReadInfo命令自动运行将信息提取到打开的图纸 + +需要配置首选项: + +Connor_MCAD_[版本对应的对象类型名称] + +描述:对应类型对象的版本下cad图纸打开时,按首选项配置将属性映射信息写到中间文件 + +格式:`TC属性位置.TC属性名称=图纸标题栏中的属性名称` + +示例: + +```text +首选项名称:Connor_MCAD_Item +值: +item.item_id=图样代号 +item.object_name=图样名称 +``` + +## 2. 登录 + +**CAD命令:**KLogin + +**配置:** + +> 需要修改文件:connor_zwcad.dll.config +> +> 该文件记录tc服务地址、是否输出日志以及记录上一次登录的用户 +> +> 配置以键值对的形式保存在appSettings + +```text + + + + + +``` + +其中`tc_host`对应的value是tc四层服务地址,`log_status`对应是否输出日志,`app_folder`对应集成文件夹名称 + +## 3. 保存和同步属性 + +**CAD命令:** + +1. 保存:KSaveToTC +2. 批量保存:KBatchSaveToTC +3. 更新属性:KSyncTitleFromTC +4. 更新BOM:KSyncBomViewFromTC +5. 更新BOM行:KSyncBomFromTC (从明细栏的id查找对象进行更新,无法同步bom属性) + +**首选项配置:** + +> 涉及首选项 +> +> Connor_MCAD_[标题栏或明细栏块名称] +> +> Connor_MCAD_UploadFile + +1. Connor_MCAD_[标题栏或明细栏块名称] + + 描述:配置对应标题栏块或明细栏块中从图纸到TC的属性映射关系 + + 格式:`TC属性位置.[#]TC属性名称=图纸块中的属性名称` + + TC属性位置: + + ```text + bomline, item, rev, itemmaster, revmaster + 分别对应 + bom行,对象,版本,对象主属性表单,版本主属性表单 + + 不区分大小写 + 重复的属性配置,下面的覆盖上面的,item.item_id读取时跳过空值 + + 注意:必须配置item.object_type=对象类型名称 + ``` + + TC属性名称前加#,表示从tc提取属性时,取字符串类型的真实值 + +2. Connor_MCAD_UploadFile + + 描述:配置文件上传信息 + + 格式: + + ``` + 第一行:数据集和版本的关系 + 第二行:数据集类型名称 + 第三行:数据集文件引用名称 + 第四行:(可选)FMS服务地址 + ``` + + 示例: + + ```text + IMAN_specification + SF6_dwg + SF6_dwg + http://127.0.0.1:4544 + ``` + + + + +## 4. 服务 + +**注意事项:由于服务在CAD程序中运行,如果图纸操作过程中出现提示窗,会导致进程等待用户执行操作,进而导致后面的请求无法正常进行,请注意不要出现这种情况** + +**CAD命令:** + +1. 启动服务:KStartServer +2. 关闭服务:KStopServer + +**首选项配置:** + +> 需要在文件`connor_zwcad.dll.config`中增加转PDF配置 + +```text + + + + + + + + + +``` + +`titles`:图框名称,多个用英文分号分隔,并与另外两个配置一一对应 + +`media_names`对应标题栏的打印图纸的纸张类型 + +`rotates`对应标题栏的打印图纸的的图纸方向,true表示旋转90度 + +## 5. 签名 + +**Action Handler:** Connor_CAD_Signature + +涉及首选项: + +> Connor_MCAD_Signature +> +> Connor_MCAD_UploadFile + +1. Connor_MCAD_Signature + + 描述:配置流程中版本属性与图纸标题栏属性的对应关系 + + 格式: + + ```text + 版本类型名称:格式占位符(随便写,非机械版的标题栏名称位置):标题栏属性名称1=属性位置1.属性名称1;标题栏属性名称2=属性位置2.属性名称2 + ``` + + ```text + 属性位置包含:item, rev, itemmaster, revmaster + 分别对应:对象,版本,对象主属性表单,版本主属性表单 + ``` + +2. Connor_MCAD_UploadFile + + 此首选项配置在“保存和同步属性”已进行说明 + +## 6. 转PDF + +**Action Handler:** Connor_CAD_Convert_PDF + +功能:将流程目标下版本中的图纸转为PDF + +不需要额外配置 + +## 7. 压力测试 + +**Action Handler:** Connor_CAD_Test + +功能:循环执行签名和转PDF操作,但是不进行上传,文件保存在Temp目录里类似`2580C76DDFB84762996724FBA4AD4CE6`名称的文件夹中,当CAD关闭时,循环结束 + +## 8. handler临时文件 + +首选项:Connor_MCAD_RemoveTempFile,逻辑型,单值 + +```text +true: 删除临时文件 +false:保留临时文件 +未找到首选项时默认为false,即保留临时文件 +``` + + + +### 更新日志 + +20210708 + +```text +1. 如果明细栏一个对象的数量有多个,保存到TC中后需要可进行打包解包 +2. 更新明细栏功能不需要再更新整个BOM结构了,需要实现的是当点击更新明细栏的时候,读取明细栏的item_id那个属性即代号,如果在TC中找到相应的对象则将其属性更新到明细栏其余对应的属性当中,如果发现没有填写或在TC中没找到相应的对象那么则不更新即可 + +配置文件中的attr_index的值需要改为“代号”,即itemid对应的cad明细栏属性名称 +``` + + diff --git a/connor_zwcadm.sln b/connor_zwcadm.sln new file mode 100644 index 0000000..0034bd1 --- /dev/null +++ b/connor_zwcadm.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.9.34902.65 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "connor_zwcadm", "connor_zwcadm\connor_zwcadm.csproj", "{F9F68DF3-2A14-4F45-998D-5497AC9047D8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F9F68DF3-2A14-4F45-998D-5497AC9047D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F9F68DF3-2A14-4F45-998D-5497AC9047D8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F9F68DF3-2A14-4F45-998D-5497AC9047D8}.Debug|x64.ActiveCfg = Debug|x64 + {F9F68DF3-2A14-4F45-998D-5497AC9047D8}.Debug|x64.Build.0 = Debug|x64 + {F9F68DF3-2A14-4F45-998D-5497AC9047D8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F9F68DF3-2A14-4F45-998D-5497AC9047D8}.Release|Any CPU.Build.0 = Release|Any CPU + {F9F68DF3-2A14-4F45-998D-5497AC9047D8}.Release|x64.ActiveCfg = Release|x64 + {F9F68DF3-2A14-4F45-998D-5497AC9047D8}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {DC4B2CA5-8159-4C2F-BF57-E4DE6A817F8A} + EndGlobalSection +EndGlobal diff --git a/connor_zwcadm/App.config b/connor_zwcadm/App.config new file mode 100644 index 0000000..e1551a8 --- /dev/null +++ b/connor_zwcadm/App.config @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/connor_zwcadm/Class1.cs b/connor_zwcadm/Class1.cs new file mode 100644 index 0000000..de4b723 --- /dev/null +++ b/connor_zwcadm/Class1.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace connor_zwcadm +{ + public class Class1 + { + } +} diff --git a/connor_zwcadm/KMain.cs b/connor_zwcadm/KMain.cs new file mode 100644 index 0000000..c944b4c --- /dev/null +++ b/connor_zwcadm/KMain.cs @@ -0,0 +1,348 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ZwSoft.ZwCAD.Runtime; +using ZwSoft.ZwCAD.DatabaseServices; +using ZwSoft.ZwCAD.EditorInput; +using ZwSoft.ZwCAD.ApplicationServices; +using connor_zwcadm.util; +using connor_zwcadm.commands; +using ZwSoft.ZwCAD.PlottingServices; +using connor_zwcadm.model; +using System.IO; +using Exception = System.Exception; + +[assembly: ExtensionApplication(typeof(connor_zwcadm.KMain))] +[assembly: CommandClass(typeof(connor_zwcadm.KMain))] +namespace connor_zwcadm { + class KMain : IExtensionApplication { + + public const string PREF_PROP_CONFIG_PREFIX = "Connor_MCAD_"; + public const string PREF_UPLOAD_FILE = "Connor_MCAD_UploadFile"; + + [CommandMethod("Hello")] + public void Hello() { + Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; + ed.WriteMessage("\nHello World."); + } + + [CommandMethod("KReadInfo")] + public void ReadInfo() { + CommandStart("ReadInfo"); + try { + Document doc = Application.DocumentManager.MdiActiveDocument; + if (doc == null) { + return; + } + AbstractCADCommand command = new ReadInfoCommand(doc.Name); + command.Execute(); + } + catch (System.Exception e) { + KUtil.LogErr(e); + Application.ShowAlertDialog(e.Message); + } + } + + [CommandMethod("KReadInfo2")] + public void ReadInfo2() { + CommandStart("ReadInfo2"); + Document doc = Application.DocumentManager.MdiActiveDocument; + if (doc == null) { + return; + } + AbstractCADCommand command = new ReadInfoCommand(doc.Name); + command.Execute(); + } + + [CommandMethod("KLogin", CommandFlags.Session)] + public void Login() { + CommandStart("Login"); + TCUtil.CheckLogin(true); + } + + [CommandMethod("KConvertPDF", CommandFlags.Session)] + public void ConvertPDF() { + CommandStart("KConvertPDF"); + try { + Dictionary plotInfos = new Dictionary(); + string[] titleBlockNames = ConfigUtil.GetValue("titles").Split(';'); + string[] mediaNames = ConfigUtil.GetValue("media_names").Split(';'); + string[] rotates = ConfigUtil.GetValue("rotates").Split(';'); + int len = KUtil.GetLen(titleBlockNames); + for (int i = 0; i < len; i++) { + PlotData plot = PlotData.Parse(i, titleBlockNames, mediaNames, rotates); + if (plot == null) { + break; + } + KUtil.Log("添加打印信息: " + plot.TitleBlockName + "|" + plot.MediaName + "|" + plot.Rotate); + KUtil.Put(plotInfos, plot.TitleBlockName, plot); + } + if (plotInfos.Count == 0) { + throw new System.Exception("未配置PDF转换数据"); + } + Document doc = Application.DocumentManager.MdiActiveDocument; + string path = ConvertPDFCommand.ConvertPDF(doc, plotInfos); + KUtil.Log("PDF: "+path); + } + catch (System.Exception e) { + KUtil.LogErr(e); + Application.ShowAlertDialog(e.Message); + } + } + + [CommandMethod("KSaveToTC", CommandFlags.Session)] + public void SaveToTC() { + if (!TCUtil.CheckLogin()) { + return; + } + CommandStart("SaveToTC"); + try { + Document doc = Application.DocumentManager.MdiActiveDocument; + AbstractCADCommand command = new SaveCommand(doc.Name, false); + command.Execute(); + } + catch (System.Exception e) { + KUtil.LogErr(e); + Application.ShowAlertDialog(e.Message); + } + } + + [CommandMethod("KBatchSaveToTC",CommandFlags.Session)] + public void BatchSaveToTC() { + if (!TCUtil.CheckLogin()) { + return; + } + CommandStart("BatchSaveToTC"); + try { + // DocumentLock m_lock = Application.DocumentManager.MdiActiveDocument.LockDocument(); + + Document doc = Application.DocumentManager.MdiActiveDocument; + if (doc == null) { + return; + } + KUtil.Log("当前图纸路径:" + doc.Name); + string folderName = System.IO.Path.GetDirectoryName(doc.Name); + + string[] filePaths = System.IO.Directory.GetFiles(folderName, "*.dwg"); + int fileCnt = KUtil.GetLen(filePaths); + List file_path = new List(); + foreach (object doc1 in Application.DocumentManager) + { + if (doc1 is Document) + { + + Document openDoc = doc1 as Document; + file_path.Add(openDoc.Name); + + } + } + KUtil.Log("当前文件夹下图纸数量:" + fileCnt); + for (int i = 0; i < fileCnt; i++) + { + string filePath = filePaths[i]; + KUtil.Log("filePath:" + filePath); + if (!file_path.Contains(filePath)) + { + OpenFile(filePath); + file_path.Add(filePath); + System.Threading.Thread.Sleep(200); + /* if (!File.Exists(filePath)) + { + OpenFile(filePath); + file_path.Add(filePath); + System.Threading.Thread.Sleep(200); + } + else + { + KUtil.Log("图纸不存在"); + }*/ + + } + + } + KUtil.Log("打开本地图纸"); + AbstractCADCommand command = new SaveCommand(doc.Name, true); + command.Execute(); + + + + // m_lock.Dispose(); + } + catch (System.Exception e) { + KUtil.LogErr(e); + Application.ShowAlertDialog(e.Message); + } + } + public void OpenFile(string filePath) + { + + DocumentCollection acDocMgr = Application.DocumentManager; + Document acNewDoc = acDocMgr.Open(filePath, false); //filepath打开的文件路径,false表示文件可改写 + Database acDbNewDoc = acNewDoc.Database; + //acDocMgr.MdiActiveDocument = acNewDoc; //将打开的文件设置为当前显示 + + } + [CommandMethod("KSyncTitleFromTC")] + public void SyncTitleFromTC() { + if (!TCUtil.CheckLogin()) { + return; + } + CommandStart("SyncTitleFromTC"); + try { + Document doc = Application.DocumentManager.MdiActiveDocument; + if (doc == null) { + return; + } + + + + + + AbstractCADCommand command = new SyncTitleCommand(doc); + command.Execute(); + } + catch (System.Exception e) { + KUtil.LogErr(e); + Application.ShowAlertDialog(e.Message); + } + } + + [CommandMethod("KSyncBomViewFromTC")] + public void SyncBomViewFromTC() { + if (!TCUtil.CheckLogin()) { + return; + } + CommandStart("SyncBomViewFromTC"); + try { + Document doc = Application.DocumentManager.MdiActiveDocument; + if (doc == null) { + return; + } + AbstractCADCommand command = new SyncBomCommand(doc.Name); + command.Execute(); + } + catch (System.Exception e) { + KUtil.LogErr(e); + Application.ShowAlertDialog(e.Message); + } + } + + [CommandMethod("KSyncBomFromTC")] + public void SyncBomLineFromTC() { + if (!TCUtil.CheckLogin()) { + return; + } + CommandStart("SyncBomLineFromTC"); + try { + Document doc = Application.DocumentManager.MdiActiveDocument; + if (doc == null) { + return; + } + AbstractCADCommand command = new SyncBomLineCommand(doc.Name); + command.Execute(); + } + catch (System.Exception e) { + KUtil.LogErr(e); + Application.ShowAlertDialog(e.Message); + } + } + + [CommandMethod("KStartServer", CommandFlags.Session)] + public void StartServer() { + CommandStart("StartServer"); + try { + SocketServerCommand command = new SocketServerCommand(); + command.ExecuteCommand(); + } + catch (System.Exception e) { + KUtil.LogErr(e); + Application.ShowAlertDialog(e.Message); + } + } + + [CommandMethod("KStopServer")] + public void StopServer() { + CommandStart("StopServer"); + try { + SocketServerCommand.StopServer(); + } + catch (System.Exception e) { + KUtil.LogErr(e); + Application.ShowAlertDialog(e.Message); + } + } + + public void CommandStart(string msg) { + KUtil.Log("======================= [ Command Start: " + msg + " ] ======================="); + } + + void IExtensionApplication.Initialize() { + + } + + void IExtensionApplication.Terminate() { + + } + + + + /* public static string Test(Document doc) + { + if (doc == null) + { + throw new Exception("图纸不能为null"); + } + string cadPath = doc.Name; + KUtil.Log("转PDF: " + cadPath); + string path = cadPath.Substring(0, cadPath.Length - 4) + ".pdf"; + KUtil.Log("PDF路径:" + path); + Database db = doc.Database; + using (Transaction tran = db.TransactionManager.StartTransaction()) + { + KUtil.Log("3"); + BlockTable blt = tran.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable; + //if (blt.Has(btlname)) + //{ + KUtil.Log("4"); + BlockTableRecord bltr = tran.GetObject(db.CurrentSpaceId, OpenMode.ForRead) as BlockTableRecord; + KUtil.Log("5"); + foreach (ObjectId item in bltr) + { + Entity ent = tran.GetObject(item, OpenMode.ForRead) as Entity; + KUtil.Log("6"); + if (ent.GetType().Name == "BlockReference") + { + BlockReference bref = (BlockReference)ent; + KUtil.Log("bref.Name :" + bref.Name); + + + if (bref.AttributeCollection.Count != 0) + { + System.Collections.IEnumerator bRefEnum = bref.AttributeCollection.GetEnumerator(); + while (bRefEnum.MoveNext()) + { + ObjectId aId = (ObjectId)bRefEnum.Current;//这一句极其关键 + + AttributeReference aRef = (AttributeReference)tran.GetObject(aId, OpenMode.ForRead); + + + } + } + + + } + } + //} + tran.Commit(); + } + KUtil.Log("转换PDF完成"); + return path; + }*/ + + + + + } +} \ No newline at end of file diff --git a/connor_zwcadm/LogConfig.xml b/connor_zwcadm/LogConfig.xml new file mode 100644 index 0000000..51bd789 --- /dev/null +++ b/connor_zwcadm/LogConfig.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/connor_zwcadm/Properties/AssemblyInfo.cs b/connor_zwcadm/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..30eaf55 --- /dev/null +++ b/connor_zwcadm/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("connor_zwcadm")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("connor_zwcadm")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 会使此程序集中的类型 +//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 +//请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("f9f68df3-2a14-4f45-998d-5497ac9047d8")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 +//通过使用 "*",如下所示: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.12.1")] diff --git a/connor_zwcadm/Properties/Resources.Designer.cs b/connor_zwcadm/Properties/Resources.Designer.cs new file mode 100644 index 0000000..528b061 --- /dev/null +++ b/connor_zwcadm/Properties/Resources.Designer.cs @@ -0,0 +1,83 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +namespace connor_zwcadm.Properties { + using System; + + + /// + /// 一个强类型的资源类,用于查找本地化的字符串等。 + /// + // 此类是由 StronglyTypedResourceBuilder + // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 + // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen + // (以 /str 作为命令选项),或重新生成 VS 项目。 + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// 返回此类使用的缓存的 ResourceManager 实例。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("connor_zwcadm.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// 使用此强类型资源类,为所有资源查找 + /// 重写当前线程的 CurrentUICulture 属性。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// 查找类似于 (图标) 的 System.Drawing.Icon 类型的本地化资源。 + /// + internal static System.Drawing.Icon logo_16 { + get { + object obj = ResourceManager.GetObject("logo_16", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap rac_login_background { + get { + object obj = ResourceManager.GetObject("rac_login_background", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/connor_zwcadm/Properties/Resources.resx b/connor_zwcadm/Properties/Resources.resx new file mode 100644 index 0000000..c7c7a87 --- /dev/null +++ b/connor_zwcadm/Properties/Resources.resx @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Resources\logo_16.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\rac_login_background.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/connor_zwcadm/Resources/logo_16.ico b/connor_zwcadm/Resources/logo_16.ico new file mode 100644 index 0000000..e29878c Binary files /dev/null and b/connor_zwcadm/Resources/logo_16.ico differ diff --git a/connor_zwcadm/Resources/rac_login_background.png b/connor_zwcadm/Resources/rac_login_background.png new file mode 100644 index 0000000..6c2783b Binary files /dev/null and b/connor_zwcadm/Resources/rac_login_background.png differ diff --git a/connor_zwcadm/clientx/AppXCredentialManager.cs b/connor_zwcadm/clientx/AppXCredentialManager.cs new file mode 100644 index 0000000..cd061a2 --- /dev/null +++ b/connor_zwcadm/clientx/AppXCredentialManager.cs @@ -0,0 +1,146 @@ +//================================================== +// +// Copyright 2020 Siemens Digital Industries Software +// +//================================================== + + + +using System; +using System.IO; + +using Teamcenter.Schemas.Soa._2006_03.Exceptions; +using Teamcenter.Soa; +using Teamcenter.Soa.Common; +using Teamcenter.Soa.Client; +using Teamcenter.Soa.Exceptions; + +namespace Teamcenter.ClientX +{ + +/** + * The CredentialManager is used by the Teamcenter Services framework to get the + * user's credentials when challanged by the server. This can occur after a period + * of inactivity and the server has timed-out the user's session, at which time + * the client application will need to re-authenitcate. The framework will + * call one of the getCredentials methods (depending on circumstances) and will + * send the SessionService.login service request. Upon successfull completion of + * the login service request. The last service request (one that cuased the challange) + * will be resent. + * + * The framework will also call the setUserPassword setGroupRole methods when ever + * these credentials change, thus allowing this implementation of the CredentialManager + * to cache these values so prompting of the user is not requried for re-authentication. + * + */ +public class AppXCredentialManager : CredentialManager +{ + + private String name = null; + private String password = null; + private String group = ""; // default group + private String role = ""; // default role + private String discriminator = "SoaAppX"; // always connect same user + // to same instance of server + + /** + * Return the type of credentials this implementation provides, + * standard (user/password) or Single-Sign-On. In this case + * Standard credentials are returned. + * + * @see com.teamcenter.soa.client.CredentialManager#getCredentialType() + */ + public int CredentialType + { + get { return SoaConstants.CLIENT_CREDENTIAL_TYPE_STD; } + } + + /** + * Prompt's the user for credentials. + * This method will only be called by the framework when a login attempt has + * failed. + * + * @see com.teamcenter.soa.client.CredentialManager#getCredentials(com.teamcenter.schemas.soa._2006_03.exceptions.InvalidCredentialsException) + */ + public string[] GetCredentials(InvalidCredentialsException e) + //throws CanceledOperationException + { + Console.WriteLine(e.Message); + return PromptForCredentials(); + } + + /** + * Return the cached credentials. + * This method will be called when a service request is sent without a valid + * session ( session has expired on the server). + * + * @see com.teamcenter.soa.client.CredentialManager#getCredentials(com.teamcenter.schemas.soa._2006_03.exceptions.InvalidUserException) + */ + public String[] GetCredentials(InvalidUserException e) + //throws CanceledOperationException + { + // Have not logged in yet, shoult not happen but just in case + if (name == null) return PromptForCredentials(); + + // Return cached credentials + String[] tokens = { name, password, group, role, discriminator }; + return tokens; + } + + /** + * Cache the group and role + * This is called after the SessionService.setSessionGroupMember service + * operation is called. + * + * @see com.teamcenter.soa.client.CredentialManager#setGroupRole(java.lang.String, + * java.lang.String) + */ + public void SetGroupRole(String group, String role) + { + this.group = group; + this.role = role; + } + + /** + * Cache the User and Password + * This is called after the SessionService.login service operation is called. + * + * @see com.teamcenter.soa.client.CredentialManager#setUserPassword(java.lang.String, + * java.lang.String, java.lang.String) + */ + public void SetUserPassword(String user, String password, String discriminator) + { + this.name = user; + this.password = password; + this.discriminator = discriminator; + } + + + public String[] PromptForCredentials() + //throws CanceledOperationException + { + try + { + Console.WriteLine("Please enter user credentials (return to quit):"); + Console.Write("User Name: "); + name = Console.ReadLine(); + + if (name.Length == 0) + throw new CanceledOperationException(""); + + Console.Write("Password: "); + password = Console.ReadLine(); + } + catch (IOException e) + { + String message = "Failed to get the name and password.\n" + e.Message; + Console.WriteLine(message); + throw new CanceledOperationException(message); + } + + String[] tokens = { name, password, group, role, discriminator }; + return tokens; + } + +} +} diff --git a/connor_zwcadm/clientx/AppXExceptionHandler.cs b/connor_zwcadm/clientx/AppXExceptionHandler.cs new file mode 100644 index 0000000..2d22270 --- /dev/null +++ b/connor_zwcadm/clientx/AppXExceptionHandler.cs @@ -0,0 +1,99 @@ +//================================================== +// +// Copyright 2020 Siemens Digital Industries Software +// +//================================================== + + +using System; +using System.IO; + +using Teamcenter.Schemas.Soa._2006_03.Exceptions; +using Teamcenter.Soa.Client; +using Teamcenter.Soa.Exceptions; + +namespace Teamcenter.ClientX +{ + + + /** + * Implementation of the ExceptionHandler. For ConnectionExceptions (server + * temporarily down .etc) prompts the user to retry the last request. For other + * exceptions convert to a RunTime exception. + */ + public class AppXExceptionHandler : ExceptionHandler + { + + /* + * (non-Javadoc) + * + * @see com.teamcenter.soa.client.ExceptionHandler#handleException(com.teamcenter.schemas.soa._2006_03.exceptions.InternalServerException) + */ + public void HandleException(InternalServerException ise) + { + Console.WriteLine(""); + Console.WriteLine("*****"); + Console.WriteLine("Exception caught in com.teamcenter.clientx.AppXExceptionHandler.handleException(InternalServerException)."); + + + if (ise is ConnectionException) + { + // ConnectionException are typically due to a network error (server + // down .etc) and can be recovered from (the last request can be sent again, + // after the problem is corrected). + throw new SystemException("\nThe server returned an connection error.\n" + ise.Message); + } + else if (ise is ProtocolException) + { + // ProtocolException are typically due to programming errors + // (content of HTTP + // request is incorrect). These are generally can not be + // recovered from. + throw new SystemException("\nThe server returned an protocol error.\n" + ise.Message + + "\nThis is most likely the result of a programming error."); + } + else + { + Console.WriteLine("\nThe server returned an internal server error.\n" + + ise.Message + + "\nThis is most likely the result of a programming error." + + "\nA RuntimeException will be thrown."); + throw new SystemException(ise.Message); + } + + //try + //{ + // String retry = Console.ReadLine(); + // // If yes, return to the calling SOA client framework, where the + // // last service request will be resent. + // if (retry.ToLower().Equals("y") || retry.ToLower().Equals("yes")) + // return; + + // throw new SystemException("The user has opted not to retry the last request"); + //} + //catch (IOException e) + //{ + // Console.Error.WriteLine("Failed to read user response.\nA RuntimeException will be thrown."); + // throw new SystemException(e.Message); + //} + } + + /* + * (non-Javadoc) + * + * @see com.teamcenter.soa.client.ExceptionHandler#handleException(com.teamcenter.soa.exceptions.CanceledOperationException) + */ + public void HandleException(CanceledOperationException coe) + { + Console.WriteLine(""); + Console.WriteLine("*****"); + Console.WriteLine("Exception caught in com.teamcenter.clientx.AppXExceptionHandler.handleException(CanceledOperationException)."); + + // Expecting this from the login tests with bad credentials, and the + // AnyUserCredentials class not + // prompting for different credentials + throw new SystemException(coe.Message); + } + + } +} diff --git a/connor_zwcadm/clientx/AppXModelEventListener.cs b/connor_zwcadm/clientx/AppXModelEventListener.cs new file mode 100644 index 0000000..e56bd2d --- /dev/null +++ b/connor_zwcadm/clientx/AppXModelEventListener.cs @@ -0,0 +1,65 @@ +//================================================== +// +// Copyright 2020 Siemens Digital Industries Software +// +//================================================== + +using System; + +using Teamcenter.Soa.Client.Model; +using Teamcenter.Soa.Exceptions; + +namespace Teamcenter.ClientX +{ + + +/** + * Implementation of the ChangeListener. Print out all objects that have been updated. + * + */ + public class AppXModelEventListener : ModelEventListener + { + + override public void LocalObjectChange(ModelObject[] objects) + { + if (objects.Length == 0) return; + System.Console.WriteLine(""); + System.Console.WriteLine("Modified Objects handled in com.teamcenter.clientx.AppXUpdateObjectListener.modelObjectChange"); + System.Console.WriteLine("The following objects have been updated in the client data model:"); + for (int i = 0; i < objects.Length; i++) + { + String uid = objects[i].Uid; + String type = objects[i].GetType().Name; + String name = ""; + if (objects[i].GetType().Name.Equals("WorkspaceObject")) + { + ModelObject wo = objects[i]; + try + { + name = wo.GetProperty("object_string").StringValue; + } + catch (NotLoadedException /*e*/) {} // just ignore + } + System.Console.WriteLine(" " + uid + " " + type + " " + name); + } + } + + + override public void LocalObjectDelete(string[] uids) + { + if (uids.Length == 0) + return; + + System.Console.WriteLine(""); + System.Console.WriteLine("Deleted Objects handled in com.teamcenter.clientx.AppXDeletedObjectListener.modelObjectDelete"); + System.Console.WriteLine("The following objects have been deleted from the server and removed from the client data model:"); + for (int i = 0; i < uids.Length; i++) + { + System.Console.WriteLine(" " + uids[i]); + } + + } + + + } +} diff --git a/connor_zwcadm/clientx/AppXPartialErrorListener.cs b/connor_zwcadm/clientx/AppXPartialErrorListener.cs new file mode 100644 index 0000000..e7cd912 --- /dev/null +++ b/connor_zwcadm/clientx/AppXPartialErrorListener.cs @@ -0,0 +1,68 @@ +//================================================== +// +// Copyright 2020 Siemens Digital Industries Software +// +//================================================== + +using System; + +using Teamcenter.Soa.Client.Model; + + +namespace Teamcenter.ClientX +{ + +/** + * Implementation of the PartialErrorListener. Print out any partial errors + * returned. + * + */ +public class AppXPartialErrorListener : PartialErrorListener +{ + + /* + * (non-Javadoc) + * + * @see com.teamcenter.soa.client.model.PartialErrorListener#handlePartialError(com.teamcenter.soa.client.model.ErrorStack[]) + */ + public void HandlePartialError(ErrorStack[] stacks) + { + if (stacks.Length == 0) return; + + Console.WriteLine(""); + Console.WriteLine("*****"); + Console.WriteLine("Partial Errors caught in com.teamcenter.clientx.AppXPartialErrorListener."); + + + for (int i = 0; i < stacks.Length; i++) + { + ErrorValue[] errors = stacks[i].ErrorValues; + Console.Write("Partial Error for "); + + // The different service implementation may optionally associate + // an ModelObject, client ID, or nothing, with each partial error + if (stacks[i].HasAssociatedObject() ) + { + Console.WriteLine("object "+ stacks[i].AssociatedObject.Uid); + } + else if (stacks[i].HasClientId()) + { + Console.WriteLine("client id "+ stacks[i].ClientId); + } + else if (stacks[i].HasClientIndex()) + { + Console.WriteLine("client index " + stacks[i].ClientIndex); + } + + // Each Partial Error will have one or more contributing error messages + for (int j = 0; j < errors.Length; j++) + { + Console.WriteLine(" Code: " + errors[j].Code + "\tSeverity: " + + errors[j].Level + "\t" + errors[j].Message); + } + } + + } + +} +} diff --git a/connor_zwcadm/clientx/AppXRequestListener.cs b/connor_zwcadm/clientx/AppXRequestListener.cs new file mode 100644 index 0000000..a70fbdc --- /dev/null +++ b/connor_zwcadm/clientx/AppXRequestListener.cs @@ -0,0 +1,42 @@ +//================================================== +// +// Copyright 2020 Siemens Digital Industries Software +// +//================================================== + +using System; + +using Teamcenter.Soa.Client; + + +namespace Teamcenter.ClientX +{ + + /** + * This implemenation of the RequestListener, logs each service request + * to the console. + * + */ + public class AppXRequestListener : RequestListener + { + + + /** + * Called before each request is sent to the server. + */ + public void ServiceRequest(ServiceInfo info) + { + // will log the service name when done + } + + /** + * Called after each response from the server. + * Log the service operation to the console. + */ + public void ServiceResponse(ServiceInfo info) + { + Console.WriteLine(info.Id + ": " + info.Service + "." + info.Operation); + } + + } +} diff --git a/connor_zwcadm/clientx/Session.cs b/connor_zwcadm/clientx/Session.cs new file mode 100644 index 0000000..7954b7b --- /dev/null +++ b/connor_zwcadm/clientx/Session.cs @@ -0,0 +1,243 @@ +//================================================== +// +// Copyright 2020 Siemens Digital Industries Software +// +//================================================== + + + + +using System; +using System.Collections; +using System.Net; + +using Teamcenter.Schemas.Soa._2006_03.Exceptions; +using Teamcenter.Services.Strong.Core; +using Teamcenter.Services.Strong.Core._2006_03.Session; +using Teamcenter.Soa; +using Teamcenter.Soa.Client; +using Teamcenter.Soa.Client.Model; +using Teamcenter.Soa.Exceptions; + +using WorkspaceObject = Teamcenter.Soa.Client.Model.Strong.WorkspaceObject; +using User = Teamcenter.Soa.Client.Model.Strong.User; +using connor_zwcadm.util; + +namespace Teamcenter.ClientX { + + + public class Session { + /** + * Single instance of the Connection object that is shared throughtout + * the application. This Connection object is needed whenever a Service + * stub is instantiated. + */ + private static Connection connection; + + /** + * The credentialManager is used both by the Session class and the Teamcenter + * Services Framework to get user credentials. + * + */ + private static AppXCredentialManager credentialManager; + + /** + * Create an instance of the Session with a connection to the specified + * server. + * + * Add implementations of the ExceptionHandler, PartialErrorListener, + * ChangeListener, and DeleteListeners. + * + * @param host Address of the host to connect to, http://serverName:port/tc + */ + public Session(String host) { + // Create an instance of the CredentialManager, this is used + // by the SOA Framework to get the user's credentials when + // challanged by the server (sesioin timeout on the web tier). + credentialManager = new AppXCredentialManager(); + string proto = null; + string envNameTccs = null; + if (host.StartsWith("http")) { + proto = SoaConstants.HTTP; + } + else if (host.StartsWith("tccs")) { + proto = SoaConstants.TCCS; + int envNameStart = host.IndexOf('/') + 2; + envNameTccs = host.Substring(envNameStart, host.Length - envNameStart); + + } + + // Create the Connection object, no contact is made with the server + // until a service request is made + connection = new Connection(host, new System.Net.CookieCollection(), credentialManager, SoaConstants.REST, proto, false); + if (proto == SoaConstants.TCCS) + connection.SetOption(Connection.TCCS_ENV_NAME, envNameTccs); + + + // Add an ExceptionHandler to the Connection, this will handle any + // InternalServerException, communication errors, xml marshalling errors + // .etc + connection.ExceptionHandler = new AppXExceptionHandler(); + + // While the above ExceptionHandler is required, all of the following + // Listeners are optional. Client application can add as many or as few Listeners + // of each type that they want. + + // Add a Partial Error Listener, this will be notified when ever a + // a service returns partial errors. + //connection.ModelManager.AddPartialErrorListener(new AppXPartialErrorListener()); + + // Add a Change and Delete Listener, this will be notified when ever a + // a service returns model objects that have been updated or deleted. + //connection.ModelManager.AddModelEventListener(new AppXModelEventListener()); + + // Add a Request Listener, this will be notified before and after each + // service request is sent to the server. + //Connection.AddRequestListener(new AppXRequestListener()); + } + + /** + * Get the single Connection object for the application + * + * @return connection + */ + public static Connection getConnection() { + return connection; + } + + /** + * Login to the Teamcenter Server + * + */ + public User login() { + // Get the service stub + SessionService sessionService = SessionService.getService(connection); + + try { + // Prompt for credentials until they are right, or until user + // cancels + String[] credentials = credentialManager.PromptForCredentials(); + while (true) { + try { + + // ***************************** + // Execute the service operation + // ***************************** + LoginResponse resp = sessionService.Login(credentials[0], credentials[1], + credentials[2], credentials[3], "", credentials[4]); + + return resp.User; + } + catch (InvalidCredentialsException e) { + credentials = credentialManager.GetCredentials(e); + } + } + } + // User canceled the operation, don't need to tell him again + catch (CanceledOperationException /*e*/) { } + + // Exit the application + //System.exit(0); + return null; + } + + public User login(string user, string password) { + // Get the service stub + SessionService sessionService = SessionService.getService(connection); + LoginResponse resp = sessionService.Login(user, password, "", "", "zh_CN", "SoaAppX"); + TCUtil.CheckPartialError(resp.ServiceData); + return resp.User; + } + /** + * Terminate the session with the Teamcenter Server + * + */ + public static void logout() { + // Get the service stub + SessionService sessionService = SessionService.getService(connection); + try { + // ***************************** + // Execute the service operation + // ***************************** + sessionService.Logout(); + connection = null; + } + catch (ServiceException /*e*/) { } + } + + /** + * Print some basic information for a list of objects + * + * @param objects + */ + public static void printObjects(ModelObject[] objects) { + if (objects == null) + return; + + + // Ensure that the referenced User objects that we will use below are loaded + getUsers(objects); + + Console.WriteLine("Name\t\tOwner\t\tLast Modified"); + Console.WriteLine("====\t\t=====\t\t============="); + for (int i = 0; i < objects.Length; i++) { + if (!(objects[i] is WorkspaceObject)) + continue; + + WorkspaceObject wo = (WorkspaceObject)objects[i]; + try { + String name = wo.Object_string; + User owner = (User)wo.Owning_user; + DateTime lastModified = wo.Last_mod_date; + + Console.WriteLine(name + "\t" + owner.User_name + "\t" + lastModified.ToString()); + } + catch (NotLoadedException e) { + // Print out a message, and skip to the next item in the folder + // Could do a DataManagementService.getProperties call at this point + Console.WriteLine(e.Message); + Console.WriteLine("The Object Property Policy ($TC_DATA/soa/policies/Default.xml) is not configured with this property."); + } + } + + } + + + private static void getUsers(ModelObject[] objects) { + if (objects == null) + return; + + DataManagementService dmService = DataManagementService.getService(Session.getConnection()); + ArrayList unKnownUsers = new ArrayList(); + for (int i = 0; i < objects.Length; i++) { + if (!(objects[i] is WorkspaceObject)) + continue; + + WorkspaceObject wo = (WorkspaceObject)objects[i]; + + User owner = null; + try { + owner = (User)wo.Owning_user; + String userName = owner.User_name; + } + catch (NotLoadedException /*e*/) { + if (owner != null) + unKnownUsers.Add(owner); + } + } + User[] users = new User[unKnownUsers.Count]; + unKnownUsers.CopyTo(users); + String[] attributes = { "user_name" }; + + + // ***************************** + // Execute the service operation + // ***************************** + dmService.GetProperties(users, attributes); + + + } + + + } +} \ No newline at end of file diff --git a/connor_zwcadm/commands/AbstractCADCommand.cs b/connor_zwcadm/commands/AbstractCADCommand.cs new file mode 100644 index 0000000..58ad79e --- /dev/null +++ b/connor_zwcadm/commands/AbstractCADCommand.cs @@ -0,0 +1,44 @@ +using connor_zwcadm.util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ZwSoft.ZwCAD.ApplicationServices; + +namespace connor_zwcadm.commands { + public abstract class AbstractCADCommand { + protected KCADUtil KCADUtil { get; } + protected string File_Path { get; } + + protected AbstractCADCommand(string file_path, bool checkFile = true) { + File_Path = file_path; + if (!string.IsNullOrWhiteSpace(file_path) && file_path.Contains(":")) { + KCADUtil = new KCADUtil(file_path); + } + else if(checkFile) { + throw new Exception("请先使用cad保存文件后再进行操作"); + } + } + + protected abstract void InitCommand(); + + protected abstract void ExecuteCommand(); + + protected void ClearCache() { + if (KCADUtil != null) { + KCADUtil.CloseDatabse(); + } + } + + public void Execute() { + InitCommand(); + try { + ExecuteCommand(); + } + finally { + ClearCache(); + } + } + } +} diff --git a/connor_zwcadm/commands/ConvertPDFCommand.cs b/connor_zwcadm/commands/ConvertPDFCommand.cs new file mode 100644 index 0000000..8560ac2 --- /dev/null +++ b/connor_zwcadm/commands/ConvertPDFCommand.cs @@ -0,0 +1,458 @@ +using connor_zwcadm.model; +using connor_zwcadm.util; +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ZwSoft.ZwCAD.ApplicationServices; +using ZwSoft.ZwCAD.DatabaseServices; +using ZwSoft.ZwCAD.Geometry; +using ZwSoft.ZwCAD.Internal; +using ZwSoft.ZwCAD.PlottingServices; + +namespace connor_zwcadm.commands +{ + public class ConvertPDFCommand + { + public static string ConvertPDF(Document doc, Dictionary plotInfos, string path) + { + if (doc == null) + { + throw new Exception("图纸不能为null"); + } + string cadPath = doc.Name; + KUtil.Log("转PDF: " + cadPath); + + KUtil.Log("PDF路径:" + path); + if (path.Contains("/")) + { + path = path.Replace("/", ""); + } + + string pdfTempPath = System.IO.Path.GetTempPath() + "\\" + path; + //string pdfTempPath = cadPath.Substring(0, cadPath.LastIndexOf('\\') + 1) + path; + Database db = doc.Database; + using (Transaction tr = db.TransactionManager.StartTransaction()) + { + + BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); + List blocks; + List blockRefRegexs; + KCADUtil.GetBlocksByRegex(tr, db, bt, OpenMode.ForRead, out blocks, out blockRefRegexs, plotInfos.Keys.ToArray()); + int blockCnt = blocks == null ? 0 : blocks.Count; + KUtil.Log("找到块数量:" + blockCnt); + if (blockCnt == 0) + { + KUtil.Log("无需转换pdf"); + + //throw new Exception("图纸中没有找到需要打印的块"); + return "OFF"; + } + PlotInfo pi = new PlotInfo(); + PlotInfoValidator piv = new PlotInfoValidator(); + piv.MediaMatchingPolicy = MatchingPolicy.MatchEnabled; + if (PlotFactory.ProcessPlotState != ProcessPlotState.NotPlotting) + { + throw new Exception("其他打印正在执行"); + } + short bgPlot = (short)Application.GetSystemVariable("BACKGROUNDPLOT"); + Application.SetSystemVariable("BACKGROUNDPLOT", 0); + using (PlotEngine pe = PlotFactory.CreatePublishEngine()) + { + using (PlotProgressDialog ppd = new PlotProgressDialog(false, blockCnt, true)) + { + PlotSettingsValidator psv = PlotSettingsValidator.Current; + StringCollection cols = psv.GetPlotStyleSheetList(); + bool StyleSheetCheck = false; + foreach (string s in cols) + { + if (string.Compare(s, "monochrome.ctb", true) == 0) + { + StyleSheetCheck = true; + } + } + BlockTableRecord acBlkTblRec = tr.GetObject(bt[BlockTableRecord.ModelSpace], + OpenMode.ForRead) as BlockTableRecord; + Layout lo = (Layout)tr.GetObject(acBlkTblRec.LayoutId, OpenMode.ForRead); + PlotSettings ps = new PlotSettings(lo.ModelType); + ps.CopyFrom(lo); + ps.PrintLineweights = true; + + for (int i = 0; i < blockCnt; i++) + { + BlockReference blockRef = blocks[i]; + PlotData plotData = plotInfos[blockRefRegexs[i]]; + //psv.SetPlotConfigurationName(ps, "DWG To PDF.pc5", plotData.MediaName); + try + { + KUtil.Log("plotData.TitleBlockName====" + plotData.TitleBlockName); + if (!string.IsNullOrEmpty(plotData.TitleBlockName) && plotData.TitleBlockName.IndexOf("portrait", StringComparison.OrdinalIgnoreCase) >= 0) + { + psv.SetPlotConfigurationName(ps, "DWG to PDF.pc5", null); + } + else + { + psv.SetPlotConfigurationName(ps, "DWG to PDF横向.pc5", null); + } + psv.RefreshLists(ps); + StringCollection medlist = psv.GetCanonicalMediaNameList(ps); + KUtil.Log(plotData.MediaName); + Boolean flag = true; + for (int j = 0; j < medlist.Count; j++) + { + + KUtil.Log("medlist[j]===="+medlist[j]); + + + if (plotData.MediaName.Equals(medlist[j])) + { + KUtil.Log("1111111111111111111"); + + + if (!string.IsNullOrEmpty(plotData.TitleBlockName) && plotData.TitleBlockName.IndexOf("portrait", StringComparison.OrdinalIgnoreCase) >= 0) + { + psv.SetPlotConfigurationName(ps, "DWG To PDF.pc5", medlist[j]); + } + else + { + psv.SetPlotConfigurationName(ps, "DWG to PDF横向.pc5", medlist[j]); + } + + + + flag = false; + break; + } + //KUtil.Log(medlist[j]); + } + if (flag) + { + + + if (!string.IsNullOrEmpty(plotData.TitleBlockName) && plotData.TitleBlockName.IndexOf("portrait", StringComparison.OrdinalIgnoreCase) >= 0) + { + psv.SetPlotConfigurationName(ps, "DWG To PDF.pc5", plotData.MediaName); + } + else + { + psv.SetPlotConfigurationName(ps, "DWG to PDF横向.pc5", plotData.MediaName); + } + + } + } + catch (SystemException ex) + { + KUtil.Log("错误行开始:"); + KUtil.Log("错误状态:" + ex.InnerException.ToString()); + KUtil.Log("异常消息:" + ex.Message.ToString()); + KUtil.Log("Source:" + ex.Source.ToString()); + KUtil.Log("StackTrace:" + ex.StackTrace.ToString()); + KUtil.Log("TargetSite:" + ex.TargetSite.ToString()); + } + Point3d minPoint = blockRef.Bounds.Value.MinPoint; + Point3d maxPoint = blockRef.Bounds.Value.MaxPoint; // + psv.SetPlotWindowArea(ps, new Extents2d(minPoint.X, minPoint.Y, maxPoint.X, maxPoint.Y)); + psv.SetPlotType(ps, ZwSoft.ZwCAD.DatabaseServices.PlotType.Window); + if (!StyleSheetCheck) + psv.SetCurrentStyleSheet(ps, "monochrome.stb"); + else + psv.SetCurrentStyleSheet(ps, "monochrome.ctb"); + psv.SetPlotCentered(ps, true); + psv.SetUseStandardScale(ps, true); + psv.SetStdScaleType(ps, StdScaleType.ScaleToFit); + psv.SetPlotRotation(ps, plotData.Rotate ? PlotRotation.Degrees090 : PlotRotation.Degrees000); + + pi.Layout = acBlkTblRec.LayoutId; + + LayoutManager.Current.CurrentLayout = lo.LayoutName; + pi.OverrideSettings = ps; + piv.Validate(pi); + if (i == 0) + { + ppd.set_PlotMsgString(PlotMessageIndex.DialogTitle, "转PDF"); + //ppd.set_PlotMsgString(PlotMessageIndex.CancelJobButtonMessage, "取消打印"); + //ppd.set_PlotMsgString(PlotMessageIndex.CancelSheetButtonMessage, "取消当前页打印"); + //ppd.set_PlotMsgString(PlotMessageIndex.SheetSetProgressCaption, "Sheet Set Progress"); + //ppd.set_PlotMsgString(PlotMessageIndex.SheetProgressCaption, "Sheet Progress"); + ppd.LowerPlotProgressRange = 0; + ppd.UpperPlotProgressRange = blockCnt; + ppd.PlotProgressPos = 0; + ppd.OnBeginPlot(); + ppd.IsVisible = true; + pe.BeginPlot(ppd, null); + pe.BeginDocument(pi, cadPath, null, 1, true, pdfTempPath); + } + ppd.StatusMsgString = "打印 " + System.IO.Path.GetFileName(cadPath) + " - 页 ( " + (i + 1) + " / " + blockCnt + " )"; + ppd.PlotProgressPos = i; + ppd.OnBeginSheet(); + ppd.LowerSheetProgressRange = 0; + ppd.UpperSheetProgressRange = 100; + ppd.SheetProgressPos = 0; + PlotPageInfo ppi = new PlotPageInfo(); + pe.BeginPage(ppi, pi, i == blockCnt - 1, null); + pe.BeginGenerateGraphics(null); + ppd.SheetProgressPos = 50; + pe.EndGenerateGraphics(null); + + pe.EndPage(null); + ppd.SheetProgressPos = 100; + ppd.OnEndSheet(); + } + pe.EndDocument(null); + ppd.PlotProgressPos = 100; + ppd.OnEndPlot(); + pe.EndPlot(null); + ppd.Dispose(); + } + } + Application.SetSystemVariable("BACKGROUNDPLOT", bgPlot); + tr.Commit(); + } + + KUtil.Log("pdfTempPath:" + pdfTempPath); + KUtil.Log("转换PDF完成"); + return pdfTempPath; + } + public static string ConvertPDF(Document doc, Dictionary plotInfos) + { + if (doc == null) + { + throw new Exception("图纸不能为null"); + } + string cadPath = doc.Name; + KUtil.Log("转PDF: " + cadPath); + string path = cadPath.Substring(0, cadPath.Length - 4) + ".pdf"; + KUtil.Log("PDF路径:" + path); + Database db = doc.Database; + using (Transaction tr = db.TransactionManager.StartTransaction()) + { + + BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); + List blocks; + List blockRefRegexs; + KCADUtil.GetBlocksByRegex(tr, db, bt, OpenMode.ForRead, out blocks, out blockRefRegexs, plotInfos.Keys.ToArray()); + int blockCnt = blocks == null ? 0 : blocks.Count; + KUtil.Log("找到块数量:" + blockCnt); + if (blockCnt == 0) + { + KUtil.Log("无需转换pdf"); + + //throw new Exception("图纸中没有找到需要打印的块"); + return "OFF"; + } + PlotInfo pi = new PlotInfo(); + PlotInfoValidator piv = new PlotInfoValidator(); + piv.MediaMatchingPolicy = MatchingPolicy.MatchEnabled; + if (PlotFactory.ProcessPlotState != ProcessPlotState.NotPlotting) + { + throw new Exception("其他打印正在执行"); + } + short bgPlot = (short)Application.GetSystemVariable("BACKGROUNDPLOT"); + Application.SetSystemVariable("BACKGROUNDPLOT", 0); + using (PlotEngine pe = PlotFactory.CreatePublishEngine()) + { + using (PlotProgressDialog ppd = new PlotProgressDialog(false, blockCnt, true)) + { + PlotSettingsValidator psv = PlotSettingsValidator.Current; + StringCollection cols = psv.GetPlotStyleSheetList(); + bool StyleSheetCheck = false; + foreach (string s in cols) + { + if (string.Compare(s, "monochrome.ctb", true) == 0) + { + StyleSheetCheck = true; + } + } + BlockTableRecord acBlkTblRec = tr.GetObject(bt[BlockTableRecord.ModelSpace], + OpenMode.ForRead) as BlockTableRecord; + Layout lo = (Layout)tr.GetObject(acBlkTblRec.LayoutId, OpenMode.ForRead); + PlotSettings ps = new PlotSettings(lo.ModelType); + ps.CopyFrom(lo); + ps.PrintLineweights = true; + for (int i = 0; i < blockCnt; i++) + { + BlockReference blockRef = blocks[i]; + PlotData plotData = plotInfos[blockRefRegexs[i]]; + psv.SetPlotConfigurationName(ps, "DWG To PDF.pc5", plotData.MediaName); + Point3d minPoint = blockRef.Bounds.Value.MinPoint; + Point3d maxPoint = blockRef.Bounds.Value.MaxPoint; // + psv.SetPlotWindowArea(ps, new Extents2d(minPoint.X, minPoint.Y, maxPoint.X, maxPoint.Y)); + psv.SetPlotType(ps, ZwSoft.ZwCAD.DatabaseServices.PlotType.Window); + if (!StyleSheetCheck) + psv.SetCurrentStyleSheet(ps, "monochrome.stb"); + else + psv.SetCurrentStyleSheet(ps, "monochrome.ctb"); + psv.SetPlotCentered(ps, true); + psv.SetUseStandardScale(ps, true); + psv.SetStdScaleType(ps, StdScaleType.ScaleToFit); + psv.SetPlotRotation(ps, plotData.Rotate ? PlotRotation.Degrees090 : PlotRotation.Degrees000); + + pi.Layout = acBlkTblRec.LayoutId; + + LayoutManager.Current.CurrentLayout = lo.LayoutName; + pi.OverrideSettings = ps; + piv.Validate(pi); + if (i == 0) + { + ppd.set_PlotMsgString(PlotMessageIndex.DialogTitle, "转PDF"); + //ppd.set_PlotMsgString(PlotMessageIndex.CancelJobButtonMessage, "取消打印"); + //ppd.set_PlotMsgString(PlotMessageIndex.CancelSheetButtonMessage, "取消当前页打印"); + //ppd.set_PlotMsgString(PlotMessageIndex.SheetSetProgressCaption, "Sheet Set Progress"); + //ppd.set_PlotMsgString(PlotMessageIndex.SheetProgressCaption, "Sheet Progress"); + ppd.LowerPlotProgressRange = 0; + ppd.UpperPlotProgressRange = blockCnt; + ppd.PlotProgressPos = 0; + ppd.OnBeginPlot(); + ppd.IsVisible = true; + pe.BeginPlot(ppd, null); + pe.BeginDocument(pi, cadPath, null, 1, true, path); + } + ppd.StatusMsgString = "打印 " + System.IO.Path.GetFileName(cadPath) + " - 页 ( " + (i + 1) + " / " + blockCnt + " )"; + ppd.PlotProgressPos = i; + ppd.OnBeginSheet(); + ppd.LowerSheetProgressRange = 0; + ppd.UpperSheetProgressRange = 100; + ppd.SheetProgressPos = 0; + PlotPageInfo ppi = new PlotPageInfo(); + pe.BeginPage(ppi, pi, i == blockCnt - 1, null); + pe.BeginGenerateGraphics(null); + ppd.SheetProgressPos = 50; + pe.EndGenerateGraphics(null); + + pe.EndPage(null); + ppd.SheetProgressPos = 100; + ppd.OnEndSheet(); + } + pe.EndDocument(null); + ppd.PlotProgressPos = 100; + ppd.OnEndPlot(); + pe.EndPlot(null); + ppd.Dispose(); + } + } + Application.SetSystemVariable("BACKGROUNDPLOT", bgPlot); + tr.Commit(); + } + KUtil.Log("转换PDF完成"); + return path; + } + public static string ConvertPDF(Database db, string cadPath, Dictionary plotInfos) + { + if (db == null) + { + throw new Exception("图纸DataBase不能为null"); + } + KUtil.Log("转PDF: " + cadPath); + string path = cadPath.Substring(0, cadPath.Length - 4) + ".pdf"; + KUtil.Log("PDF路径:" + path); + using (Transaction tr = db.TransactionManager.StartTransaction()) + { + BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); + List blocks; + List blockRefRegexs; + KCADUtil.GetBlocksByRegex(tr, db, bt, OpenMode.ForRead, out blocks, out blockRefRegexs, plotInfos.Keys.ToArray()); + int blockCnt = blocks == null ? 0 : blocks.Count; + KUtil.Log("找到块数量:" + blockCnt); + if (blockCnt == 0) + { + //throw new Exception("图纸中没有找到需要打印的块"); + return path; + } + PlotInfo pi = new PlotInfo(); + PlotInfoValidator piv = new PlotInfoValidator(); + piv.MediaMatchingPolicy = MatchingPolicy.MatchEnabled; + if (PlotFactory.ProcessPlotState != ProcessPlotState.NotPlotting) + { + throw new Exception("其他打印正在执行"); + } + short bgPlot = (short)Application.GetSystemVariable("BACKGROUNDPLOT"); + Application.SetSystemVariable("BACKGROUNDPLOT", 0); + using (PlotEngine pe = PlotFactory.CreatePublishEngine()) + { + //using (PlotProgressDialog ppd = new PlotProgressDialog(false, blockCnt, true)) { + PlotSettingsValidator psv = PlotSettingsValidator.Current; + StringCollection cols = psv.GetPlotStyleSheetList(); + bool StyleSheetCheck = false; + foreach (string s in cols) + { + if (string.Compare(s, "monochrome.ctb", true) == 0) + { + StyleSheetCheck = true; + } + } + BlockTableRecord acBlkTblRec = tr.GetObject(bt[BlockTableRecord.ModelSpace], + OpenMode.ForRead) as BlockTableRecord; + Layout lo = (Layout)tr.GetObject(acBlkTblRec.LayoutId, OpenMode.ForRead); + PlotSettings ps = new PlotSettings(lo.ModelType); + ps.CopyFrom(lo); + ps.PrintLineweights = true; + for (int i = 0; i < blockCnt; i++) + { + BlockReference blockRef = blocks[i]; + PlotData plotData = plotInfos[blockRefRegexs[i]]; + psv.SetPlotConfigurationName(ps, "DWG To PDF.pc5", plotData.MediaName); + Point3d minPoint = blockRef.Bounds.Value.MinPoint; + Point3d maxPoint = blockRef.Bounds.Value.MaxPoint; // + psv.SetPlotWindowArea(ps, new Extents2d(minPoint.X, minPoint.Y, maxPoint.X, maxPoint.Y)); + psv.SetPlotType(ps, ZwSoft.ZwCAD.DatabaseServices.PlotType.Window); + if (!StyleSheetCheck) + psv.SetCurrentStyleSheet(ps, "monochrome.stb"); + else + psv.SetCurrentStyleSheet(ps, "monochrome.ctb"); + psv.SetPlotCentered(ps, true); + psv.SetUseStandardScale(ps, true); + psv.SetStdScaleType(ps, StdScaleType.ScaleToFit); + psv.SetPlotRotation(ps, plotData.Rotate ? PlotRotation.Degrees090 : PlotRotation.Degrees000); + pi.Layout = acBlkTblRec.LayoutId; + LayoutManager.Current.CurrentLayout = lo.LayoutName; + pi.OverrideSettings = ps; + piv.Validate(pi); + if (i == 0) + { + //ppd.set_PlotMsgString(PlotMessageIndex.DialogTitle, "转PDF"); + ////ppd.set_PlotMsgString(PlotMessageIndex.CancelJobButtonMessage, "取消打印"); + ////ppd.set_PlotMsgString(PlotMessageIndex.CancelSheetButtonMessage, "取消当前页打印"); + ////ppd.set_PlotMsgString(PlotMessageIndex.SheetSetProgressCaption, "Sheet Set Progress"); + ////ppd.set_PlotMsgString(PlotMessageIndex.SheetProgressCaption, "Sheet Progress"); + //ppd.LowerPlotProgressRange = 0; + //ppd.UpperPlotProgressRange = blockCnt; + //ppd.PlotProgressPos = 0; + //ppd.OnBeginPlot(); + //ppd.IsVisible = true; + pe.BeginPlot(null, null); + pe.BeginDocument(pi, cadPath, null, 1, true, path); + } + //ppd.StatusMsgString = "打印 " + System.IO.Path.GetFileName(cadPath) + " - 页 ( " + (i + 1) + " / " + blockCnt + " )"; + //ppd.PlotProgressPos = i; + //ppd.OnBeginSheet(); + //ppd.LowerSheetProgressRange = 0; + //ppd.UpperSheetProgressRange = 100; + //ppd.SheetProgressPos = 0; + PlotPageInfo ppi = new PlotPageInfo(); + pe.BeginPage(ppi, pi, i == blockCnt - 1, null); + pe.BeginGenerateGraphics(null); + //ppd.SheetProgressPos = 50; + pe.EndGenerateGraphics(null); + + pe.EndPage(null); + // ppd.SheetProgressPos = 100; + // ppd.OnEndSheet(); + } + pe.EndDocument(null); + // ppd.PlotProgressPos = 100; + //ppd.OnEndPlot(); + pe.EndPlot(null); + // ppd.Dispose(); + } + //} + Application.SetSystemVariable("BACKGROUNDPLOT", bgPlot); + tr.Commit(); + } + KUtil.Log("转换PDF完成"); + return path; + } + + } +} diff --git a/connor_zwcadm/commands/ReadInfoCommand.cs b/connor_zwcadm/commands/ReadInfoCommand.cs new file mode 100644 index 0000000..8905cc5 --- /dev/null +++ b/connor_zwcadm/commands/ReadInfoCommand.cs @@ -0,0 +1,68 @@ +using connor_zwcadm.util; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ZWCAD; +using ZwmToolKitLib; +using ZwSoft.ZwCAD.ApplicationServices; + +namespace connor_zwcadm.commands { + public class ReadInfoCommand : AbstractCADCommand { + + public const string FILE_NAME = "info.txt"; + + public ReadInfoCommand(string file_path) : base(file_path, false) { } + + protected override void InitCommand() { } + + protected override void ExecuteCommand() { + if (string.IsNullOrWhiteSpace(File_Path)) { + throw new Exception("文件路径不能为空"); + } + if (!File_Path.Contains(":")) { + KUtil.Log("非本地文件:"+File_Path); + //return; + } + if (!File.Exists(File_Path)) { + throw new Exception("文件不存在:" + File_Path); + } + InitCommand(); + string infoPath = Path.Combine(Path.GetDirectoryName(File_Path), FILE_NAME); + KUtil.Log("读取本地同步信息:" + File_Path); + if (!File.Exists(infoPath)) { + KUtil.Log("没有数据文件"); + return; + } + string[] info = File.ReadAllLines(infoPath, Encoding.UTF8); + KUtil.Log("文件信息"); + KUtil.Log("------------------------------------------------------"); + int lineCnt = KUtil.GetLen(info); + Dictionary titleProps = new Dictionary(); + for (int i = 0; i < lineCnt; i++) { + string text = info[i]; + KUtil.Log(text); + if (string.IsNullOrWhiteSpace(text)) { + continue; + } + int ind = text.IndexOf('='); + if (ind < 0) { + continue; + } + string name = text.Substring(0, ind); + string value = text.Substring(ind + 1); + KUtil.Put(titleProps, name, value); + } + KUtil.Log("------------------------------------------------------"); + if (titleProps.Count == 0) { + KUtil.Log("无有效数据"); + return; + } + KCADUtil.WriteTitle(titleProps); + KUtil.Log("更新标题栏完成"); + } + + } +} diff --git a/connor_zwcadm/commands/SaveCommand.cs b/connor_zwcadm/commands/SaveCommand.cs new file mode 100644 index 0000000..2e7d716 --- /dev/null +++ b/connor_zwcadm/commands/SaveCommand.cs @@ -0,0 +1,459 @@ +using connor_zwcadm.dialog; +using connor_zwcadm.model; +using connor_zwcadm.util; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.IO; +using System.Text; +using System.Windows.Forms; +using ZwSoft.ZwCAD.ApplicationServices; +using ZwSoft.ZwCAD.DatabaseServices; +using Application = ZwSoft.ZwCAD.ApplicationServices.Application; + +namespace connor_zwcadm.commands { + public class SaveCommand : AbstractCADCommand { + + public const bool IS_PACK = true; + + public SaveCommand(string file_path, bool isBatchSave) : base(file_path) { + bgWorker = new KBackgroundWorker(); + if (isBatchSave) { + bgWorker.backgroundWorker.DoWork += DoBatchSave; + } + else { + bgWorker.backgroundWorker.DoWork += DoSave; + } + TCUtil = new TCUtil(bgWorker); + } + + private string[] uploadFileConfig; // 关系 数据集类型 数据集引用 fms地址 + + private string fmsUrl; + private KBackgroundWorker bgWorker { get; } + public TCUtil TCUtil { get; } + + public void CycleBom(TCData parentData, Dictionary docDatas, List savedDocs, List docsToSave, List checkedIds,List fuIds) { + if (parentData == null) { + return; + } + List childDatas = parentData.BomLineDatas; + int childCnt = childDatas == null ? 0 : childDatas.Count; + List currentLevelIds = new List(); + string itemId = parentData.Item_id; + for (int i = 0; i < childCnt; i++) { + string childId = childDatas[i].Item_id; + if (fuIds.Contains(childId)) + { + throw new Exception("图纸存在循环结构,请检查。子件ID为:" + childId+ ",母件ID为:"+ itemId); + } + if (!currentLevelIds.Contains(childId)) { + currentLevelIds.Add(childId); + } + } + /* if (childCnt > 0) + { + fuIds.Add(itemId); + } + else + { + string topID = fuIds[0]; + fuIds = new List(); + fuIds.Add(topID); + }*/ + + childCnt = currentLevelIds.Count; + for (int i = 0; i < childCnt; i++) { + string childId = currentLevelIds[i]; + if (!checkedIds.Contains(childId)) { + checkedIds.Add(childId); + } + else { + //throw new Exception("图纸存在循环结构,请检查。问题ID为:" + childId); + } + if (!docDatas.ContainsKey(childId)) { + KUtil.Log("图纸中子件ID为\"" + childId + "\"的图纸不存在:" + parentData.DocFileName); + continue; + } + List childDatas2 = docDatas[childId].BomLineDatas; + string itemId2 = docDatas[childId].Item_id; + if (childDatas2.Count > 0) + { + fuIds.Add(itemId2); + } + else + { + string topID = fuIds[0]; + fuIds.Clear(); + fuIds.Add(topID); + } + KUtil.Log("fuID.count:" + fuIds.Count); + CycleBom(docDatas[childId], docDatas, savedDocs, docsToSave, checkedIds, fuIds); + } + + if (savedDocs.Contains(itemId)) { + return; + } + savedDocs.Add(itemId); + docsToSave.Add(parentData); + } + + //批量保存 + public void DoBatchSave(object sender, DoWorkEventArgs e) { + + bgWorker.Progress("初始化","", 0); + bgWorker.Progress("读取图纸数据", 0); + TCData titleData = KCADUtil.ReadDocData(true, TCUtil); + string currentDocId = titleData.Item_id; + string currentDocPath = File_Path; + KUtil.Log("当前图纸路径:" + currentDocPath); + string folderName = System.IO.Path.GetDirectoryName(currentDocPath); + KUtil.Log("查询文件夹中的图纸: " + folderName); + string[] filePaths = System.IO.Directory.GetFiles(folderName, "*.dwg"); + int fileCnt = KUtil.GetLen(filePaths); + KUtil.Log("找到图纸数量:" + fileCnt); + Dictionary docDatas = new Dictionary(); + docDatas.Add(currentDocId, titleData); + for (int i = 0; i < fileCnt; i++) { + string filePath = filePaths[i]; + + bgWorker.Progress("读取文件夹中的图纸数据 ( " + (i + 1) + " / " + fileCnt + " )", 0); + KUtil.Log((i + 1) + ". 加载文件" + filePath); + if (currentDocPath.Equals(filePath)) { + KUtil.Log("跳过当前图纸"); + continue; + } + TCData docData; + KCADUtil kCADUtil = new KCADUtil(filePath); + try { + docData = kCADUtil.ReadDocData(true, TCUtil); + } catch (Exception ex) { + KUtil.Log("读取图纸数据失败:" + ex.Message); + continue; + } + finally { + kCADUtil.CloseDatabse(); + } + string docId = docData.Item_id; + if (docDatas.ContainsKey(docId)) { + throw new Exception("存在对象ID重复的图纸[" + docId + "]:\r\n" + docData.DocFileName + "\r\n" + docDatas[docId].DocFileName); + } + docDatas.Add(docId, docData); + } + + KUtil.Log("找到文件夹中的标题栏对象:"+string.Join(", ", docDatas.Keys)); + List docsToSave = new List(); + List docIdsToSave = new List(); + List fuIDs = new List(); + fuIDs.Add(titleData.Item_id); + CycleBom(titleData, docDatas, docIdsToSave, docsToSave, new List(), fuIDs); + KUtil.Log("将按顺序保存以下图纸\r\n"+string.Join(" > ", docIdsToSave)+"\r\n"+string.Join("\r\n", docsToSave)); + int docCnt = docsToSave.Count; + //检查所有图纸 + List idsToCreate = new List(); + StringBuilder propertyInfo = new StringBuilder(); + for (int i=0; i bomlineDatas = parentData.BomLineDatas; + int bomlineCnt = bomlineDatas == null ? 0 : bomlineDatas.Count; + for (int j = 0; j < bomlineCnt; j++) { + bgWorker.ProgressDetail("检查明细栏数据 ( " + (j + 1) + " / " + bomlineCnt + " )"); + TCData bomlineData = bomlineDatas[j]; + CheckIdInBom(bomlineData, propertyInfo, idsToCreate); + } + } + if (propertyInfo.Length > 0) { + string msg = "下列图号的零组件存在属性与TC系统不一致的情况,是否同步图纸属性并继续?" + propertyInfo.ToString(); + System.Windows.MessageBoxResult dialogResult = System.Windows.MessageBoxResult.No; + bgWorker.pbDialog.Dispatcher.Invoke(new Action(delegate { + dialogResult = System.Windows.MessageBox.Show(msg, "提示", System.Windows.MessageBoxButton.YesNo); + })); + if (dialogResult != System.Windows.MessageBoxResult.Yes) { + bgWorker.CompleteMessage = null; + KUtil.Log("取消批量保存"); + return; + } + } + StringBuilder errSB = new StringBuilder(); + for (int i = 0; i < docCnt; i++) { + TCData parentData = docsToSave[i]; + string itemId = parentData.Item_id; + bgWorker.Progress("保存图纸:" + itemId, (i * 100) / docCnt); + KUtil.Log("-------------------------------------------------------------------"); + KUtil.Log("开始保存图纸[" + itemId + "]:" + parentData.DocFileName); + //同步对象属性 + Boolean iserr = TCUtil.CreateOrUpdateItem(parentData); + //更新BOM + TCUtil.GetProperties(parentData.Rev, "object_name"); + TCUtil.GetProperties(parentData.Rev, "item_revision_id"); + TCUtil.CreateOrUpdateBom(parentData, IS_PACK); + if (!iserr) + { + errSB.Append(parentData.Item_id); + errSB.Append("-"); + errSB.Append(parentData.Rev.Item_revision_id); + errSB.Append("-"); + errSB.Append(parentData.Rev.Object_name); + errSB.Append(";"); + continue; + } + //上传文件 + + string dsName = itemId + "-" + parentData.Rev.Object_name; + + + List tempFiles = new List(); + //DocumentLock m_DocumentLock = ZwSoft.ZwCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument(); + TCUtil.UploadFile(parentData, uploadFileConfig[0], uploadFileConfig[1], uploadFileConfig[2], dsName, tempFiles, fmsUrl); + //m_DocumentLock.Dispose(); + + + ConvertPDFAndUpload(parentData); + + KUtil.Log("保存图纸完成:" + parentData.DocFileName); + // 清理缓存 + foreach (string path in tempFiles) + { + File.Delete(path); + } + } + + bgWorker.Progress("保存完成", "", 100); + if (!("".Equals(errSB.ToString()))) + { + MessageBox.Show("数据保存成功,但"+errSB.ToString()+ "对象数据更新失败,请查看权限!!!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); + + } + System.Threading.Thread.Sleep(800); + } + //单个保存 + public void DoSave(object sender, DoWorkEventArgs e) { + bgWorker.Progress("初始化", "",0); + //读取图纸数据 + bgWorker.Progress("读取图纸数据", 10); + TCData titleData = KCADUtil.ReadDocData(true, TCUtil); + string itemId = titleData.Item_id; + List bomlineDatas = titleData.BomLineDatas; + //检查ID + bgWorker.Progress("检查标题栏数据", 30); + CheckIdInTitle(itemId, null, titleData.ItemTypeName); + // 检查BOM + bgWorker.Progress("检查明细栏数据", 40); + int bomlineCnt = bomlineDatas == null ? 0 : bomlineDatas.Count; + StringBuilder propertyInfo = new StringBuilder(); + for(int i = 0; i < bomlineCnt; i++) { + bgWorker.ProgressDetail("检查明细栏数据 ( " + (i + 1) + " / " + bomlineCnt + " )"); + TCData bomlineData = bomlineDatas[i]; + CheckIdInBom(bomlineData, propertyInfo, null); + } + if (propertyInfo.Length > 0) { + string msg = "下列图号的零组件存在属性与TC系统不一致的情况,是否同步图纸属性并继续?"+propertyInfo.ToString(); + System.Windows.MessageBoxResult dialogResult = System.Windows.MessageBoxResult.No; + bgWorker.pbDialog.Dispatcher.Invoke(new Action(delegate { + dialogResult = System.Windows.MessageBox.Show(msg, "提示", System.Windows.MessageBoxButton.YesNo); + })); + if (dialogResult != System.Windows.MessageBoxResult.Yes) { + bgWorker.CompleteMessage = null; + KUtil.Log("取消保存"); + return; + } + } + //同步对象属性 + bgWorker.Progress("保存标题栏数据", 60); + Boolean iserr = TCUtil.CreateOrUpdateItem(titleData); + //更新BOM + bgWorker.Progress("保存明细栏数据", 80); + TCUtil.CreateOrUpdateBom(titleData, IS_PACK); + + //上传文件 + bgWorker.Progress("上传文件", 90); + + TCUtil.GetProperties(titleData.Rev, "item_revision_id"); + TCUtil.GetProperties(titleData.Rev, "object_name"); + if (!iserr) + { + StringBuilder errSB = new StringBuilder(); + errSB.Append(itemId); + errSB.Append("-"); + errSB.Append(titleData.Rev.Item_revision_id); + errSB.Append("-"); + errSB.Append(titleData.Rev.Object_name); + errSB.Append(":数据更新失败,请查看权限!!!"); + throw new Exception(errSB.ToString()); + } + string dsName = itemId + "-" + titleData.Rev.Object_name; + + + List tempFiles = new List(); + //DocumentLock m_DocumentLock = ZwSoft.ZwCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument(); + //TCUtil.UploadFile(titleData, uploadFileConfig[0], uploadFileConfig[1], uploadFileConfig[2], dsName,tempFiles, fmsUrl); + //m_DocumentLock.Dispose(); + KCADUtil.saveData(); + ConvertPDFAndUpload(titleData); + // 清理缓存 + foreach (string path in tempFiles) + { + //File.Delete(path); + } + + bgWorker.Progress("保存完成", "", 100); + System.Threading.Thread.Sleep(800); + } + + + public void CheckIdInBom(TCData bomlineData, StringBuilder propertyInfo, List idsToCreate) { + string itemId = bomlineData.Item_id; + if (string.IsNullOrWhiteSpace(itemId)) { + throw new Exception("对象ID不可为空"); + } + Teamcenter.Soa.Client.Model.Strong.Item item = TCUtil.QueryItem(itemId, bomlineData.ItemTypeName, true); + //if (itemId.StartsWith("M")) { + // if (item == null) { + // throw new Exception("[" + itemId + "]未查询到TC系统中ItemID是[图号]或[MDM编码]的零组件,请确认填写正确或TC系统中已存在该零组件。"); + // } + //} + //if (item == null) { + // if (idsToCreate != null && idsToCreate.Contains(itemId)) { + // return; + // } + // throw new Exception("[" + itemId + "]未查询到TC系统中ItemID是[图号]或[MDM编码]的零组件,请确认填写正确或TC系统中已存在该零组件。"); + //} + if (item != null) { + //检查属性 + List changedProps = TCUtil.ComparePropertiesInTC(bomlineData); + if (changedProps != null && changedProps.Count > 0) { + propertyInfo.Append(string.Format("\r\n[{0}]: {1}", itemId, string.Join(", ", changedProps))); + } + } + } + + public void CheckIdInTitle(string itemId, List idsToCreate, string itemTypeName) { + if (string.IsNullOrWhiteSpace(itemId)) { + throw new Exception("对象ID不可为空"); + } + Teamcenter.Soa.Client.Model.Strong.Item item = TCUtil.QueryItem(itemId, itemTypeName); + //if (itemId.StartsWith("M")) { + // if (item == null) { + // throw new Exception("M开头编码需先在TC中申请后才能使用。"); + // } + //} + if (item != null && !TCUtil.CheckCanWrite(item)) { + throw new Exception("当前用户无对应零组件编辑权限,无法保存。"); + } + if (item == null && idsToCreate!=null) { + idsToCreate.Add(itemId); + } + } + + protected override void InitCommand() { + uploadFileConfig = TCUtil.GetPrefValues(KMain.PREF_UPLOAD_FILE); + KUtil.Log("文件上传配置:" + string.Join(", ", uploadFileConfig)); + if (KUtil.GetLen(uploadFileConfig) < 3) { + throw new Exception("首选项配置错误:" + KMain.PREF_UPLOAD_FILE); + } + if (KUtil.GetLen(uploadFileConfig) > 3) { + fmsUrl = uploadFileConfig[3]; + } + string[] titleBlockNames = ConfigUtil.GetValue("titles").Split(';'); + string[] mediaNames = ConfigUtil.GetValue("media_names").Split(';'); + string[] rotates = ConfigUtil.GetValue("rotates").Split(';'); + int len = KUtil.GetLen(titleBlockNames); + for (int i = 0; i < len; i++) + { + PlotData plot = PlotData.Parse(i, titleBlockNames, mediaNames, rotates); + if (plot == null) + { + break; + } + KUtil.Log("添加打印信息: " + plot.TitleBlockName + "|" + plot.MediaName + "|" + plot.Rotate); + KUtil.Put(plotInfos, plot.TitleBlockName, plot); + } + if (plotInfos.Count == 0) + { + throw new System.Exception("未配置PDF转换数据"); + } + } + + protected override void ExecuteCommand() { + bgWorker.Start(null); + } + private Dictionary plotInfos = new Dictionary(); + public void ConvertPDFAndUpload(TCData data) + { + string itemId = data.Item_id; + TCUtil.GetProperties(data.Rev, "object_name"); + TCUtil.GetProperties(data.Rev, "item_revision_id"); + string dsName = itemId + "-" + data.Rev.Object_name; + string file = data.DocFileName; + KUtil.Log("file:" + file); + string path = itemId+ "-" + data.Rev.Item_revision_id + "-"+ data.Rev.Object_name+ ".pdf"; + if (!System.IO.File.Exists(file)) + { + throw new Exception("上传文件失败,文件不存在:" + file); + } + Document openDoc = GetOpenedDoc(file); + KUtil.Log("path:" + path); + bool close = openDoc == null; + KUtil.Log("close:" + close); + if (close) + { + DocumentCollection acDocMgr = ZwSoft.ZwCAD.ApplicationServices.Application.DocumentManager; + // DocumentLock m_lock = acDocMgr.MdiActiveDocument.LockDocument(); + openDoc = acDocMgr.Open(file, false); //filepath打开的文件路径,false表示文件可改写 + Database acDbNewDoc = openDoc.Database; + //acDocMgr.MdiActiveDocument = openDoc; +/* openDoc = Application.DocumentManager.Open(file, false); + // openDoc = Application.DocumentManager.Open(file); + Application.DocumentManager.MdiActiveDocument = openDoc;*/ + } + try + { + using (openDoc.LockDocument()) + { + KUtil.Log("开始转换PDF" ); + string pdfFilePath = ConvertPDFCommand.ConvertPDF(openDoc, plotInfos,path); + if (pdfFilePath.Equals("OFF")) + { + return; + } + if (!System.IO.File.Exists(pdfFilePath)) + { + throw new Exception("PDF转换失败:" + file); + } + data.DocFileName = pdfFilePath; + List tempFiles = new List(); + TCUtil.UploadFile(data, uploadFileConfig[0], "PDF", "PDF_Reference", dsName, tempFiles, fmsUrl); + KUtil.Log("PDF上传完成:" + data.DocFileName); + + } + } + finally + { + data.DocFileName = file; + if (close) + { + openDoc.CloseAndDiscard(); + } + } + } + public static Document GetOpenedDoc(string file) + { + foreach (object doc in Application.DocumentManager) + { + if (doc is Document) + { + if (file.Equals(((Document)doc).Name)) + { + return doc as Document; + } + } + } + return null; + } + } +} diff --git a/connor_zwcadm/commands/SocketServerCommand.cs b/connor_zwcadm/commands/SocketServerCommand.cs new file mode 100644 index 0000000..67d0cd3 --- /dev/null +++ b/connor_zwcadm/commands/SocketServerCommand.cs @@ -0,0 +1,249 @@ +using connor_zwcadm.dialog; +using connor_zwcadm.model; +using connor_zwcadm.util; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Net; +using System.Net.Sockets; +using System.Text; +using ZwSoft.ZwCAD.ApplicationServices; +using ZwSoft.ZwCAD.DatabaseServices; + +namespace connor_zwcadm.commands { + public class SocketServerCommand { + + public const int PORT = 11415; + // Incoming data from the client. + public static string data = null; + public const string CLOSE_SOCKET = "CLose"; + public const string SUCCESS_MESSAGE = "OK"; + public const char REQUEST_SPLITTER = '|'; + public const string CMD_SYNC_PROPERTIES = "SYNC"; + public const string CMD_CONVERT_PDF = "PDF"; + public Dictionary plotInfos = new Dictionary(); + private KBackgroundWorker bgWorker { get; } + public SocketServerCommand() { + bgWorker = new KBackgroundWorker(); + bgWorker.backgroundWorker.DoWork += StartServer; + } + + public static void StopServer() { + byte[] bytes = new byte[1024]; + KUtil.Log("开始关闭Socket服务"); + IPAddress ipAddress = IPAddress.Loopback; + IPEndPoint remoteEP = new IPEndPoint(ipAddress, PORT); + Socket sender = new Socket(ipAddress.AddressFamily, + SocketType.Stream, ProtocolType.Tcp); + sender.Connect(remoteEP); + try { + byte[] msg = Encoding.UTF8.GetBytes(CLOSE_SOCKET); + sender.Send(msg); + int bytesRec = sender.Receive(bytes); + KUtil.Log("收到返沪数据:" + Encoding.UTF8.GetString(bytes, 0, bytesRec)); + } + finally { + sender.Shutdown(SocketShutdown.Both); + sender.Close(); + } + } + + public void StartServer(object sender, DoWorkEventArgs e) { + KUtil.Log("开始启动Socket服务"); + bgWorker.Progress("服务运行中", "", 0); + // Data buffer for incoming data. + byte[] bytes = new byte[1024]; + + // Establish the local endpoint for the socket. + // Dns.GetHostName returns the name of the + // host running the application. + //IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName()); + IPAddress ipAddress = IPAddress.Any; // ipHostInfo.AddressList[0]; + IPEndPoint localEndPoint = new IPEndPoint(ipAddress, PORT); + // Create a TCP/IP socket. + Socket listener = new Socket(ipAddress.AddressFamily, + SocketType.Stream, ProtocolType.Tcp); + + // Bind the socket to the local endpoint and + // listen for incoming connections. + + listener.Bind(localEndPoint); + listener.Listen(20); + // Start listening for connections. + while (true) { + bgWorker.Progress("服务运行中", "", 0); + KUtil.Log("--------------------------------------------------------------------------"); + KUtil.Log("等待连接"); + // Program is suspended while waiting for an incoming connection. + Socket handler = listener.Accept(); + try { + data = null; + // An incoming connection needs to be processed. + while (true) { + int bytesRec = handler.Receive(bytes); + data += Encoding.UTF8.GetString(bytes, 0, bytesRec); + if (data.IndexOf("") > -1) { + break; + } + } + if (CLOSE_SOCKET.Equals(data)) { + handler.Send(Encoding.UTF8.GetBytes("Closed")); + handler.Shutdown(SocketShutdown.Both); + handler.Close(); + break; + } + bgWorker.Progress("处理请求", "", 30); + string resp; + KUtil.Log("收到请求:" + data); + try { + resp = ProcessRequest(data); + } + catch (Exception ex1) { + KUtil.LogErr(ex1); + resp = ex1.Message; + } + KUtil.Log("返回:" + resp); + bgWorker.Progress("返回数据", "", 100); + // Echo the data back to the client. + byte[] msg = Encoding.UTF8.GetBytes(resp); + handler.Send(msg); + } + catch (Exception ex) { + KUtil.LogErr(ex); + } + { + try { + handler.Shutdown(SocketShutdown.Both); + handler.Close(); + } + catch (Exception ex) { + KUtil.LogErr(ex); + } + } + } + KUtil.Log("Socket服务已关闭"); + } + + public static Document OpenDoc(string path, bool readOnly) { + KUtil.Log("打开:"+path); + Document doc = Application.DocumentManager.Open(path, readOnly); + Application.DocumentManager.MdiActiveDocument = doc; + return doc; + } + + public static void CloseAllDoc() { + foreach (Document doc in Application.DocumentManager) { + doc.CloseAndDiscard(); + } + } + + public static void CloseDoc(Document doc, bool save) { + if (doc == null) { + return; + } + KUtil.Log("关闭:"+doc.Name+",保存:"+save); + if (save) { + doc.CloseAndSave(doc.Name); + } + else { + doc.CloseAndDiscard(); + } + KUtil.Log("关闭完成"); + } + + public string ProcessRequest(string request) { + string[] split = request.Split(REQUEST_SPLITTER); + int len = KUtil.GetLen(split); + if (len == 0) { + return "无请求信息"; + } + // CloseAllDoc(); + string command = split[0].Trim().ToUpper(); + string tukuai = null; + switch (command) { + case CMD_CONVERT_PDF: + bgWorker.ProgressDetail("转换PDF"); // 文件路径 标题栏名称 MediaName + if (len < 3) { + throw new Exception("参数错误"); + } + bgWorker.pbDialog.Dispatcher.Invoke(new Action(delegate { + Document doc = OpenDoc(split[1].Trim(), true); + try { + using (DocumentLock docLock = doc.LockDocument()) { + tukuai = ConvertPDFCommand.ConvertPDF(doc, plotInfos); + } + } + finally { + CloseDoc(doc, false); + } + // 后台打开图纸 + //using (Database db = new Database(false, true)) { + // db.ReadDwgFile(split[1].Trim(), FileOpenMode.OpenForReadAndAllShare, false, null); + // db.CloseInput(true); + // ConvertPDFCommand.ConvertPDF(db, split[1].Trim(), plotInfos); + // db.Dispose(); + //} + })); + break; + case CMD_SYNC_PROPERTIES: + bgWorker.ProgressDetail("同步属性"); + if (len < 3) { + throw new Exception("参数错误"); + } + bgWorker.pbDialog.Dispatcher.Invoke(new Action(delegate { + // 前台打开图纸 + Document doc = OpenDoc(split[1].Trim(), false); + try { + //new ReadInfoCommand().ExecuteCommand(doc); + new ReadInfoCommand(split[1].Trim()).Execute(); + } + finally { + CloseDoc(doc, true); + } + // new ReadInfoCommand(split[1].Trim()).Execute(); + + // 后台打开图纸 + //using (Database db = new Database(false, true)) { + // db.ReadDwgFile(split[1].Trim(), FileOpenMode.OpenForReadAndAllShare, false, null); + // db.CloseInput(true); + // new ReadInfoCommand(split[1].Trim()).Execute(); + // // new ReadInfoCommand().ExecuteCommand(db, split[1].Trim()); + // //db.SaveAs(split[1].Trim(), DwgVersion.Current); // 不能用这里的保存 + // db.Dispose(); + //} + })); + break; + default: + return "未知命令\""+command+"\""; + } + if ("OFF".Equals(tukuai)) { + return tukuai; + } + return SUCCESS_MESSAGE; + } + + private void InitCommand() { + string[] titleBlockNames = ConfigUtil.GetValue("titles").Split(';'); + string[] mediaNames = ConfigUtil.GetValue("media_names").Split(';'); + string[] rotates = ConfigUtil.GetValue("rotates").Split(';'); + int len = KUtil.GetLen(titleBlockNames); + for (int i = 0; i < len; i++) { + PlotData plot = PlotData.Parse(i, titleBlockNames, mediaNames, rotates); + if (plot == null) { + break; + } + KUtil.Log("添加打印信息: " + plot.TitleBlockName + "|" + plot.MediaName + "|" + plot.Rotate); + KUtil.Put(plotInfos, plot.TitleBlockName, plot); + } + if (plotInfos.Count == 0) { + throw new Exception("未配置PDF转换数据"); + } + } + + public void ExecuteCommand() { + InitCommand(); + bgWorker.Start(null); + } + + } +} diff --git a/connor_zwcadm/commands/SyncBomCommand.cs b/connor_zwcadm/commands/SyncBomCommand.cs new file mode 100644 index 0000000..07fb07a --- /dev/null +++ b/connor_zwcadm/commands/SyncBomCommand.cs @@ -0,0 +1,62 @@ +using connor_zwcadm.dialog; +using connor_zwcadm.model; +using connor_zwcadm.util; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ZwSoft.ZwCAD.ApplicationServices; + +namespace connor_zwcadm.commands { + public class SyncBomCommand : AbstractCADCommand { + private KBackgroundWorker bgWorker { get; } + public TCUtil TCUtil { get; } + + public SyncBomCommand(string file_path):base(file_path) { + bgWorker = new KBackgroundWorker(); + bgWorker.backgroundWorker.DoWork += DoSync; + TCUtil = new TCUtil(bgWorker); + } + + public void DoSync(object sender, DoWorkEventArgs e) { + bgWorker.Progress("初始化", "", 0); + InitCommand(); + //读取图纸数据 + bgWorker.Progress("读取对象数据", 40); + FrameInfo frameInfo = KCADUtil.ReadFrame(); + TCData titleData = KCADUtil.ReadDocData(false, TCUtil); + List saveBomConfig = KCADUtil.GetSaveConfig(frameInfo.Bom_Name, TCUtil); + TCData bomConfig = TCData.Parse(saveBomConfig); + if (bomConfig == null) { + throw new System.Exception("首选项配置错误:" + KMain.PREF_PROP_CONFIG_PREFIX + frameInfo.Bom_Name); + } + Dictionary cadProps = TCUtil.ReadTCData(titleData); + bgWorker.Progress("读取BOM数据", 80); + List> cadBomProps = TCUtil.ReadBomData(bomConfig, titleData.Rev); + KUtil.Log("BOM数量:"+(cadBomProps==null?0:cadBomProps.Count)); + if (cadBomProps == null || cadBomProps.Count == 0) { + throw new Exception("零组件无BOM结构,取消更新"); + } + //更新图纸数据 + bgWorker.Progress("更新图纸", 90); + bgWorker.pbDialog.Dispatcher.Invoke(new Action(delegate { + KCADUtil.WriteBom(cadBomProps); + //using (DocumentLock docLoc = doc.LockDocument()) { + // doc.Editor.Regen(); + //} + })); + bgWorker.Progress("更新完成", "", 100); + System.Threading.Thread.Sleep(800); + } + + protected override void InitCommand() { + } + + protected override void ExecuteCommand() { + bgWorker.Start(null); + } + + } +} diff --git a/connor_zwcadm/commands/SyncBomLineCommand.cs b/connor_zwcadm/commands/SyncBomLineCommand.cs new file mode 100644 index 0000000..9071a07 --- /dev/null +++ b/connor_zwcadm/commands/SyncBomLineCommand.cs @@ -0,0 +1,63 @@ +using connor_zwcadm.dialog; +using connor_zwcadm.model; +using connor_zwcadm.util; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using ZwmToolKitLib; + +namespace connor_zwcadm.commands { + class SyncBomLineCommand : AbstractCADCommand { + private KBackgroundWorker bgWorker { get; } + public TCUtil TCUtil { get; } + + public SyncBomLineCommand(string file_path) : base(file_path) { + bgWorker = new KBackgroundWorker(); + bgWorker.backgroundWorker.DoWork += DoSync; + TCUtil = new TCUtil(bgWorker); + } + + public void DoSync(object sender, DoWorkEventArgs e) { + String err = ""; + bgWorker.Progress("初始化", "", 0); + InitCommand(); + //读取图纸数据 + bgWorker.Progress("读取图纸Bom", 30); + Dictionary bomlineMap = KCADUtil.ReadCADBomLine(TCUtil); + KUtil.Log("BOM数量:" + (bomlineMap == null ? 0 : bomlineMap.Count)); + if (bomlineMap == null || bomlineMap.Count == 0) { + throw new Exception("图纸中无有效BOM信息,取消更新"); + } + bgWorker.Progress("读取BOM数据", 50); + Dictionary> propMap = new Dictionary>(); + foreach (int row in bomlineMap.Keys) { + TCData data = bomlineMap[row]; + Dictionary props = TCUtil.ReadTCData(data); + propMap.Add(row, props); + } + //更新图纸数据 + bgWorker.Progress("更新图纸", 90); + bgWorker.pbDialog.Dispatcher.Invoke(new Action(delegate { + err = KCADUtil.WriteBomLine(propMap); + + })); + bgWorker.Progress("更新完成", "", 100); + System.Threading.Thread.Sleep(800); + if (!("".Equals(err.Trim()))) + { + MessageBox.Show("明细栏更新成功,但第" + err + "行数据更新失败,在TC系统中未找到对应的对象!!!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); + } + } + + protected override void InitCommand() { + } + + protected override void ExecuteCommand() { + bgWorker.Start(null); + } + } +} diff --git a/connor_zwcadm/commands/SyncTitleCommand.cs b/connor_zwcadm/commands/SyncTitleCommand.cs new file mode 100644 index 0000000..515bb82 --- /dev/null +++ b/connor_zwcadm/commands/SyncTitleCommand.cs @@ -0,0 +1,265 @@ +using connor_zwcadm.dialog; +using connor_zwcadm.model; +using connor_zwcadm.util; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ZwSoft.ZwCAD.ApplicationServices; +using ZwSoft.ZwCAD.DatabaseServices; +using ZwSoft.ZwCAD.EditorInput; + +namespace connor_zwcadm.commands { + public class SyncTitleCommand : AbstractCADCommand { + + private KBackgroundWorker bgWorker { get; } + public TCUtil TCUtil { get; } + public SyncTitleCommand(Document doc):base(doc.Name) { + bgWorker = new KBackgroundWorker(); + bgWorker.backgroundWorker.DoWork += DoSync; + TCUtil = new TCUtil(bgWorker); + Test(doc, TCUtil); + } + + public void DoSync(object sender, DoWorkEventArgs e) { + bgWorker.Progress("初始化", "", 0); + //读取图纸数据 + bgWorker.Progress("读取图纸数据", 20); + TCData titleData = KCADUtil.ReadDocData(false, TCUtil); + Dictionary cadProps = TCUtil.ReadTCData(titleData); + //更新图纸数据 + bgWorker.Progress("更新图纸数据", 80); + bgWorker.pbDialog.Dispatcher.Invoke(new Action(delegate { + KCADUtil.WriteTitle(cadProps); + // using (DocumentLock docLoc = doc.LockDocument()) { + // // CADUtil.UpdateBlockProperty(doc.Database, titleData.BlockName, cadProps, IsMechanical, doc.Name); + //} + })); + KUtil.Log("更新完成"); + bgWorker.Progress("更新完成", "", 100); + System.Threading.Thread.Sleep(800); + } + + protected override void InitCommand() { + } + + protected override void ExecuteCommand() { + bgWorker.Start(null); + } + public static string Test(Document doc, TCUtil tcUtil) + { + // 1. 基础检查与路径处理 + if (doc == null) + { + throw new Exception("图纸不能为null"); + } + + string cadPath = doc.Name; + KUtil.Log("转PDF: " + cadPath); + string path = cadPath.Substring(0, cadPath.Length - 4) + ".pdf"; + KUtil.Log("PDF路径:" + path); + + Database db = doc.Database; + Editor ed = doc.Editor; // 获取编辑器用于输出消息(可选) + + + + string prefName = KMain.PREF_PROP_CONFIG_PREFIX + "力邦更改栏"; + string[] prefVals = tcUtil.GetPrefValues(prefName); + KUtil.Log("读取同步配置:" + prefName); + int len = prefVals == null ? 0 : prefVals.Length; + List res = new List(); + for (int i = 0; i < len; i++) + { + string config = prefVals[i]; + int ind = config.IndexOf('='); + if (ind <= 0) + { + continue; + } + // KUtil.Log(">> "+config); + string tcConfig = config.Substring(0, ind); + string cadConfig = config.Substring(ind + 1); + PropertyInfo info = PropertyInfo.parse(cadConfig, tcConfig); + if (info == null) + { + KUtil.Log("无效配置: " + config); + continue; + } + + KUtil.Log("info: " + info.TcPropName); + KUtil.Log("info: " + info.Location); + KUtil.Log("info: " + info.CadPropName); + res.Add(info); + } + + + Dictionary propMap = new Dictionary(); + + string th = ""; + string bb = ""; + + using (Transaction tran = db.TransactionManager.StartTransaction()) + { + + BlockTable blt = tran.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable; + + + BlockTableRecord bltr = tran.GetObject(db.CurrentSpaceId, OpenMode.ForRead) as BlockTableRecord; + + + foreach (ObjectId item in bltr) + { + // 先以只读方式打开,提高性能 + Entity ent = tran.GetObject(item, OpenMode.ForRead) as Entity; + + // 优化判断:直接使用 is 关键字,比 GetType().Name 更安全高效 + if (ent is BlockReference bref) + { + if (bref.Name.Contains("更改栏")) + { + if (bref.AttributeCollection.Count > 0) + { + foreach (ObjectId attId in bref.AttributeCollection) + { + AttributeReference aRef = tran.GetObject(attId, OpenMode.ForRead) as AttributeReference; + + if (aRef != null) + { + KUtil.Put(propMap, aRef.Tag, aRef.TextString); + } + } + } + } + + + if (bref.Name.Contains("标题栏")) + { + if (bref.AttributeCollection.Count > 0) + { + foreach (ObjectId attId in bref.AttributeCollection) + { + AttributeReference aRef = tran.GetObject(attId, OpenMode.ForRead) as AttributeReference; + + if (aRef != null) + { + if (aRef.Tag == "图号") { + th = aRef.TextString; + } + else if (aRef.Tag == "版本") + { + bb = aRef.TextString; + } + } + } + } + } + } + } + + } + + KUtil.Log("--------------"+KUtil.PrintDictionary(propMap)); + + + + TCData titleData = TCData.Parse(res, propMap); + + KUtil.Log("1"); + + + Dictionary cadProps = tcUtil.ReadTCData2(titleData,th,bb); + + KUtil.Log("--------------1" + KUtil.PrintDictionary(cadProps)); + + + + + + + using (Transaction tran = db.TransactionManager.StartTransaction()) + { + KUtil.Log("3. 开始事务"); + BlockTable blt = tran.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable; + + KUtil.Log("4. 获取块表"); + // 注意:这里只遍历了当前空间 (CurrentSpaceId)。 + // 如果标题栏在布局(Layout)中而当前在模型空间,可能遍历不到。 + // 如果需要遍历所有布局,逻辑需要扩展(见下方提示)。 + BlockTableRecord bltr = tran.GetObject(db.CurrentSpaceId, OpenMode.ForRead) as BlockTableRecord; + + KUtil.Log("5. 开始遍历实体"); + foreach (ObjectId item in bltr) + { + // 先以只读方式打开,提高性能 + Entity ent = tran.GetObject(item, OpenMode.ForRead) as Entity; + + // 优化判断:直接使用 is 关键字,比 GetType().Name 更安全高效 + if (ent is BlockReference bref) + { + + if (bref.Name.Contains("更改栏")) + { + + + KUtil.Log("发现块引用:" + bref.Name); + + if (bref.AttributeCollection.Count > 0) + { + // 遍历属性集合 + foreach (ObjectId attId in bref.AttributeCollection) + { + // 先以只读方式打开属性 + AttributeReference aRef = tran.GetObject(attId, OpenMode.ForRead) as AttributeReference; + + if (aRef != null) + { + + + + foreach (KeyValuePair item2 in cadProps) + { + string key = item2.Key; // 属性标签 (Tag),例如 "PROJECT_NAME" + string value = item2.Value; // 属性值 (TextString),例如 "某某大厦项目" + // 【核心逻辑】检查 Tag 是否为 "编制" + // 注意:Tag 区分大小写,请确认 CAD 中该属性的 Tag 确实是 "编制" + // 有时可能是 "DESIGNER", "DRAWN_BY" 等,如果不确定可以先打印 aRef.Tag 看看 + if (aRef.Tag.Equals(key)) + { + // 【关键步骤】升级为写模式,否则无法赋值 + aRef.UpgradeOpen(); + + // 设置新值 + aRef.TextString = value; + + KUtil.Log($"已修改块 '{bref.Name}' ======: {value}"); + + // 如果只需要修改第一个找到的,可以在这里 break; + // 如果要修改所有符合条件的块,则继续循环 + } + } + + + + + + + } + } + } + } + } + } + + // 提交事务,保存修改 + tran.Commit(); + KUtil.Log("事务已提交,属性修改生效"); + } + + KUtil.Log("转换PDF完成(属性已预设置)"); + return path; + } + } +} diff --git a/connor_zwcadm/connor_zwcadm.csproj b/connor_zwcadm/connor_zwcadm.csproj new file mode 100644 index 0000000..9304e10 --- /dev/null +++ b/connor_zwcadm/connor_zwcadm.csproj @@ -0,0 +1,277 @@ + + + + + Debug + AnyCPU + {F9F68DF3-2A14-4F45-998D-5497AC9047D8} + Library + Properties + connor_zwcadm + connor_zwcadm + v4.6.2 + 512 + true + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + x64 + Auto + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + x64 + true + + + true + bin\x64\Debug\ + DEBUG;TRACE + full + x64 + 7.3 + prompt + + + bin\x64\Release\ + TRACE + true + true + pdbonly + x64 + 7.3 + prompt + + + + tclib\FCCNetClientProxy40.dll + + + tclib\FMSNetTicket40.dll + + + tclib\FSCNetClientProxy40.dll + + + ..\net\libs\ICSharpCode.SharpZipLib.dll + + + ..\2018\Interop.ZWCAD.dll + True + + + ..\2018\Interop.ZwmToolKitLib.dll + True + + + tclib\log4net.dll + + + + + + tclib\Serilog.dll + + + tclib\Serilog.Settings.AppSettings.dll + + + tclib\Serilog.Sinks.Console.dll + + + tclib\Serilog.Sinks.Email.dll + + + tclib\Serilog.Sinks.EventLog.dll + + + tclib\Serilog.Sinks.File.dll + + + tclib\Serilog.Sinks.PeriodicBatching.dll + + + tclib\Serilog.Sinks.RollingFile.dll + + + + + + + + + + + + + + + + False + ..\tc12\TcMemNetBinding40.dll + + + False + ..\tc12\TcMemNetBindingInterface40.dll + + + ..\tc12\TcServerNetBinding40.dll + + + False + ..\tc12\TcServerNetBindingInterface40.dll + + + False + ..\tc12\TcSoaAdministrationLoose.dll + + + tclib\TcSoaCadBomAlignmentStrong.dll + + + False + ..\tc12\TcSoaCadLoose.dll + + + False + ..\tc12\TcSoaClient.dll + + + False + ..\tc12\TcSoaCommon.dll + + + False + ..\tc12\TcSoaCoreStrong.dll + + + False + ..\tc12\TcSoaFMS.dll + + + False + ..\tc12\TcSoaQueryStrong.dll + + + False + ..\tc12\TcSoaStrongModel.dll + + + ..\net\libs\Teamcenter_SSO.dll + + + ..\net\libs\Teamcenter_SSOloader.dll + + + + False + ..\2018\ZwDatabaseMgd.dll + + + False + ..\2018\ZwManaged.dll + + + + + + + + + + + + + + + + + + + + + KProgressBar.xaml + + + Login.xaml + + + + + + + + + + + + + True + True + Resources.resx + + + + + + + + + + + + {00020430-0000-0000-C000-000000000046} + 2 + 0 + 0 + primary + False + True + + + + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + + Designer + + + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + + + + + + + + + \ No newline at end of file diff --git a/connor_zwcadm/dialog/KBackgroundWorker.cs b/connor_zwcadm/dialog/KBackgroundWorker.cs new file mode 100644 index 0000000..22fdfce --- /dev/null +++ b/connor_zwcadm/dialog/KBackgroundWorker.cs @@ -0,0 +1,101 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.ComponentModel; +using connor_zwcadm.util; + +namespace connor_zwcadm.dialog { + public class KBackgroundWorker { + public BackgroundWorker backgroundWorker { get; } + private Window parent; + public KProgressBar pbDialog; + public string CompleteMessage { get; set; } + + public KBackgroundWorker(string completeMessage=null, Window parent = null) { + this.parent = parent; + this.CompleteMessage = completeMessage; + //可以返回工作进度 + backgroundWorker = new BackgroundWorker(); + backgroundWorker.WorkerReportsProgress = true; + //允许取消 + backgroundWorker.WorkerSupportsCancellation = true; + backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted; + //更新进度条 + backgroundWorker.ProgressChanged += backgroundWorker_ProgressChanged; + } + + public void Start(object param, bool disableCancel = true) { + if (backgroundWorker.IsBusy) { + return; + } + if (parent != null) { + parent.IsEnabled = false; + } + pbDialog = new KProgressBar(backgroundWorker); + if (disableCancel) { + pbDialog.tb_cancel.Width = 0; + pbDialog.tb_cancel.Visibility = Visibility.Hidden; + } + backgroundWorker.RunWorkerAsync(param); + } + + public bool IsCancel() { + return backgroundWorker.CancellationPending; + } + + + private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { + pbDialog.Dispatcher.Invoke(new Action(delegate { + pbDialog.Close(); + })); + if (parent != null) { + parent.IsEnabled = true; + } + if (e.Error != null) { + KUtil.LogErr(e.Error); + ZwSoft.ZwCAD.ApplicationServices.Application.ShowAlertDialog(e.Error.Message); + } + else { + if (e.Cancelled) { + ZwSoft.ZwCAD.ApplicationServices.Application.ShowAlertDialog("已取消"); + } + else if(!string.IsNullOrWhiteSpace(CompleteMessage)) { + ZwSoft.ZwCAD.ApplicationServices.Application.ShowAlertDialog(CompleteMessage); + } + } + } + + private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) { + pbDialog.Dispatcher.Invoke(new Action(delegate { + pbDialog.progressBar.Value = e.ProgressPercentage; + })); + } + + public void Progress(string text, string detail, int progress) { + pbDialog.Dispatcher.Invoke(new Action(delegate { + pbDialog.l_MainProgress.Content = text; + pbDialog.l_SubProcess.Content = detail; + })); + if (progress >= 0) { + backgroundWorker.ReportProgress(progress); + } + } + + public void Progress(string text, int progress) { + Progress(text, text, progress); + } + + public void ProgressDetail(string text) { + pbDialog.Dispatcher.Invoke(new Action(delegate { + pbDialog.l_SubProcess.Content = text; + })); + } + + public void Progress(string text, int index, int limit) { + Progress(text, (index + 1) * 100 / limit); + } + } +} diff --git a/connor_zwcadm/dialog/KProgressBar.xaml b/connor_zwcadm/dialog/KProgressBar.xaml new file mode 100644 index 0000000..cefd140 --- /dev/null +++ b/connor_zwcadm/dialog/KProgressBar.xaml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + diff --git a/connor_zwcadm/dialog/KProgressBar.xaml.cs b/connor_zwcadm/dialog/KProgressBar.xaml.cs new file mode 100644 index 0000000..cf87eb5 --- /dev/null +++ b/connor_zwcadm/dialog/KProgressBar.xaml.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace connor_zwcadm.dialog { + /// + /// KProgressBar.xaml 的交互逻辑 + /// + public partial class KProgressBar : Window { + + private BackgroundWorker backgroundWorker; + + public KProgressBar(BackgroundWorker backgroundWorker, Window parent = null) { + InitializeComponent(); + if (parent == null) { + util.UIUtil.SetOwnerWindow(this); + } + else { + Owner = parent; + } + + this.backgroundWorker = backgroundWorker; + } + + private void Window_MouseDown(object sender, MouseButtonEventArgs e) { + if (e.ChangedButton == MouseButton.Left) + this.DragMove(); + } + + private void CancelWork(object sender, RoutedEventArgs e) { + backgroundWorker.CancelAsync(); + Close(); + } + } +} diff --git a/connor_zwcadm/dialog/Login.xaml b/connor_zwcadm/dialog/Login.xaml new file mode 100644 index 0000000..54db8be --- /dev/null +++ b/connor_zwcadm/dialog/Login.xaml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + +