diff --git a/README.md b/README.md
index c1f01f0..55961dd 100644
--- a/README.md
+++ b/README.md
@@ -30,16 +30,16 @@
```
成套报价软件\ 主程序源码(MainForm 拆 14 个 partial;xiangmu/shezhi/ku 子模块窗体)
- └ 扒图\ CAD/PDF 扒图窗口 + OCR/PDF 基础设施(唯一权威源,pdfbt 链接共享)
-cadbt\ CAD 扒图独立程序(含 CAD-Viewer 网页引擎)
-pdfbt\ PDF 扒图独立程序(OCR 等基础设施链接主项目扒图\ 源码)
+ └ 扒图\ CAD/PDF 扒图窗口 + OCR/PDF 基础设施(唯一权威源)
+cadbt\ CAD 网页引擎运行时(node.exe + CAD-Viewer;2026-10-01 独立 cadbt.exe 退役)
ai助手\ ZCode 引擎发行包 + 启停脚本(发行包不进 git)
会员服务器\ 肥牛 fnnas 会员服务端 v1.5.1(fpk 工程)
tools\ 构建/打包/维护脚本(见下表)
release\ 组装产物(仅 setup.iss 进 git)
-ghj\ yjktool\ 历史试验小工具
```
+(已退役:独立 cadbt.exe/pdfbt.exe 扒图程序、ghj/yjktool 试验小工具、cadcj 旧 AutoCAD 插件——扒图功能全部由主程序内嵌窗口承载。)
+
**数据目录**(运行时,均不进 git):`sjk\bjb\项目<编号>.db` 每项目一库;`sjk\fak.db` 公式库;`sjk\方案库\*.db` 一方案一库;`shezhi\` 用户配置;`xiangmu\` 报表模板。
## 构建与验证
diff --git a/cadbt/cadbt.sln b/cadbt/cadbt.sln
deleted file mode 100644
index 12435b1..0000000
--- a/cadbt/cadbt.sln
+++ /dev/null
@@ -1,20 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2012
-# SharpDevelop 5.2
-VisualStudioVersion = 12.0.20827.3
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "cadbt", "cadbt\cadbt.csproj", "{0A91D57B-B279-4672-9440-78088D022EB1}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {0A91D57B-B279-4672-9440-78088D022EB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {0A91D57B-B279-4672-9440-78088D022EB1}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {0A91D57B-B279-4672-9440-78088D022EB1}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {0A91D57B-B279-4672-9440-78088D022EB1}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
-EndGlobal
diff --git a/cadbt/cadbt/CadBridge.cs b/cadbt/cadbt/CadBridge.cs
deleted file mode 100644
index 48c3421..0000000
--- a/cadbt/cadbt/CadBridge.cs
+++ /dev/null
@@ -1,213 +0,0 @@
-// ============================================================
-// CadBridge:WinForms 宿主与网页 CAD(CAD-Viewer)之间的互操作桥
-// · 下行(C#→网页):PostMessage 发 startPick/zoomToHandle/deleteHandles/clearHighlight
-// · 上行(网页→C#):WebMessageReceived 收 paPicked/entityErased/paExited
-// · 扒图结果与实体删除事件以 C# 事件形式提供给 Form3(替代 AutoCAD 版
-// 的 PaTextSelector.BatchTextsPicked 与 Database.ObjectErased)
-// ============================================================
-using System;
-using System.Collections.Generic;
-using System.Web.Script.Serialization;
-using Microsoft.Web.WebView2.Core;
-using Microsoft.Web.WebView2.WinForms;
-
-namespace cadbt
-{
- public static class CadBridge
- {
- private static WebView2 _wv;
- private static readonly JavaScriptSerializer _json = new JavaScriptSerializer();
-
- /// 网页 CAD 是否已挂载(WebView2 已附加)。
- public static bool IsViewerReady
- {
- get { return _wv != null && _wv.CoreWebView2 != null; }
- }
-
- /// 网页 CAD 中实体被删除(句柄十六进制字符串)。
- public static event Action EntityErased;
-
- /// 网页 CAD 扒图完成一批(图号/箱号/元件)。
- public static event Action> PaPicked;
-
- /// 用户按 ESC 退出网页扒图连续模式。
- public static event Action PaExited;
-
- /// 用户按 F1(焦点在网页或宿主时都触发)——元件两两合并。
- public static event Action F1Requested;
-
- /// 用户按 F2——元件三个一组合并。
- public static event Action F2Requested;
-
- /// 用户按 F3——元件四个一组合并。
- public static event Action F3Requested;
-
- /// 触发 F1 请求(消息过滤器等宿主侧来源调用)。
- public static void RaiseF1()
- {
- if (F1Requested != null) F1Requested();
- }
-
- /// 触发 F2 请求(消息过滤器等宿主侧来源调用)。
- public static void RaiseF2()
- {
- if (F2Requested != null) F2Requested();
- }
-
- /// 触发 F3 请求(消息过滤器等宿主侧来源调用)。
- public static void RaiseF3()
- {
- if (F3Requested != null) F3Requested();
- }
-
- /// 把 WebView2 挂到桥上(在控件初始化完成后调用一次)。
- public static void Attach(WebView2 wv)
- {
- if (_wv == wv) return;
- if (_wv != null) _wv.WebMessageReceived -= OnMessage;
- _wv = wv;
- if (_wv != null) _wv.WebMessageReceived += OnMessage;
- }
-
- private static void OnMessage(object sender, CoreWebView2WebMessageReceivedEventArgs e)
- {
- try
- {
- if (e.TryGetWebMessageAsString() != null) return; // 只处理 JSON 消息
- }
- catch { }
- try
- {
- var msg = _json.Deserialize>(e.WebMessageAsJson);
- if (msg == null || !msg.ContainsKey("type")) return;
- string type = msg["type"] as string;
-
- if (type == "paPicked")
- {
- int mode = Convert.ToInt32(msg["mode"]);
- var results = new List();
- var arr = msg["results"] as System.Collections.ArrayList;
- if (arr != null)
- {
- foreach (Dictionary item in arr)
- {
- results.Add(new MyApp.PaTextResult
- {
- Text = Convert.ToString(item["text"]) ?? "",
- FrameHandle = Convert.ToString(item["frameHandle"]) ?? "",
- TextHandle = Convert.ToString(item["textHandle"]) ?? ""
- });
- }
- }
- // WebMessageReceived 在 UI 线程触发,可直接调用 Form3
- if (PaPicked != null)
- PaPicked((MyApp.PaMode)mode, results);
- }
- else if (type == "entityErased")
- {
- string handle = Convert.ToString(msg["handle"]);
- if (!string.IsNullOrWhiteSpace(handle) && EntityErased != null)
- EntityErased(handle);
- }
- else if (type == "paError")
- {
- string errMsg = Convert.ToString(msg["message"]);
- System.Windows.Forms.MessageBox.Show(
- "网页 CAD 返回错误:\n" + errMsg,
- "扒数据", System.Windows.Forms.MessageBoxButtons.OK,
- System.Windows.Forms.MessageBoxIcon.Warning);
- }
- else if (type == "f1")
- {
- if (F1Requested != null) F1Requested();
- }
- else if (type == "f2")
- {
- if (F2Requested != null) F2Requested();
- }
- else if (type == "f3")
- {
- if (F3Requested != null) F3Requested();
- }
- else if (type == "paExited")
- {
- if (PaExited != null) PaExited();
- }
- }
- catch (Exception)
- {
- // 消息格式异常直接忽略,不影响宿主
- }
- }
-
- private static void Post(object msg)
- {
- if (!IsViewerReady) return;
- try
- {
- _wv.CoreWebView2.PostWebMessageAsJson(_json.Serialize(msg));
- }
- catch { }
- }
-
- ///
- /// 发送扒图命令。接受原 CAD 命令名(CADPATU/CADPAXH/CADPAYJ/CADPACL)
- /// 或网页命令名(patu/paxh/payj)。
- ///
- public static void SendPaCommand(string cmd)
- {
- if (string.IsNullOrWhiteSpace(cmd)) return;
- string c = cmd.Trim().ToUpperInvariant();
- int mode = 0;
- if (c == "CADPATU" || c == "PATU") mode = 0;
- else if (c == "CADPAXH" || c == "PAXH") mode = 1;
- else if (c == "CADPAYJ" || c == "PAYJ") mode = 2;
- else if (c == "CADPACL" || c == "PACL")
- {
- ClearHighlight();
- return;
- }
- else return;
- Post(new { type = "startPick", mode = mode });
- }
-
- /// 缩放居中到指定 Handle 的实体并高亮(点击表格行定位框)。
- public static void ZoomToFrameHandle(string handle)
- {
- if (string.IsNullOrWhiteSpace(handle)) return;
- Post(new { type = "zoomToHandle", handle = handle });
- }
-
- /// 批量删除指定 Handle 的实体(删表格行联动删框)。
- public static void DeleteFramesByHandles(IEnumerable handles)
- {
- if (handles == null) return;
- var list = new List();
- foreach (string h in handles)
- if (!string.IsNullOrWhiteSpace(h)) list.Add(h);
- if (list.Count == 0) return;
- Post(new { type = "deleteHandles", handles = list });
- }
-
- ///
- /// 合并蒙版:保留 keep 句柄的蒙版并扩大到所有 removes 蒙版的并集,
- /// 被合并行的蒙版从网页 CAD 移除(元件合并时蒙版同步合并)。
- ///
- public static void MergeMasks(string keep, System.Collections.Generic.IEnumerable removes)
- {
- if (string.IsNullOrWhiteSpace(keep)) return;
- var list = new List();
- if (removes != null)
- foreach (string h in removes)
- if (!string.IsNullOrWhiteSpace(h) && h != keep) list.Add(h);
- if (list.Count == 0) return;
- Post(new { type = "mergeMasks", keep = keep, removes = list });
- }
-
- /// 清除网页 CAD 中的所有高亮。
- public static void ClearHighlight()
- {
- Post(new { type = "clearHighlight" });
- }
- }
-}
diff --git a/cadbt/cadbt/DockWindows/CadViewerWindow.Designer.cs b/cadbt/cadbt/DockWindows/CadViewerWindow.Designer.cs
deleted file mode 100644
index fb81aee..0000000
--- a/cadbt/cadbt/DockWindows/CadViewerWindow.Designer.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-namespace cadbt.DockWindows
-{
- partial class CadViewerWindow
- {
- private System.ComponentModel.IContainer components = null;
-
- protected override void Dispose(bool disposing)
- {
- if (disposing && (components != null)) components.Dispose();
- base.Dispose(disposing);
- }
-
- #region Designer generated code
-
- private void InitializeComponent()
- {
- this.SuspendLayout();
- //
- // CadViewerWindow
- //
- this.Name = "CadViewerWindow";
- this.ResumeLayout(false);
- }
-
- #endregion
- }
-}
diff --git a/cadbt/cadbt/DockWindows/CadViewerWindow.cs b/cadbt/cadbt/DockWindows/CadViewerWindow.cs
deleted file mode 100644
index 83d85c9..0000000
--- a/cadbt/cadbt/DockWindows/CadViewerWindow.cs
+++ /dev/null
@@ -1,187 +0,0 @@
-// ============================================================
-// 停靠窗口:CAD 查看器(中央文档区)
-// WebView2 承载网页版 CAD-Viewer(localhost:5173),并挂到 CadBridge。
-// ★ 网页服务自启动:exe 旁 node\node.exe + CAD-Viewer\dist\server.cjs
-// (静态产物零依赖,客户机无需 Node 环境/pnpm dev;主程序同款端口探测模式)
-// ============================================================
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Net.Sockets;
-using System.Windows.Forms;
-using Microsoft.Web.WebView2.WinForms;
-
-namespace cadbt.DockWindows
-{
- /// 停靠窗口:网页 CAD 查看器(DockState.Document)。
- public partial class CadViewerWindow : WeifenLuo.WinFormsUI.Docking.DockContent
- {
- private WebView2 _webView;
- private Label _hint;
-
- /// 静态服务进程句柄(退出时杀进程树)。
- private static Process _serverProcess;
-
- public CadViewerWindow()
- {
- InitializeComponent();
- Text = "CAD 查看器";
- TabText = "CAD 查看器";
- FormClosed += (s, e) => 停止网页服务();
- LoadViewer();
- }
-
- /// CAD 网页服务端口(与 server.cjs 一致)。
- private const int 服务端口 = 5173;
-
- private async void LoadViewer()
- {
- try
- {
- _webView = new WebView2();
- _webView.Dock = DockStyle.Fill;
- Controls.Add(_webView);
- await _webView.EnsureCoreWebView2Async(null);
- CadBridge.Attach(_webView);
-
- // ★ 禁用浏览器快捷键(F5/Ctrl+R/Ctrl+F 等):刷新会丢掉所有扒图蒙版
- _webView.CoreWebView2.Settings.AreBrowserAcceleratorKeysEnabled = false;
-
- // ★ 先确保静态服务在线(复刻主程序 StartPriceWebView 的探测+拉起模式)
- 启动网页服务();
-
- // 服务不可达时给用户明确提示
- _webView.CoreWebView2.NavigationCompleted += (s, e) =>
- {
- if (!e.IsSuccess && _hint == null)
- ShowLoadHint("无法连接网页 CAD 服务(端口 " + 服务端口 + ")。\r\n请确认 cadbt\\node\\node.exe 与 cadbt\\CAD-Viewer\\dist 目录完整,然后点击\"重新加载\"。");
- };
- _webView.CoreWebView2.Navigate("http://localhost:" + 服务端口 + "/");
- }
- catch (Exception ex)
- {
- ShowLoadHint("WebView2 初始化失败: " + ex.Message + "\r\n请确认系统已安装 Microsoft Edge WebView2 运行时。");
- }
- }
-
- /// 启动 CAD 网页静态服务(端口已通=复用;不通=node server.cjs 后台拉起)。
- private void 启动网页服务()
- {
- try
- {
- if (端口已通()) return; // 上次实例或手动 dev server 已在服务
-
- string baseDir = AppDomain.CurrentDomain.BaseDirectory;
- string nodeExe = Path.Combine(baseDir, "node", "node.exe");
- // dist 与 server.cjs 同目录;找不到时尝试上一级 CAD-Viewer 结构(开发机)
- // 安装布局: {app}\cadbt\CAD-Viewer\dist\ (make_package 已展平 packages 层)
- string serverScript = Path.Combine(baseDir, "CAD-Viewer", "dist", "server.cjs");
- if (!File.Exists(serverScript))
- {
- // 开发机回退: bin\Debug 上两级 = cadbt\cadbt\,保留 monorepo 原始层级
- serverScript = Path.GetFullPath(Path.Combine(baseDir, @"..\..\CAD-Viewer\packages\cad-viewer-example\dist\server.cjs"));
- }
-
- if (!File.Exists(nodeExe) || !File.Exists(serverScript))
- {
- WriteDiag("[CAD服务] 缺少 node.exe 或 server.cjs: node=" + nodeExe + " script=" + serverScript);
- return;
- }
-
- var psi = new ProcessStartInfo
- {
- FileName = nodeExe,
- Arguments = "\"" + Path.GetFullPath(serverScript) + "\"",
- WorkingDirectory = Path.GetDirectoryName(Path.GetFullPath(serverScript)),
- UseShellExecute = false,
- CreateNoWindow = true,
- WindowStyle = ProcessWindowStyle.Hidden,
- };
- _serverProcess = Process.Start(psi);
- WriteDiag("[CAD服务] 已启动 node PID=" + (_serverProcess == null ? "?" : _serverProcess.Id.ToString()));
-
- // 等端口就绪(最多 8 秒)
- for (int i = 0; i < 40; i++)
- {
- System.Threading.Thread.Sleep(200);
- if (端口已通()) { WriteDiag("[CAD服务] 端口就绪, 耗时 " + (i + 1) * 200 + "ms"); return; }
- }
- WriteDiag("[CAD服务] 端口 8 秒未就绪(继续导航,由 NavigationCompleted 提示)");
- }
- catch (Exception ex) { WriteDiag("[CAD服务] 启动异常: " + ex.Message); }
- }
-
- /// 快速探测本机端口。
- private static bool 端口已通()
- {
- try
- {
- using (var client = new TcpClient())
- {
- var ar = client.BeginConnect("127.0.0.1", 服务端口, null, null);
- bool ok = ar.AsyncWaitHandle.WaitOne(400);
- if (ok && client.Connected) { client.EndConnect(ar); return true; }
- }
- }
- catch { }
- return false;
- }
-
- /// 退出清理:杀 node 静态服务进程树(taskkill /T 覆盖可能的子进程)。
- private void 停止网页服务()
- {
- try
- {
- if (_serverProcess != null && !_serverProcess.HasExited)
- {
- int pid = _serverProcess.Id;
- Process.Start(new ProcessStartInfo("taskkill", "/PID " + pid + " /T /F")
- {
- CreateNoWindow = true, UseShellExecute = false, WindowStyle = ProcessWindowStyle.Hidden
- });
- WriteDiag("[CAD服务] 已停止 PID=" + pid);
- }
- _serverProcess = null;
- }
- catch (Exception ex) { WriteDiag("[CAD服务] 停止异常: " + ex.Message); }
- }
-
- /// 简单诊断日志(logs\cad服务.log)。
- private static void WriteDiag(string msg)
- {
- try
- {
- string dir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "logs");
- Directory.CreateDirectory(dir);
- File.AppendAllText(Path.Combine(dir, "cad服务.log"),
- DateTime.Now.ToString("HH:mm:ss.fff") + " " + msg + Environment.NewLine);
- }
- catch { }
- }
-
- private void ShowLoadHint(string text)
- {
- if (_hint != null) return;
- _hint = new Label();
- _hint.Dock = DockStyle.Fill;
- _hint.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
- _hint.Text = text;
- var reload = new Button();
- reload.Text = "重新加载";
- reload.Dock = DockStyle.Bottom;
- reload.Click += (s, e) =>
- {
- Controls.Remove(_hint);
- _hint.Dispose();
- _hint = null;
- 启动网页服务();
- if (_webView != null && _webView.CoreWebView2 != null)
- _webView.CoreWebView2.Navigate("http://localhost:" + 服务端口 + "/");
- };
- Controls.Add(reload);
- Controls.Add(_hint);
- _hint.BringToFront();
- }
-
- }
-}
diff --git a/cadbt/cadbt/DockWindows/QuoteWindow.Designer.cs b/cadbt/cadbt/DockWindows/QuoteWindow.Designer.cs
deleted file mode 100644
index 8b5f4f7..0000000
--- a/cadbt/cadbt/DockWindows/QuoteWindow.Designer.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-namespace cadbt.DockWindows
-{
- partial class QuoteWindow
- {
- private System.ComponentModel.IContainer components = null;
-
- protected override void Dispose(bool disposing)
- {
- if (disposing && (components != null)) components.Dispose();
- base.Dispose(disposing);
- }
-
- #region Designer generated code
-
- private void InitializeComponent()
- {
- this.SuspendLayout();
- //
- // QuoteWindow
- //
- this.Name = "QuoteWindow";
- this.ResumeLayout(false);
- }
-
- #endregion
- }
-}
diff --git a/cadbt/cadbt/DockWindows/QuoteWindow.cs b/cadbt/cadbt/DockWindows/QuoteWindow.cs
deleted file mode 100644
index b6a572f..0000000
--- a/cadbt/cadbt/DockWindows/QuoteWindow.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-// ============================================================
-// 停靠窗口:报价插件工具栏(左侧)
-// 把 cadcj 的 Form3 报价界面作为子控件嵌入(TopLevel=false)。
-// ============================================================
-using System.Windows.Forms;
-
-namespace cadbt.DockWindows
-{
- /// 停靠窗口:报价插件工具栏(DockState.DockLeft)。
- public partial class QuoteWindow : WeifenLuo.WinFormsUI.Docking.DockContent
- {
- public QuoteWindow()
- {
- InitializeComponent();
- Text = "报价工具";
- TabText = "报价工具";
-
- var form = new MyApp.Form3();
- form.TopLevel = false;
- form.FormBorderStyle = FormBorderStyle.None;
- form.Dock = DockStyle.Fill;
- Controls.Add(form);
- form.Show();
- }
- }
-}
diff --git a/cadbt/cadbt/MainForm.Designer.cs b/cadbt/cadbt/MainForm.Designer.cs
deleted file mode 100644
index e7da564..0000000
--- a/cadbt/cadbt/MainForm.Designer.cs
+++ /dev/null
@@ -1,69 +0,0 @@
-namespace cadbt
-{
- partial class MainForm
- {
- ///
- /// Designer variable used to keep track of non-visual components.
- ///
- private System.ComponentModel.IContainer components = null;
-
- ///
- /// Disposes resources used by the form.
- ///
- /// true if managed resources should be disposed; otherwise, false.
- protected override void Dispose(bool disposing)
- {
- if (disposing) {
- if (components != null) {
- components.Dispose();
- }
- }
- base.Dispose(disposing);
- }
-
- ///
- /// This method is required for Windows Forms designer support.
- /// Do not change the method contents inside the source code editor. The Forms designer might
- /// not be able to load this method if it was changed manually.
- ///
- private void InitializeComponent()
- {
- this.dockSurface1 = new Smart.CustomComponents.DockSurface();
- Smart.CustomComponents.DockWindows.DockWindowItem dockWindowItem1 = new Smart.CustomComponents.DockWindows.DockWindowItem();
- Smart.CustomComponents.DockWindows.DockWindowItem dockWindowItem2 = new Smart.CustomComponents.DockWindows.DockWindowItem();
- this.SuspendLayout();
- //
- // dockSurface1
- //
- dockWindowItem1.ClassName = "QuoteWindow";
- dockWindowItem1.Title = "报价工具";
- dockWindowItem1.DockState = WeifenLuo.WinFormsUI.Docking.DockState.DockLeft;
- dockWindowItem1.DefaultWidth = 440;
- dockWindowItem1.ShowCloseButton = false;
- this.dockSurface1.DockWindows.Add(dockWindowItem1);
- dockWindowItem2.ClassName = "CadViewerWindow";
- dockWindowItem2.Title = "CAD 查看器";
- dockWindowItem2.DockState = WeifenLuo.WinFormsUI.Docking.DockState.Document;
- dockWindowItem2.ShowCloseButton = false;
- this.dockSurface1.DockWindows.Add(dockWindowItem2);
- this.dockSurface1.Dock = System.Windows.Forms.DockStyle.Fill;
- this.dockSurface1.Location = new System.Drawing.Point(0, 0);
- this.dockSurface1.Name = "dockSurface1";
- this.dockSurface1.Size = new System.Drawing.Size(1184, 661);
- this.dockSurface1.TabIndex = 0;
- //
- // MainForm
- //
- this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(1184, 661);
- this.Controls.Add(this.dockSurface1);
- this.Name = "MainForm";
- this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
- this.Text = "cadbt - 报价工具 + 网页 CAD";
- this.ResumeLayout(false);
- this.PerformLayout();
- }
-
- private Smart.CustomComponents.DockSurface dockSurface1;
- }
-}
diff --git a/cadbt/cadbt/MainForm.DockWindows.cs b/cadbt/cadbt/MainForm.DockWindows.cs
deleted file mode 100644
index 31695ef..0000000
--- a/cadbt/cadbt/MainForm.DockWindows.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-// 本文件由『生成停靠窗口代码』自动生成格式参考手写,集合变更后请同步刷新。
-using System;
-using WeifenLuo.WinFormsUI.Docking;
-
-namespace cadbt
-{
- public partial class MainForm
- {
- void CreateDockWindows_dockSurface1()
- {
- var dockSurface1 = this.dockSurface1 as Smart.CustomComponents.DockSurface;
- if (dockSurface1 == null) return;
- dockSurface1.EnsureDefaultTheme(); // 必须:Show 前保证有效主题
-
- var quote = new cadbt.DockWindows.QuoteWindow();
- quote.CloseButtonVisible = false;
- quote.TabText = "报价工具";
- quote.Text = "报价工具";
- quote.Show(dockSurface1, DockState.DockLeft);
-
- var viewer = new cadbt.DockWindows.CadViewerWindow();
- viewer.CloseButtonVisible = false;
- viewer.TabText = "CAD 查看器";
- viewer.Text = "CAD 查看器";
- viewer.Show(dockSurface1, DockState.Document);
- }
- }
-}
diff --git a/cadbt/cadbt/MainForm.cs b/cadbt/cadbt/MainForm.cs
deleted file mode 100644
index 8c6ddb3..0000000
--- a/cadbt/cadbt/MainForm.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 由SharpDevelop创建。
- * 用户: 099978
- * 日期: 2026-09-04
- * 时间: 12:24
- *
- * 要改变这种模板请点击 工具|选项|代码编写|编辑标准头文件
- */
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Windows.Forms;
-
-namespace cadbt
-{
- ///
- /// Description of MainForm.
- ///
- public partial class MainForm : Form
- {
- public MainForm()
- {
- //
- // The InitializeComponent() call is required for Windows Forms designer support.
- //
- InitializeComponent();
- CreateDockWindows_dockSurface1();
-
- // ★ 全局 F1 过滤器:焦点在任何 WinForms 控件上都触发元件合并
- // (焦点在网页时由网页端转发,两路都汇聚到 CadBridge.F1Requested)
- Application.AddMessageFilter(new F1MessageFilter());
- FormClosed += (s, e) => Application.RemoveMessageFilter(f1Filter);
- }
-
- private readonly F1MessageFilter f1Filter = new F1MessageFilter();
-
- /// 把 F1 按键(0x70)转成 CadBridge.F1Requested,不拦截按键本身。
- private class F1MessageFilter : IMessageFilter
- {
- public bool PreFilterMessage(ref Message m)
- {
- const int WM_KEYDOWN = 0x0100;
- if (m.Msg == WM_KEYDOWN && (int)m.WParam == 0x70)
- {
- try { CadBridge.RaiseF1(); } catch { }
- }
- else if (m.Msg == WM_KEYDOWN && (int)m.WParam == 0x71)
- {
- try { CadBridge.RaiseF2(); } catch { }
- }
- else if (m.Msg == WM_KEYDOWN && (int)m.WParam == 0x72)
- {
- try { CadBridge.RaiseF3(); } catch { }
- }
- return false;
- }
- }
- }
-}
diff --git a/cadbt/cadbt/Plugin/Form3.cs b/cadbt/cadbt/Plugin/Form3.cs
deleted file mode 100644
index a1e5f87..0000000
--- a/cadbt/cadbt/Plugin/Form3.cs
+++ /dev/null
@@ -1,6794 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Data;
-using System.Drawing;
-using System.IO;
-using System.Windows.Forms;
-using Microsoft.Win32;
-using Zuby.ADGV;
-
-namespace MyApp
-{
- ///
- /// Form3 的交互逻辑(CAD 2018 插件报价窗口)。
- /// 功能与主项目报价页面一致:项目表 + 图号/箱号/元件三级联动 + 公式重算 + 右键菜单 + 项目导出。
- /// UI 布局定义见 Form3.ui.cs。数据库独立存放在 cadcj\sjk\ 目录。
- ///
- public partial class Form3
- {
- // ============================================================
- // 数据库路径与表名常量(独立于主项目,存放在 cadcj\sjk\ 下)
- // ============================================================
-
- private const string ProjectsDbPath = @"sjk\advancedDataGridView6Table.db";
- private const string ProjectsTableName = "advancedDataGridView6Table";
- private const string QuoteDbDir = @"sjk\bjb";
- private const string TuhaoTableName = "advancedDataGridView9Table";
- private const string ProjectInfoTableName = "项目信息";
- private const string IndexTableName = "表索引";
-
- private const string CadRegPath = @"SOFTWARE\Autodesk\AutoCAD\R22.0\ACAD-1001:804\Apps\CADCJ";
-
- ///
- /// 插件所在目录(cadcj)。优先从注册表读取 CAD 自动加载的 DLL 路径(最可靠),
- /// 然后尝试 CodeBase / Location,最后兜底 BaseDirectory(可能是 CAD 目录,会报错)。
- ///
- private static readonly string _baseDir = GetPluginBaseDir();
-
- private static string GetPluginBaseDir()
- {
- // ★ 方案0(2026-09-04 standalone 版):exe 所在目录即数据根
- // (cadbt 独立运行,不再依赖 AutoCAD 注册表定位——旧 cadcj 注册表残留在
- // 退役机器上会把数据库指向已删除的目录)
- try
- {
- var baseDir = AppDomain.CurrentDomain.BaseDirectory;
- if (!string.IsNullOrEmpty(baseDir) && Directory.Exists(baseDir))
- {
- WriteDebugLog("[GetPluginBaseDir] BaseDirectory 成功: " + baseDir);
- return baseDir;
- }
- }
- catch (Exception ex) { WriteDebugLog("[GetPluginBaseDir] BaseDirectory 异常: " + ex.Message); }
-
- // ★ 方案2:CodeBase(不受 shadow copy 影响)
- try
- {
- var codeBase = System.Reflection.Assembly.GetExecutingAssembly().CodeBase;
- WriteDebugLog("[GetPluginBaseDir] CodeBase=" + codeBase);
- if (!string.IsNullOrEmpty(codeBase))
- {
- var localPath = new Uri(codeBase).LocalPath;
- var dir = Path.GetDirectoryName(localPath);
- if (!string.IsNullOrEmpty(dir) && Directory.Exists(dir))
- {
- WriteDebugLog("[GetPluginBaseDir] CodeBase方案成功: " + dir);
- return dir;
- }
- }
- }
- catch (Exception ex) { WriteDebugLog("[GetPluginBaseDir] CodeBase方案异常: " + ex.Message); }
-
- // ★ 方案3:Location
- try
- {
- var loc = System.Reflection.Assembly.GetExecutingAssembly().Location;
- WriteDebugLog("[GetPluginBaseDir] Location=" + loc);
- if (!string.IsNullOrEmpty(loc))
- {
- var dir = Path.GetDirectoryName(loc);
- if (!string.IsNullOrEmpty(dir) && Directory.Exists(dir))
- {
- WriteDebugLog("[GetPluginBaseDir] Location方案成功: " + dir);
- return dir;
- }
- }
- }
- catch (Exception ex) { WriteDebugLog("[GetPluginBaseDir] Location方案异常: " + ex.Message); }
-
- // ★ 方案4(最后兜底):BaseDirectory(CAD 目录,数据库会找不到)
- var fallback = AppDomain.CurrentDomain.BaseDirectory;
- WriteDebugLog("[GetPluginBaseDir] ⚠ 兜底BaseDirectory=" + fallback + " (数据库会找不到!)");
- return fallback;
- }
-
- private static void WriteDebugLog(string msg)
- {
- try
- {
- var logDir = Path.Combine(
- Path.GetDirectoryName(
- new Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase).LocalPath),
- "sjk");
- if (!Directory.Exists(logDir)) logDir = Path.GetTempPath();
- var logPath = Path.Combine(logDir, "form3_path_debug.log");
- File.AppendAllText(logPath,
- "[" + DateTime.Now.ToString("HH:mm:ss") + "] " + msg + Environment.NewLine);
- }
- catch { }
- }
-
- // ============================================================
- // 当前层级选中状态(联动核心)
- // ============================================================
-
- private string _currentProjectId = "";
- private string _currentTuhao = "";
- private string _currentXianghao = "";
- private bool _isReloading = false;
- private bool _isRecalculating = false;
- private DateTime _lastRecalcTime = DateTime.MinValue;
-
- // 价格显示格式化配置(每个项目独立,随项目信息表加载)
- private string _单台小数位文本 = "保留2位小数";
- private string _单台取整方式 = "不取整";
- private string _项目小数位文本 = "保留2位小数";
- private string _项目取整方式 = "不取整";
-
- // 当前各表的内存数据(用于关闭/切换时回写数据库)
- private DataTable _tuhaoTable;
- private DataTable _xianghaoTable;
- private DataTable _yuanjianTable;
-
- // 内存缓存:切换图号/箱号时不丢编辑,点保存才写库
- private Dictionary _xianghaoCache = new Dictionary();
- private Dictionary _yuanjianCache = new Dictionary();
-
- // 右键菜单组件(运行时创建,不在设计器 XML 里)
- private ContextMenuStrip _menuTuhao;
- private ContextMenuStrip _menuXianghao;
- private ContextMenuStrip _menuYuanjian;
-
- private static readonly string[] ProjectInfoColumns =
- {
- "项目编号", "项目名称", "客户名称", "客户地址",
- "联系人", "联系电话", "项目日期", "备注",
- "成套厂名称", "成套厂地址", "成套厂联系人", "成套厂联系电话",
- "单台小数位", "单台取整方式", "项目小数位", "项目取整方式"
- };
-
- /// 公式计算列集合(只包含程序算出来的价格列)。
- private static readonly HashSet s_公式列集合 =
- new HashSet(StringComparer.OrdinalIgnoreCase)
- {
- "表价", "采购单价", "采购价", "报出单价", "报出价",
- "单台成本", "成本价", "单台报出", "利润",
- "单价", "总价", "成本总价", "毛利",
- "成本总价", "报出总价", "利润"
- };
-
- /// 构造函数:初始化 UI 并绑定事件。
- public Form3()
- {
- InitializeComponent();
-
- // ★ 立即创建数据库(不依赖 Load 事件,UserControl 嵌入 PaletteSet 时 Load 可能延迟)
- try
- {
- Log("[Form3] _baseDir = " + _baseDir);
- Log("[Form3] ProjectsDbPath = " + GetDbFullPath(ProjectsDbPath));
- EnsureProjectDbExists(GetDbFullPath(ProjectsDbPath));
- Log("[Form3] 数据库创建/验证成功");
- }
- catch (System.Exception ex)
- {
- Log("[Form3] 数据库创建失败: " + ex.Message);
- }
-
- // ★ 诊断:后续初始化步骤逐步打点(定位面板空白问题)
- try
- {
- Log("[Form3.init] 开始双缓冲设置");
- EnableDoubleBuffered(this.advancedDataGridView6);
- EnableDoubleBuffered(this.advancedDataGridView9);
- EnableDoubleBuffered(this.advancedDataGridView4);
- EnableDoubleBuffered(this.advancedDataGridView5);
- Log("[Form3.init] 双缓冲完成");
-
- ApplyReadOnlyColumns(this.advancedDataGridView6, new string[] {
- "项目编号", "项目名称", "客户名称", "客户地址", "联系人", "联系电话",
- "项目日期", "箱柜台数", "成本总价", "报出总价", "利润", "利润率", "备注"
- });
- ApplyReadOnlyColumns(this.advancedDataGridView9, new string[] {
- "序号", "箱柜数量", "单价", "总价", "成本总价", "毛利", "毛利率"
- });
- ApplyReadOnlyColumns(this.advancedDataGridView4, new string[] {
- "序号", "单台成本", "成本价", "单台报出", "报出价", "利润", "利润率", "毛利率"
- });
- ApplyReadOnlyColumns(this.advancedDataGridView5, new string[] {
- "序号", "采购单价", "采购价", "报出单价", "报出价"
- });
- Log("[Form3.init] 只读列完成");
-
- // 工具栏按钮事件
- this.toolStripButton1.Click += toolStripButton1_Click;
- this.toolStripButton5.Click += toolStripButton5_Click;
- this.toolStripButton6.Click += toolStripButton6_Click;
- this.toolStripButton2.Click += (s, e) => SendCadPaCommand("CADPATU");
- this.toolStripButton3.Click += (s, e) => SendCadPaCommand("CADPAXH");
- this.toolStripButton4.Click += (s, e) => SendCadPaCommand("CADPAYJ");
- this.toolStripButton7.Click += (s, e) => ShowDeepSeekSettings();
- Log("[Form3.init] 工具栏事件完成");
-
- this.button28.Click += button28_Click;
- this.advancedDataGridView6.CellDoubleClick += advancedDataGridView6_CellDoubleClick;
-
- this.advancedDataGridView9.SelectionChanged += advancedDataGridView9_SelectionChanged;
- this.advancedDataGridView4.SelectionChanged += advancedDataGridView4_SelectionChanged;
- this.advancedDataGridView5.SelectionChanged += advancedDataGridView5_SelectionChanged;
-
- this.advancedDataGridView9.CellClick += Grid_CellClick_Zoom;
- this.advancedDataGridView4.CellClick += Grid_CellClick_Zoom;
- this.advancedDataGridView5.CellClick += Grid_CellClick_Zoom;
-
- this.advancedDataGridView5.CellValueChanged += Yuanjian_CellValueChanged;
- this.advancedDataGridView4.CurrentCellDirtyStateChanged += Grid_DirtyStateChanged;
- this.advancedDataGridView4.CellValueChanged += Xianghao_CellValueChanged;
- this.advancedDataGridView9.CurrentCellDirtyStateChanged += Grid_DirtyStateChanged;
- this.advancedDataGridView9.CellValueChanged += Tuhao_CellValueChanged;
-
- this.advancedDataGridView5.CellEndEdit += Grid_CellEndEdit;
- this.advancedDataGridView4.CellEndEdit += Grid_CellEndEdit;
- this.advancedDataGridView9.CellEndEdit += Grid_CellEndEdit;
-
- this.advancedDataGridView5.DataError += (s, e) => { e.Cancel = true; };
- this.advancedDataGridView4.DataError += (s, e) => { e.Cancel = true; };
- this.advancedDataGridView9.DataError += (s, e) => { e.Cancel = true; };
- this.advancedDataGridView6.DataError += (s, e) => { e.Cancel = true; };
-
- this.advancedDataGridView9.MouseDown += Grid_MouseDown_KeepMultiSelect;
- this.advancedDataGridView4.MouseDown += Grid_MouseDown_KeepMultiSelect;
- this.advancedDataGridView5.MouseDown += Grid_MouseDown_KeepMultiSelect;
-
- this.advancedDataGridView9.KeyDown += Grid_KeyDown_Delete;
- this.advancedDataGridView4.KeyDown += Grid_KeyDown_Delete;
- this.advancedDataGridView5.KeyDown += Grid_KeyDown_Delete;
- Log("[Form3.init] 表格事件完成");
-
- BuildContextMenus();
- Log("[Form3.init] 右键菜单完成");
-
- this.Disposed += Form3_Disposed;
-
- this.Load += (s, e) =>
- {
- try
- {
- EnsureProjectDbExists(GetDbFullPath(ProjectsDbPath));
- ReloadProjectsFromDatabase();
- ApplyPriceFormat(this.advancedDataGridView6, _项目小数位文本);
- this.advancedDataGridView9.DataSource = null;
- this.advancedDataGridView4.DataSource = null;
- this.advancedDataGridView5.DataSource = null;
- Log("[Form3.Load] 初始化完成");
- }
- catch (System.Exception ex)
- {
- Log("[Form3.Load] 初始化异常: " + ex.Message);
- }
-
- try
- {
- // 网页 CAD 桥:订阅实体删除事件(用户在网页里删框时联动删行)
- cadbt.CadBridge.EntityErased -= Database_ObjectErased;
- cadbt.CadBridge.EntityErased += Database_ObjectErased;
- // 网页 CAD 桥:订阅扒图结果事件(框选完成立即插入表格)
- cadbt.CadBridge.PaPicked -= OnPaTextsPicked;
- cadbt.CadBridge.PaPicked += OnPaTextsPicked;
- // 网页 CAD 桥:F1/F2 元件合并(焦点在网页时按键由网页转发)
- cadbt.CadBridge.F1Requested -= OnF1FromBridge;
- cadbt.CadBridge.F1Requested += OnF1FromBridge;
- cadbt.CadBridge.F2Requested -= OnF2FromBridge;
- cadbt.CadBridge.F2Requested += OnF2FromBridge;
- cadbt.CadBridge.F3Requested -= OnF3FromBridge;
- cadbt.CadBridge.F3Requested += OnF3FromBridge;
- }
- catch (System.Exception ex)
- {
- Log("[Form3.Load] 订阅CadBridge事件失败: " + ex.Message);
- }
- };
- Log("[Form3.init] 构造函数全部完成 ✓");
- }
- catch (System.Exception ex)
- {
- Log("[Form3.init] ⚠ 初始化异常: " + ex.ToString());
- }
- }
-
- ///
- /// ★ 网页 CAD 中实体被删除时触发。如果删除的是 __CADCJ_PA_FRAME 图层上的扒图框,
- /// 通过 Handle 查找当前项目下的图号表/箱号表/元件表对应行,同步删除。
- ///
- private void Database_ObjectErased(string handle)
- {
- try
- {
- if (string.IsNullOrWhiteSpace(handle)) return;
- // ★ 如果正在通过表格删除(_isReloading=true),跳过网页 CAD 事件触发的删除
- // 避免表格删除和 CAD 事件删除互相干扰导致蒙版/数据不一致
- if (_isReloading) return;
-
- Log("[ObjectErased] 触发! Handle=" + handle);
-
- this.BeginInvoke((Action)(() =>
- {
- try
- {
- // 再次检查(异步执行时状态可能已变化)
- if (_isReloading) { Log("[ObjectErased] _isReloading=true,跳过"); return; }
- DeleteRowsByFrameHandle(handle);
- }
- catch (System.Exception ex)
- {
- Log("[ObjectErased.BeginInvoke] 异常: " + ex.Message);
- }
- }));
- }
- catch (System.Exception ex)
- {
- Log("[ObjectErased] 异常: " + ex.Message);
- }
- }
-
- ///
- /// 根据框Handle在当前项目的图号表/箱号表/元件表中删除对应数据行。
- ///
- private void DeleteRowsByFrameHandle(string frameHandle)
- {
- if (string.IsNullOrWhiteSpace(frameHandle)) return;
- if (string.IsNullOrWhiteSpace(_currentProjectId)) { Log("[DeleteRowsByFrameHandle] _currentProjectId 为空,放弃"); return; }
- _isReloading = true;
- try
- {
- string dbPath = GetQuoteDbPath(_currentProjectId);
- if (!File.Exists(dbPath)) { Log("[DeleteRowsByFrameHandle] 数据库不存在: " + dbPath); return; }
-
- bool deleted = false;
- string deletedTuhao = null;
- string deletedXianghao = null;
- // ★ 收集级联删除的框Handle(图号→箱号→元件,删除数据时同步删蒙版)
- var cascadeFrames = new List();
-
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
-
- // 1) 图号表
- using (var sel = new System.Data.SQLite.SQLiteCommand(
- "SELECT 图号 FROM " + TuhaoTableName + " WHERE 框Handle=@fh;", conn))
- {
- sel.Parameters.AddWithValue("@fh", frameHandle);
- using (var reader = sel.ExecuteReader())
- {
- if (reader.Read())
- {
- deletedTuhao = reader.IsDBNull(0) ? "" : reader.GetString(0);
- Log("[DeleteRowsByFrameHandle] 命中图号表: " + deletedTuhao);
- }
- }
- }
- if (!string.IsNullOrWhiteSpace(deletedTuhao))
- {
- // ★ 删除图号前,先收集该图号下所有箱号和元件的框Handle(级联删蒙版)
- CollectFrameHandlesForTuhao(_currentProjectId, deletedTuhao, cascadeFrames);
- DeleteTuhao(_currentProjectId, deletedTuhao);
- deleted = true;
- }
-
- if (!deleted)
- {
- // 2) 箱号表:通过表索引找到所有箱号表,逐个查
- List allXhTables = new List();
- using (var selIdx = new System.Data.SQLite.SQLiteCommand(
- "SELECT 实际表名, 图号 FROM 表索引 WHERE 类型='箱号';", conn))
- using (var rIdx = selIdx.ExecuteReader())
- {
- while (rIdx.Read())
- {
- string realTbl = rIdx.IsDBNull(0) ? "" : rIdx.GetString(0);
- string th = rIdx.IsDBNull(1) ? "" : rIdx.GetString(1);
- if (!string.IsNullOrWhiteSpace(realTbl))
- allXhTables.Add(realTbl + "|" + th);
- }
- }
- Log("[DeleteRowsByFrameHandle] 箱号表数量: " + allXhTables.Count);
- foreach (string info in allXhTables)
- {
- string[] parts = info.Split('|');
- string realTbl = parts[0];
- string th = parts.Length > 1 ? parts[1] : "";
- using (var sel = new System.Data.SQLite.SQLiteCommand(
- "SELECT 箱号 FROM \"" + realTbl + "\" WHERE 框Handle=@fh;", conn))
- {
- sel.Parameters.AddWithValue("@fh", frameHandle);
- using (var reader = sel.ExecuteReader())
- {
- if (reader.Read())
- {
- deletedTuhao = th;
- deletedXianghao = reader.IsDBNull(0) ? "" : reader.GetString(0);
- Log("[DeleteRowsByFrameHandle] 命中箱号表: 图号=" + th + " 箱号=" + deletedXianghao);
- break;
- }
- }
- }
- if (!string.IsNullOrWhiteSpace(deletedXianghao)) break;
- }
- if (!string.IsNullOrWhiteSpace(deletedXianghao))
- {
- // ★ 删除箱号前,先收集该箱号下元件表的框Handle(级联删蒙版)
- CollectFrameHandlesForXianghao(_currentProjectId, deletedTuhao, deletedXianghao, cascadeFrames);
- DeleteXianghao(_currentProjectId, deletedTuhao, deletedXianghao);
- deleted = true;
- }
- }
-
- if (!deleted)
- {
- // 3) 元件表:通过表索引找到所有元件表,逐个查
- List allYjTables = new List();
- using (var selIdx = new System.Data.SQLite.SQLiteCommand(
- "SELECT 实际表名, 图号, 箱号 FROM 表索引 WHERE 类型='元件';", conn))
- using (var rIdx = selIdx.ExecuteReader())
- {
- while (rIdx.Read())
- {
- string realTbl = rIdx.IsDBNull(0) ? "" : rIdx.GetString(0);
- string th = rIdx.IsDBNull(1) ? "" : rIdx.GetString(1);
- string xh = rIdx.IsDBNull(2) ? "" : rIdx.GetString(2);
- if (!string.IsNullOrWhiteSpace(realTbl))
- allYjTables.Add(realTbl + "|" + th + "|" + xh);
- }
- }
- Log("[DeleteRowsByFrameHandle] 元件表数量: " + allYjTables.Count + " 查找Handle=" + frameHandle);
- foreach (string info in allYjTables)
- {
- string[] parts = info.Split('|');
- string realTbl = parts[0];
- string th = parts.Length > 1 ? parts[1] : "";
- string xh = parts.Length > 2 ? parts[2] : "";
- // ★ 先列出该表所有的框Handle,排查是否真的写进去了
- using (var selAll = new System.Data.SQLite.SQLiteCommand(
- "SELECT 序号, 框Handle FROM \"" + realTbl + "\";", conn))
- using (var rAll = selAll.ExecuteReader())
- {
- while (rAll.Read())
- {
- string s = rAll.IsDBNull(0) ? "" : rAll.GetString(0);
- string h = rAll.IsDBNull(1) ? "" : rAll.GetString(1);
- Log(" [元件表 " + realTbl + "] 序号=" + s + " 框Handle=[" + h + "]");
- }
- }
- using (var sel = new System.Data.SQLite.SQLiteCommand(
- "SELECT COUNT(*) FROM \"" + realTbl + "\" WHERE 框Handle=@fh;", conn))
- {
- sel.Parameters.AddWithValue("@fh", frameHandle);
- object cnt = sel.ExecuteScalar();
- int matchCount = (cnt != null && cnt != DBNull.Value) ? Convert.ToInt32(cnt) : 0;
- if (matchCount > 0)
- {
- deletedTuhao = th;
- deletedXianghao = xh;
- Log("[DeleteRowsByFrameHandle] 命中元件表: 图号=" + th + " 箱号=" + xh + " 匹配行数=" + matchCount);
-
- // ★ 直接用框Handle 删除所有匹配行(解决重复行问题)
- using (var delCmd = new System.Data.SQLite.SQLiteCommand(
- "DELETE FROM \"" + realTbl + "\" WHERE 框Handle=@fh;", conn))
- {
- delCmd.Parameters.AddWithValue("@fh", frameHandle);
- int affected = delCmd.ExecuteNonQuery();
- Log("[DeleteRowsByFrameHandle] DELETE 完成,影响行数=" + affected);
- }
- deleted = true;
- break;
- }
- }
- }
- }
- }
-
- if (deleted)
- {
- Log("[DeleteRowsByFrameHandle] 删除成功: Handle=" + frameHandle + " cascadeFrames=" + cascadeFrames.Count);
-
- _xianghaoCache.Clear();
- _yuanjianCache.Clear();
-
- // 重新编号(直接操作数据库)
- if (!string.IsNullOrWhiteSpace(deletedTuhao) && !string.IsNullOrWhiteSpace(deletedXianghao))
- {
- string yjTbl = GetYuanjianTableByIndex(_currentProjectId, deletedTuhao, deletedXianghao);
- if (!string.IsNullOrEmpty(yjTbl))
- RenumberTable(_currentProjectId, "\"" + yjTbl + "\"");
- string xhTbl = GetXianghaoTableByIndex(_currentProjectId, deletedTuhao);
- if (!string.IsNullOrEmpty(xhTbl))
- RenumberTable(_currentProjectId, "\"" + xhTbl + "\"");
- }
- else if (!string.IsNullOrWhiteSpace(deletedTuhao))
- {
- string xhTbl = GetXianghaoTableByIndex(_currentProjectId, deletedTuhao);
- if (!string.IsNullOrEmpty(xhTbl))
- RenumberTable(_currentProjectId, "\"" + xhTbl + "\"");
- }
-
- // ★ 直接在数据库层面重算(不经过内存表,不触发回写)
- try { RecalcAllFromDatabase(_currentProjectId); } catch { }
-
- // ★ 从数据库重新加载到 UI(覆盖内存表,确保 UI 与数据库一致)
- if (!string.IsNullOrWhiteSpace(deletedTuhao) && !string.IsNullOrWhiteSpace(deletedXianghao))
- {
- if (_currentTuhao == deletedTuhao)
- {
- ReloadXianghaoByTuhao(_currentProjectId, deletedTuhao);
- if (_currentXianghao == deletedXianghao)
- ReloadYuanjianByXianghao(_currentProjectId, deletedTuhao, deletedXianghao);
- }
- }
- else if (!string.IsNullOrWhiteSpace(deletedTuhao))
- {
- ReloadTuhaoByProject(_currentProjectId);
- if (_currentTuhao == deletedTuhao)
- ReloadXianghaoByTuhao(_currentProjectId, deletedTuhao);
- }
-
- // ★ 删除级联的框实体(图号删除时,其下箱号和元件的蒙版也要删除)
- Log("[DeleteRowsByFrameHandle] cascadeFrames 数量: " + cascadeFrames.Count + " 当前Handle=" + frameHandle);
- if (cascadeFrames.Count > 0)
- {
- // ★ 收集后一次性批量删除(排除当前正在删除的 frameHandle,已由 CAD 端删除)
- var toDel = new List();
- foreach (string h in cascadeFrames)
- {
- if (h != frameHandle) toDel.Add(h);
- }
- if (toDel.Count > 0)
- {
- Log("[DeleteRowsByFrameHandle] 级联删除框Handle数: " + toDel.Count);
- DeleteFramesByHandles(toDel);
- }
- SaveCurrentDwg();
- Log("[DeleteRowsByFrameHandle] 级联删除完成");
- }
- }
- }
- finally
- {
- _isReloading = false;
- }
- }
-
- /// 重写 OnLoad:在所有 Load 事件订阅者之前确保项目库文件存在。
- protected override void OnLoad(EventArgs e)
- {
- try { EnsureProjectDbExists(GetDbFullPath(ProjectsDbPath)); }
- catch { }
- base.OnLoad(e);
- }
-
- // ============================================================
- // 通用辅助方法
- // ============================================================
-
- private void Log(string msg)
- {
- try
- {
- string logPath = Path.Combine(_baseDir, "diag.log");
- File.AppendAllText(logPath,
- DateTime.Now.ToString("HH:mm:ss.fff") + " " + msg + "\r\n");
- }
- catch { }
- }
-
- private string GetDbFullPath(string relativePath)
- {
- return Path.Combine(_baseDir, relativePath);
- }
-
- private string GetConnString(string dbPath)
- {
- // ★ busy_timeout=3000:数据库被 CAD 或其他进程短暂占用时等待重试而非卡死;
- // Pooling 关闭,避免连接池长期持有文件句柄
- return "Data Source=" + dbPath + ";Version=3;busy_timeout=3000;";
- }
-
- private string GetQuoteDbPath(string projectId)
- {
- string safeName = projectId;
- char[] invalidChars = Path.GetInvalidFileNameChars();
- foreach (char c in invalidChars) safeName = safeName.Replace(c, '_');
- return GetDbFullPath(QuoteDbDir + @"\项目" + safeName + ".db");
- }
-
- private static decimal ParseDecimal(object v)
- {
- if (v == null || v == DBNull.Value) return 0m;
- decimal d;
- if (decimal.TryParse(v.ToString().Trim(), out d)) return d;
- return 0m;
- }
-
- private static DataGridViewColumn FindColumn(DataGridView dgv, string name)
- {
- if (dgv == null || dgv.Columns == null) return null;
- foreach (DataGridViewColumn c in dgv.Columns)
- {
- if (c == null) continue;
- if (c.DataPropertyName == name || c.HeaderText == name || c.Name == name) return c;
- }
- return null;
- }
-
- private static string GetCellString(DataGridViewRow row, string name)
- {
- if (row == null || row.DataGridView == null) return "";
- DataGridViewColumn col = FindColumn(row.DataGridView, name);
- if (col == null) return "";
- object v = row.Cells[col.Index].Value;
- return v == null ? "" : v.ToString().Trim();
- }
-
- private static decimal GetCellDecimal(DataGridViewRow row, string name)
- {
- return ParseDecimal(GetCellString(row, name));
- }
-
- private static string GetCellValueAsString(DataGridViewRow row, string colName)
- {
- if (row == null || row.Cells == null || string.IsNullOrEmpty(colName)) return "";
- DataGridView grid = row.DataGridView;
- if (grid != null)
- {
- foreach (DataGridViewColumn col in grid.Columns)
- {
- if (col == null) continue;
- string key = !string.IsNullOrEmpty(col.DataPropertyName)
- ? col.DataPropertyName
- : (!string.IsNullOrEmpty(col.HeaderText) ? col.HeaderText : col.Name);
- if (key == colName)
- {
- object v = row.Cells[col.Index].Value;
- return v == null ? "" : v.ToString().Trim();
- }
- }
- }
- return "";
- }
-
- private static void SetCell(DataGridViewRow row, string colName, decimal value)
- {
- if (row == null || row.DataGridView == null) return;
- DataGridViewColumn col = FindColumn(row.DataGridView, colName);
- if (col == null) return;
- row.Cells[col.Index].Value = value == 0m ? 0d : (double)value;
- }
-
- private static DataGridViewRow GetFirstSelectedRow(DataGridView dgv)
- {
- if (dgv == null || dgv.Rows == null || dgv.Rows.Count == 0) return null;
- foreach (DataGridViewRow r in dgv.SelectedRows)
- {
- if (r == null || r.IsNewRow) continue;
- return r;
- }
- if (dgv.CurrentRow != null && !dgv.CurrentRow.IsNewRow) return dgv.CurrentRow;
- return null;
- }
-
- private static List GetAllSelectedRows(DataGridView dgv)
- {
- var result = new List();
- if (dgv == null || dgv.Rows == null || dgv.Rows.Count == 0) return result;
- var seenRows = new HashSet();
- if (dgv.SelectedRows != null)
- {
- foreach (DataGridViewRow r in dgv.SelectedRows)
- {
- if (r == null || r.IsNewRow) continue;
- if (seenRows.Add(r.Index)) result.Add(r);
- }
- }
- // ★ 总是通过 SelectedCells 补充收集(不再限制 result.Count == 0)
- // ADGV 多选时 SelectedRows 可能不完整,SelectedCells 能覆盖所有选中行
- if (dgv.SelectedCells != null)
- {
- foreach (DataGridViewCell c in dgv.SelectedCells)
- {
- if (c == null || c.RowIndex < 0) continue;
- DataGridViewRow r = dgv.Rows[c.RowIndex];
- if (r == null || r.IsNewRow) continue;
- if (seenRows.Add(r.Index)) result.Add(r);
- }
- }
- // 兜底:如果以上都没收集到,取当前行
- if (result.Count == 0 && dgv.CurrentRow != null && !dgv.CurrentRow.IsNewRow)
- {
- result.Add(dgv.CurrentRow);
- }
- return result;
- }
-
- private DataGridViewRow GetFirstSelectedProjectRow()
- {
- DataGridView dgv = this.advancedDataGridView6;
- if (dgv == null || dgv.Rows == null || dgv.Rows.Count == 0) return null;
- foreach (DataGridViewRow r in dgv.SelectedRows)
- {
- if (r == null || r.IsNewRow) continue;
- return r;
- }
- if (dgv.CurrentRow != null && !dgv.CurrentRow.IsNewRow) return dgv.CurrentRow;
- return null;
- }
-
- private DataGridViewRow FindProjectRowById(string projectId)
- {
- if (string.IsNullOrWhiteSpace(projectId)) return null;
- DataGridView dgv = this.advancedDataGridView6;
- if (dgv == null || dgv.Rows == null) return null;
- foreach (DataGridViewRow r in dgv.Rows)
- {
- if (r == null || r.IsNewRow) continue;
- if (GetCellValueAsString(r, "项目编号") == projectId) return r;
- }
- return null;
- }
-
- private static void SetCurrentCell(DataGridView dgv, int rowIndex, int colIndex = 0)
- {
- if (dgv == null || dgv.Rows == null || rowIndex < 0 || rowIndex >= dgv.Rows.Count) return;
- try
- {
- if (dgv.Rows[rowIndex].IsNewRow) return;
- if (colIndex < 0 || colIndex >= dgv.Columns.Count) colIndex = 0;
- dgv.ClearSelection();
- dgv.Rows[rowIndex].Selected = true;
- dgv.CurrentCell = dgv.Rows[rowIndex].Cells[colIndex];
- }
- catch { }
- }
-
- private void SelectRowByValue(DataGridView dgv, string colName, string value)
- {
- if (dgv == null || dgv.Rows == null || string.IsNullOrEmpty(value)) return;
- try
- {
- _isReloading = true;
- foreach (DataGridViewRow r in dgv.Rows)
- {
- if (r == null || r.IsNewRow) continue;
- if (GetCellValueAsString(r, colName) == value)
- {
- dgv.ClearSelection();
- r.Selected = true;
- dgv.CurrentCell = r.Cells[0];
- return;
- }
- }
- }
- catch { }
- finally { _isReloading = false; }
- }
-
- private static int GetSelectedRowIndex(DataGridView dgv)
- {
- if (dgv == null) return -1;
- if (dgv.CurrentRow == null || dgv.CurrentRow.IsNewRow) return -1;
- return dgv.CurrentRow.Index;
- }
-
- private static string MakeSafeFileName(string s)
- {
- if (string.IsNullOrEmpty(s)) return "未命名";
- string r = s;
- char[] invalid = Path.GetInvalidFileNameChars();
- foreach (char c in invalid) r = r.Replace(c, '_');
- return r;
- }
-
- private static string EscapeJsonString(string s)
- {
- if (s == null) return "";
- return s.Replace("\\", "\\\\").Replace("\"", "\\\"")
- .Replace("\r", "\\r").Replace("\n", "\\n").Replace("\t", "\\t");
- }
-
- private string ShowInputDialog(string title, string prompt, string defaultValue)
- {
- using (var dlg = new Form())
- {
- dlg.Text = title;
- dlg.StartPosition = FormStartPosition.CenterParent;
- dlg.FormBorderStyle = FormBorderStyle.FixedDialog;
- dlg.MinimizeBox = false;
- dlg.MaximizeBox = false;
- dlg.Width = 340;
- dlg.Height = 170;
-
- var lbl = new Label();
- lbl.Text = prompt;
- lbl.Left = 12; lbl.Top = 15;
- lbl.Width = 300; lbl.Height = 30;
- dlg.Controls.Add(lbl);
-
- var txt = new TextBox();
- txt.Text = defaultValue;
- txt.Left = 12; txt.Top = 55;
- txt.Width = 300;
- dlg.Controls.Add(txt);
-
- var btnOk = new Button();
- btnOk.Text = "确定";
- btnOk.Left = 210; btnOk.Top = 92;
- btnOk.Width = 90;
- btnOk.DialogResult = DialogResult.OK;
- dlg.Controls.Add(btnOk);
-
- var btnCancel = new Button();
- btnCancel.Text = "取消";
- btnCancel.Left = 108; btnCancel.Top = 92;
- btnCancel.Width = 90;
- btnCancel.DialogResult = DialogResult.Cancel;
- dlg.Controls.Add(btnCancel);
-
- dlg.AcceptButton = btnOk;
- dlg.CancelButton = btnCancel;
-
- if (dlg.ShowDialog(this) == DialogResult.OK) return txt.Text;
- return "";
- }
- }
-
- /// 开启 DataGridView 的双缓冲(消除闪烁)。
- private static void EnableDoubleBuffered(DataGridView dgv)
- {
- if (dgv == null) return;
- try
- {
- typeof(DataGridView).InvokeMember("DoubleBuffered",
- System.Reflection.BindingFlags.SetProperty |
- System.Reflection.BindingFlags.Instance |
- System.Reflection.BindingFlags.NonPublic,
- null, dgv, new object[] { true });
- }
- catch { }
- }
-
- /// 按列名设置只读(运行时按 DataPropertyName/HeaderText 查找)。
- private static void ApplyReadOnlyColumns(DataGridView dgv, string[] colNames)
- {
- if (dgv == null || colNames == null) return;
- foreach (string name in colNames)
- {
- DataGridViewColumn col = FindColumn(dgv, name);
- if (col != null) col.ReadOnly = true;
- }
- }
-
- // ============================================================
- // 价格显示格式化
- // ============================================================
-
- /// 把"保留2位小数"/"保留整数"等转成 .NET 格式字符串(F0/F2)。
- private static string ToFormatString(string 小数位文本)
- {
- int n = 解析小数位(小数位文本);
- if (n < 0) n = 2;
- return "F" + n.ToString();
- }
-
- private static int 解析小数位(string text)
- {
- if (string.IsNullOrWhiteSpace(text)) return 2;
- string t = text.Trim();
- if (t.Contains("整数")) return 0;
- if (t.Contains("1位")) return 1;
- if (t.Contains("2位")) return 2;
- if (t.Contains("3位")) return 3;
- if (t.Contains("4位")) return 4;
- return 2;
- }
-
- private void ApplyPriceFormat(DataGridView dgv, string 小数位文本)
- {
- if (dgv == null || dgv.Columns == null) return;
- string fmt = ToFormatString(小数位文本);
- foreach (DataGridViewColumn col in dgv.Columns)
- {
- if (col == null) continue;
- string name = !string.IsNullOrEmpty(col.DataPropertyName)
- ? col.DataPropertyName : col.HeaderText;
- if (string.IsNullOrEmpty(name)) continue;
- if (s_公式列集合.Contains(name))
- {
- col.DefaultCellStyle.Format = fmt;
- }
- }
- }
-
- /// 老库兼容:把 DataTable 中公式列的类型从 string 转为 double。
- private static DataTable ConvertFormulaColumnsToDouble(DataTable table)
- {
- if (table == null || table.Columns.Count == 0) return table;
- bool needsConvert = false;
- foreach (DataColumn dc in table.Columns)
- {
- if (s_公式列集合.Contains(dc.ColumnName) && dc.DataType == typeof(string))
- {
- needsConvert = true;
- break;
- }
- }
- if (!needsConvert) return table;
-
- var newTable = new DataTable();
- foreach (DataColumn dc in table.Columns)
- {
- Type t = s_公式列集合.Contains(dc.ColumnName) ? typeof(double) : dc.DataType;
- newTable.Columns.Add(dc.ColumnName, t);
- }
- foreach (DataRow row in table.Rows)
- {
- var newRow = newTable.NewRow();
- foreach (DataColumn dc in table.Columns)
- {
- if (s_公式列集合.Contains(dc.ColumnName))
- {
- object v = row[dc];
- if (v == null || v == DBNull.Value) newRow[dc.ColumnName] = 0d;
- else if (v is double) newRow[dc.ColumnName] = v;
- else
- {
- double d;
- newRow[dc.ColumnName] = double.TryParse(v.ToString().Trim(), out d) ? d : 0d;
- }
- }
- else newRow[dc.ColumnName] = row[dc];
- }
- newTable.Rows.Add(newRow);
- }
- newTable.TableName = table.TableName;
- return newTable;
- }
-
- // ============================================================
- // 数据库结构维护
- // ============================================================
-
- private void EnsureProjectDbExists(string dbPath)
- {
- string dir = Path.GetDirectoryName(dbPath);
- if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- string sql =
- "CREATE TABLE IF NOT EXISTS " + ProjectsTableName + " (" +
- " 项目编号 TEXT, 项目名称 TEXT, 客户名称 TEXT, 客户地址 TEXT," +
- " 联系人 TEXT, 联系电话 TEXT, 项目日期 TEXT, 箱柜台数 REAL," +
- " 成本总价 REAL, 报出总价 REAL, 利润 REAL, 利润率 REAL, 备注 TEXT" +
- ");";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn)) cmd.ExecuteNonQuery();
- EnsureColumns(conn, ProjectsTableName, new[] {
- "成套厂名称", "成套厂地址", "成套厂联系人", "成套厂联系电话"
- });
- }
- }
-
- private static void EnsureColumns(System.Data.SQLite.SQLiteConnection conn, string tableName, string[] columns)
- {
- if (columns == null || columns.Length == 0) return;
- var existing = new HashSet(StringComparer.OrdinalIgnoreCase);
- using (var infoCmd = new System.Data.SQLite.SQLiteCommand("PRAGMA table_info(" + tableName + ");", conn))
- using (var reader = infoCmd.ExecuteReader())
- {
- while (reader.Read())
- {
- object nameObj = reader["name"];
- if (nameObj != null && nameObj != DBNull.Value) existing.Add(nameObj.ToString());
- }
- }
- foreach (string col in columns)
- {
- if (!existing.Contains(col))
- {
- string sql = "ALTER TABLE " + tableName + " ADD COLUMN " + col + " TEXT;";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn)) cmd.ExecuteNonQuery();
- }
- }
- }
-
- private static List GetProjectTableColumns(System.Data.SQLite.SQLiteConnection conn)
- {
- var cols = new List();
- try
- {
- using (var infoCmd = new System.Data.SQLite.SQLiteCommand("PRAGMA table_info(" + ProjectsTableName + ");", conn))
- using (var reader = infoCmd.ExecuteReader())
- {
- while (reader.Read())
- {
- object nameObj = reader["name"];
- if (nameObj != null && nameObj != DBNull.Value) cols.Add(nameObj.ToString());
- }
- }
- }
- catch { }
- return cols;
- }
-
- private void EnsureQuoteDbExists(string projectId)
- {
- if (string.IsNullOrWhiteSpace(projectId)) return;
- string dbPath = GetQuoteDbPath(projectId);
- string dir = Path.GetDirectoryName(dbPath);
- if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
-
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- string sqlTuhao =
- "CREATE TABLE IF NOT EXISTS " + TuhaoTableName + " (" +
- " 序号 TEXT, 图号 TEXT, 图名 TEXT, 台数 TEXT, 箱柜数量 REAL," +
- " 单价 REAL, 总价 REAL, 成本总价 REAL, 毛利 REAL, 毛利率 REAL," +
- " 框Handle TEXT, 文本Handle TEXT" +
- ");";
- string sqlIndex =
- "CREATE TABLE IF NOT EXISTS 表索引 (" +
- " 类型 TEXT, 图号 TEXT, 箱号 TEXT, 实际表名 TEXT" +
- ");";
- string sqlProjectInfo =
- "CREATE TABLE IF NOT EXISTS " + ProjectInfoTableName + " (" +
- " 项目编号 TEXT, 项目名称 TEXT, 客户名称 TEXT, 客户地址 TEXT," +
- " 联系人 TEXT, 联系电话 TEXT, 项目日期 TEXT, 备注 TEXT," +
- " 成套厂名称 TEXT, 成套厂地址 TEXT, 成套厂联系人 TEXT, 成套厂联系电话 TEXT," +
- " 单台小数位 TEXT, 单台取整方式 TEXT, 项目小数位 TEXT, 项目取整方式 TEXT" +
- ");";
- foreach (string sql in new[] { sqlTuhao, sqlIndex, sqlProjectInfo })
- {
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn)) cmd.ExecuteNonQuery();
- }
- EnsureColumns(conn, ProjectInfoTableName, new[] {
- "成套厂名称", "成套厂地址", "成套厂联系人", "成套厂联系电话",
- "单台小数位", "单台取整方式", "项目小数位", "项目取整方式"
- });
- // ★ 确保旧库的图号表也有"框Handle"/"文本Handle"列
- EnsureColumns(conn, TuhaoTableName, new[] { "框Handle", "文本Handle" });
- }
- }
-
- // ---------- 箱号表(每个图号一张独立表,表名=图号原名,双引号括起)----------
-
- private static string GetXianghaoTableName(string tuhao)
- {
- if (string.IsNullOrWhiteSpace(tuhao)) return "\"图号箱号表\"";
- return "\"" + tuhao.Replace("\"", "\"\"") + "\"";
- }
-
- private void EnsureXianghaoTableExists(string projectId, string tuhao)
- {
- if (string.IsNullOrWhiteSpace(projectId) || string.IsNullOrWhiteSpace(tuhao)) return;
- // 先查表索引,已有则跳过
- string existing = GetXianghaoTableByIndex(projectId, tuhao);
- if (!string.IsNullOrEmpty(existing)) return;
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return;
- // 用唯一ID做表名,避免图号名含特殊字符
- string realTbl = GetNextTableId(projectId, "箱号");
- try
- {
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- string sql =
- "CREATE TABLE \"" + realTbl + "\" (" +
- " 序号 TEXT, 箱号 TEXT, 型号 TEXT, 规格 TEXT, 单位 TEXT, 数量 TEXT," +
- " 单台成本 REAL, 成本价 REAL, 单台报出 REAL, 报出价 REAL," +
- " 利润 REAL, 利润率 REAL, 毛利率 REAL, 箱柜类型 TEXT, 备注 TEXT, 图纸 TEXT," +
- " 框Handle TEXT, 文本Handle TEXT" +
- ");";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn)) cmd.ExecuteNonQuery();
- }
- // ★ 注册到表索引,后续 GetXianghaoTableByIndex 才能查到
- AddTableIndex(projectId, "箱号", tuhao, "", realTbl);
- }
- catch { }
- }
-
- private string GetXianghaoCount(string projectId, string tuhao)
- {
- if (string.IsNullOrWhiteSpace(projectId) || string.IsNullOrWhiteSpace(tuhao)) return "1";
- string realTbl = GetXianghaoTableByIndex(projectId, tuhao);
- if (string.IsNullOrEmpty(realTbl)) return "1";
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return "1";
- try
- {
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- string sql = "SELECT COUNT(*) FROM \"" + realTbl + "\";";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- int n = 0;
- object o = cmd.ExecuteScalar();
- if (o != null && o != DBNull.Value) n = Convert.ToInt32(o);
- return (n + 1).ToString();
- }
- }
- }
- catch { return "1"; }
- }
-
- // ---------- 元件计数(用于新建元件命名"新元件N")----------
-
- private string GetYuanjianCount(string projectId, string tuhao, string xianghao)
- {
- if (string.IsNullOrWhiteSpace(projectId) ||
- string.IsNullOrWhiteSpace(xianghao)) return "1";
- // 查索引表拿该箱号元件表的真实表名
- string realTbl = GetYuanjianTableByIndex(projectId, tuhao, xianghao);
- if (string.IsNullOrEmpty(realTbl)) return "1";
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return "1";
- try
- {
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- string sql = "SELECT COUNT(*) FROM \"" + realTbl + "\";";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- int n = 0;
- object o = cmd.ExecuteScalar();
- if (o != null && o != DBNull.Value) n = Convert.ToInt32(o);
- return (n + 1).ToString();
- }
- }
- }
- catch { return "1"; }
- }
-
- // ---------- 元件表(每个箱号一张独立表)----------
-
- private static string GetYuanjianTableName(string xianghao)
- {
- if (string.IsNullOrWhiteSpace(xianghao)) return "\"元件表\"";
- return "\"" + xianghao.Replace("\"", "\"\"") + "\"";
- }
-
- private void EnsureYuanjianTableExists(string projectId, string tuhao, string xianghao)
- {
- if (string.IsNullOrWhiteSpace(projectId) || string.IsNullOrWhiteSpace(tuhao) || string.IsNullOrWhiteSpace(xianghao)) return;
- // 先查表索引,已有则跳过
- string existing = GetYuanjianTableByIndex(projectId, tuhao, xianghao);
- if (!string.IsNullOrEmpty(existing)) return;
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return;
- // 用唯一ID做表名
- string realTbl = GetNextTableId(projectId, "元件");
- try
- {
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- string sql =
- "CREATE TABLE \"" + realTbl + "\" (" +
- " 序号 TEXT, 元件名称 TEXT, 规格 TEXT, 单位 TEXT, 数量 TEXT," +
- " 表价 REAL, 采购单价 REAL, 采购系数 TEXT, 采购价 REAL," +
- " 报出单价 REAL, 报出系数 TEXT, 报出价 REAL," +
- " 图纸规格 TEXT, 品牌 TEXT, 系列 TEXT, 类型 TEXT, 备注 TEXT," +
- " 框Handle TEXT, 文本Handle TEXT" +
- ");";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn)) cmd.ExecuteNonQuery();
- }
- // ★ 注册到表索引(类型=元件,图号,箱号) — 后续 GetYuanjianTableByIndex 才能查到
- AddTableIndex(projectId, "元件", tuhao, xianghao, realTbl);
- }
- catch { }
- }
-
- // ---------- 表索引(用唯一ID做表名,索引表记录 图号/箱号 → 真实表名)----------
-
- private string GetNextTableId(string projectId, string prefix)
- {
- if (string.IsNullOrWhiteSpace(projectId)) return prefix + "_1";
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return prefix + "_1";
- try
- {
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- string sql = "SELECT 实际表名 FROM 表索引 WHERE 实际表名 LIKE @p;";
- int maxN = 0;
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- cmd.Parameters.AddWithValue("@p", prefix + "_%");
- using (var reader = cmd.ExecuteReader())
- {
- while (reader.Read())
- {
- string t = reader.IsDBNull(0) ? "" : reader.GetString(0);
- string numPart = t.StartsWith(prefix + "_") ? t.Substring(prefix.Length + 1) : "";
- int n;
- if (int.TryParse(numPart, out n) && n > maxN) maxN = n;
- }
- }
- }
- return prefix + "_" + (maxN + 1).ToString();
- }
- }
- catch { return prefix + "_1"; }
- }
-
- private void AddTableIndex(string projectId, string type, string tuhao, string xianghao, string realTableName)
- {
- if (string.IsNullOrWhiteSpace(projectId) || string.IsNullOrWhiteSpace(realTableName)) return;
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return;
- try
- {
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- string sql = "INSERT INTO 表索引 (类型, 图号, 箱号, 实际表名) VALUES (@t, @th, @xh, @real);";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- cmd.Parameters.AddWithValue("@t", type);
- cmd.Parameters.AddWithValue("@th", tuhao ?? "");
- cmd.Parameters.AddWithValue("@xh", xianghao ?? "");
- cmd.Parameters.AddWithValue("@real", realTableName);
- cmd.ExecuteNonQuery();
- }
- }
- }
- catch { }
- }
-
- private void RemoveTableIndex(string projectId, string type, string tuhao, string xianghao)
- {
- if (string.IsNullOrWhiteSpace(projectId)) return;
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return;
- try
- {
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- string sql = "DELETE FROM 表索引 WHERE 类型=@t AND 图号=@th AND 箱号=@xh;";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- cmd.Parameters.AddWithValue("@t", type);
- cmd.Parameters.AddWithValue("@th", tuhao ?? "");
- cmd.Parameters.AddWithValue("@xh", xianghao ?? "");
- cmd.ExecuteNonQuery();
- }
- }
- }
- catch { }
- }
-
- private string GetXianghaoTableByIndex(string projectId, string tuhao)
- {
- return LookupTableByIndex(projectId, "箱号", tuhao, "");
- }
-
- private string GetYuanjianTableByIndex(string projectId, string tuhao, string xianghao)
- {
- return LookupTableByIndex(projectId, "元件", tuhao, xianghao);
- }
-
- private string LookupTableByIndex(string projectId, string type, string tuhao, string xianghao)
- {
- if (string.IsNullOrWhiteSpace(projectId) || string.IsNullOrWhiteSpace(tuhao)) return "";
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return "";
- try
- {
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- return LookupTableByIndex(type, tuhao, xianghao, conn);
- }
- }
- catch { return ""; }
- }
-
- private string LookupTableByIndex(string type, string tuhao, string xianghao, System.Data.SQLite.SQLiteConnection conn)
- {
- if (conn == null || string.IsNullOrWhiteSpace(tuhao)) return "";
- try
- {
- string sql = "SELECT 实际表名 FROM 表索引 WHERE 类型=@t AND 图号=@th AND 箱号=@xh LIMIT 1;";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- cmd.Parameters.AddWithValue("@t", type);
- cmd.Parameters.AddWithValue("@th", tuhao);
- cmd.Parameters.AddWithValue("@xh", xianghao ?? "");
- object o = cmd.ExecuteScalar();
- return (o == null || o == DBNull.Value) ? "" : o.ToString();
- }
- }
- catch { return ""; }
- }
-
- private string GetXianghaoTableByIndex(string tuhao, System.Data.SQLite.SQLiteConnection conn)
- {
- return LookupTableByIndex("箱号", tuhao, "", conn);
- }
-
- private string GetYuanjianTableByIndex(string tuhao, string xianghao, System.Data.SQLite.SQLiteConnection conn)
- {
- return LookupTableByIndex("元件", tuhao, xianghao, conn);
- }
-
- private void CreateXianghaoTable(string projectId, string realTableName)
- {
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return;
- try
- {
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- string sql =
- "CREATE TABLE \"" + realTableName + "\" (" +
- " 序号 TEXT, 箱号 TEXT, 箱名 TEXT, 型号 TEXT, 规格 TEXT, 单位 TEXT, 数量 TEXT," +
- " 单台成本 REAL, 成本价 REAL, 单台报出 REAL, 报出价 REAL," +
- " 利润 REAL, 利润率 REAL, 毛利率 REAL, 箱柜类型 TEXT, 备注 TEXT, 图纸 TEXT" +
- ");";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn)) cmd.ExecuteNonQuery();
- }
- }
- catch { }
- }
-
- private void RenumberTable(string projectId, string quotedTableName)
- {
- if (string.IsNullOrWhiteSpace(projectId) || string.IsNullOrWhiteSpace(quotedTableName)) return;
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return;
- try
- {
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- string selSql = "SELECT rowid FROM " + quotedTableName + " ORDER BY rowid;";
- var rowids = new List();
- using (var sel = new System.Data.SQLite.SQLiteCommand(selSql, conn))
- using (var reader = sel.ExecuteReader())
- {
- while (reader.Read()) rowids.Add(reader.GetInt64(0));
- }
- int newSeq = 1;
- foreach (long rowid in rowids)
- {
- string updSql = "UPDATE " + quotedTableName + " SET 序号 = @seq WHERE rowid = @rid;";
- using (var upd = new System.Data.SQLite.SQLiteCommand(updSql, conn))
- {
- upd.Parameters.AddWithValue("@seq", newSeq.ToString());
- upd.Parameters.AddWithValue("@rid", rowid);
- upd.ExecuteNonQuery();
- }
- newSeq++;
- }
- }
- }
- catch { }
- }
-
- // ============================================================
- // 报价库「项目信息」表读写
- // ============================================================
-
- private void InsertProjectInfoToQuoteDb(string projectId, Dictionary values)
- {
- if (string.IsNullOrWhiteSpace(projectId) || values == null) return;
- EnsureQuoteDbExists(projectId);
- string dbPath = GetQuoteDbPath(projectId);
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- string delSql = "DELETE FROM " + ProjectInfoTableName + " WHERE 项目编号 = @id;";
- using (var del = new System.Data.SQLite.SQLiteCommand(delSql, conn))
- {
- del.Parameters.AddWithValue("@id", projectId);
- del.ExecuteNonQuery();
- }
- var cols = new List();
- var paras = new List();
- foreach (string c in ProjectInfoColumns)
- {
- if (values.ContainsKey(c)) { cols.Add(c); paras.Add("@" + c); }
- }
- if (cols.Count == 0) return;
- string sql = "INSERT INTO " + ProjectInfoTableName + " (" +
- string.Join(", ", cols.ToArray()) + ") VALUES (" +
- string.Join(", ", paras.ToArray()) + ");";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- foreach (string c in cols) cmd.Parameters.AddWithValue("@" + c, values[c] ?? "");
- cmd.ExecuteNonQuery();
- }
- }
- }
-
- private Dictionary GetProjectInfoFromQuoteDb(string projectId)
- {
- var info = new Dictionary();
- if (string.IsNullOrWhiteSpace(projectId)) return info;
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return info;
- try
- {
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- string chkSql = "SELECT name FROM sqlite_master WHERE type='table' AND name=@n;";
- using (var chk = new System.Data.SQLite.SQLiteCommand(chkSql, conn))
- {
- chk.Parameters.AddWithValue("@n", ProjectInfoTableName);
- if (chk.ExecuteScalar() == null) return info;
- }
- string sql = "SELECT * FROM " + ProjectInfoTableName + " WHERE 项目编号 = @id LIMIT 1;";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- cmd.Parameters.AddWithValue("@id", projectId);
- using (var reader = cmd.ExecuteReader())
- {
- if (reader.Read())
- {
- var existCols = new HashSet(StringComparer.OrdinalIgnoreCase);
- for (int i = 0; i < reader.FieldCount; i++) existCols.Add(reader.GetName(i));
- foreach (string c in ProjectInfoColumns)
- {
- if (!existCols.Contains(c)) continue;
- object v = reader[c];
- info[c] = (v == null || v == DBNull.Value) ? "" : v.ToString();
- }
- }
- }
- }
- }
- }
- catch { }
- return info;
- }
-
- private void LoadPriceFormatConfig(string projectId)
- {
- _单台小数位文本 = "保留2位小数";
- _单台取整方式 = "不取整";
- _项目小数位文本 = "保留2位小数";
- _项目取整方式 = "不取整";
- try
- {
- var info = GetProjectInfoFromQuoteDb(projectId);
- if (info == null || info.Count == 0) return;
- string v;
- if (info.TryGetValue("单台小数位", out v) && !string.IsNullOrWhiteSpace(v)) _单台小数位文本 = v;
- if (info.TryGetValue("单台取整方式", out v) && !string.IsNullOrWhiteSpace(v)) _单台取整方式 = v;
- if (info.TryGetValue("项目小数位", out v) && !string.IsNullOrWhiteSpace(v)) _项目小数位文本 = v;
- if (info.TryGetValue("项目取整方式", out v) && !string.IsNullOrWhiteSpace(v)) _项目取整方式 = v;
- }
- catch { }
- }
-
- // ============================================================
- // 项目库 CRUD
- // ============================================================
-
- private int InsertProjectToDatabase(Dictionary values)
- {
- if (values == null || values.Count == 0) return 0;
- string dbPath = GetDbFullPath(ProjectsDbPath);
- if (!File.Exists(dbPath))
- {
- EnsureProjectDbExists(dbPath);
- if (!File.Exists(dbPath))
- throw new FileNotFoundException("无法创建项目数据库文件: " + dbPath, dbPath);
- }
- int affected;
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- var allowed = new HashSet(GetProjectTableColumns(conn), StringComparer.OrdinalIgnoreCase);
- var colNames = new List();
- var paramNames = new List();
- foreach (string col in values.Keys)
- {
- if (allowed.Contains(col)) { colNames.Add(col); paramNames.Add("@" + col); }
- }
- if (colNames.Count == 0) { affected = 0; }
- else
- {
- string sql = "INSERT INTO " + ProjectsTableName + " (" +
- string.Join(", ", colNames.ToArray()) + ") VALUES (" +
- string.Join(", ", paramNames.ToArray()) + ");";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- foreach (string col in colNames) cmd.Parameters.AddWithValue("@" + col, values[col]);
- affected = cmd.ExecuteNonQuery();
- }
- }
- }
- string projectId;
- values.TryGetValue("项目编号", out projectId);
- if (!string.IsNullOrWhiteSpace(projectId)) InsertProjectInfoToQuoteDb(projectId, values);
- return affected;
- }
-
- private int DeleteProjectFromDatabase(string projectId)
- {
- if (string.IsNullOrWhiteSpace(projectId)) return 0;
- string dbPath = GetDbFullPath(ProjectsDbPath);
- if (!File.Exists(dbPath)) throw new FileNotFoundException("找不到项目数据库文件: " + dbPath, dbPath);
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- string sql = "DELETE FROM " + ProjectsTableName + " WHERE 项目编号 = @id;";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- cmd.Parameters.AddWithValue("@id", projectId);
- return cmd.ExecuteNonQuery();
- }
- }
- }
-
- private void CascadeDeleteByProject(string projectId)
- {
- if (string.IsNullOrWhiteSpace(projectId)) return;
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return;
- try { File.Delete(dbPath); }
- catch { }
- }
-
- private List> ReadAllProjectsFromDatabase()
- {
- var list = new List>();
- try
- {
- string dbPath = GetDbFullPath(ProjectsDbPath);
- if (!File.Exists(dbPath)) return list;
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- using (var cmd = new System.Data.SQLite.SQLiteCommand(
- "SELECT * FROM " + ProjectsTableName + " ORDER BY rowid;", conn))
- using (var rd = cmd.ExecuteReader())
- {
- while (rd.Read())
- {
- var dict = new Dictionary(StringComparer.Ordinal);
- for (int i = 0; i < rd.FieldCount; i++)
- {
- object v = rd.GetValue(i);
- if (v == null || v == DBNull.Value) v = "";
- dict[rd.GetName(i)] = v;
- }
- list.Add(dict);
- }
- }
- }
- }
- catch { }
- return list;
- }
-
- private Dictionary ReadProjectMetaData(string pid)
- {
- var dict = new Dictionary(StringComparer.Ordinal);
- try
- {
- string dbPath = GetDbFullPath(ProjectsDbPath);
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- using (var cmd = new System.Data.SQLite.SQLiteCommand(
- "SELECT * FROM " + ProjectsTableName + " WHERE 项目编号 = @p LIMIT 1;", conn))
- {
- cmd.Parameters.AddWithValue("@p", pid);
- using (var rd = cmd.ExecuteReader())
- {
- if (!rd.Read()) return null;
- for (int i = 0; i < rd.FieldCount; i++)
- {
- object v = rd.GetValue(i);
- if (v == null || v == DBNull.Value) v = "";
- dict[rd.GetName(i)] = v;
- }
- }
- }
- }
- }
- catch { return null; }
- return dict;
- }
-
- // ============================================================
- // 图号/箱号/元件 CRUD
- // ============================================================
-
- private string GetNextSeqNumber(string tableName, string nameCol, string projectId, string tuhao = null)
- {
- if (string.IsNullOrWhiteSpace(projectId)) return "1";
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return "1";
- try
- {
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- string sql;
- if (tuhao == null)
- {
- sql = "SELECT COUNT(*) FROM " + tableName + ";";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- int n = 0;
- object o = cmd.ExecuteScalar();
- if (o != null && o != DBNull.Value) n = Convert.ToInt32(o);
- return (n + 1).ToString();
- }
- }
- else
- {
- sql = "SELECT COUNT(*) FROM " + tableName + " WHERE 图号 = @th;";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- cmd.Parameters.AddWithValue("@th", tuhao);
- int n = 0;
- object o = cmd.ExecuteScalar();
- if (o != null && o != DBNull.Value) n = Convert.ToInt32(o);
- return (n + 1).ToString();
- }
- }
- }
- }
- catch { return "1"; }
- }
-
- // ============================================================
- // 扒图号/扒箱号/扒元件:CAD 文本选择交互
- // ============================================================
-
- ///
- /// 向 CAD 发送扒数据命令,触发框选交互。
- /// ★ 关键:先发 ESC 取消当前可能正在进行的扒图循环,再发新命令
- /// 这样用户从"扒图号"循环里点"扒箱号"也能立即切换
- ///
- private void SendCadPaCommand(string cmd)
- {
- try
- {
- if (!cadbt.CadBridge.IsViewerReady)
- {
- MessageBox.Show(this, "网页 CAD 尚未就绪,请先在文档区打开图纸。",
- "扒数据", MessageBoxButtons.OK, MessageBoxIcon.Warning);
- return;
- }
- // 转发到网页 CAD 桥(patu/paxh/payj/pacl 命令)
- cadbt.CadBridge.SendPaCommand(cmd);
- }
- catch (Exception ex)
- {
- MessageBox.Show(this, "发送扒图命令失败:\n" + ex.Message,
- "扒数据", MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- }
-
- ///
- /// CAD 选中文本后的回调:把选中的文本批量插入到对应表格。
- /// 由 CadPlugin.ExecutePaCommand 在 UI 线程调用。
- ///
- public void OnPaTextsPicked(PaMode mode, List results)
- {
- if (results == null || results.Count == 0) return;
- if (string.IsNullOrWhiteSpace(_currentProjectId))
- {
- MessageBox.Show(this, "请先在项目表中双击选择一个项目,再扒数据。",
- "扒数据", MessageBoxButtons.OK, MessageBoxIcon.Information);
- return;
- }
-
- switch (mode)
- {
- case PaMode.Tuhao:
- PaTuhaoInsert(results);
- break;
- case PaMode.Xianghao:
- PaXianghaoInsert(results);
- break;
- case PaMode.Yuanjian:
- PaYuanjianInsert(results);
- break;
- }
- }
-
- /// 扒图号:把选中文本作为图号批量插入到当前项目,同时保存框Handle。
- /// ★ 重复扒图:如果图号已存在,删除旧框和数据库行(不新增)。
- private void PaTuhaoInsert(List results)
- {
- string lastInsertedTuhao = null; // ★ 记录最后插入的图号,用于自动选中联动
- try
- {
- _isReloading = true;
- // 先 AcceptChanges,避免 SaveAllQuoteTablesIfDirty 把旧内存表回写
- if (_tuhaoTable != null) _tuhaoTable.AcceptChanges();
- if (_xianghaoTable != null) _xianghaoTable.AcceptChanges();
- if (_yuanjianTable != null) _yuanjianTable.AcceptChanges();
-
- // ★ 新增框架Handle列表: PaTextSelector刚画的框,如果是重复,需要删除这些新框
- var newFramesToErase = new List();
- int deletedCount = 0;
- int inserted = 0;
-
- foreach (var r in results)
- {
- if (string.IsNullOrWhiteSpace(r.Text)) continue;
- string clean = r.Text.Trim();
- // ★ 按"同一个文本实体"判断重复:查该文本实体Handle是否已入库。
- // 不同位置的相同内容文本 Handle 不同 → 不算重复,正常插入。
- string oldFrame = GetTuhaoFrameHandleByTextHandle(_currentProjectId, clean, r.TextHandle);
- if (!string.IsNullOrEmpty(oldFrame))
- {
- // ★ 重复(同一个文本再次选中):删除旧框+数据库行+新框
- DeleteTuhao(_currentProjectId, clean);
- DeleteFrameByHandle(oldFrame);
- if (!string.IsNullOrWhiteSpace(r.FrameHandle)) newFramesToErase.Add(r.FrameHandle);
- deletedCount++;
- }
- else
- {
- InsertTuhao(_currentProjectId, clean, r.FrameHandle, r.TextHandle);
- lastInsertedTuhao = clean; // ★ 记录最后插入的图号
- inserted++;
- }
- }
-
- // ★ 删除重复图号对应的新框(PaTextSelector已经画出来了,但不需要保留)——批量一次删
- DeleteFramesByHandles(newFramesToErase);
-
- _xianghaoCache.Clear();
- _yuanjianCache.Clear();
-
- // 直接在数据库层面重算(不经过内存回写)
- try { RecalcAllFromDatabase(_currentProjectId); } catch { }
- ReloadTuhaoByProject(_currentProjectId);
-
- // 保存
- try
- {
- if (this.advancedDataGridView9 != null) this.advancedDataGridView9.EndEdit();
- if (_tuhaoTable != null)
- {
- SaveTableToDatabase(_tuhaoTable, _currentProjectId, TuhaoTableName, null, null, true);
- _tuhaoTable.AcceptChanges();
- }
- }
- catch { }
- SaveCurrentDwg();
-
- if (deletedCount > 0 && inserted == 0)
- {
- Log("[PaTuhaoInsert] 删除了 " + deletedCount + " 条重复图号");
- }
- }
- catch (Exception ex)
- {
- MessageBox.Show(this, "扒图号失败:\n" + ex.Message,
- "扒图号", MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- finally
- {
- _isReloading = false;
- // ★ 扒完图号后自动选中刚插入的图号行,联动刷新箱号表
- if (!string.IsNullOrWhiteSpace(lastInsertedTuhao))
- {
- _currentTuhao = lastInsertedTuhao;
- SelectRowByValue(this.advancedDataGridView9, "图号", lastInsertedTuhao);
- // 手动联动刷新箱号表(SelectRowByValue 在 _isReloading 下不触发 SelectionChanged)
- ReloadXianghaoByTuhao(_currentProjectId, lastInsertedTuhao);
- }
- }
- }
-
- /// 扒箱号:把选中文本作为箱号批量插入到当前图号,同时保存框Handle。
- /// ★ 重复扒图:如果箱号已存在,删除旧框和数据库行(不新增)。
- private void PaXianghaoInsert(List results)
- {
- string lastInsertedXianghao = null; // ★ 记录最后插入的箱号,用于自动选中联动
- if (string.IsNullOrWhiteSpace(_currentTuhao))
- {
- MessageBox.Show(this, "请先在图号表中选择一个图号,再扒箱号。",
- "扒箱号", MessageBoxButtons.OK, MessageBoxIcon.Information);
- return;
- }
- try
- {
- _isReloading = true;
- // 先 AcceptChanges,避免 SaveAllQuoteTablesIfDirty 把旧内存表回写
- if (_tuhaoTable != null) _tuhaoTable.AcceptChanges();
- if (_xianghaoTable != null) _xianghaoTable.AcceptChanges();
- if (_yuanjianTable != null) _yuanjianTable.AcceptChanges();
-
- var newFramesToErase = new List();
- int deletedCount = 0;
- int inserted = 0;
-
- foreach (var r in results)
- {
- if (string.IsNullOrWhiteSpace(r.Text)) continue;
- string clean = r.Text.Trim();
- // ★ 按"同一个文本实体"判断重复(不同位置的相同内容文本不算重复)
- string oldFrame = GetXianghaoFrameHandleByTextHandle(_currentProjectId, _currentTuhao, clean, r.TextHandle);
- if (!string.IsNullOrEmpty(oldFrame))
- {
- // ★ 重复(同一个文本再次选中):删除旧框+数据库行+新框
- DeleteXianghao(_currentProjectId, _currentTuhao, clean);
- DeleteFrameByHandle(oldFrame);
- if (!string.IsNullOrWhiteSpace(r.FrameHandle)) newFramesToErase.Add(r.FrameHandle);
- deletedCount++;
- }
- else
- {
- InsertXianghao(_currentProjectId, _currentTuhao, clean, r.FrameHandle, r.TextHandle);
- lastInsertedXianghao = clean; // ★ 记录最后插入的箱号
- inserted++;
- }
- }
-
- DeleteFramesByHandles(newFramesToErase);
-
- _xianghaoCache.Clear();
- _yuanjianCache.Clear();
-
- try { RecalcAllFromDatabase(_currentProjectId); } catch { }
- ReloadXianghaoByTuhao(_currentProjectId, _currentTuhao);
-
- try
- {
- if (this.advancedDataGridView4 != null) this.advancedDataGridView4.EndEdit();
- if (_xianghaoTable != null && !string.IsNullOrWhiteSpace(_xianghaoTable.TableName))
- {
- SaveTableToDatabase(_xianghaoTable, _currentProjectId,
- "\"" + _xianghaoTable.TableName + "\"", null, null, true);
- _xianghaoTable.AcceptChanges();
- }
- }
- catch { }
- SaveCurrentDwg();
-
- if (deletedCount > 0 && inserted == 0)
- {
- Log("[PaXianghaoInsert] 删除了 " + deletedCount + " 条重复箱号");
- }
- }
- catch (Exception ex)
- {
- MessageBox.Show(this, "扒箱号失败:\n" + ex.Message,
- "扒箱号", MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- finally
- {
- _isReloading = false;
- // ★ 扒完箱号后自动选中刚插入的箱号行,联动刷新元件表
- if (!string.IsNullOrWhiteSpace(lastInsertedXianghao))
- {
- _currentXianghao = lastInsertedXianghao;
- SelectRowByValue(this.advancedDataGridView4, "箱号", lastInsertedXianghao);
- // 手动联动刷新元件表(SelectRowByValue 在 _isReloading 下不触发 SelectionChanged)
- ReloadYuanjianByXianghao(_currentProjectId, _currentTuhao, lastInsertedXianghao);
- }
- }
- }
-
- /// 扒元件:把选中文本作为【规格】批量插入到当前箱号(写到规格列),同时保存框Handle。
- /// ★ 关键:在单个事务里按 results 顺序依次插入,保证序号连续。
- /// ★ 重复扒图:如果规格已存在,删除旧框+数据库行(不新增)。
- private void PaYuanjianInsert(List results)
- {
- if (string.IsNullOrWhiteSpace(_currentXianghao))
- {
- MessageBox.Show(this, "请先在箱号表中选择一个箱号,再扒元件。",
- "扒元件", MessageBoxButtons.OK, MessageBoxIcon.Information);
- return;
- }
- try
- {
- _isReloading = true;
- // ★ 关键:先 AcceptChanges 清掉内存表的改动标记,避免 SaveAllQuoteTablesIfDirty
- // 用旧的内存数据覆盖数据库
- if (_yuanjianTable != null) _yuanjianTable.AcceptChanges();
- if (_xianghaoTable != null) _xianghaoTable.AcceptChanges();
- if (_tuhaoTable != null) _tuhaoTable.AcceptChanges();
- EnsureQuoteDbExists(_currentProjectId);
- string dbPath = GetQuoteDbPath(_currentProjectId);
- EnsureYuanjianTableExists(_currentProjectId, _currentTuhao, _currentXianghao);
- string tblName = GetYuanjianTableByIndex(_currentProjectId, _currentTuhao, _currentXianghao);
- if (string.IsNullOrEmpty(tblName))
- {
- MessageBox.Show("元件表创建失败(表索引未注册),图号=" + _currentTuhao + " 箱号=" + _currentXianghao);
- return;
- }
-
- // ★ 确保旧元件表也有"框Handle"/"文本Handle"列
- using (var connEns = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- connEns.Open();
- EnsureColumns(connEns, "\"" + tblName + "\"", new[] { "框Handle", "文本Handle" });
- }
-
- // 过滤掉空文本,保留原始顺序(同时保留框Handle+文本Handle)
- var cleanResults = new List();
- foreach (var r in results)
- {
- if (!string.IsNullOrWhiteSpace(r.Text))
- {
- cleanResults.Add(new PaTextResult
- {
- Text = r.Text.Trim(),
- FrameHandle = r.FrameHandle ?? "",
- TextHandle = r.TextHandle ?? ""
- });
- }
- }
- if (cleanResults.Count == 0) return;
-
- // ★ 判断是否是逆向合并模式(所有result共用同一个框Handle且数量>1)
- bool isMergeMode = cleanResults.Count > 1;
- string mergeHandle = cleanResults[0].FrameHandle;
- if (isMergeMode)
- {
- foreach (var r in cleanResults)
- {
- if (r.FrameHandle != mergeHandle) { isMergeMode = false; break; }
- }
- }
-
- // ★ 新增:重复检测辅助集合
- // newFramesToErase: PaTextSelector刚画的框,如果是重复项,这些框要删除
- var newFramesToErase = new List();
- // oldFrameHandlesToDelete: 数据库里匹配到的旧框,要删除
- var oldFrameHandlesToDelete = new List();
- // toInsert: 不重复、需要插入的项
- var toInsert = new List();
- // ★ 本地匹配失败的规格(收集后交给 DeepSeek AI 兜底识别)
- var aiFailedSpecs = new List();
- int deletedCount = 0;
-
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
-
- if (isMergeMode)
- {
- // ★ 合并模式:所有文本按图纸阅读顺序拼成一个规格
- // (PaTextSelector 已按列分组、列内从上到下排好序,保持此顺序
- // 与库中自然书写顺序一致,如 HD13BX-1500/31 + 1500A)
- // 文本Handle串与文本一一对应拼接(同一批文本Handle集合相同即重复)。
- var orderedTexts = new List();
- var orderedHandles = new List();
- foreach (var r in cleanResults)
- {
- orderedTexts.Add(r.Text);
- orderedHandles.Add(r.TextHandle ?? "");
- }
- string mergedSpec = string.Join("", orderedTexts.ToArray());
- // ★ Handle串排序后拼接(Handle集合相同即同一批文本,与顺序无关)
- var sortedHandles = new List(orderedHandles);
- sortedHandles.Sort(StringComparer.Ordinal);
- string mergedTextHandle = string.Join("|", sortedHandles.ToArray());
-
- // ★ 1. 查"同一批文本实体"的合并规格是否已存在
- // (文本Handle拼接串相同 = 同一批文本再次被选中,才是真重复)
- var matchFrames = new List();
- using (var selCmd = new System.Data.SQLite.SQLiteCommand(
- "SELECT 框Handle FROM \"" + tblName + "\" WHERE 规格=@spec AND 文本Handle=@th;", conn))
- {
- selCmd.Parameters.AddWithValue("@spec", mergedSpec);
- selCmd.Parameters.AddWithValue("@th", mergedTextHandle);
- using (var reader = selCmd.ExecuteReader())
- {
- while (reader.Read())
- {
- object v = reader["框Handle"];
- if (v != null && v != DBNull.Value)
- {
- string s = v.ToString();
- if (!string.IsNullOrWhiteSpace(s) && !matchFrames.Contains(s))
- matchFrames.Add(s);
- }
- }
- }
- }
-
- // ★ 2. 再查:本批每个文本实体是否已作为"独立元件"入库(按文本Handle精确匹配)
- var perTextFrames = new List();
- var perTextSpecs = new List();
- foreach (var r in cleanResults)
- {
- List fhs = GetYuanjianFrameHandlesByTextHandle(
- _currentProjectId, _currentTuhao, _currentXianghao, r.Text, r.TextHandle);
- foreach (string fh in fhs)
- {
- if (!perTextFrames.Contains(fh)) perTextFrames.Add(fh);
- }
- if (fhs.Count > 0 && !perTextSpecs.Contains(r.Text)) perTextSpecs.Add(r.Text);
- }
-
- // ★ 只要匹配到(1.同一批文本的合并规格 或 2.同一文本实体的独立元件) → 执行删除
- bool hitMergeMatch = matchFrames.Count > 0;
- bool hitPerTextMatch = perTextSpecs.Count > 0;
-
- if (hitMergeMatch || hitPerTextMatch)
- {
- // ★ 删除:同一批文本的合并规格匹配的行(文本Handle+规格双条件)
- if (hitMergeMatch)
- {
- using (var delCmd = new System.Data.SQLite.SQLiteCommand(
- "DELETE FROM \"" + tblName + "\" WHERE 规格=@spec AND 文本Handle=@th;", conn))
- {
- delCmd.Parameters.AddWithValue("@spec", mergedSpec);
- delCmd.Parameters.AddWithValue("@th", mergedTextHandle);
- int aff = delCmd.ExecuteNonQuery();
- deletedCount += aff;
- }
- foreach (string fh in matchFrames)
- if (!oldFrameHandlesToDelete.Contains(fh)) oldFrameHandlesToDelete.Add(fh);
- }
- // ★ 删除:同一文本实体的独立元件行(按文本Handle删除)
- if (hitPerTextMatch)
- {
- foreach (var r in cleanResults)
- {
- if (string.IsNullOrWhiteSpace(r.TextHandle)) continue;
- using (var selCmd2 = new System.Data.SQLite.SQLiteCommand(
- "SELECT COUNT(*) FROM \"" + tblName + "\" WHERE 文本Handle=@th;", conn))
- {
- selCmd2.Parameters.AddWithValue("@th", r.TextHandle);
- object cnt = selCmd2.ExecuteScalar();
- int n = (cnt != null && cnt != DBNull.Value) ? Convert.ToInt32(cnt) : 0;
- if (n > 0)
- {
- using (var delCmd = new System.Data.SQLite.SQLiteCommand(
- "DELETE FROM \"" + tblName + "\" WHERE 文本Handle=@th;", conn))
- {
- delCmd.Parameters.AddWithValue("@th", r.TextHandle);
- int aff = delCmd.ExecuteNonQuery();
- deletedCount += aff;
- }
- }
- }
- }
- foreach (string fh in perTextFrames)
- if (!oldFrameHandlesToDelete.Contains(fh)) oldFrameHandlesToDelete.Add(fh);
- }
- // ★ 删除 PaTextSelector 刚画的新合并框
- if (!string.IsNullOrWhiteSpace(mergeHandle))
- if (!newFramesToErase.Contains(mergeHandle))
- newFramesToErase.Add(mergeHandle);
- Log("[PaYuanjianInsert] 合并模式:删除重复项 mergedMatch=" + hitMergeMatch
- + " perTextMatch=" + hitPerTextMatch + ", 删除行数=" + deletedCount
- + ", 删除旧框数=" + oldFrameHandlesToDelete.Count);
- }
- else
- {
- // ★ 没有匹配:新增一行(合并规格)
- toInsert.Add(new PaTextResult
- {
- Text = mergedSpec,
- FrameHandle = mergeHandle,
- TextHandle = mergedTextHandle
- });
- }
- }
- else
- {
- // ★ 正向模式:每个文本一条记录,按"同一个文本实体"判断是否重复
- foreach (var r in cleanResults)
- {
- // ★ 按文本Handle精确匹配:同一文本实体才删除,
- // 不同位置的相同内容文本(Handle不同)正常插入
- List matchFrames = GetYuanjianFrameHandlesByTextHandle(
- _currentProjectId, _currentTuhao, _currentXianghao, r.Text, r.TextHandle);
- if (matchFrames.Count > 0)
- {
- // 重复:按文本Handle删除数据库行 + 旧框 + 新画的框
- using (var delCmd = new System.Data.SQLite.SQLiteCommand(
- "DELETE FROM \"" + tblName + "\" WHERE 文本Handle=@th;", conn))
- {
- delCmd.Parameters.AddWithValue("@th", r.TextHandle);
- int aff = delCmd.ExecuteNonQuery();
- deletedCount += aff;
- }
- foreach (string fh in matchFrames) oldFrameHandlesToDelete.Add(fh);
- if (!string.IsNullOrWhiteSpace(r.FrameHandle)) newFramesToErase.Add(r.FrameHandle);
- }
- else
- {
- toInsert.Add(r);
- }
- }
- }
-
- // ★ 写入需要新增的项
- if (toInsert.Count > 0)
- {
- // 先取当前最大序号(用MAX函数)
- int startSeq = 0;
- using (var cntCmd = new System.Data.SQLite.SQLiteCommand(
- "SELECT COALESCE(MAX(CAST(序号 AS INTEGER)), 0) FROM \"" + tblName + "\";", conn))
- {
- object o = cntCmd.ExecuteScalar();
- if (o != null && o != DBNull.Value) startSeq = Convert.ToInt32(o);
- }
- string sql = "INSERT INTO \"" + tblName + "\"" +
- " (序号, 元件名称, 规格, 单位, 数量, 采购系数, 报出系数," +
- " 表价, 采购单价, 采购价, 报出单价, 报出价, 类型, 框Handle, 文本Handle) " +
- "VALUES (@seq, @name, @spec, @unit, @shuliang, @caigou, @baochu, 0, 0, 0, 0, 0, '元件', @fh, @th);";
- for (int i = 0; i < toInsert.Count; i++)
- {
- // ★ 自动匹配元件名称(用户库CSV模糊匹配,匹配不上为空)
- string matchedName = MatchSpecName(toInsert[i].Text) ?? "";
- if (matchedName.Length == 0) aiFailedSpecs.Add(toInsert[i].Text);
- using (var insCmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- insCmd.Parameters.AddWithValue("@seq", (startSeq + i + 1).ToString());
- insCmd.Parameters.AddWithValue("@name", matchedName);
- insCmd.Parameters.AddWithValue("@spec", toInsert[i].Text);
- insCmd.Parameters.AddWithValue("@unit", "只");
- insCmd.Parameters.AddWithValue("@shuliang", "1");
- insCmd.Parameters.AddWithValue("@caigou", "1");
- insCmd.Parameters.AddWithValue("@baochu", "1");
- insCmd.Parameters.AddWithValue("@fh", toInsert[i].FrameHandle ?? "");
- insCmd.Parameters.AddWithValue("@th", toInsert[i].TextHandle ?? "");
- insCmd.ExecuteNonQuery();
- }
- }
- }
- }
-
- // ★ 删除旧框和重复新框——合并成一次批量删除(单事务+单次刷新)
- var framesToErase = new List(oldFrameHandlesToDelete);
- framesToErase.AddRange(newFramesToErase);
- DeleteFramesByHandles(framesToErase);
-
- // ★ 重新编号(删除后序号可能不连续)
- RenumberTable(_currentProjectId, "\"" + tblName + "\"");
-
- _yuanjianCache.Clear();
- _xianghaoCache.Clear();
-
- // 直接在数据库层面重算(不经过内存回写)
- try { RecalcAllFromDatabase(_currentProjectId); } catch { }
- ReloadYuanjianByXianghao(_currentProjectId, _currentTuhao, _currentXianghao);
-
- // ★ 收集新插入元件的框Handle(finally 里再统一选中,
- // 避免被后续 SaveTable/AcceptChanges/表格刷新清掉选中)
- foreach (var r in toInsert)
- if (!string.IsNullOrWhiteSpace(r.FrameHandle))
- _pendingSelectYuanjianHandles.Add(r.FrameHandle);
-
- // 保存
- try
- {
- if (this.advancedDataGridView5 != null) this.advancedDataGridView5.EndEdit();
- if (_yuanjianTable != null)
- {
- SaveTableToDatabase(_yuanjianTable, _currentProjectId,
- "\"" + _yuanjianTable.TableName + "\"", null, null, true);
- _yuanjianTable.AcceptChanges();
- }
- }
- catch { }
- SaveCurrentDwg();
-
- if (deletedCount > 0)
- {
- Log("[PaYuanjianInsert] 删除了 " + deletedCount + " 条重复元件(匹配框:" + oldFrameHandlesToDelete.Count + ")");
- }
-
- // ★ DeepSeek AI 兜底:本地未匹配到名称的规格,异步提交 AI 识别并回填
- if (aiFailedSpecs.Count > 0)
- {
- Log("[PaYuanjianInsert] " + aiFailedSpecs.Count + " 条本地未匹配,提交AI识别");
- AiFillMissingNames(aiFailedSpecs, tblName);
- }
- }
- catch (Exception ex)
- {
- MessageBox.Show(this, "扒元件失败:\n" + ex.Message,
- "扒元件", MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- finally
- {
- _isReloading = false;
- // ★ 扒到的元件行保持选中(供 F1 合并):延迟两拍执行,
- // 等保存/刷新/绑定事件链全部走完,否则选中会被冲掉
- if (_pendingSelectYuanjianHandles.Count > 0)
- {
- var snapshot = new List(_pendingSelectYuanjianHandles);
- _pendingSelectYuanjianHandles.Clear();
- BeginInvoke((Action)(() =>
- {
- BeginInvoke((Action)(() =>
- {
- SelectYuanjianRowsByFrameHandles(snapshot);
- Log("[PaYuanjianInsert] 已选中 " + snapshot.Count + " 条新元件行(供F1合并)");
- }));
- }));
- }
- }
- }
-
- /// 查询图号是否已存在(避免重复插入)。
- private bool TuhaoExists(string projectId, string tuhao)
- {
- return !string.IsNullOrEmpty(GetTuhaoFrameHandle(projectId, tuhao));
- }
-
- ///
- /// ★ 按"同一个文本实体"判断重复:查该文本实体Handle是否已入库。
- /// 命中返回旧框Handle(真重复);未命中返回 null(不同位置的相同内容文本,正常插入)。
- ///
- private string GetTuhaoFrameHandleByTextHandle(string projectId, string tuhao, string textHandle)
- {
- // 旧数据没有文本Handle → 按旧逻辑(文本内容)判断,保持旧行为
- if (string.IsNullOrWhiteSpace(textHandle)) return GetTuhaoFrameHandle(projectId, tuhao);
- try
- {
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return null;
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- // ★ 先确保旧图号表有"文本Handle"列,避免查询报错
- EnsureColumns(conn, TuhaoTableName, new[] { "文本Handle" });
- // ★ 双条件:同一文本实体(Handle精确匹配) 或 旧数据行(无文本Handle,按内容兜底)
- using (var cmd = new System.Data.SQLite.SQLiteCommand(
- "SELECT 框Handle FROM " + TuhaoTableName +
- " WHERE 文本Handle=@th OR (图号=@t AND (文本Handle IS NULL OR 文本Handle='')) LIMIT 1;", conn))
- {
- cmd.Parameters.AddWithValue("@th", textHandle);
- cmd.Parameters.AddWithValue("@t", tuhao);
- using (var rdr = cmd.ExecuteReader())
- {
- if (rdr.Read())
- {
- object v = rdr["框Handle"];
- if (v != null && v != DBNull.Value)
- {
- string s = v.ToString();
- if (!string.IsNullOrWhiteSpace(s)) return s;
- }
- }
- }
- }
- }
- }
- catch { }
- return null;
- }
-
- /// 查询指定图号的框Handle(不存在返回null)。
- private string GetTuhaoFrameHandle(string projectId, string tuhao)
- {
- try
- {
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return null;
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- using (var cmd = new System.Data.SQLite.SQLiteCommand(
- "SELECT 框Handle FROM " + TuhaoTableName + " WHERE 图号=@t LIMIT 1;", conn))
- {
- cmd.Parameters.AddWithValue("@t", tuhao);
- using (var rdr = cmd.ExecuteReader())
- {
- if (rdr.Read())
- {
- object v = rdr["框Handle"];
- if (v != null && v != DBNull.Value)
- {
- string s = v.ToString();
- if (!string.IsNullOrWhiteSpace(s)) return s;
- }
- }
- }
- }
- }
- }
- catch { }
- return null;
- }
-
- /// 查询箱号是否已存在(避免重复插入)。
- private bool XianghaoExists(string projectId, string tuhao, string xianghao)
- {
- return !string.IsNullOrEmpty(GetXianghaoFrameHandle(projectId, tuhao, xianghao));
- }
-
- ///
- /// ★ 按"同一个文本实体"判断重复:查该文本实体Handle是否已入库。
- /// 命中返回旧框Handle(真重复);未命中返回 null(不同位置的相同内容文本,正常插入)。
- ///
- private string GetXianghaoFrameHandleByTextHandle(string projectId, string tuhao, string xianghao, string textHandle)
- {
- // 旧数据没有文本Handle → 按旧逻辑(文本内容)判断,保持旧行为
- if (string.IsNullOrWhiteSpace(textHandle)) return GetXianghaoFrameHandle(projectId, tuhao, xianghao);
- try
- {
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return null;
- string tableName = GetQuoteTableName(projectId, tuhao);
- if (string.IsNullOrEmpty(tableName)) return null;
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- // ★ 先确保旧箱号表有"文本Handle"列,避免查询报错
- EnsureColumns(conn, "\"" + tableName + "\"", new[] { "文本Handle" });
- // ★ 双条件:同一文本实体(Handle精确匹配) 或 旧数据行(无文本Handle,按内容兜底)
- using (var cmd = new System.Data.SQLite.SQLiteCommand(
- "SELECT 框Handle FROM \"" + tableName + "\"" +
- " WHERE 文本Handle=@th OR (箱号=@x AND (文本Handle IS NULL OR 文本Handle='')) LIMIT 1;", conn))
- {
- cmd.Parameters.AddWithValue("@th", textHandle);
- cmd.Parameters.AddWithValue("@x", xianghao);
- using (var rdr = cmd.ExecuteReader())
- {
- if (rdr.Read())
- {
- object v = rdr["框Handle"];
- if (v != null && v != DBNull.Value)
- {
- string s = v.ToString();
- if (!string.IsNullOrWhiteSpace(s)) return s;
- }
- }
- }
- }
- }
- }
- catch { }
- return null;
- }
-
- /// 查询指定箱号的框Handle(不存在返回null)。
- private string GetXianghaoFrameHandle(string projectId, string tuhao, string xianghao)
- {
- try
- {
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return null;
- string tableName = GetQuoteTableName(projectId, tuhao);
- if (string.IsNullOrEmpty(tableName)) return null;
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- using (var cmd = new System.Data.SQLite.SQLiteCommand(
- "SELECT 框Handle FROM \"" + tableName + "\" WHERE 箱号=@x LIMIT 1;", conn))
- {
- cmd.Parameters.AddWithValue("@x", xianghao);
- using (var rdr = cmd.ExecuteReader())
- {
- if (rdr.Read())
- {
- object v = rdr["框Handle"];
- if (v != null && v != DBNull.Value)
- {
- string s = v.ToString();
- if (!string.IsNullOrWhiteSpace(s)) return s;
- }
- }
- }
- }
- }
- }
- catch { }
- return null;
- }
-
- /// 查询指定元件规格的所有框Handle(可能有多个重复行,返回List)。
- private List GetYuanjianFrameHandles(string projectId, string tuhao, string xianghao, string spec)
- {
- var list = new List();
- try
- {
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return list;
- string tableName = GetYuanjianTableByIndex(projectId, tuhao, xianghao);
- if (string.IsNullOrEmpty(tableName)) return list;
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- using (var cmd = new System.Data.SQLite.SQLiteCommand(
- "SELECT 框Handle FROM \"" + tableName + "\" WHERE 规格=@s;", conn))
- {
- cmd.Parameters.AddWithValue("@s", spec);
- using (var rdr = cmd.ExecuteReader())
- {
- while (rdr.Read())
- {
- object v = rdr["框Handle"];
- if (v != null && v != DBNull.Value)
- {
- string s = v.ToString();
- if (!string.IsNullOrWhiteSpace(s)) list.Add(s);
- }
- }
- }
- }
- }
- }
- catch { }
- return list;
- }
-
- ///
- /// ★ 按"同一个文本实体"判断重复:查该文本实体Handle在元件表中是否已入库。
- /// 命中返回旧框Handle列表(真重复);未命中返回空列表(不同位置的相同内容文本,正常插入)。
- ///
- private List GetYuanjianFrameHandlesByTextHandle(string projectId, string tuhao, string xianghao, string spec, string textHandle)
- {
- var list = new List();
- // 旧数据没有文本Handle → 按旧逻辑(文本内容)判断,保持旧行为
- if (string.IsNullOrWhiteSpace(textHandle)) return GetYuanjianFrameHandles(projectId, tuhao, xianghao, spec);
- try
- {
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return list;
- string tableName = GetYuanjianTableByIndex(projectId, tuhao, xianghao);
- if (string.IsNullOrEmpty(tableName)) return list;
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- // ★ 先确保旧元件表有"文本Handle"列,避免查询报错
- EnsureColumns(conn, "\"" + tableName + "\"", new[] { "文本Handle" });
- // ★ 双条件:同一文本实体(Handle精确匹配) 或 旧数据行(无文本Handle,按规格兜底)
- using (var cmd = new System.Data.SQLite.SQLiteCommand(
- "SELECT 框Handle FROM \"" + tableName + "\"" +
- " WHERE 文本Handle=@th OR (规格=@s AND (文本Handle IS NULL OR 文本Handle=''));", conn))
- {
- cmd.Parameters.AddWithValue("@th", textHandle);
- cmd.Parameters.AddWithValue("@s", spec);
- using (var rdr = cmd.ExecuteReader())
- {
- while (rdr.Read())
- {
- object v = rdr["框Handle"];
- if (v != null && v != DBNull.Value)
- {
- string s = v.ToString();
- if (!string.IsNullOrWhiteSpace(s)) list.Add(s);
- }
- }
- }
- }
- }
- }
- catch { }
- return list;
- }
-
- // ============================================================
- // 扒元件自动匹配元件名称(用户库CSV模糊匹配)
- // · 扫描插件上级目录/自身目录下最新的 用户库_*.csv(GBK编码)
- // · 匹配策略:L1归一化相等 → L2包含(60%长度) → L3编辑距离≥0.70
- // · 硬保护:模糊匹配时数字序列必须完全一致(63A 不会配到 100A)
- // ============================================================
-
- /// 用户库条目:规格 → 元件名称
- private class SpecNameEntry
- {
- public string Name;
- public string NormSpec; // 归一化后的规格
- public string[] Numbers; // 规格中的数字序列(模糊匹配保护用)
- public string Skeleton; // 字母骨架(去数字/分隔符/尾部单位,如 DZ47-4P/C80A → DZPC)
- }
-
- private static List _specNameLib = null;
- private static string _specLibCsvPath = null;
- private static DateTime _specLibCsvTime = DateTime.MinValue;
-
- ///
- /// 确保用户库CSV已加载(取最新修改时间的 用户库_*.csv,
- /// 文件时间戳变化时自动重新加载;文件被 Excel 占用时用共享读)。
- ///
- private static void EnsureUserLibCsvLoaded()
- {
- try
- {
- // 候选目录:上级目录(成套报价软件根目录) + 插件目录自身
- var dirs = new List();
- try
- {
- var parent = Path.GetDirectoryName(_baseDir);
- if (!string.IsNullOrEmpty(parent) && Directory.Exists(parent)) dirs.Add(parent);
- }
- catch { }
- dirs.Add(_baseDir);
-
- string best = null;
- DateTime bestTime = DateTime.MinValue;
- foreach (string d in dirs)
- {
- try
- {
- string[] files = Directory.GetFiles(d, "用户库*.csv");
- foreach (string f in files)
- {
- DateTime t = File.GetLastWriteTime(f);
- if (best == null || t > bestTime) { best = f; bestTime = t; }
- }
- }
- catch { }
- }
- if (best == null) return; // 没找到CSV,保持空库
-
- // 时间戳没变且已加载 → 不重复加载
- if (_specNameLib != null &&
- string.Equals(best, _specLibCsvPath, StringComparison.OrdinalIgnoreCase) &&
- bestTime == _specLibCsvTime) return;
-
- var lib = new List();
- var prefixRules = new List();
- // ★ 共享读:文件被 Excel 打开也能读
- using (var fs = new FileStream(best, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
- using (var sr = new StreamReader(fs, DetectCsvEncoding(fs)))
- {
- string line;
- bool first = true;
- while ((line = sr.ReadLine()) != null)
- {
- if (string.IsNullOrWhiteSpace(line)) continue;
- string[] cols = SplitCsvLine(line);
- if (cols.Length < 2) continue;
- string name = cols[0].Trim();
- string spec = cols[1].Trim();
- if (first)
- {
- first = false;
- // 跳过表头
- if (name == "元件名称") continue;
- }
- if (name.Length == 0 || spec.Length == 0) continue;
-
- // ★ "元件类型"列 = "前缀" 的行是型号前缀规则(不是库条目)
- string elemType = cols.Length >= 10 ? cols[9].Trim() : "";
- if (elemType == "前缀")
- {
- string pfx = spec.ToUpperInvariant();
- if (pfx.Length >= 2) prefixRules.Add(new[] { pfx, name });
- continue;
- }
-
- string normSpec = NormalizeSpec(spec);
- lib.Add(new SpecNameEntry
- {
- Name = name,
- NormSpec = normSpec,
- // ★ 必须用原始 spec 提取数字(保留空格/符号作数字边界);
- // 用 normSpec 会导致 3300 800 粘连成 3300800,数字序列错位
- Numbers = ExtractNumbers(spec),
- Skeleton = ExtractSkeleton(spec)
- });
- }
- }
- _specNameLib = lib;
- _prefixRules = prefixRules;
- _specLibCsvPath = best;
- _specLibCsvTime = bestTime;
- WriteDebugLog("[用户库匹配] 加载CSV: " + best + " 条数=" + lib.Count +
- " 前缀规则=" + prefixRules.Count);
- }
- catch (Exception ex) { WriteDebugLog("[用户库匹配] 加载CSV异常: " + ex.Message); }
- }
-
- /// 检测CSV编码:有UTF-8 BOM用UTF8,否则按GBK(主程序导出编码)。
- private static System.Text.Encoding DetectCsvEncoding(FileStream fs)
- {
- try
- {
- long pos = fs.Position;
- int b1 = fs.ReadByte();
- int b2 = fs.ReadByte();
- int b3 = fs.ReadByte();
- fs.Position = pos;
- if (b1 == 0xEF && b2 == 0xBB && b3 == 0xBF) return System.Text.Encoding.UTF8;
- }
- catch { }
- return System.Text.Encoding.GetEncoding("GBK");
- }
-
- /// 按CSV规则拆分一行(支持双引号包裹和转义"")。
- private static string[] SplitCsvLine(string line)
- {
- var parts = new List();
- var sb = new System.Text.StringBuilder();
- bool inQuotes = false;
- for (int i = 0; i < line.Length; i++)
- {
- char c = line[i];
- if (c == '"')
- {
- if (inQuotes && i + 1 < line.Length && line[i + 1] == '"') { sb.Append('"'); i++; }
- else inQuotes = !inQuotes;
- }
- else if (c == ',' && !inQuotes)
- {
- parts.Add(sb.ToString());
- sb.Length = 0;
- }
- else sb.Append(c);
- }
- parts.Add(sb.ToString());
- return parts.ToArray();
- }
-
- /// 规格归一化:全角→半角、统一大写、去空白和分隔符号(保留字母/数字/中文)。
- private static string NormalizeSpec(string s)
- {
- if (string.IsNullOrEmpty(s)) return "";
- var sb = new System.Text.StringBuilder(s.Length);
- foreach (char c0 in s)
- {
- char c = c0;
- // 全角→半角
- if (c >= 0xFF01 && c <= 0xFF5E) c = (char)(c - 0xFEE0);
- else if (c == 0x3000) c = ' ';
- if (c == ' ' || c == '\t') continue;
- if (IsSpecSeparator(c)) continue;
- sb.Append(char.ToUpperInvariant(c));
- }
- return sb.ToString();
- }
-
- /// 规格中的分隔符号(归一化时删除;数字提取时作为数字段边界)。
- private static bool IsSpecSeparator(char c)
- {
- return c == '-' || c == '/' || c == '*' || c == '×' || c == '·' || c == '.' ||
- c == '、' || c == ',' || c == ',' || c == '(' || c == ')' || c == '(' ||
- c == ')' || c == '#' || c == '+' || c == '_' || c == ':' || c == ':' ||
- c == '~' || c == '~';
- }
-
- ///
- /// 轻量归一化(保留分隔符和空格):全角→半角、统一大写。
- /// ★ 用于数字序列提取:分隔符和空格是数字段的天然边界,
- /// 先删分隔符会导致 HYM1-63/3300 的 63 和 3300 粘连成 633300;
- /// 删空格会导致 3300 800 粘连成 3300800(与 3300,800 数字序列不一致)。
- ///
- private static string NormalizeKeepSeparators(string s)
- {
- if (string.IsNullOrEmpty(s)) return "";
- var sb = new System.Text.StringBuilder(s.Length);
- foreach (char c0 in s)
- {
- char c = c0;
- if (c >= 0xFF01 && c <= 0xFF5E) c = (char)(c - 0xFEE0);
- else if (c == 0x3000) c = ' ';
- if (c == '\t') c = ' '; // 制表符当空格
- sb.Append(char.ToUpperInvariant(c));
- }
- return sb.ToString();
- }
-
- ///
- /// 提取规格中的所有数字序列(在保留分隔符的版本上提取,
- /// 如 HYM1-63/3300 63A → ["1","63","3300","63"])。
- ///
- private static string[] ExtractNumbers(string spec)
- {
- var list = new List();
- if (string.IsNullOrEmpty(spec)) return list.ToArray();
- string light = NormalizeKeepSeparators(spec);
- var sb = new System.Text.StringBuilder();
- foreach (char c in light)
- {
- if (c >= '0' && c <= '9') sb.Append(c);
- else if (sb.Length > 0) { list.Add(sb.ToString()); sb.Length = 0; }
- }
- if (sb.Length > 0) list.Add(sb.ToString());
- return list.ToArray();
- }
-
- /// 两个数字序列是否完全一致。
- private static bool NumbersEqual(string[] a, string[] b)
- {
- if (a == null || b == null) return false;
- if (a.Length != b.Length) return false;
- for (int i = 0; i < a.Length; i++)
- if (a[i] != b[i]) return false;
- return true;
- }
-
- ///
- /// 数字序列兼容(子序列检查):短方的数字按顺序都能在长方中找到即通过。
- /// ★ 用于 L2 包含关系:一方文本是另一方的一部分,数字自然也可能少
- /// (如图纸只写 HD13BX-1500/31,库里是 HD13BX-1500/31 1500A)。
- /// ★ 依然防误配:63A vs 100A 时 63 不在对方序列对应位置,拒绝。
- ///
- private static bool NumbersCompatible(string[] a, string[] b)
- {
- if (a == null || b == null) return false;
- string[] shorter = a.Length <= b.Length ? a : b;
- string[] longer = a.Length <= b.Length ? b : a;
- if (longer.Length == 0) return shorter.Length == 0;
- int i = 0;
- foreach (string n in longer)
- {
- if (i < shorter.Length && n == shorter[i]) i++;
- }
- return i == shorter.Length;
- }
-
- ///
- /// 数字序列严格相等 + 两种容错(L3 模糊匹配用):
- /// 1.粘连拆分:图纸连写导致数字粘连(如 0.66+1500 提取出 661500),拆成两段后对上即通过;
- /// 2.壳架容错:图纸把额定电流写进型号段(如 HYW1-2500/3P 2500A,2500出现两次),
- /// 库里型号段是壳架等级(HYW1-3200),删掉图纸型号段那个数字后能对上即通过。
- /// ★ 仅当该数字在图纸中出现≥2次才允许删,220V/380V 这类无重复差异依然拒绝。
- ///
- private static bool NumbersEqualEx(string[] a, string[] b)
- {
- if (a == null || b == null) return false;
- if (NumbersEqual(a, b)) return true;
- // 容错1:粘连拆分
- if (TrySplitAndCompatible(a, b)) return true;
- if (TrySplitAndCompatible(b, a)) return true;
- // 容错2:壳架(删图纸中重复出现的电流数字之一)
- if (TryDropFrameCurrent(a, b)) return true;
- if (TryDropFrameCurrent(b, a)) return true;
- return false;
- }
-
- ///
- /// 壳架容错:seq 中存在出现≥2次的数字 X,删掉其中一次后作为子序列能对上 other。
- /// 典型:图纸 HYW1-2500/3P 2500A(2500×2) vs 库 HYW1-3200/3P 2500A(3200×1,2500×1)。
- ///
- private static bool TryDropFrameCurrent(string[] seq, string[] other)
- {
- for (int i = 0; i < seq.Length; i++)
- {
- string s = seq[i];
- if (s == null || s.Length < 2) continue;
- // 该数字必须在 seq 中出现≥2次(型号段+电流段重复)
- int cnt = 0;
- foreach (string n in seq) if (n == s) cnt++;
- if (cnt < 2) continue;
- // 删掉第 i 个,其余保持顺序
- var list = new List(seq.Length - 1);
- for (int k = 0; k < seq.Length; k++)
- if (k != i) list.Add(seq[k]);
- if (NumbersCompatible(list.ToArray(), other)) return true;
- }
- return false;
- }
-
- /// 把 seq 中某个数字串拆成两段,拆分后作为子序列能对上 other 即返回 true。
- private static bool TrySplitAndCompatible(string[] seq, string[] other)
- {
- for (int i = 0; i < seq.Length; i++)
- {
- string s = seq[i];
- if (s == null || s.Length < 2) continue;
- for (int cut = 1; cut < s.Length; cut++)
- {
- var list = new List(seq.Length + 1);
- for (int k = 0; k < seq.Length; k++)
- {
- if (k == i)
- {
- list.Add(s.Substring(0, cut));
- list.Add(s.Substring(cut));
- }
- else list.Add(seq[k]);
- }
- if (NumbersCompatible(list.ToArray(), other)) return true;
- }
- }
- return false;
- }
-
- ///
- /// 提取字母骨架:去数字、去分隔符、去尾部单位词(A/V/kA 等)。
- /// ★ 用于图纸省略壳架等级的场景:DZ47-4P/C80A 与 DZ47-100 4P C80
- /// 骨架同为 DZPC,配合数字子序列保护可安全匹配。
- ///
- private static string ExtractSkeleton(string spec)
- {
- if (string.IsNullOrEmpty(spec)) return "";
- string light = NormalizeKeepSeparators(spec);
- var sb = new System.Text.StringBuilder();
- for (int i = 0; i < light.Length; i++)
- {
- char c = light[i];
- if (c >= 'A' && c <= 'Z')
- {
- // 单位词必须紧跟在数字后面才有效(如 80A、450V);
- // 6L2-V 的 V 前面是分隔符,属于型号的一部分,不能截断
- bool prevIsDigit = i > 0 && light[i - 1] >= '0' && light[i - 1] <= '9';
- if (prevIsDigit && IsTailUnit(light.Substring(i))) break;
- sb.Append(c);
- }
- // 数字、分隔符、中文等其他字符全部跳过
- }
- return sb.ToString();
- }
-
- /// 判断剩余部分是否为纯尾部单位词(如 "A"、"80A" 里的 A、"0~450V" 里的 V)。
- private static bool IsTailUnit(string rest)
- {
- if (string.IsNullOrEmpty(rest)) return false;
- string r = rest.Trim();
- if (r.Length > 2) return false; // 单位最多2字符(HZ/KA/KW/VA)
- return r == "A" || r == "V" || r == "W" || r == "VA" || r == "HZ" || r == "KA" || r == "KW";
- }
-
- /// Levenshtein 编辑距离(滚动数组实现)。
- private static int LevenshteinDistance(string a, string b)
- {
- if (string.IsNullOrEmpty(a)) return string.IsNullOrEmpty(b) ? 0 : b.Length;
- if (string.IsNullOrEmpty(b)) return a.Length;
- int n = a.Length, m = b.Length;
- int[] prev = new int[m + 1];
- int[] cur = new int[m + 1];
- for (int j = 0; j <= m; j++) prev[j] = j;
- for (int i = 1; i <= n; i++)
- {
- cur[0] = i;
- for (int j = 1; j <= m; j++)
- {
- int cost = (a[i - 1] == b[j - 1]) ? 0 : 1;
- int v1 = prev[j] + 1;
- int v2 = cur[j - 1] + 1;
- int v3 = prev[j - 1] + cost;
- cur[j] = Math.Min(v1, Math.Min(v2, v3));
- }
- int[] tmp = prev; prev = cur; cur = tmp;
- }
- return prev[m];
- }
-
- ///
- /// 规格匹配元件名称(模糊):
- /// L1 归一化后完全相等 → 直接命中;
- /// L2 包含关系(短方长度≥长方60%,数字序列一致);
- /// L3 编辑距离相似度≥0.70(数字序列必须完全一致,唯一最高分才命中)。
- /// 都不中返回 null(不硬猜)。
- ///
- ///
- /// 粘连清洗:扒图可能把相邻文本粘连(如 "0mAVigiC65N-...")。
- /// 若文本开头是"数字+单位(mA/A/V/W)"且后面紧跟大写字母开头的型号,
- /// 从型号处截取;否则原样返回。
- ///
- private static string CleanLeadingNoise(string spec)
- {
- if (string.IsNullOrEmpty(spec)) return spec;
- string s = spec.Trim();
-
- // ★ 先剥"数量×"前缀:如 "3xLMZ1-0.5" → "LMZ1-0.5"、"2×AD16" → "AD16"
- // (图纸常在型号前写元件数量,3x=3只)
- if (s.Length > 2)
- {
- char c0 = s[0];
- if (c0 >= '0' && c0 <= '9')
- {
- int i = 0;
- while (i < s.Length && s[i] >= '0' && s[i] <= '9') i++;
- if (i < s.Length && (s[i] == 'x' || s[i] == 'X' || s[i] == '×' || s[i] == '*'))
- {
- int after = i + 1;
- if (after < s.Length && s[after] >= 'A' && s[after] <= 'Z')
- return s.Substring(after);
- }
- }
- }
-
- // 找开头最长的"数字(可含小数点)+单位"模式
- int j = 0;
- while (j < s.Length && ((s[j] >= '0' && s[j] <= '9') || s[j] == '.')) j++;
- if (j == 0 || j >= s.Length) return spec; // 开头不是数字
- // 单位段(1~3个字母)
- int u = j;
- while (u < s.Length && u - j <= 3 && s[u] >= 'A' && s[u] <= 'z') u++;
- if (u == j || u >= s.Length) return spec; // 没有单位或后面没内容
- string unit = s.Substring(j, u - j).ToUpperInvariant();
- if (unit != "MA" && unit != "A" && unit != "V" && unit != "W" && unit != "KW" && unit != "HZ") return spec;
- // 单位后必须紧跟大写字母(型号开头)
- char next = s[u];
- if (next < 'A' || next > 'Z') return spec;
- return s.Substring(u); // 从型号处截取
- }
-
- // ★ 匹配结果缓存:同一规格文本(一批框选里重复文本很常见)只完整跑一次 L0-L5。
- // L3 会按库逐条算编辑距离(库大时是 CPU 热点),缓存能直接砍掉重复计算。
- private static readonly System.Collections.Generic.Dictionary _specMatchCache =
- new System.Collections.Generic.Dictionary(System.StringComparer.Ordinal);
- private static readonly object _specMatchCacheLock = new object();
-
- /// 规格匹配元件名称(带结果缓存):相同规格文本第二次起直接返回缓存结果。
- private static string MatchSpecName(string spec)
- {
- if (string.IsNullOrWhiteSpace(spec)) return null;
- string cached;
- lock (_specMatchCacheLock)
- {
- if (_specMatchCache.TryGetValue(spec, out cached)) return cached;
- }
- string result = MatchSpecNameCore(spec);
- lock (_specMatchCacheLock)
- {
- // 上限保护:超过2万条清空重来(规格文本总量有限,防内存无限增长)
- if (_specMatchCache.Count > 20000) _specMatchCache.Clear();
- _specMatchCache[spec] = result;
- }
- return result;
- }
-
- private static string MatchSpecNameCore(string spec)
- {
- if (string.IsNullOrWhiteSpace(spec)) return null;
-
- // ★ 粘连清洗:扒图可能把相邻文本粘连(如 "0mAVigiC65N-...")。
- // 若文本前部含"数字+单位(mA/A/V)"后跟已知型号,从型号处截取
- spec = CleanLeadingNoise(spec);
-
- EnsureUserLibCsvLoaded();
- if (_specNameLib == null || _specNameLib.Count == 0) return null;
-
- string norm = NormalizeSpec(spec);
- if (norm.Length == 0) return null;
- string[] nums = ExtractNumbers(spec);
-
- string result = null;
- string via = "none";
-
- // L0: 型号前缀规则(本地权威,最优先,覆盖国标型号命名体系)
- string ruleName = MatchByPrefixRule(spec);
- if (ruleName != null)
- {
- WriteDebugLog("[用户库匹配] 「" + spec + "」 → " + ruleName + " via L0规则");
- return ruleName;
- }
-
- // L0.5: JB/T 2930 国标类组代号(官方定义:前2位字母=品类代号)
- string gbName = MatchByGbCode(spec);
- if (gbName != null)
- {
- WriteDebugLog("[用户库匹配] 「" + spec + "」 → " + gbName + " via L0.5国标");
- return gbName;
- }
-
- // L1: 归一化后完全相等
- foreach (var e in _specNameLib)
- {
- if (e.NormSpec == norm) { result = e.Name; via = "L1相等"; break; }
- }
-
- // L2: 包含关系(如图纸只写型号主体,库里有完整版)
- if (result == null)
- {
- foreach (var e in _specNameLib)
- {
- if (e.NormSpec.Length == 0) continue;
- bool contains = e.NormSpec.Contains(norm) || norm.Contains(e.NormSpec);
- if (!contains) continue;
- int shortLen = Math.Min(e.NormSpec.Length, norm.Length);
- int longLen = Math.Max(e.NormSpec.Length, norm.Length);
- if (longLen == 0 || (double)shortLen / longLen < 0.6) continue;
- if (!NumbersCompatible(nums, e.Numbers)) continue; // ★ 数字子序列兼容(允许少,不允许错)
- result = e.Name; via = "L2包含"; break;
- }
- }
-
- // L3: 编辑距离模糊匹配(字母/符号容错,数字绝对不放过)
- if (result == null)
- {
- string bestName = null;
- double bestScore = 0.0;
- int bestCount = 0;
- foreach (var e in _specNameLib)
- {
- if (e.NormSpec.Length == 0) continue;
- if (!NumbersEqualEx(nums, e.Numbers)) continue; // ★ 数字一致(含粘连拆分容错)
- // ★ 长度差剪枝:编辑距离 ≥ 长度差,长度差已超过 0.30×maxLen 时
- // score 必然 < 0.70,直接跳过(编辑距离是 O(m×n),库里条目多时全算是卡顿热点)
- int maxLen = Math.Max(norm.Length, e.NormSpec.Length);
- if (Math.Abs(norm.Length - e.NormSpec.Length) * 10 > maxLen * 3) continue;
- int dist = LevenshteinDistance(norm, e.NormSpec);
- double score = 1.0 - (double)dist / maxLen;
- if (score >= 0.70)
- {
- if (score > bestScore + 0.0001) { bestScore = score; bestName = e.Name; bestCount = 1; }
- else if (Math.Abs(score - bestScore) <= 0.0001 && bestName != e.Name) bestCount++;
- }
- }
- if (bestCount == 1 && bestName != null) { result = bestName; via = "L3模糊"; }
- }
-
- // L4: 字母骨架匹配(图纸省略壳架等级的场景)
- // DZ47-4P/C80A 与 DZ47-100 4P C80:骨架同为 DZPC,
- // 且图纸数字 [47,4,80] 是库数字 [47,100,4,80] 的子序列 → 命中
- if (result == null)
- {
- string skel = ExtractSkeleton(spec);
- if (skel.Length >= 3)
- {
- string bestName = null;
- int bestLen = int.MaxValue;
- foreach (var e in _specNameLib)
- {
- if (e.Skeleton == null || e.Skeleton.Length < 3) continue;
- if (e.Skeleton != skel) continue;
- if (!NumbersCompatible(nums, e.Numbers)) continue; // ★ 数字子序列保护
- // 多条同骨架时取数字数量最接近的
- int diff = Math.Abs(nums.Length - e.Numbers.Length);
- if (diff < bestLen) { bestLen = diff; bestName = e.Name; }
- }
- if (bestName != null) { result = bestName; via = "L4骨架"; }
- }
- }
-
- // L5: 大电流启发式(最后兜底)
- // 框架级特征:数字≥1600 + 3P/4P + 型号含W(万能式标记) → 万能式/智能断路器
- if (result == null)
- {
- string sUp = spec.Trim().ToUpperInvariant();
- bool hasBig = false;
- foreach (string n in nums)
- {
- long v;
- if (long.TryParse(n, out v) && v >= 1600 && v <= 6300) { hasBig = true; break; }
- }
- bool hasPole = sUp.Contains("/3P") || sUp.Contains("/4P") || sUp.Contains(" 3P") || sUp.Contains(" 4P") ||
- sUp.EndsWith("3P") || sUp.EndsWith("4P");
- bool hasW = sUp.IndexOf('W') >= 0;
- if (hasBig && hasPole && hasW)
- {
- // 含 I/E(智能型标记,如 HUWI/CW1I) → 智能断路器
- bool hasSmart = sUp.IndexOf('I') >= 0 || sUp.IndexOf('E') >= 0;
- result = hasSmart ? "智能断路器" : "万能式断路器";
- via = "L5大电流启发";
- }
- }
-
- // ★ 匹配日志:输入/归一化/数字序列/结果,失败可从日志直接定位原因
- WriteDebugLog("[用户库匹配] 「" + spec + "」 norm=" + norm +
- " nums=[" + string.Join(",", nums) + "] → " +
- (result == null ? "(未匹配)" : result + " via " + via));
- return result;
- }
-
- // ============================================================
- // DeepSeek AI 智能匹配(本地匹配失败后的兜底)
- // · 设置窗口填 API Key,存插件目录 deepseek.json
- // · 扒元件后本地未命中的规格批量提交 AI 识别元器件名称
- // · 结果缓存到 deepseek_cache.json(同规格只问一次)
- // · AI 结果回填元件表"元件名称"列
- // ============================================================
-
- private string DeepSeekConfigPath { get { return GetDbFullPath("deepseek.json"); } }
- private string DeepSeekCachePath { get { return GetDbFullPath("deepseek_cache.json"); } }
-
- /// DeepSeek 设置(加载/保存 JSON)
- private class DeepSeekConfig
- {
- public string ApiKey = "";
- public string BaseUrl = "https://api.deepseek.com";
- public string Model = "deepseek-v4-flash"; // ★ 支持联网搜索的模型
- public bool Enabled = false;
- public bool WebSearch = true; // ★ 联网搜索(罕见型号也能查)
- }
-
- private DeepSeekConfig _dsConfig;
- private System.Collections.Hashtable _dsCache;
-
- private DeepSeekConfig LoadDsConfig()
- {
- if (_dsConfig != null) return _dsConfig;
- var cfg = new DeepSeekConfig();
- try
- {
- if (File.Exists(DeepSeekConfigPath))
- {
- string json = File.ReadAllText(DeepSeekConfigPath, System.Text.Encoding.UTF8);
- var map = SimpleJsonParse(json);
- if (map.ContainsKey("ApiKey")) cfg.ApiKey = (string)map["ApiKey"] ?? "";
- if (map.ContainsKey("BaseUrl")) cfg.BaseUrl = (string)map["BaseUrl"] ?? "https://api.deepseek.com";
- if (map.ContainsKey("Model")) cfg.Model = (string)map["Model"] ?? "deepseek-v4-flash";
- // ★ 布尔值无引号,解析出的 val 可能带换行/空格前缀,比较前必须 Trim
- if (map.ContainsKey("Enabled")) cfg.Enabled = ((string)map["Enabled"] ?? "").Trim() == "true";
- if (map.ContainsKey("WebSearch")) cfg.WebSearch = ((string)map["WebSearch"] ?? "").Trim() != "false";
- // ★ 旧模型(deepseek-chat 不支持联网)自动迁移到 v4
- if (cfg.Model == "deepseek-chat" || cfg.Model == "deepseek-reasoner") cfg.Model = "deepseek-v4-flash";
- }
- }
- catch { }
- _dsConfig = cfg;
- return cfg;
- }
-
- private void SaveDsConfig(DeepSeekConfig cfg)
- {
- try
- {
- string json = "{\n" +
- " \"ApiKey\": \"" + (cfg.ApiKey ?? "").Replace("\"", "\\\"") + "\",\n" +
- " \"BaseUrl\": \"" + (cfg.BaseUrl ?? "").Replace("\"", "\\\"") + "\",\n" +
- " \"Model\": \"" + (cfg.Model ?? "").Replace("\"", "\\\"") + "\",\n" +
- " \"Enabled\": " + (cfg.Enabled ? "true" : "false") + ",\n" +
- " \"WebSearch\": " + (cfg.WebSearch ? "true" : "false") + "\n" +
- "}";
- File.WriteAllText(DeepSeekConfigPath, json, System.Text.Encoding.UTF8);
- _dsConfig = cfg;
- }
- catch (Exception ex) { Log("[DeepSeek配置] 保存失败: " + ex.Message); }
- }
-
- /// AI 匹配缓存:规格 → 元件名称(未命中/失败也缓存,避免反复请求)
- private System.Collections.Hashtable LoadDsCache()
- {
- if (_dsCache != null) return _dsCache;
- var ht = new System.Collections.Hashtable();
- try
- {
- if (File.Exists(DeepSeekCachePath))
- {
- string json = File.ReadAllText(DeepSeekCachePath, System.Text.Encoding.UTF8);
- var map = SimpleJsonParse(json);
- foreach (System.Collections.DictionaryEntry kv in map)
- ht[kv.Key.ToString()] = (kv.Value ?? "").ToString();
- }
- }
- catch { }
- _dsCache = ht;
- return ht;
- }
-
- private void SaveDsCache()
- {
- if (_dsCache == null) return;
- try
- {
- var sb = new System.Text.StringBuilder("{\n");
- bool first = true;
- foreach (System.Collections.DictionaryEntry kv in _dsCache)
- {
- if (!first) sb.Append(",\n");
- sb.Append(" \"" + kv.Key.ToString().Replace("\"", "\\\"") + "\": \"" +
- kv.Value.ToString().Replace("\"", "\\\"") + "\"");
- first = false;
- }
- sb.Append("\n}");
- File.WriteAllText(DeepSeekCachePath, sb.ToString(), System.Text.Encoding.UTF8);
- }
- catch (Exception ex) { Log("[DeepSeek缓存] 保存失败: " + ex.Message); }
- }
-
- /// 极简 JSON 解析(扁平 key:value 结构,支持字符串/数字/布尔值)
- private static System.Collections.Hashtable SimpleJsonParse(string json)
- {
- var ht = new System.Collections.Hashtable();
- if (string.IsNullOrEmpty(json)) return ht;
- int depth = 0; bool inStr = false;
- var key = new System.Text.StringBuilder();
- var val = new System.Text.StringBuilder();
- bool inKey = true;
- for (int i = 0; i < json.Length; i++)
- {
- char c = json[i];
- if (inStr)
- {
- if (c == '\\' && i + 1 < json.Length) { val.Append(json[i + 1]); i++; continue; }
- if (c == '"') { inStr = false; continue; }
- (inKey ? key : val).Append(c);
- continue;
- }
- if (c == '"') { inStr = true; continue; }
- if (c == '{' || c == '[') { depth++; continue; }
- if (c == '}' || c == ']')
- {
- // ★ 闭合括号收掉最后一个键值对(布尔值结尾无逗号)
- if (depth == 1 && key.Length > 0)
- {
- ht[key.ToString()] = val.ToString().Trim();
- key.Length = 0; val.Length = 0; inKey = true;
- }
- depth--; continue;
- }
- if (c == ':' && depth == 1) { inKey = false; val.Length = 0; continue; }
- if (c == ',' && depth == 1)
- {
- if (key.Length > 0) ht[key.ToString()] = val.ToString().Trim();
- key.Length = 0; val.Length = 0; inKey = true;
- continue;
- }
- // ★ 无引号值(true/false/数字)必须累积,否则解析成空
- if (!inKey && !char.IsWhiteSpace(c)) val.Append(c);
- }
- if (key.Length > 0) ht[key.ToString()] = val.ToString().Trim();
- return ht;
- }
-
- // ============================================================
- // 电器型号前缀规则(与用户库共用同一个 CSV 数据文件)
- // ★ 用户库 CSV 中"元件类型"列 = "前缀" 的行即为前缀规则:
- // 隔离开关,HGL,只,1,0,1,1,规则,0,前缀
- // (元件名称列=名称,规格列=型号前缀)
- // ★ Excel 里直接编辑用户库即可增删规则,随库自动重载
- // ★ 规则结果与 AI 冲突时,以规则为准(根治 AI 误判)
- // ============================================================
-
- private static List _prefixRules = new List();
-
- /// 内置最小规则集(仅当用户库无任何前缀行时兜底)。
- private static readonly string[,] s_BuiltinPrefixRules =
- {
- { "HGL", "隔离开关" }, { "DZ47", "小型断路器" }, { "NM1", "塑壳断路器" },
- { "CJX2", "交流接触器" }, { "RT16", "熔断器" }, { "LMZ", "电流互感器" },
- };
-
- // ============================================================
- // ★ JB/T 2930 国标类组代号表(低压电器型号编制方法的官方定义)
- // 国标型号前2位字母=品类代号:第1位类别+第2位组别。
- // 在前缀规则(L0)之后、CSV 库(L1)之前执行,覆盖所有国标型号。
- // ============================================================
- private static readonly System.Collections.Hashtable s_GbClassCodes = new System.Collections.Hashtable(StringComparer.OrdinalIgnoreCase)
- {
- // H 刀开关/隔离开关族
- { "HD", "隔离开关" }, // 单投刀开关
- { "HS", "隔离开关" }, // 双投刀开关(转换)
- { "HR", "隔离开关" }, // 熔断器式刀开关
- { "HH", "隔离开关" }, // 封闭式负荷开关
- { "HK", "隔离开关" }, // 开启式负荷开关(胶盖闸)
- { "HZ", "转换开关" }, // 组合开关
- { "HG", "隔离开关" }, // 熔断器式隔离器(另:HG1/HG13)
- // R 熔断器族
- { "RC", "熔断器" }, // 插入式
- { "RL", "熔断器" }, // 螺旋式(RL6/RL8)
- { "RM", "熔断器" }, // 密封管式
- { "RS", "快速熔断器" }, // 快速(RS0/RS3)
- { "RT", "熔断器" }, // 有填料管式(RT0/RT16/RT18)
- { "RX", "熔断器" }, // 限流
- { "RTO", "熔断器" },
- // D 断路器族
- { "DW", "万能式断路器" }, // 框架式(DW15/DW45)
- { "DZ", "塑壳断路器" }, // 装置式/塑料外壳(DZ15/DZ20)
- { "DX", "小型断路器" },
- { "DM", "塑壳断路器" },
- { "DC", "断路器" },
- // C 接触器族
- { "CJ", "交流接触器" }, // 交流(CJ20/CJX)
- { "CZ", "直流接触器" }, // 直流
- { "CG", "接触器" }, // 高压
- { "CP", "接触器" }, // 中频
- { "CS", "接触器" }, // 时间
- // Q 起动器族
- { "QC", "电磁起动器" }, { "QS", "手动起动器" }, { "QX", "星三角起动器" },
- { "QJ", "自耦减压起动器" }, { "QT", "起动器" }, { "QU", "起动器" },
- // J 控制继电器族
- { "JL", "电流继电器" }, { "JR", "热过载继电器" }, { "JS", "时间继电器" },
- { "JT", "通用继电器" }, { "JW", "温度继电器" }, { "JZ", "中间继电器" },
- { "JX", "继电器" },
- // L 主令电器族
- { "LA", "按钮" }, // 按钮(LA38/LA39)
- { "LK", "主令控制器" }, { "LT", "主令开关" }, { "LW", "转换开关" },
- { "LX", "行程开关" }, { "LU", "足踏开关" }, { "LS", "主令开关" },
- // Z 电阻/终端族
- { "ZB", "电阻器" }, { "ZG", "电阻器" }, { "ZC", "电阻器" },
- // B 变阻器族
- { "BL", "励磁变阻器" }, { "BP", "频敏变阻器" }, { "BQ", "起动变阻器" },
- { "BT", "变阻器" }, { "BC", "旋臂变阻器" },
- // M 电磁铁族
- { "MQ", "牵引电磁铁" }, { "MZ", "制动电磁铁" }, { "MW", "起重电磁铁" },
- // A 其他族
- { "AD", "指示灯" }, // 信号灯(AD11/AD16 习惯用)
- { "AN", "按钮" },
- // P 仪用互感器(行业习惯,P 不在 JB/T2930 主表,单列)
- { "LQG", "电流互感器" },
- // 变压器(控制变压器 BK 不在 JB/T2930,行业通用)
- { "BK", "控制变压器" },
- };
-
- ///
- /// ★ 国标类组代号解析:按 JB/T 2930 定义,取型号前2位字母查类组表。
- /// 仅当:①前缀规则未命中 ②开头≥2位字母 ③类组表命中 时返回名称。
- /// 数字开头/单字母/进口品牌型号不适用(返回 null 交给后续层)。
- ///
- private static string MatchByGbCode(string spec)
- {
- if (string.IsNullOrWhiteSpace(spec)) return null;
- string s = spec.Trim();
- // 前2位必须是字母(国标类组代号为2位拼音)
- if (s.Length < 3) return null;
- if (!((s[0] >= 'A' && s[0] <= 'Z') || (s[0] >= 'a' && s[0] <= 'z'))) return null;
- if (!((s[1] >= 'A' && s[1] <= 'Z') || (s[1] >= 'a' && s[1] <= 'z'))) return null;
- // 第3位应是数字或分隔符(确认是类组代号+设计序号结构,排除品牌词)
- if (s.Length > 2)
- {
- char c2 = s[2];
- bool ok = (c2 >= '0' && c2 <= '9') || c2 == '-' || c2 == ' ' || c2 == '/';
- if (!ok) return null;
- }
- string code = s.Substring(0, 2).ToUpperInvariant();
- object v = s_GbClassCodes[code];
- return v as string;
- }
-
- ///
- /// 按型号前缀规则查元器件名称。
- /// ★ 规则来自用户库 CSV"元件类型=前缀"的行(EnsureUserLibCsvLoaded 时提取),
- /// 规则前缀直接与规格开头比对(支持字母+数字混合前缀,如 DZ47/CDM3/CJX2),
- /// 最长前缀优先(7→2字符)。
- /// 返回 null 表示无规则。
- ///
- private static string MatchByPrefixRule(string spec)
- {
- if (string.IsNullOrWhiteSpace(spec)) return null;
- string s = spec.Trim().ToUpperInvariant();
- if (s.Length < 2) return null;
-
- var rules = _prefixRules;
- if (rules.Count == 0)
- {
- // 用户库无前缀行 → 内置兜底
- for (int i = 0; i < s_BuiltinPrefixRules.GetLength(0); i++)
- rules.Add(new[] { s_BuiltinPrefixRules[i, 0], s_BuiltinPrefixRules[i, 1] });
- _prefixRules = rules;
- }
-
- for (int plen = 7; plen >= 2; plen--)
- {
- if (s.Length < plen) continue;
- string head = s.Substring(0, plen);
- foreach (var rule in rules)
- {
- if (rule[0].Length != plen || rule[0] != head) continue;
- return rule[1];
- }
- }
- return null;
- }
-
- /// 打开 DeepSeek 设置窗口(运行时创建,不改 ui.cs)
- private void ShowDeepSeekSettings()
- {
- var cfg = LoadDsConfig();
- var form = new System.Windows.Forms.Form();
- form.Text = "DeepSeek AI 匹配设置";
- form.Size = new System.Drawing.Size(420, 260);
- form.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
- form.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
- form.MaximizeBox = false; form.MinimizeBox = false;
-
- var lblKey = new System.Windows.Forms.Label { Text = "API Key:", Location = new System.Drawing.Point(15, 18), AutoSize = true };
- var txtKey = new System.Windows.Forms.TextBox
- {
- Location = new System.Drawing.Point(80, 15), Size = new System.Drawing.Size(310, 23),
- Text = cfg.ApiKey, UseSystemPasswordChar = true
- };
- var chkShow = new System.Windows.Forms.CheckBox
- {
- Text = "显示密钥", Location = new System.Drawing.Point(80, 44), AutoSize = true
- };
- chkShow.CheckedChanged += (s2, e2) => txtKey.UseSystemPasswordChar = !chkShow.Checked;
-
- var lblModel = new System.Windows.Forms.Label { Text = "模型:", Location = new System.Drawing.Point(15, 78), AutoSize = true };
- var cboModel = new System.Windows.Forms.ComboBox
- {
- Location = new System.Drawing.Point(80, 74), Size = new System.Drawing.Size(180, 23),
- DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
- };
- cboModel.Items.Add("deepseek-v4-flash");
- cboModel.Items.Add("deepseek-v4-pro");
- cboModel.Items.Add("deepseek-chat");
- cboModel.SelectedItem = string.IsNullOrEmpty(cfg.Model) ? "deepseek-v4-flash" : cfg.Model;
-
- var chkEnable = new System.Windows.Forms.CheckBox
- {
- Text = "启用 AI 匹配(本地匹配失败后自动提交 DeepSeek 识别)",
- Location = new System.Drawing.Point(15, 108), AutoSize = true, Checked = cfg.Enabled
- };
-
- var lblTip = new System.Windows.Forms.Label
- {
- Text = "提示:AI 结果会缓存到本地,相同规格只请求一次。\nAPI Key 从 platform.deepseek.com 获取。",
- Location = new System.Drawing.Point(15, 138), AutoSize = true, ForeColor = System.Drawing.Color.Gray
- };
-
- var btnClear = new System.Windows.Forms.Button { Text = "清空AI缓存", Location = new System.Drawing.Point(80, 178), Size = new System.Drawing.Size(100, 28) };
- btnClear.Click += (s2, e2) =>
- {
- try { if (File.Exists(DeepSeekCachePath)) File.Delete(DeepSeekCachePath); _dsCache = null; }
- catch { }
- MessageBox.Show(form, "AI 缓存已清空。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
- };
-
- var btnOk = new System.Windows.Forms.Button { Text = "保存", Location = new System.Drawing.Point(240, 178), Size = new System.Drawing.Size(75, 28) };
- var btnCancel = new System.Windows.Forms.Button { Text = "取消", Location = new System.Drawing.Point(325, 178), Size = new System.Drawing.Size(75, 28) };
-
- btnOk.Click += (s2, e2) =>
- {
- cfg.ApiKey = txtKey.Text.Trim();
- cfg.Model = cboModel.SelectedItem == null ? "deepseek-v4-flash" : cboModel.SelectedItem.ToString();
- cfg.Enabled = chkEnable.Checked && cfg.ApiKey.Length > 0;
- SaveDsConfig(cfg);
- form.Close();
- };
- btnCancel.Click += (s2, e2) => form.Close();
-
- form.Controls.AddRange(new System.Windows.Forms.Control[] { lblKey, txtKey, chkShow, lblModel, cboModel, chkEnable, lblTip, btnClear, btnOk, btnCancel });
- form.ShowDialog(this);
- }
-
- ///
- /// 调 DeepSeek API 批量识别规格对应的元器件名称。
- /// 返回 规格→名称 的哈希表(失败的规格不在结果里)。
- ///
- private System.Collections.Hashtable CallDeepSeekMatch(List specs)
- {
- var result = new System.Collections.Hashtable();
- var cfg = LoadDsConfig();
- if (!cfg.Enabled || string.IsNullOrWhiteSpace(cfg.ApiKey)) return result;
-
- // 构造提问:证据链推理法(查厂商→确认型号→按厂商定义归类)
- var sb = new System.Text.StringBuilder();
- sb.Append("你是低压电器型号识别专家,精通 JB/T 2930《低压电器产品型号编制方法》。为每个规格型号返回【元器件名称】(中文标准品类词)。\n\n");
- sb.Append("【推理方法】(对每个型号按证据链三步走,不要直接猜):\n");
- sb.Append("第1步·识别厂商:从型号前缀判断是哪家厂(如 HUWI→沪工/环宇系、NM→正泰、CDM→德力西、CM→常熟、CW→常熟框架、SZRM→上海人民、XBK→湘湖/新宝凯、QAM→七仪);\n");
- sb.Append("第2步·确认系列:该厂商的此系列号是否存在、属于什么产品线(用你的产品知识回忆厂商型录:如 HUWI=沪工智能型万能式、YLEM=某厂智能框架、BM3=塑壳);\n");
- sb.Append("第3步·按厂商定义归类:厂商型录里该系列挂哪个品类就答什么,不要凭字母表面猜。\n\n");
- sb.Append("【辅助规律】(第2步无记忆时用):\n");
- sb.Append("· 国标类组:前2位字母=品类(DW万能断路器/DZ塑壳/CJ交流接触器/JR热继/LA按钮/HD-HS-HR隔离开关/RT熔断器);\n");
- sb.Append("· 结构特征:电流≥1600A+3P/4P+含W → 框架级(万能式/智能断路器);壳架≤630A+3P → 塑壳;63A以下+1P/2P → 微型;\n");
- sb.Append("· 派生代号:L/E=漏电或电子式,I=智能型,Z=直流/智能,N=可逆;\n");
- sb.Append("· 进口系列:施耐德(NSX/iC65/Vigi/LC1/LR)、ABB(S/SH)、西门子(3RT/5SL)、伊顿(IS)。\n\n");
- sb.Append("【输出格式】(严格遵守):\n");
- sb.Append("只返回纯 JSON 对象 {\"规格原文\":\"元器件名称\",...},不要任何解释、思考过程或其他文字;\n");
- sb.Append("每个规格都必须给出判断:按证据链推理,无法确认厂商和系列时按结构特征推断,实在无据可依才给空字符串;\n");
- sb.Append("名称用标准品类词:万能式断路器/智能断路器/塑壳断路器/小型断路器/漏电断路器/交流接触器/直流接触器/热过载继电器/时间继电器/中间继电器/电流互感器/电压互感器/熔断器/快速熔断器/隔离开关/负荷开关/转换开关/按钮/指示灯/行程开关/双电源/电磁起动器/自耦减压起动器/控制变压器/干式变压器/电涌保护器/电容器/电能表/软启动器/变频器等。\n");
- sb.Append("规格列表:\n");
- for (int i = 0; i < specs.Count; i++)
- sb.Append((i + 1) + ". " + specs[i] + "\n");
-
- try
- {
- // ★ 纯AI知识模式:chat/completions(不走联网搜索,快且稳)
- // deepseek-v4 系列是思考模型:正式回答在 content,思考过程在 reasoning_content;
- // 有时 content 空、答案藏在 reasoning_content 末尾 → 两处都提取
- string body = "{" +
- "\"model\":\"" + cfg.Model + "\"," +
- "\"messages\":[" +
- "{\"role\":\"user\",\"content\":\"" + JsonEscape(sb.ToString()) + "\"}" +
- "]," +
- "\"temperature\":0.1," +
- "\"max_tokens\":3000" +
- "}";
-
- string url = (cfg.BaseUrl ?? "https://api.deepseek.com").TrimEnd('/') + "/chat/completions";
- var req = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url);
- req.Method = "POST";
- req.ContentType = "application/json";
- req.Headers.Add("Authorization", "Bearer " + cfg.ApiKey);
- req.Timeout = 60000; // 60秒
- req.ReadWriteTimeout = 60000;
- req.Proxy = null; // ★ 不走系统代理(防代理环境卡死)
- byte[] data = System.Text.Encoding.UTF8.GetBytes(body);
- req.ContentLength = data.Length;
- Log("[DeepSeek] 发起请求: " + specs.Count + " 条规格(AI知识模式), url=" + url);
- using (var rs = req.GetRequestStream()) rs.Write(data, 0, data.Length);
-
- string respText;
- using (var resp = (System.Net.HttpWebResponse)req.GetResponse())
- using (var sr = new StreamReader(resp.GetResponseStream(), System.Text.Encoding.UTF8))
- respText = sr.ReadToEnd();
- Log("[DeepSeek] 响应长度: " + respText.Length + " 字符");
-
- // 从响应提取 content(手工解析,取 choices[0].message.content)
- string content = ExtractJsonContent(respText);
- if (string.IsNullOrEmpty(content))
- {
- Log("[DeepSeek] 响应解析失败: " + (respText.Length > 400 ? respText.Substring(0, 400) : respText));
- return result;
- }
- // ★ 诊断:AI原始输出(排查"返回0条"问题,只打前400字符)
- Log("[DeepSeek] AI输出内容: " + (content.Length > 400 ? content.Substring(0, 400) + "..." : content));
- // content 里是 {"规格":"名称",...}
- // ★ 思考模型(deepseek-v4)的 content 可能为空,答案在 reasoning_content 末尾:
- // 思维链最后一般会写出最终 JSON,从 reasoning_content 里找 {...} 提取
- var map = SimpleJsonParse(content);
- if (map.Count == 0)
- {
- // 从 reasoning_content 提取最后一个完整 JSON 对象
- int rIdx = respText.IndexOf("\"reasoning_content\":\"", System.StringComparison.Ordinal);
- if (rIdx >= 0)
- {
- string reasoning = ExtractEscapedString(respText, rIdx + 21);
- int braceStart = reasoning.LastIndexOf('{');
- if (braceStart >= 0)
- {
- // 从最后一个 { 找到配对的 }
- int depth2 = 0; int end = -1;
- for (int k = braceStart; k < reasoning.Length; k++)
- {
- if (reasoning[k] == '{') depth2++;
- else if (reasoning[k] == '}')
- {
- depth2--;
- if (depth2 == 0) { end = k; break; }
- }
- }
- if (end > braceStart)
- {
- string jsonPart = reasoning.Substring(braceStart, end - braceStart + 1);
- map = SimpleJsonParse(jsonPart);
- Log("[DeepSeek] 从思维链提取到 " + map.Count + " 条结果");
- }
- }
- }
- }
- foreach (System.Collections.DictionaryEntry kv in map)
- {
- string key = kv.Key.ToString();
- string name = (kv.Value ?? "").ToString().Trim();
- if (name.Length == 0) continue;
-
- // ★ 防线:AI 结果先过本地前缀规则校验,冲突时以规则为准
- // (根治 AI 偶发误判,如把 HGL 隔离开关答成熔断器)
- string rule = MatchByPrefixRule(key);
- if (rule != null && rule != name)
- {
- Log("[DeepSeek校验] 「" + key + "」 AI答[" + name + "] 与规则冲突,已改用[" + rule + "]");
- name = rule;
- }
- result[key] = name;
- }
- Log("[DeepSeek] 识别 " + specs.Count + " 条,返回 " + result.Count + " 条结果");
- }
- catch (Exception ex)
- {
- Log("[DeepSeek] 请求失败: " + ex.Message);
- }
- return result;
- }
-
- ///
- /// 从 API 响应中提取模型输出文本。
- /// 兼容两种格式:
- /// · chat/completions: choices[0].message.content("content":"...")
- /// · responses API: output[].content[].text("text":"...")或顶层"output_text"
- ///
- private static string ExtractJsonContent(string respText)
- {
- try
- {
- // 方式1:responses API 的 "output_text":"..."
- int idx = respText.IndexOf("\"output_text\":\"", System.StringComparison.Ordinal);
- if (idx >= 0)
- {
- string s = ExtractEscapedString(respText, idx + 15);
- if (!string.IsNullOrEmpty(s)) return s;
- }
- // 方式2:responses API 的输出项文本 "text":"..."(跳过 summary/reasoning,
- // 直接找最后一个大 text——输出 message 的正文通常最大)
- int best = -1, bestLen = 0;
- int pos = 0;
- while (true)
- {
- int t = respText.IndexOf("\"text\":\"", pos, System.StringComparison.Ordinal);
- if (t < 0) break;
- // 取这个字符串的长度估算
- int len = EstimateEscapedLen(respText, t + 8);
- if (len > bestLen) { bestLen = len; best = t; }
- pos = t + 8;
- }
- if (best >= 0)
- {
- string s = ExtractEscapedString(respText, best + 8);
- if (!string.IsNullOrEmpty(s)) return s;
- }
- // 方式3:chat 的 "content":"..."
- idx = respText.IndexOf("\"content\":\"", System.StringComparison.Ordinal);
- if (idx >= 0)
- {
- return ExtractEscapedString(respText, idx + 11);
- }
- return null;
- }
- catch { return null; }
- }
-
- /// 从 start 位置读取一个 JSON 转义字符串(处理 \n \" \\ \uXXXX)。
- private static string ExtractEscapedString(string text, int start)
- {
- var sb = new System.Text.StringBuilder();
- int i = start;
- while (i < text.Length)
- {
- char c = text[i];
- if (c == '\\' && i + 1 < text.Length)
- {
- char n = text[i + 1];
- if (n == 'n') sb.Append('\n');
- else if (n == 't') sb.Append('\t');
- else if (n == 'r') sb.Append('\r');
- else if (n == '"') sb.Append('"');
- else if (n == '\\') sb.Append('\\');
- else if (n == '/' ) sb.Append('/');
- else if (n == 'u' && i + 5 < text.Length)
- {
- int code = Convert.ToInt32(text.Substring(i + 2, 4), 16);
- sb.Append((char)code);
- i += 4;
- }
- else sb.Append(n);
- i += 2;
- continue;
- }
- if (c == '"') break;
- sb.Append(c);
- i++;
- }
- return sb.ToString();
- }
-
- /// 估算 start 位置转义字符串的长度(到未转义引号为止)。
- private static int EstimateEscapedLen(string text, int start)
- {
- int i = start, len = 0;
- while (i < text.Length)
- {
- char c = text[i];
- if (c == '\\' && i + 1 < text.Length) { i += 2; len += 2; continue; }
- if (c == '"') break;
- i++; len++;
- }
- return len;
- }
-
- private static string JsonEscape(string s)
- {
- if (string.IsNullOrEmpty(s)) return "";
- var sb = new System.Text.StringBuilder();
- foreach (char c in s)
- {
- if (c == '"') sb.Append("\\\"");
- else if (c == '\\') sb.Append("\\\\");
- else if (c == '\n') sb.Append("\\n");
- else if (c == '\t') sb.Append("\\t");
- else if (c == '\r') sb.Append("");
- else sb.Append(c);
- }
- return sb.ToString();
- }
-
- ///
- /// 扒元件插入后:对本地匹配失败的规格异步调用 DeepSeek 补名称,
- /// 完成后回填数据库 + 刷新表格(UI 线程)。
- /// ★ 单飞+排队:上一个 AI 批次未完成时,后续规格累积到待办队列,
- /// 完成后一并提交(防并发互踩/请求堆积)。
- ///
- private static readonly object _aiLock = new object();
- private static bool _aiRunning = false;
- private static List _aiPendingSpecs = new List();
- private static string _aiPendingTbl = null;
-
- private void AiFillMissingNames(List failedSpecs, string tblName)
- {
- if (failedSpecs == null || failedSpecs.Count == 0) return;
- var cfg = LoadDsConfig();
- if (!cfg.Enabled || string.IsNullOrWhiteSpace(cfg.ApiKey)) return;
-
- lock (_aiLock)
- {
- // 并发防抖:AI 批次进行中 → 累积到待办,由运行中的批次完成后接力
- if (_aiRunning)
- {
- foreach (string sp in failedSpecs)
- if (!_aiPendingSpecs.Contains(sp)) _aiPendingSpecs.Add(sp);
- if (_aiPendingTbl == null) _aiPendingTbl = tblName;
- Log("[AI队列] 批次进行中," + failedSpecs.Count + " 条已加入待办(累计 " + _aiPendingSpecs.Count + ")");
- return;
- }
- _aiRunning = true;
- _aiPendingTbl = tblName;
- }
-
- RunAiBatch(failedSpecs, tblName);
- }
-
- /// 执行一个 AI 批次(完成后处理待办队列)。
- private void RunAiBatch(List specs, string tblName)
- {
- var bgw = new System.ComponentModel.BackgroundWorker();
- bgw.DoWork += (s, e) =>
- {
- try
- {
- // 先查缓存,未缓存的才提交 AI
- var cache = LoadDsCache();
- var toAsk = new List();
- var localHits = new System.Collections.Hashtable();
- lock (_aiLock)
- {
- foreach (string sp in specs)
- {
- if (cache.ContainsKey(sp))
- {
- string cached = (cache[sp] ?? "").ToString();
- // ★ 规则有结果但缓存为空(AI曾未识别) → 用规则(补漏)
- string rule = MatchByPrefixRule(sp);
- if (rule != null && rule.Length > 0 && rule != cached)
- {
- Log("[缓存校验] 「" + sp + "」 缓存[" + cached + "]与规则冲突,已纠正为[" + rule + "]");
- cached = rule;
- cache[sp] = rule;
- }
- if (cached.Length > 0) localHits[sp] = cached;
- }
- else if (!toAsk.Contains(sp)) toAsk.Add(sp);
- }
- }
-
- var ai = new System.Collections.Hashtable();
- if (toAsk.Count > 0)
- {
- ai = CallDeepSeekMatch(toAsk);
- // 写缓存(包括未命中的,避免反复问)
- lock (_aiLock)
- {
- foreach (string sp in toAsk)
- cache[sp] = ai.Contains(sp) ? ai[sp].ToString() : "";
- SaveDsCache();
- }
- }
-
- // 合并结果
- var final = new System.Collections.Hashtable();
- foreach (System.Collections.DictionaryEntry kv in localHits) final[kv.Key] = kv.Value;
- foreach (System.Collections.DictionaryEntry kv in ai) final[kv.Key] = kv.Value;
- e.Result = final;
- }
- catch (Exception ex)
- {
- Log("[AI回填] 后台异常: " + ex);
- e.Result = new System.Collections.Hashtable();
- }
- };
- bgw.RunWorkerCompleted += (s, e) =>
- {
- // ★ 无论成败都处理:先取走待办队列并释放单飞标记
- List pending;
- string pendingTbl;
- lock (_aiLock)
- {
- pending = new List(_aiPendingSpecs);
- pendingTbl = _aiPendingTbl;
- _aiPendingSpecs = new List();
- _aiPendingTbl = null;
- _aiRunning = false;
- }
-
- try
- {
- var final = e.Result as System.Collections.Hashtable;
- if (final == null || final.Count == 0) { if (pending.Count > 0) StartNextAiBatch(pending, pendingTbl); return; }
- int updated = 0;
- string dbPath = GetQuoteDbPath(_currentProjectId);
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- using (var tx = conn.BeginTransaction())
- {
- foreach (System.Collections.DictionaryEntry kv in final)
- {
- using (var cmd = new System.Data.SQLite.SQLiteCommand(
- "UPDATE \"" + tblName + "\" SET 元件名称=@name WHERE 规格=@spec AND (元件名称 IS NULL OR 元件名称='');", conn))
- {
- cmd.Parameters.AddWithValue("@name", kv.Value.ToString());
- cmd.Parameters.AddWithValue("@spec", kv.Key.ToString());
- updated += cmd.ExecuteNonQuery();
- }
- }
- tx.Commit();
- }
- }
- if (updated > 0)
- {
- Log("[AI回填] 已回填 " + updated + " 条元件名称");
- _yuanjianCache.Clear();
- ReloadYuanjianByXianghao(_currentProjectId, _currentTuhao, _currentXianghao);
- }
-
- // ★ AI 识别成功的结果追加进用户库 CSV(库越用越全,
- // 下次同规格本地直接命中,不再消耗 AI)
- AppendAiResultsToUserLibCsv(final);
- }
- catch (Exception ex) { Log("[AI回填] 回填异常: " + ex.Message); }
-
- // ★ 接力:待办队列有货 → 继续下一个批次
- if (pending.Count > 0) StartNextAiBatch(pending, pendingTbl);
- };
- bgw.RunWorkerAsync();
- }
-
- /// 启动下一个 AI 批次(带单飞保护)。
- private void StartNextAiBatch(List specs, string tblName)
- {
- lock (_aiLock)
- {
- if (_aiRunning)
- {
- foreach (string sp in specs)
- if (!_aiPendingSpecs.Contains(sp)) _aiPendingSpecs.Add(sp);
- return;
- }
- _aiRunning = true;
- _aiPendingTbl = tblName;
- }
- Log("[AI队列] 接力下一批 " + specs.Count + " 条");
- RunAiBatch(specs, tblName);
- }
-
- ///
- /// 把 AI 识别结果(规格→名称)追加到最新用户库 CSV(GBK 编码),
- /// 并同步更新内存库 _specNameLib(当前会话立即生效)。
- /// 已存在的规格跳过;每条占一行:名称,规格,只,1,0,1,1,AI识别,0,元件
- ///
- private void AppendAiResultsToUserLibCsv(System.Collections.Hashtable aiResults)
- {
- try
- {
- if (aiResults == null || aiResults.Count == 0) return;
-
- // 找最新 CSV(与 EnsureUserLibCsvLoaded 同规则:上级目录+插件目录取最新)
- string best = null; DateTime bestTime = DateTime.MinValue;
- var dirs = new List();
- try
- {
- var parent = Path.GetDirectoryName(_baseDir);
- if (!string.IsNullOrEmpty(parent) && Directory.Exists(parent)) dirs.Add(parent);
- }
- catch { }
- dirs.Add(_baseDir);
- foreach (string d in dirs)
- {
- try
- {
- foreach (string f in Directory.GetFiles(d, "用户库*.csv"))
- {
- DateTime t = File.GetLastWriteTime(f);
- if (best == null || t > bestTime) { best = f; bestTime = t; }
- }
- }
- catch { }
- }
- if (best == null) { Log("[AI入库] 未找到用户库CSV,跳过"); return; }
-
- // ★ 共享读写:文件可能被 Excel 打开
- var gbk = System.Text.Encoding.GetEncoding("GBK");
- var existing = new HashSet(StringComparer.OrdinalIgnoreCase);
- var fs = System.IO.File.Open(best, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
- using (var sr = new StreamReader(fs, gbk))
- {
- string line;
- while ((line = sr.ReadLine()) != null)
- {
- if (string.IsNullOrWhiteSpace(line)) continue;
- int comma = line.IndexOf(',');
- if (comma > 0) existing.Add(line.Substring(comma + 1).Trim());
- }
- }
-
- // 组装新增行
- var newLines = new List();
- foreach (System.Collections.DictionaryEntry kv in aiResults)
- {
- string spec = kv.Key.ToString().Trim();
- string name = kv.Value.ToString().Trim();
- if (spec.Length == 0 || name.Length == 0) continue;
- if (existing.Contains(spec)) continue;
- newLines.Add(name + "," + spec + ",只,1,0,1,1,AI识别,0,元件");
- existing.Add(spec); // 防同批重复
- }
- if (newLines.Count == 0) { Log("[AI入库] 全部已存在,无新增"); return; }
-
- // 追加写(共享读写防 Excel 锁;失败重试3次——扒图进程可能正读CSV)
- bool written = false;
- for (int attempt = 0; attempt < 3 && !written; attempt++)
- {
- try
- {
- using (var fs2 = new FileStream(best, FileMode.Append, FileAccess.Write, FileShare.ReadWrite))
- using (var sw = new StreamWriter(fs2, gbk))
- {
- foreach (string nl in newLines) sw.WriteLine(nl);
- }
- written = true;
- }
- catch (System.IO.IOException)
- {
- System.Threading.Thread.Sleep(300); // 等 CSV 读取方释放
- }
- }
- if (!written) Log("[AI入库] 写入失败(文件被占用),跳过本次(下次扒图会再尝试)");
-
- // ★ 同步内存库:当前会话的本地匹配立即可用
- try
- {
- EnsureUserLibCsvLoaded();
- if (_specNameLib != null)
- {
- foreach (string nl in newLines)
- {
- string[] cols = nl.Split(',');
- if (cols.Length >= 2)
- _specNameLib.Add(new SpecNameEntry
- {
- Name = cols[0],
- NormSpec = NormalizeSpec(cols[1]),
- Numbers = ExtractNumbers(cols[1]),
- Skeleton = ExtractSkeleton(cols[1])
- });
- }
- }
- }
- catch { }
-
- Log("[AI入库] 新增 " + newLines.Count + " 条到 " + Path.GetFileName(best));
- }
- catch (Exception ex) { Log("[AI入库] 失败: " + ex.Message); }
- }
-
- /// 根据项目ID和图号获取箱号表名(查"表索引"表)。
- private string GetQuoteTableName(string projectId, string tuhao)
- {
- try
- {
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return "";
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- using (var cmd = new System.Data.SQLite.SQLiteCommand(
- "SELECT 表名 FROM " + IndexTableName + " WHERE 图号=@t LIMIT 1;", conn))
- {
- cmd.Parameters.AddWithValue("@t", tuhao);
- object o = cmd.ExecuteScalar();
- return o == null ? "" : o.ToString();
- }
- }
- }
- catch { return ""; }
- }
-
- private void InsertTuhao(string projectId, string tuhao, string frameHandle, string textHandle)
- {
- if (string.IsNullOrWhiteSpace(projectId)) return;
- EnsureQuoteDbExists(projectId);
- string dbPath = GetQuoteDbPath(projectId);
- string sql = "INSERT INTO " + TuhaoTableName +
- " (序号, 图号, 台数, 箱柜数量, 单价, 总价, 成本总价, 毛利, 毛利率, 框Handle, 文本Handle) " +
- "VALUES (@seq, @th, @taishu, 0, 0, 0, 0, 0, 0, @frameHandle, @textHandle);";
- string seq = GetNextSeqNumber(TuhaoTableName, "图号", projectId);
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- cmd.Parameters.AddWithValue("@seq", seq);
- cmd.Parameters.AddWithValue("@th", tuhao);
- cmd.Parameters.AddWithValue("@taishu", "1");
- cmd.Parameters.AddWithValue("@frameHandle", frameHandle ?? "");
- cmd.Parameters.AddWithValue("@textHandle", textHandle ?? "");
- cmd.ExecuteNonQuery();
- }
- }
- }
-
- private void DeleteTuhao(string projectId, string tuhao)
- {
- if (string.IsNullOrWhiteSpace(projectId)) return;
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return;
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- var tablesToDrop = new List();
- string selIdx = "SELECT 实际表名 FROM 表索引 WHERE 图号 = @th;";
- using (var sel = new System.Data.SQLite.SQLiteCommand(selIdx, conn))
- {
- sel.Parameters.AddWithValue("@th", tuhao);
- using (var reader = sel.ExecuteReader())
- {
- while (reader.Read())
- {
- string realTbl = reader.IsDBNull(0) ? "" : reader.GetString(0);
- if (!string.IsNullOrWhiteSpace(realTbl)) tablesToDrop.Add(realTbl);
- }
- }
- }
- foreach (string realTbl in tablesToDrop)
- {
- using (var dropCmd = new System.Data.SQLite.SQLiteCommand(
- "DROP TABLE IF EXISTS \"" + realTbl + "\";", conn))
- dropCmd.ExecuteNonQuery();
- }
- using (var cmd = new System.Data.SQLite.SQLiteCommand(
- "DELETE FROM " + TuhaoTableName + " WHERE 图号 = @th;", conn))
- {
- cmd.Parameters.AddWithValue("@th", tuhao);
- cmd.ExecuteNonQuery();
- }
- using (var cmd = new System.Data.SQLite.SQLiteCommand(
- "DELETE FROM 表索引 WHERE 图号 = @th;", conn))
- {
- cmd.Parameters.AddWithValue("@th", tuhao);
- cmd.ExecuteNonQuery();
- }
- }
- }
-
- private void InsertXianghao(string projectId, string tuhao, string xianghao, string frameHandle, string textHandle)
- {
- if (string.IsNullOrWhiteSpace(projectId) || string.IsNullOrWhiteSpace(tuhao)) return;
- EnsureQuoteDbExists(projectId);
- string dbPath = GetQuoteDbPath(projectId);
- string tblName = GetXianghaoTableByIndex(projectId, tuhao);
- if (string.IsNullOrEmpty(tblName))
- {
- tblName = GetNextTableId(projectId, "xh");
- CreateXianghaoTable(projectId, tblName);
- AddTableIndex(projectId, "箱号", tuhao, "", tblName);
- }
- // ★ 确保旧箱号表也有"箱名"/"框Handle"/"文本Handle"列
- using (var connEns = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- connEns.Open();
- EnsureColumns(connEns, "\"" + tblName + "\"", new[] { "箱名", "框Handle", "文本Handle" });
- }
- string seq = GetXianghaoCount(projectId, tuhao);
- string sql = "INSERT INTO \"" + tblName + "\"" +
- " (序号, 箱号, 箱名, 单位, 数量," +
- " 单台成本, 成本价, 单台报出, 报出价, 利润, 利润率, 毛利率, 框Handle, 文本Handle) " +
- "VALUES (@seq, @xh, @xm, @unit, @shuliang, 0, 0, 0, 0, 0, 0, 0, @frameHandle, @textHandle);";
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- cmd.Parameters.AddWithValue("@seq", seq);
- cmd.Parameters.AddWithValue("@xh", xianghao);
- cmd.Parameters.AddWithValue("@xm", ""); // 箱名默认空,由用户在表格里填写
- cmd.Parameters.AddWithValue("@unit", "台");
- cmd.Parameters.AddWithValue("@shuliang", "1");
- cmd.Parameters.AddWithValue("@frameHandle", frameHandle ?? "");
- cmd.Parameters.AddWithValue("@textHandle", textHandle ?? "");
- cmd.ExecuteNonQuery();
- }
- }
- }
-
- private void DeleteXianghao(string projectId, string tuhao, string xianghao)
- {
- if (string.IsNullOrWhiteSpace(projectId) || string.IsNullOrWhiteSpace(tuhao)) return;
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return;
- string yjTbl = GetYuanjianTableByIndex(projectId, tuhao, xianghao);
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- if (!string.IsNullOrEmpty(yjTbl))
- {
- using (var cmd = new System.Data.SQLite.SQLiteCommand(
- "DROP TABLE IF EXISTS \"" + yjTbl + "\";", conn))
- cmd.ExecuteNonQuery();
- }
- string xhTbl = GetXianghaoTableByIndex(projectId, tuhao);
- if (!string.IsNullOrEmpty(xhTbl))
- {
- using (var cmd = new System.Data.SQLite.SQLiteCommand(
- "DELETE FROM \"" + xhTbl + "\" WHERE 箱号 = @xh;", conn))
- {
- cmd.Parameters.AddWithValue("@xh", xianghao);
- cmd.ExecuteNonQuery();
- }
- }
- }
- RemoveTableIndex(projectId, "元件", tuhao, xianghao);
- }
-
- private void InsertYuanjian(string projectId, string tuhao, string xianghao, string name)
- {
- if (string.IsNullOrWhiteSpace(projectId) || string.IsNullOrWhiteSpace(tuhao) || string.IsNullOrWhiteSpace(xianghao)) return;
- EnsureQuoteDbExists(projectId);
- string dbPath = GetQuoteDbPath(projectId);
- EnsureYuanjianTableExists(projectId, tuhao, xianghao);
- string tblName = GetYuanjianTableByIndex(projectId, tuhao, xianghao);
- if (string.IsNullOrEmpty(tblName))
- {
- System.Windows.Forms.MessageBox.Show("元件表创建失败(表索引未注册),图号=" + tuhao + " 箱号=" + xianghao);
- return;
- }
- string seq;
- using (var conn0 = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn0.Open();
- using (var c = new System.Data.SQLite.SQLiteCommand(
- "SELECT COUNT(*) FROM \"" + tblName + "\";", conn0))
- {
- int n = 0;
- object o = c.ExecuteScalar();
- if (o != null && o != DBNull.Value) n = Convert.ToInt32(o);
- seq = (n + 1).ToString();
- }
- }
- string sql = "INSERT INTO \"" + tblName + "\"" +
- " (序号, 元件名称, 单位, 数量, 采购系数, 报出系数," +
- " 表价, 采购单价, 采购价, 报出单价, 报出价, 类型) " +
- "VALUES (@seq, @name, @unit, @shuliang, @caigou, @baochu, 0, 0, 0, 0, 0, '元件');";
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- cmd.Parameters.AddWithValue("@seq", seq);
- cmd.Parameters.AddWithValue("@name", name);
- cmd.Parameters.AddWithValue("@unit", "只");
- cmd.Parameters.AddWithValue("@shuliang", "1");
- cmd.Parameters.AddWithValue("@caigou", "1");
- cmd.Parameters.AddWithValue("@baochu", "1");
- cmd.ExecuteNonQuery();
- }
- }
- }
-
- /// 扒元件专用:把文本写到【规格】列(元件名称留空),同时写入框Handle。
- private void InsertYuanjianSpec(string projectId, string tuhao, string xianghao, string spec, string frameHandle)
- {
- if (string.IsNullOrWhiteSpace(projectId) || string.IsNullOrWhiteSpace(tuhao) || string.IsNullOrWhiteSpace(xianghao)) return;
- EnsureQuoteDbExists(projectId);
- string dbPath = GetQuoteDbPath(projectId);
- EnsureYuanjianTableExists(projectId, tuhao, xianghao);
- string tblName = GetYuanjianTableByIndex(projectId, tuhao, xianghao);
- if (string.IsNullOrEmpty(tblName))
- {
- System.Windows.Forms.MessageBox.Show("元件表创建失败(表索引未注册),图号=" + tuhao + " 箱号=" + xianghao);
- return;
- }
- string seq;
- using (var conn0 = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn0.Open();
- using (var c = new System.Data.SQLite.SQLiteCommand(
- "SELECT COUNT(*) FROM \"" + tblName + "\";", conn0))
- {
- int n = 0;
- object o = c.ExecuteScalar();
- if (o != null && o != DBNull.Value) n = Convert.ToInt32(o);
- seq = (n + 1).ToString();
- }
- }
- // ★ 写入"规格"列 + 框Handle
- string sql = "INSERT INTO \"" + tblName + "\"" +
- " (序号, 元件名称, 规格, 单位, 数量, 采购系数, 报出系数," +
- " 表价, 采购单价, 采购价, 报出单价, 报出价, 类型, 框Handle) " +
- "VALUES (@seq, '', @spec, @unit, @shuliang, @caigou, @baochu, 0, 0, 0, 0, 0, '元件', @frameHandle);";
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- cmd.Parameters.AddWithValue("@seq", seq);
- cmd.Parameters.AddWithValue("@spec", spec);
- cmd.Parameters.AddWithValue("@unit", "只");
- cmd.Parameters.AddWithValue("@shuliang", "1");
- cmd.Parameters.AddWithValue("@caigou", "1");
- cmd.Parameters.AddWithValue("@baochu", "1");
- cmd.Parameters.AddWithValue("@frameHandle", frameHandle ?? "");
- cmd.ExecuteNonQuery();
- }
- }
- }
-
- private void DeleteYuanjian(string projectId, string tuhao, string xianghao, string seq)
- {
- if (string.IsNullOrWhiteSpace(projectId) || string.IsNullOrWhiteSpace(xianghao)) return;
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return;
- string realTbl = GetYuanjianTableByIndex(projectId, tuhao, xianghao);
- if (string.IsNullOrEmpty(realTbl)) return;
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- using (var cmd = new System.Data.SQLite.SQLiteCommand(
- "DELETE FROM \"" + realTbl + "\" WHERE 序号 = @seq;", conn))
- {
- cmd.Parameters.AddWithValue("@seq", seq);
- cmd.ExecuteNonQuery();
- }
- }
- }
-
- // ============================================================
- // 数据库回写:把内存 DataTable 的改动写回报价库
- // ============================================================
-
- private void SaveTableToDatabase(DataTable table, string projectId, string tableName,
- string whereClause, Dictionary whereParams, bool force = false)
- {
- if (table == null || string.IsNullOrWhiteSpace(projectId)) return;
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return;
-
- DataGridView dgv = null;
- if (table == _tuhaoTable) dgv = this.advancedDataGridView9;
- else if (table == _xianghaoTable) dgv = this.advancedDataGridView4;
- else if (table == _yuanjianTable) dgv = this.advancedDataGridView5;
- if (dgv != null) dgv.EndEdit();
-
- if (table.Rows.Count == 0) return;
- if (!force && table.GetChanges() == null) return;
-
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- using (var tx = conn.BeginTransaction())
- {
- string delSql = "DELETE FROM " + tableName;
- if (!string.IsNullOrWhiteSpace(whereClause)) delSql += " WHERE " + whereClause;
- delSql += ";";
- using (var delCmd = new System.Data.SQLite.SQLiteCommand(delSql, conn))
- {
- if (whereParams != null)
- {
- foreach (var kv in whereParams) delCmd.Parameters.AddWithValue(kv.Key, kv.Value);
- }
- delCmd.ExecuteNonQuery();
- }
- if (table.Rows.Count > 0)
- {
- var colNames = new List(table.Columns.Count);
- foreach (DataColumn c in table.Columns) colNames.Add(c.ColumnName);
- var paramList = new List(colNames.Count);
- foreach (string c in colNames) paramList.Add("@" + c);
- string insertSql = "INSERT INTO " + tableName + " (" +
- string.Join(", ", colNames.ToArray()) + ") VALUES (" +
- string.Join(", ", paramList.ToArray()) + ");";
- using (var insCmd = new System.Data.SQLite.SQLiteCommand(insertSql, conn))
- {
- foreach (string col in colNames)
- insCmd.Parameters.Add("@" + col, System.Data.DbType.String);
- try { insCmd.Prepare(); } catch { }
- foreach (DataRow row in table.Rows)
- {
- if (row.RowState == DataRowState.Deleted) continue;
- foreach (string col in colNames)
- {
- object v = row[col];
- insCmd.Parameters["@" + col].Value =
- (v == null || v == DBNull.Value) ? "" : v.ToString();
- }
- insCmd.ExecuteNonQuery();
- }
- }
- }
- tx.Commit();
- }
- table.AcceptChanges();
- }
- }
-
- private void SaveTuhaoTableIfDirty()
- {
- SaveTableToDatabase(_tuhaoTable, _currentProjectId, TuhaoTableName, null, null);
- }
-
- private void SaveXianghaoTableIfDirty()
- {
- if (_xianghaoTable == null || string.IsNullOrWhiteSpace(_xianghaoTable.TableName)) return;
- SaveTableToDatabase(_xianghaoTable, _currentProjectId,
- "\"" + _xianghaoTable.TableName + "\"", null, null);
- }
-
- private void SaveYuanjianTableIfDirty()
- {
- if (_yuanjianTable == null || string.IsNullOrWhiteSpace(_yuanjianTable.TableName)) return;
- SaveTableToDatabase(_yuanjianTable, _currentProjectId,
- "\"" + _yuanjianTable.TableName + "\"", null, null);
- }
-
- private void SaveAllQuoteTablesIfDirty(bool force = true)
- {
- if (string.IsNullOrWhiteSpace(_currentProjectId)) return;
- try
- {
- if (this.advancedDataGridView5 != null) this.advancedDataGridView5.EndEdit();
- if (this.advancedDataGridView4 != null) this.advancedDataGridView4.EndEdit();
- if (this.advancedDataGridView9 != null) this.advancedDataGridView9.EndEdit();
- if (_yuanjianTable != null && !string.IsNullOrWhiteSpace(_yuanjianTable.TableName))
- SaveTableToDatabase(_yuanjianTable, _currentProjectId,
- "\"" + _yuanjianTable.TableName + "\"", null, null, force);
- if (_xianghaoTable != null && !string.IsNullOrWhiteSpace(_xianghaoTable.TableName))
- SaveTableToDatabase(_xianghaoTable, _currentProjectId,
- "\"" + _xianghaoTable.TableName + "\"", null, null, force);
- if (_tuhaoTable != null)
- SaveTableToDatabase(_tuhaoTable, _currentProjectId, TuhaoTableName, null, null, force);
- }
- catch { }
- }
-
- private void SaveAllToDatabaseSilent()
- {
- if (string.IsNullOrWhiteSpace(_currentProjectId)) return;
- if (this.advancedDataGridView5 != null) this.advancedDataGridView5.EndEdit();
- if (this.advancedDataGridView4 != null) this.advancedDataGridView4.EndEdit();
- if (this.advancedDataGridView9 != null) this.advancedDataGridView9.EndEdit();
- try
- {
- if (_tuhaoTable != null)
- SaveTableToDatabase(_tuhaoTable, _currentProjectId, TuhaoTableName, null, null, true);
- foreach (var kv in _xianghaoCache)
- if (kv.Value != null && !string.IsNullOrWhiteSpace(kv.Value.TableName))
- SaveTableToDatabase(kv.Value, _currentProjectId,
- "\"" + kv.Value.TableName + "\"", null, null, true);
- foreach (var kv in _yuanjianCache)
- if (kv.Value != null && !string.IsNullOrWhiteSpace(kv.Value.TableName))
- SaveTableToDatabase(kv.Value, _currentProjectId,
- "\"" + kv.Value.TableName + "\"", null, null, true);
- RecalcAllFromDatabase(_currentProjectId);
- ReloadProjectsFromDatabase();
- }
- catch { }
- }
-
- // ============================================================
- // 联动刷新:项目 → 图号 → 箱号 → 元件
- // ============================================================
-
- private void ReloadProjectsFromDatabase()
- {
- string dbPath = GetDbFullPath(ProjectsDbPath);
- if (!File.Exists(dbPath)) return;
-
- var indexTable = new DataTable();
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- string sql = "SELECT 项目编号, 箱柜台数, 成本总价, 报出总价, 利润, 利润率 FROM " +
- ProjectsTableName + " ORDER BY rowid;";
- using (var adapter = new System.Data.SQLite.SQLiteDataAdapter(sql, conn))
- adapter.Fill(indexTable);
- }
-
- var table = new DataTable();
- table.Columns.Add("项目编号", typeof(string));
- table.Columns.Add("项目名称", typeof(string));
- table.Columns.Add("客户名称", typeof(string));
- table.Columns.Add("客户地址", typeof(string));
- table.Columns.Add("联系人", typeof(string));
- table.Columns.Add("联系电话", typeof(string));
- table.Columns.Add("项目日期", typeof(string));
- table.Columns.Add("箱柜台数", typeof(string));
- table.Columns.Add("成本总价", typeof(string));
- table.Columns.Add("报出总价", typeof(string));
- table.Columns.Add("利润", typeof(string));
- table.Columns.Add("利润率", typeof(string));
- table.Columns.Add("备注", typeof(string));
-
- foreach (DataRow idxRow in indexTable.Rows)
- {
- string projectId = idxRow["项目编号"] == null ? "" : idxRow["项目编号"].ToString().Trim();
- if (string.IsNullOrEmpty(projectId)) continue;
- var info = GetProjectInfoFromQuoteDb(projectId);
- var row = table.NewRow();
- row["项目编号"] = projectId;
- row["项目名称"] = GetInfoOrDefault(info, "项目名称");
- row["客户名称"] = GetInfoOrDefault(info, "客户名称");
- row["客户地址"] = GetInfoOrDefault(info, "客户地址");
- row["联系人"] = GetInfoOrDefault(info, "联系人");
- row["联系电话"] = GetInfoOrDefault(info, "联系电话");
- row["项目日期"] = GetInfoOrDefault(info, "项目日期");
- row["备注"] = GetInfoOrDefault(info, "备注");
- row["箱柜台数"] = idxRow["箱柜台数"] == null ? "" : idxRow["箱柜台数"].ToString();
- row["成本总价"] = idxRow["成本总价"] == null ? "" : idxRow["成本总价"].ToString();
- row["报出总价"] = idxRow["报出总价"] == null ? "" : idxRow["报出总价"].ToString();
- row["利润"] = idxRow["利润"] == null ? "" : idxRow["利润"].ToString();
- row["利润率"] = idxRow["利润率"] == null ? "" : idxRow["利润率"].ToString();
- table.Rows.Add(row);
- }
-
- this.advancedDataGridView6.AutoGenerateColumns = false;
- table = ConvertFormulaColumnsToDouble(table);
- this.advancedDataGridView6.DataSource = table;
- }
-
- private static string GetInfoOrDefault(Dictionary info, string key)
- {
- if (info == null) return "";
- string v;
- return info.TryGetValue(key, out v) ? (v ?? "") : "";
- }
-
- private void ReloadTuhaoByProject(string projectId)
- {
- bool outerGuard = _isReloading;
- _isReloading = true;
- try
- {
- if (string.IsNullOrWhiteSpace(projectId) || !File.Exists(GetQuoteDbPath(projectId)))
- {
- this.advancedDataGridView9.DataSource = null;
- _tuhaoTable = null;
- _currentTuhao = "";
- ReloadXianghaoByTuhao("", "");
- return;
- }
- string dbPath = GetQuoteDbPath(projectId);
- string sql = "SELECT * FROM " + TuhaoTableName + " ORDER BY CAST(序号 AS INTEGER);";
- var table = new DataTable();
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- using (var adapter = new System.Data.SQLite.SQLiteDataAdapter(cmd))
- adapter.Fill(table);
- }
- table = ConvertFormulaColumnsToDouble(table);
- this.advancedDataGridView9.AutoGenerateColumns = false;
- this.advancedDataGridView9.DataSource = table;
- _tuhaoTable = table;
- ApplyPriceFormat(this.advancedDataGridView9, _单台小数位文本);
-
- _currentTuhao = "";
- if (this.advancedDataGridView9.Rows.Count > 0)
- {
- SetCurrentCell(this.advancedDataGridView9, 0);
- _currentTuhao = GetCellValueAsString(this.advancedDataGridView9.Rows[0], "图号");
- }
- ReloadXianghaoByTuhao(_currentProjectId, _currentTuhao);
- }
- finally { _isReloading = outerGuard; }
- }
-
- private void ReloadXianghaoByTuhao(string projectId, string tuhao)
- {
- bool outerGuard = _isReloading;
- _isReloading = true;
- try
- {
- if (this.advancedDataGridView4 != null) this.advancedDataGridView4.EndEdit();
-
- if (string.IsNullOrWhiteSpace(projectId) || string.IsNullOrWhiteSpace(tuhao) ||
- !File.Exists(GetQuoteDbPath(projectId)))
- {
- this.advancedDataGridView4.DataSource = null;
- _xianghaoTable = null;
- _currentXianghao = "";
- ReloadYuanjianByXianghao("", "", "");
- return;
- }
- string dbPath = GetQuoteDbPath(projectId);
- string realTbl = GetXianghaoTableByIndex(projectId, tuhao);
- if (string.IsNullOrEmpty(realTbl))
- {
- realTbl = GetNextTableId(projectId, "xh");
- CreateXianghaoTable(projectId, realTbl);
- AddTableIndex(projectId, "箱号", tuhao, "", realTbl);
- }
-
- DataTable table;
- // ★ 禁用缓存命中:每次都从数据库重新读取,确保删除/变更能及时反映到UI
- if (_xianghaoCache.ContainsKey(tuhao)) _xianghaoCache.Remove(tuhao);
- {
- string sql = "SELECT * FROM \"" + realTbl + "\" ORDER BY CAST(序号 AS INTEGER);";
- table = new DataTable();
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- // ★ 老库结构兼容:箱号表可能还没有"箱名"列,读取前幂等补列(表格绑定依赖该列)
- EnsureColumns(conn, "\"" + realTbl + "\"", new[] { "箱名" });
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- using (var adapter = new System.Data.SQLite.SQLiteDataAdapter(cmd))
- adapter.Fill(table);
- }
- table = ConvertFormulaColumnsToDouble(table);
- table.TableName = realTbl;
- _xianghaoCache[tuhao] = table;
- }
-
- this.advancedDataGridView4.AutoGenerateColumns = false;
- this.advancedDataGridView4.DataSource = table;
- _xianghaoTable = table;
- ApplyPriceFormat(this.advancedDataGridView4, _单台小数位文本);
-
- _currentXianghao = "";
- if (this.advancedDataGridView4.Rows.Count > 0)
- {
- SetCurrentCell(this.advancedDataGridView4, 0);
- _currentXianghao = GetCellValueAsString(this.advancedDataGridView4.Rows[0], "箱号");
- }
- ReloadYuanjianByXianghao(_currentProjectId, _currentTuhao, _currentXianghao);
- }
- finally { _isReloading = outerGuard; }
- }
-
- private void ReloadYuanjianByXianghao(string projectId, string tuhao, string xianghao)
- {
- if (this.advancedDataGridView5 != null) this.advancedDataGridView5.EndEdit();
-
- if (string.IsNullOrWhiteSpace(projectId) || string.IsNullOrWhiteSpace(tuhao) ||
- string.IsNullOrWhiteSpace(xianghao) || !File.Exists(GetQuoteDbPath(projectId)))
- {
- this.advancedDataGridView5.DataSource = null;
- _yuanjianTable = null;
- return;
- }
- string realTbl = GetYuanjianTableByIndex(projectId, tuhao, xianghao);
- string dbPath = GetQuoteDbPath(projectId);
- string cacheKey = tuhao + "\n" + xianghao;
- DataTable table;
- // ★ 禁用缓存命中:每次都从数据库重新读取,确保删除/变更能及时反映到UI
- if (_yuanjianCache.ContainsKey(cacheKey)) _yuanjianCache.Remove(cacheKey);
- {
- table = new DataTable();
- if (!string.IsNullOrEmpty(realTbl))
- {
- string sql = "SELECT * FROM \"" + realTbl + "\" ORDER BY CAST(序号 AS INTEGER);";
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- using (var adapter = new System.Data.SQLite.SQLiteDataAdapter(cmd))
- adapter.Fill(table);
- }
- table = ConvertFormulaColumnsToDouble(table);
- }
- table.TableName = realTbl;
- _yuanjianCache[cacheKey] = table;
- }
- this.advancedDataGridView5.AutoGenerateColumns = false;
- this.advancedDataGridView5.DataSource = table;
- _yuanjianTable = table;
- ApplyPriceFormat(this.advancedDataGridView5, _单台小数位文本);
- }
-
- // ============================================================
- // 公式重算
- // ============================================================
-
- private void RecalcYuanjianRow(DataGridViewRow row)
- {
- if (row == null) return;
- decimal biaoJia = GetCellDecimal(row, "表价");
- decimal caiGouXiShu = GetCellDecimal(row, "采购系数");
- decimal baoChuXiShu = GetCellDecimal(row, "报出系数");
- decimal shuLiang = GetCellDecimal(row, "数量");
- decimal caiGouDanJia = biaoJia * caiGouXiShu;
- decimal caiGouJia = caiGouDanJia * shuLiang;
- decimal baoChuDanJia = caiGouDanJia * baoChuXiShu;
- decimal baoChuJia = baoChuDanJia * shuLiang;
- SetCell(row, "采购单价", caiGouDanJia);
- SetCell(row, "采购价", caiGouJia);
- SetCell(row, "报出单价", baoChuDanJia);
- SetCell(row, "报出价", baoChuJia);
- }
-
- private void RecalcXianghaoRowFromYuanjian(DataGridViewRow xianghaoRow)
- {
- if (xianghaoRow == null) return;
- decimal sumCaiGouJia = 0m;
- decimal sumBaoChuJia = 0m;
- DataGridView dgv5 = this.advancedDataGridView5;
- if (dgv5 != null && dgv5.Rows != null)
- {
- foreach (DataGridViewRow yj in dgv5.Rows)
- {
- if (yj == null || yj.IsNewRow) continue;
- sumCaiGouJia += GetCellDecimal(yj, "采购价");
- sumBaoChuJia += GetCellDecimal(yj, "报出价");
- }
- }
- decimal shuLiang = GetCellDecimal(xianghaoRow, "数量");
- decimal danTaiChengBen = sumCaiGouJia;
- decimal chengBenJia = danTaiChengBen * shuLiang;
- decimal danTaiBaoChu = sumBaoChuJia;
- decimal baoChuJia = danTaiBaoChu * shuLiang;
- decimal liRun = baoChuJia - chengBenJia;
- decimal liRunLv = chengBenJia == 0m ? 0m : liRun / chengBenJia;
- decimal maoLiLv = baoChuJia == 0m ? 0m : liRun / baoChuJia;
- SetCell(xianghaoRow, "单台成本", danTaiChengBen);
- SetCell(xianghaoRow, "成本价", chengBenJia);
- SetCell(xianghaoRow, "单台报出", danTaiBaoChu);
- SetCell(xianghaoRow, "报出价", baoChuJia);
- SetCell(xianghaoRow, "利润", liRun);
- SetCell(xianghaoRow, "利润率", liRunLv);
- SetCell(xianghaoRow, "毛利率", maoLiLv);
- }
-
- private void RecalcTuhaoRowFromXianghao(DataGridViewRow tuhaoRow)
- {
- if (tuhaoRow == null) return;
- decimal sumShuLiang = 0m;
- decimal sumBaoChuJia = 0m;
- decimal sumChengBenJia = 0m;
- DataGridView dgv4 = this.advancedDataGridView4;
- if (dgv4 != null && dgv4.Rows != null)
- {
- foreach (DataGridViewRow xh in dgv4.Rows)
- {
- if (xh == null || xh.IsNewRow) continue;
- sumShuLiang += GetCellDecimal(xh, "数量");
- sumBaoChuJia += GetCellDecimal(xh, "报出价");
- sumChengBenJia += GetCellDecimal(xh, "成本价");
- }
- }
- decimal taiShu = GetCellDecimal(tuhaoRow, "台数");
- decimal xiangGuiShuLiang = sumShuLiang;
- decimal danJia = sumBaoChuJia;
- decimal zongJia = danJia * taiShu;
- decimal chengBenZongJia = sumChengBenJia * taiShu;
- decimal maoLi = zongJia - chengBenZongJia;
- decimal maoLiLv = zongJia == 0m ? 0m : maoLi / zongJia;
- SetCell(tuhaoRow, "箱柜数量", xiangGuiShuLiang);
- SetCell(tuhaoRow, "单价", danJia);
- SetCell(tuhaoRow, "总价", zongJia);
- SetCell(tuhaoRow, "成本总价", chengBenZongJia);
- SetCell(tuhaoRow, "毛利", maoLi);
- SetCell(tuhaoRow, "毛利率", maoLiLv);
- RecalcProjectRowFromTuhao();
- }
-
- private void RecalcProjectRowFromTuhao()
- {
- if (string.IsNullOrWhiteSpace(_currentProjectId)) return;
- decimal sumXiangGuiShuLiang = 0m;
- decimal sumChengBenZongJia = 0m;
- decimal sumZongJia = 0m;
- DataGridView dgv9 = this.advancedDataGridView9;
- if (dgv9 != null && dgv9.Rows != null)
- {
- foreach (DataGridViewRow th in dgv9.Rows)
- {
- if (th == null || th.IsNewRow) continue;
- sumXiangGuiShuLiang += GetCellDecimal(th, "箱柜数量");
- sumChengBenZongJia += GetCellDecimal(th, "成本总价");
- sumZongJia += GetCellDecimal(th, "总价");
- }
- }
- decimal xiangGuiTaiShu = sumXiangGuiShuLiang;
- decimal baoChuZongJia = sumZongJia;
- decimal liRun = baoChuZongJia - sumChengBenZongJia;
- decimal liRunLv = sumChengBenZongJia == 0m ? 0m : liRun / sumChengBenZongJia;
- DataGridViewRow projRow = FindProjectRowById(_currentProjectId);
- if (projRow != null)
- {
- SetCell(projRow, "箱柜台数", xiangGuiTaiShu);
- SetCell(projRow, "成本总价", sumChengBenZongJia);
- SetCell(projRow, "报出总价", baoChuZongJia);
- SetCell(projRow, "利润", liRun);
- SetCell(projRow, "利润率", liRunLv);
- }
- }
-
- private void RecalcAllAfterReload()
- {
- if (string.IsNullOrWhiteSpace(_currentProjectId)) return;
- _isRecalculating = true;
- _isReloading = true;
- try
- {
- DataGridView dgv5 = this.advancedDataGridView5;
- if (dgv5 != null && dgv5.Rows != null)
- {
- foreach (DataGridViewRow yj in dgv5.Rows)
- {
- if (yj == null || yj.IsNewRow) continue;
- RecalcYuanjianRow(yj);
- }
- }
- var xhRow = GetFirstSelectedRow(this.advancedDataGridView4);
- if (xhRow != null) RecalcXianghaoRowFromYuanjian(xhRow);
- var thRow = GetFirstSelectedRow(this.advancedDataGridView9);
- if (thRow != null) RecalcTuhaoRowFromXianghao(thRow);
-
- SaveYuanjianTableIfDirty();
- SaveXianghaoTableIfDirty();
- SaveTuhaoTableIfDirty();
- if (_yuanjianTable != null) _yuanjianTable.AcceptChanges();
- if (_xianghaoTable != null) _xianghaoTable.AcceptChanges();
- if (_tuhaoTable != null) _tuhaoTable.AcceptChanges();
- }
- finally
- {
- _isRecalculating = false;
- _lastRecalcTime = DateTime.Now;
- _isReloading = false;
- }
- }
-
- // ---------- 全量数据库重算 ----------
-
- private class TuhaoCalcRow { public long RowId; public decimal TaiShu; public string Tuhao; }
- private class XianghaoCalcRow { public long RowId; public decimal ShuLiang; public string Xianghao; }
-
- private void RecalcAllFromDatabase(string projectId)
- {
- if (string.IsNullOrWhiteSpace(projectId)) projectId = _currentProjectId;
- if (string.IsNullOrWhiteSpace(projectId)) return;
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return;
- try
- {
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- var tuhaoRows = new List();
- string selTuhao = "SELECT rowid, 台数, 图号 FROM " + TuhaoTableName + " ORDER BY rowid;";
- using (var sel = new System.Data.SQLite.SQLiteCommand(selTuhao, conn))
- using (var rdr = sel.ExecuteReader())
- {
- while (rdr.Read())
- {
- var t = new TuhaoCalcRow();
- t.RowId = rdr.GetInt64(0);
- t.TaiShu = ParseDecimal(rdr.IsDBNull(1) ? "" : rdr.GetValue(1));
- t.Tuhao = rdr.IsDBNull(2) ? "" : rdr.GetValue(2).ToString().Trim();
- tuhaoRows.Add(t);
- }
- }
- decimal sumProjXiangGui = 0m;
- decimal sumProjChengBen = 0m;
- decimal sumProjZongJia = 0m;
- foreach (var t in tuhaoRows)
- {
- if (string.IsNullOrWhiteSpace(t.Tuhao)) continue;
- try
- {
- string xhTable = GetXianghaoTableByIndex(t.Tuhao, conn);
- if (string.IsNullOrEmpty(xhTable))
- {
- UpdateTuhaoCalc(conn, t.RowId, 0m, 0m, 0m, 0m, 0m, 0m);
- continue;
- }
- string xhQuoted = "\"" + xhTable + "\"";
- decimal sumThXiangGuiShuLiang = 0m;
- decimal sumThBaoChuJia = 0m;
- decimal sumThChengBenJia = 0m;
- var xhRows = new List();
- string selXh = "SELECT rowid, 数量, 箱号 FROM " + xhQuoted + " ORDER BY rowid;";
- using (var sel = new System.Data.SQLite.SQLiteCommand(selXh, conn))
- using (var rdr = sel.ExecuteReader())
- {
- while (rdr.Read())
- {
- var x = new XianghaoCalcRow();
- x.RowId = rdr.GetInt64(0);
- x.ShuLiang = ParseDecimal(rdr.IsDBNull(1) ? "" : rdr.GetValue(1));
- x.Xianghao = rdr.IsDBNull(2) ? "" : rdr.GetValue(2).ToString();
- xhRows.Add(x);
- }
- }
- foreach (var x in xhRows)
- {
- try
- {
- sumThXiangGuiShuLiang += x.ShuLiang;
- string yjTable = GetYuanjianTableByIndex(t.Tuhao, x.Xianghao, conn);
- decimal sumCaiGou = 0m;
- decimal sumBaoChu = 0m;
- if (!string.IsNullOrEmpty(yjTable))
- {
- string yjQuoted = "\"" + yjTable + "\"";
- string selYj = "SELECT rowid, 表价, 采购系数, 报出系数, 数量 FROM " +
- yjQuoted + " ORDER BY rowid;";
- using (var sel = new System.Data.SQLite.SQLiteCommand(selYj, conn))
- using (var sr = sel.ExecuteReader())
- {
- while (sr.Read())
- {
- long yjRid = sr.GetInt64(0);
- decimal yjBiaoJia = ParseDecimal(sr.IsDBNull(1) ? "" : sr.GetValue(1));
- decimal yjCgXs = ParseDecimal(sr.IsDBNull(2) ? "" : sr.GetValue(2));
- decimal yjBcXs = ParseDecimal(sr.IsDBNull(3) ? "" : sr.GetValue(3));
- decimal yjSl = ParseDecimal(sr.IsDBNull(4) ? "" : sr.GetValue(4));
- decimal yjCaiGouDanJia = yjBiaoJia * yjCgXs;
- decimal yjCaiGouJia = yjCaiGouDanJia * yjSl;
- decimal yjBaoChuDanJia = yjCaiGouDanJia * yjBcXs;
- decimal yjBaoChuJia = yjBaoChuDanJia * yjSl;
- sumCaiGou += yjCaiGouJia;
- sumBaoChu += yjBaoChuJia;
- UpdateYuanjianCalc(conn, yjQuoted, yjRid,
- yjCaiGouDanJia, yjCaiGouJia, yjBaoChuDanJia, yjBaoChuJia);
- }
- }
- }
- decimal danTaiChengBen = sumCaiGou;
- decimal chengBenJia = danTaiChengBen * x.ShuLiang;
- decimal danTaiBaoChu = sumBaoChu;
- decimal baoChuJia = danTaiBaoChu * x.ShuLiang;
- decimal xhLiRun = baoChuJia - chengBenJia;
- decimal xhLiRunLv = chengBenJia == 0m ? 0m : xhLiRun / chengBenJia;
- decimal xhMaoLiLv = baoChuJia == 0m ? 0m : xhLiRun / baoChuJia;
- sumThBaoChuJia += baoChuJia;
- sumThChengBenJia += chengBenJia;
- UpdateXianghaoCalc(conn, xhQuoted, x.RowId,
- danTaiChengBen, chengBenJia, danTaiBaoChu, baoChuJia,
- xhLiRun, xhLiRunLv, xhMaoLiLv);
- }
- catch { }
- }
- decimal xiangGuiShuLiang = sumThXiangGuiShuLiang;
- decimal danJia = sumThBaoChuJia;
- decimal zongJia = danJia * t.TaiShu;
- decimal chengBenZongJia = sumThChengBenJia * t.TaiShu;
- decimal maoLi = zongJia - chengBenZongJia;
- decimal maoLiLv = zongJia == 0m ? 0m : maoLi / zongJia;
- sumProjXiangGui += xiangGuiShuLiang;
- sumProjChengBen += chengBenZongJia;
- sumProjZongJia += zongJia;
- UpdateTuhaoCalc(conn, t.RowId, xiangGuiShuLiang, danJia,
- zongJia, chengBenZongJia, maoLi, maoLiLv);
- }
- catch { }
- }
- decimal projLiRun = sumProjZongJia - sumProjChengBen;
- decimal projLiRunLv = sumProjChengBen == 0m ? 0m : projLiRun / sumProjChengBen;
- UpdateProjectQuoteTotalsById(projectId, sumProjXiangGui,
- sumProjChengBen, sumProjZongJia, projLiRun, projLiRunLv);
- }
- }
- catch { }
- }
-
- private static void UpdateYuanjianCalc(System.Data.SQLite.SQLiteConnection conn,
- string yjQuoted, long rowId,
- decimal caiGouDanJia, decimal caiGouJia, decimal baoChuDanJia, decimal baoChuJia)
- {
- string sql = "UPDATE " + yjQuoted + " SET " +
- "采购单价=@a, 采购价=@b, 报出单价=@c, 报出价=@d WHERE rowid=@rid;";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- cmd.Parameters.AddWithValue("@a", caiGouDanJia == 0m ? (object)DBNull.Value : (object)caiGouDanJia);
- cmd.Parameters.AddWithValue("@b", caiGouJia == 0m ? (object)DBNull.Value : (object)caiGouJia);
- cmd.Parameters.AddWithValue("@c", baoChuDanJia == 0m ? (object)DBNull.Value : (object)baoChuDanJia);
- cmd.Parameters.AddWithValue("@d", baoChuJia == 0m ? (object)DBNull.Value : (object)baoChuJia);
- cmd.Parameters.AddWithValue("@rid", rowId);
- cmd.ExecuteNonQuery();
- }
- }
-
- private static void UpdateXianghaoCalc(System.Data.SQLite.SQLiteConnection conn,
- string xhQuoted, long rowId,
- decimal danTaiChengBen, decimal chengBenJia, decimal danTaiBaoChu, decimal baoChuJia,
- decimal liRun, decimal liRunLv, decimal maoLiLv)
- {
- string sql = "UPDATE " + xhQuoted + " SET " +
- "单台成本=@a, 成本价=@b, 单台报出=@c, 报出价=@d, " +
- "利润=@e, 利润率=@f, 毛利率=@g WHERE rowid=@rid;";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- cmd.Parameters.AddWithValue("@a", danTaiChengBen == 0m ? (object)DBNull.Value : (object)danTaiChengBen);
- cmd.Parameters.AddWithValue("@b", chengBenJia == 0m ? (object)DBNull.Value : (object)chengBenJia);
- cmd.Parameters.AddWithValue("@c", danTaiBaoChu == 0m ? (object)DBNull.Value : (object)danTaiBaoChu);
- cmd.Parameters.AddWithValue("@d", baoChuJia == 0m ? (object)DBNull.Value : (object)baoChuJia);
- cmd.Parameters.AddWithValue("@e", liRun == 0m ? (object)DBNull.Value : (object)liRun);
- cmd.Parameters.AddWithValue("@f", liRunLv.ToString());
- cmd.Parameters.AddWithValue("@g", maoLiLv.ToString());
- cmd.Parameters.AddWithValue("@rid", rowId);
- cmd.ExecuteNonQuery();
- }
- }
-
- private static void UpdateTuhaoCalc(System.Data.SQLite.SQLiteConnection conn,
- long rowId, decimal xiangGuiShuLiang, decimal danJia,
- decimal zongJia, decimal chengBenZongJia, decimal maoLi, decimal maoLiLv)
- {
- string sql = "UPDATE " + TuhaoTableName + " SET " +
- "箱柜数量=@a, 单价=@b, 总价=@c, 成本总价=@d, 毛利=@e, 毛利率=@f " +
- "WHERE rowid=@rid;";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- cmd.Parameters.AddWithValue("@a", xiangGuiShuLiang == 0m ? (object)DBNull.Value : (object)xiangGuiShuLiang);
- cmd.Parameters.AddWithValue("@b", danJia == 0m ? (object)DBNull.Value : (object)danJia);
- cmd.Parameters.AddWithValue("@c", zongJia == 0m ? (object)DBNull.Value : (object)zongJia);
- cmd.Parameters.AddWithValue("@d", chengBenZongJia == 0m ? (object)DBNull.Value : (object)chengBenZongJia);
- cmd.Parameters.AddWithValue("@e", maoLi == 0m ? (object)DBNull.Value : (object)maoLi);
- cmd.Parameters.AddWithValue("@f", maoLiLv.ToString());
- cmd.Parameters.AddWithValue("@rid", rowId);
- cmd.ExecuteNonQuery();
- }
- }
-
- private void UpdateProjectQuoteTotalsById(string projectId,
- decimal xiangGuiTaiShu, decimal chengBenZongJia,
- decimal baoChuZongJia, decimal liRun, decimal liRunLv)
- {
- if (string.IsNullOrWhiteSpace(projectId)) return;
- string dbPath = GetDbFullPath(ProjectsDbPath);
- if (!File.Exists(dbPath)) return;
- try
- {
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- string sql = "UPDATE " + ProjectsTableName + " SET " +
- "箱柜台数=@xgts, 成本总价=@cbzj, 报出总价=@bczj, " +
- "利润=@lr, 利润率=@lrl WHERE 项目编号=@id;";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- cmd.Parameters.AddWithValue("@xgts", xiangGuiTaiShu == 0m ? (object)DBNull.Value : (object)xiangGuiTaiShu);
- cmd.Parameters.AddWithValue("@cbzj", chengBenZongJia == 0m ? (object)DBNull.Value : (object)chengBenZongJia);
- cmd.Parameters.AddWithValue("@bczj", baoChuZongJia == 0m ? (object)DBNull.Value : (object)baoChuZongJia);
- cmd.Parameters.AddWithValue("@lr", liRun == 0m ? (object)DBNull.Value : (object)liRun);
- cmd.Parameters.AddWithValue("@lrl", liRunLv.ToString());
- cmd.Parameters.AddWithValue("@id", projectId);
- cmd.ExecuteNonQuery();
- }
- }
- }
- catch { }
- }
-
- // ============================================================
- // 事件:CellValueChanged / DirtyStateChanged / CellEndEdit
- // ============================================================
-
- private void Grid_DirtyStateChanged(object sender, EventArgs e)
- {
- if (_isRecalculating || _isReloading) return;
- var msSinceRecalc = (DateTime.Now - _lastRecalcTime).TotalMilliseconds;
- if (msSinceRecalc < 2000) return;
- var dgv = sender as DataGridView;
- if (dgv != null && dgv.IsCurrentCellDirty)
- dgv.CommitEdit(DataGridViewDataErrorContexts.Commit);
- }
-
- private void Yuanjian_CellValueChanged(object sender, DataGridViewCellEventArgs e)
- {
- if (_isRecalculating || _isReloading) return;
- if (e.RowIndex < 0) return;
- var dgv = this.advancedDataGridView5;
- if (dgv == null || e.RowIndex >= dgv.Rows.Count) return;
- var row = dgv.Rows[e.RowIndex];
- if (row == null || row.IsNewRow) return;
- _isRecalculating = true;
- try
- {
- RecalcYuanjianRow(row);
- var xhRow = GetFirstSelectedRow(this.advancedDataGridView4);
- if (xhRow != null)
- {
- RecalcXianghaoRowFromYuanjian(xhRow);
- var thRow = GetFirstSelectedRow(this.advancedDataGridView9);
- if (thRow != null) RecalcTuhaoRowFromXianghao(thRow);
- }
- }
- finally { _isRecalculating = false; _lastRecalcTime = DateTime.Now; }
- }
-
- private void Xianghao_CellValueChanged(object sender, DataGridViewCellEventArgs e)
- {
- if (_isRecalculating || _isReloading) return;
- if (e.RowIndex < 0) return;
- var dgv = this.advancedDataGridView4;
- if (dgv == null || e.RowIndex >= dgv.Rows.Count) return;
- var row = dgv.Rows[e.RowIndex];
- if (row == null || row.IsNewRow) return;
- _isRecalculating = true;
- try
- {
- var thRow = GetFirstSelectedRow(this.advancedDataGridView9);
- if (thRow != null) RecalcTuhaoRowFromXianghao(thRow);
- }
- finally { _isRecalculating = false; _lastRecalcTime = DateTime.Now; }
- }
-
- private void Tuhao_CellValueChanged(object sender, DataGridViewCellEventArgs e)
- {
- if (_isRecalculating || _isReloading) return;
- if (e.RowIndex < 0) return;
- var dgv = this.advancedDataGridView9;
- if (dgv == null || e.RowIndex >= dgv.Rows.Count) return;
- var row = dgv.Rows[e.RowIndex];
- if (row == null || row.IsNewRow) return;
- DataGridViewColumn col = e.ColumnIndex >= 0 ? dgv.Columns[e.ColumnIndex] : null;
- string colName = col == null ? "" :
- (!string.IsNullOrEmpty(col.DataPropertyName) ? col.DataPropertyName : col.HeaderText);
- if (colName != "台数") return;
- _isRecalculating = true;
- try { RecalcTuhaoRowFromXianghao(row); }
- finally { _isRecalculating = false; _lastRecalcTime = DateTime.Now; }
- }
-
- /// CellEndEdit:把公式列的字符串值转为 double,让 DefaultCellStyle.Format 生效。
- private void Grid_CellEndEdit(object sender, DataGridViewCellEventArgs e)
- {
- var dgv = sender as DataGridView;
- if (dgv == null || e.ColumnIndex < 0 || e.ColumnIndex >= dgv.Columns.Count) return;
- string dp = dgv.Columns[e.ColumnIndex].DataPropertyName;
- string cn = dgv.Columns[e.ColumnIndex].HeaderText;
- string colKey = !string.IsNullOrEmpty(dp) ? dp : cn;
- if (!s_公式列集合.Contains(colKey)) return;
- if (e.RowIndex < 0 || e.RowIndex >= dgv.Rows.Count) return;
- object v = dgv.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
- if (v == null || v is double) return;
- string str = v.ToString().Trim();
- if (string.IsNullOrEmpty(str)) return;
- double d;
- if (double.TryParse(str, out d))
- dgv.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = d;
- }
-
- // ============================================================
- // SelectionChanged 联动
- // ============================================================
-
- private void advancedDataGridView9_SelectionChanged(object sender, EventArgs e)
- {
- if (_isReloading) return;
- if (this.advancedDataGridView9 != null && this.advancedDataGridView9.SelectedCells.Count > 1) return;
- DataGridViewRow row = GetFirstSelectedRow(this.advancedDataGridView9);
- if (row == null) return;
- string tuhao = GetCellValueAsString(row, "图号");
- if (tuhao == _currentTuhao) return;
- _currentTuhao = tuhao;
- ReloadXianghaoByTuhao(_currentProjectId, _currentTuhao);
- }
-
- private void advancedDataGridView4_SelectionChanged(object sender, EventArgs e)
- {
- if (_isReloading) return;
- if (this.advancedDataGridView4 != null && this.advancedDataGridView4.SelectedCells.Count > 1) return;
- DataGridViewRow row = GetFirstSelectedRow(this.advancedDataGridView4);
- if (row == null) return;
- string xh = GetCellValueAsString(row, "箱号");
- if (xh == _currentXianghao) return;
- _currentXianghao = xh;
- ReloadYuanjianByXianghao(_currentProjectId, _currentTuhao, _currentXianghao);
- }
-
- private void advancedDataGridView5_SelectionChanged(object sender, EventArgs e) { }
-
- // ============================================================
- // ★ 点击表格行 → 定位到对应的扒图框(缩放居中)
- // 读取数据行的"框Handle"列,用 Handle 反查 CAD 实体,缩放到实体范围
- // ============================================================
- private void Grid_CellClick_Zoom(object sender, DataGridViewCellEventArgs e)
- {
- if (_isReloading) return;
- if (e.RowIndex < 0) return;
- DataGridView dgv = sender as DataGridView;
- if (dgv == null) return;
- DataGridViewRow row = dgv.Rows[e.RowIndex];
- if (row == null || row.IsNewRow) return;
- // ★ 直接从 DataRow 读取"框Handle"(不依赖 DataGridView 列映射)
- string handle = "";
- var drv = row.DataBoundItem as DataRowView;
- if (drv != null && drv.Row != null && drv.Row.Table.Columns.Contains("框Handle"))
- {
- object v = drv.Row["框Handle"];
- if (v != null && v != DBNull.Value) handle = v.ToString().Trim();
- }
- if (!string.IsNullOrWhiteSpace(handle))
- {
- ZoomToFrameHandle(handle);
- }
- }
-
- ///
- /// 根据框 Handle 字符串定位网页 CAD 视图:缩放居中到框的位置并高亮。
- /// Handle 是扒图时绘制的彩色矩形框的句柄(十六进制字符串),
- /// 与网页端实体 objectId 一致,通过 CadBridge 转发给网页 CAD 执行。
- ///
- private static void ZoomToFrameHandle(string handle)
- {
- if (string.IsNullOrWhiteSpace(handle)) return;
- try
- {
- cadbt.CadBridge.ZoomToFrameHandle(handle);
- }
- catch { }
- }
-
- ///
- /// ★ 网页 CAD 会话内的扒图框由网页端持有,无需像 AutoCAD 版那样
- /// 定期 SaveAs 整个 DWG(原为防止 CAD 关闭时框丢失)。保留空实现
- /// 以兼容调用点。
- ///
- private static DateTime _lastDwgSaveTime = DateTime.MinValue;
-
- // ★ 扒元件后待选中的行(框Handle),finally 延迟执行选中
- private List _pendingSelectYuanjianHandles = new List();
-
- private static void SaveCurrentDwg()
- {
- // 网页版:扒图框保存在网页 CAD 会话中,无需保存 DWG 文件。
- }
-
- ///
- /// ★ 删除指定 Handle 对应的 CAD 框实体(单个,转发到批量方法)。
- ///
- private void DeleteFrameByHandle(string handle)
- {
- DeleteFramesByHandles(new string[] { handle });
- }
-
- ///
- /// ★ 批量删除多个 Handle 对应的框:打包成一条消息发给网页 CAD,
- /// 网页端逐个 erase 后只 regen 一次(保持原版"批量一次刷新"的优化)。
- ///
- private void DeleteFramesByHandles(System.Collections.Generic.IEnumerable handles)
- {
- var list = new List();
- if (handles != null)
- foreach (string h in handles)
- if (!string.IsNullOrWhiteSpace(h)) list.Add(h);
- if (list.Count == 0) { Log("[DeleteFramesByHandles] 无有效 handle,跳过"); return; }
- try
- {
- cadbt.CadBridge.DeleteFramesByHandles(list);
- Log("[DeleteFramesByHandles] 已发送网页删除请求: 请求=" + list.Count);
- }
- catch (System.Exception ex) { Log("[DeleteFramesByHandles] 异常: " + ex.Message); }
- }
-
- ///
- /// ★ 收集指定图号下所有箱号表和元件表的框Handle(级联删框用)。
- /// 不包含图号表自身的框(图号行框由调用方从内存表收集)。
- ///
- private void CollectFrameHandlesForTuhao(string projectId, string tuhao, List handles)
- {
- if (string.IsNullOrWhiteSpace(projectId) || string.IsNullOrWhiteSpace(tuhao)) return;
- try
- {
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) { Log("[CollectFrameHandlesForTuhao] 数据库不存在: " + dbPath); return; }
- int beforeCount = handles.Count;
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- // 箱号表
- string xhTbl = GetXianghaoTableByIndex(projectId, tuhao);
- Log("[CollectFrameHandlesForTuhao] 图号=" + tuhao + " 箱号表名=" + (xhTbl ?? "(null)"));
- if (!string.IsNullOrEmpty(xhTbl) && TableExists(conn, xhTbl))
- {
- using (var cmd = new System.Data.SQLite.SQLiteCommand(
- "SELECT 框Handle, 箱号 FROM \"" + xhTbl + "\";", conn))
- using (var reader = cmd.ExecuteReader())
- {
- while (reader.Read())
- {
- string h = reader.IsDBNull(0) ? "" : reader.GetString(0);
- if (!string.IsNullOrWhiteSpace(h)) handles.Add(h);
- string xh = reader.IsDBNull(1) ? "" : reader.GetString(1);
- Log("[CollectFrameHandlesForTuhao] 箱号=" + xh + " 框Handle=" + h);
- // 查该箱号的元件表
- if (!string.IsNullOrWhiteSpace(xh))
- {
- string yjTbl = GetYuanjianTableByIndex(projectId, tuhao, xh);
- if (!string.IsNullOrEmpty(yjTbl) && TableExists(conn, yjTbl))
- {
- using (var yjCmd = new System.Data.SQLite.SQLiteCommand(
- "SELECT 框Handle FROM \"" + yjTbl + "\";", conn))
- using (var yjReader = yjCmd.ExecuteReader())
- while (yjReader.Read())
- {
- string yh = yjReader.IsDBNull(0) ? "" : yjReader.GetString(0);
- if (!string.IsNullOrWhiteSpace(yh)) handles.Add(yh);
- Log("[CollectFrameHandlesForTuhao] 元件框Handle=" + yh);
- }
- }
- }
- }
- }
- }
- }
- Log("[CollectFrameHandlesForTuhao] 新增框Handle数: " + (handles.Count - beforeCount));
- }
- catch (Exception ex) { Log("[CollectFrameHandlesForTuhao] 异常: " + ex.Message); }
- }
-
- ///
- /// ★ 收集指定箱号下元件表的框Handle(级联删框用)。
- /// 不包含箱号表自身的框(箱号行框由调用方从内存表收集)。
- ///
- private void CollectFrameHandlesForXianghao(string projectId, string tuhao, string xianghao, List handles)
- {
- if (string.IsNullOrWhiteSpace(projectId) || string.IsNullOrWhiteSpace(tuhao) ||
- string.IsNullOrWhiteSpace(xianghao)) return;
- try
- {
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) { Log("[CollectFrameHandlesForXianghao] 数据库不存在: " + dbPath); return; }
- int beforeCount = handles.Count;
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- // ★ 先收集箱号表自身该箱号的框Handle(之前遗漏,导致删箱号时蒙版不删)
- string xhTbl = GetXianghaoTableByIndex(projectId, tuhao);
- Log("[CollectFrameHandlesForXianghao] 图号=" + tuhao + " 箱号=" + xianghao + " 箱号表名=" + (xhTbl ?? "(null)"));
- if (!string.IsNullOrEmpty(xhTbl) && TableExists(conn, xhTbl))
- {
- using (var cmd = new System.Data.SQLite.SQLiteCommand(
- "SELECT 框Handle FROM \"" + xhTbl + "\" WHERE 箱号=@xh;", conn))
- {
- cmd.Parameters.AddWithValue("@xh", xianghao);
- using (var reader = cmd.ExecuteReader())
- while (reader.Read())
- {
- string h = reader.IsDBNull(0) ? "" : reader.GetString(0);
- if (!string.IsNullOrWhiteSpace(h)) handles.Add(h);
- Log("[CollectFrameHandlesForXianghao] 箱号自身框Handle=" + h);
- }
- }
- }
- // ★ 再收集该箱号下元件表的框Handle
- string yjTbl = GetYuanjianTableByIndex(projectId, tuhao, xianghao);
- Log("[CollectFrameHandlesForXianghao] 元件表名=" + (yjTbl ?? "(null)"));
- if (!string.IsNullOrEmpty(yjTbl) && TableExists(conn, yjTbl))
- {
- using (var cmd = new System.Data.SQLite.SQLiteCommand(
- "SELECT 框Handle FROM \"" + yjTbl + "\";", conn))
- using (var reader = cmd.ExecuteReader())
- while (reader.Read())
- {
- string h = reader.IsDBNull(0) ? "" : reader.GetString(0);
- if (!string.IsNullOrWhiteSpace(h)) handles.Add(h);
- Log("[CollectFrameHandlesForXianghao] 元件框Handle=" + h);
- }
- }
- }
- Log("[CollectFrameHandlesForXianghao] 新增框Handle数: " + (handles.Count - beforeCount));
- }
- catch (Exception ex) { Log("[CollectFrameHandlesForXianghao] 异常: " + ex.Message); }
- }
-
- /// 检查表是否存在(SQLite)。
- private static bool TableExists(System.Data.SQLite.SQLiteConnection conn, string tableName)
- {
- if (conn == null || string.IsNullOrWhiteSpace(tableName)) return false;
- try
- {
- string name = tableName.Trim().Trim('"');
- using (var cmd = new System.Data.SQLite.SQLiteCommand(
- "SELECT name FROM sqlite_master WHERE type='table' AND name=@n;", conn))
- {
- cmd.Parameters.AddWithValue("@n", name);
- object o = cmd.ExecuteScalar();
- return o != null && o != DBNull.Value;
- }
- }
- catch { return false; }
- }
-
- // ============================================================
- // 双击项目行 → 进入项目
- // ============================================================
-
- private void advancedDataGridView6_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
- {
- if (e.RowIndex < 0) return;
- DataGridViewRow row = this.advancedDataGridView6.Rows[e.RowIndex];
- string pid = GetCellValueAsString(row, "项目编号");
- if (string.IsNullOrWhiteSpace(pid)) return;
-
- // 切项目前:先把当前项目的所有改动回写库,然后清空缓存
- if (!string.IsNullOrWhiteSpace(_currentProjectId) && _currentProjectId != pid)
- {
- try
- {
- if (this.advancedDataGridView5 != null) this.advancedDataGridView5.EndEdit();
- if (this.advancedDataGridView4 != null) this.advancedDataGridView4.EndEdit();
- if (this.advancedDataGridView9 != null) this.advancedDataGridView9.EndEdit();
- if (_tuhaoTable != null)
- SaveTableToDatabase(_tuhaoTable, _currentProjectId, TuhaoTableName, null, null, true);
- foreach (var kv in _xianghaoCache)
- if (kv.Value != null && !string.IsNullOrWhiteSpace(kv.Value.TableName))
- SaveTableToDatabase(kv.Value, _currentProjectId,
- "\"" + kv.Value.TableName + "\"", null, null, true);
- foreach (var kv in _yuanjianCache)
- if (kv.Value != null && !string.IsNullOrWhiteSpace(kv.Value.TableName))
- SaveTableToDatabase(kv.Value, _currentProjectId,
- "\"" + kv.Value.TableName + "\"", null, null, true);
- }
- catch { }
- _xianghaoCache.Clear();
- _yuanjianCache.Clear();
- _tuhaoTable = null;
- }
- _currentProjectId = pid;
- EnterProjectCore(pid);
- }
-
- private void EnterProjectCore(string pid)
- {
- // 切换主区域到报价页(tabPage4)
- this.tabControl2.SelectedTab = this.tabPage4;
- EnsureQuoteDbExists(pid);
- LoadPriceFormatConfig(pid);
- RecalcAllFromDatabase(pid);
- ReloadTuhaoByProject(pid);
- ApplyPriceFormat(this.advancedDataGridView9, _单台小数位文本);
- ApplyPriceFormat(this.advancedDataGridView4, _单台小数位文本);
- ApplyPriceFormat(this.advancedDataGridView5, _单台小数位文本);
- ApplyPriceFormat(this.advancedDataGridView6, _项目小数位文本);
- }
-
- // ============================================================
- // ★ 右键点击时保持多行选中
- // WinForms 默认行为:右键点击未选中行 → 清除多选,只选一行
- // 修正:右键点击已选中行 → 保持多选;点击未选中行 → 正常切换
- // ============================================================
- private void Grid_MouseDown_KeepMultiSelect(object sender, MouseEventArgs e)
- {
- if (e.Button != MouseButtons.Right) return;
- var dgv = sender as DataGridView;
- if (dgv == null) return;
- var hit = dgv.HitTest(e.X, e.Y);
- if (hit.Type != DataGridViewHitTestType.Cell && hit.Type != DataGridViewHitTestType.RowHeader) return;
- if (hit.RowIndex < 0) return;
- // 如果右键点击的行已经在选中行中,不做任何操作(保持多选)
- // 如果不在选中行中,让默认行为生效(选中该行)
- foreach (DataGridViewRow r in dgv.SelectedRows)
- {
- if (r.Index == hit.RowIndex) return;
- }
- // 选中行中没有包含右键点击的行 → 手动选中该行
- dgv.ClearSelection();
- dgv.Rows[hit.RowIndex].Selected = true;
- dgv.CurrentCell = dgv.Rows[hit.RowIndex].Cells[0];
- }
-
- // ============================================================
- // ★ 键盘 Delete 键批量删除选中行
- // 图号表→MenuTuhao_Delete_Click;箱号表→MenuXianghao_Delete_Click;元件表→MenuYuanjian_Delete_Click
- // ============================================================
- // 连续批量模式标记:Shift+F1 触发,或 1 秒内连按 F1 触发
- private DateTime _lastF1Time = DateTime.MinValue;
- private bool _f1BatchMode;
-
- /// F1:元件两两配对合并;F2:元件三个一组配对合并。
- protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
- {
- if ((keyData & Keys.KeyCode) == Keys.F1 && this.advancedDataGridView5 != null)
- {
- try { RunF1Merge(); } catch (Exception ex) { Log("[F1] " + ex.Message); }
- return true;
- }
- if ((keyData & Keys.KeyCode) == Keys.F2 && this.advancedDataGridView5 != null)
- {
- try { MergeYuanjianByGroup(3); } catch (Exception ex) { Log("[F2] " + ex.Message); }
- return true;
- }
- if ((keyData & Keys.KeyCode) == Keys.F3 && this.advancedDataGridView5 != null)
- {
- try { MergeYuanjianByGroup(4); } catch (Exception ex) { Log("[F3] " + ex.Message); }
- return true;
- }
- return base.ProcessCmdKey(ref msg, keyData);
- }
-
- /// 统一 F1 入口(宿主按键/网页转发共用)。
- private void RunF1Merge()
- {
- MergeAdjacentYuanjianByF1();
- }
-
- private void Grid_KeyDown_Delete(object sender, KeyEventArgs e)
- {
- if (e.KeyCode != Keys.Delete) return;
- var dgv = sender as DataGridView;
- if (dgv == null) return;
- if (dgv.SelectedRows.Count == 0 && dgv.SelectedCells.Count == 0) return;
- if (dgv.IsCurrentCellInEditMode) return; // 编辑模式下不拦截 Delete
-
- e.SuppressKeyPress = true;
- e.Handled = true;
-
- if (dgv == this.advancedDataGridView9)
- MenuTuhao_Delete_Click(null, null);
- else if (dgv == this.advancedDataGridView4)
- MenuXianghao_Delete_Click(null, null);
- else if (dgv == this.advancedDataGridView5)
- MenuYuanjian_Delete_Click(null, null);
- }
-
- // ============================================================
- // 右键菜单:创建 + 行移动
- // ============================================================
-
- private void BuildContextMenus()
- {
- // 图号菜单(advancedDataGridView9)
- _menuTuhao = new ContextMenuStrip();
- _menuTuhao.Items.Add("新建图号", null, MenuTuhao_New_Click);
- _menuTuhao.Items.Add("删除图号", null, MenuTuhao_Delete_Click);
- _menuTuhao.Items.Add(new ToolStripSeparator());
- _menuTuhao.Items.Add("置顶", null, (s, e) => MoveSelectedRowInGrid(this.advancedDataGridView9, RowMoveAction.Top));
- _menuTuhao.Items.Add("向上移动", null, (s, e) => MoveSelectedRowInGrid(this.advancedDataGridView9, RowMoveAction.Up));
- _menuTuhao.Items.Add("向下移动", null, (s, e) => MoveSelectedRowInGrid(this.advancedDataGridView9, RowMoveAction.Down));
- _menuTuhao.Items.Add("置底", null, (s, e) => MoveSelectedRowInGrid(this.advancedDataGridView9, RowMoveAction.Bottom));
- _menuTuhao.Items.Add("移动到...", null, (s, e) => MoveSelectedRowInGrid(this.advancedDataGridView9, RowMoveAction.To));
- this.advancedDataGridView9.ContextMenuStrip = _menuTuhao;
-
- // 箱号菜单(advancedDataGridView4)
- _menuXianghao = new ContextMenuStrip();
- _menuXianghao.Items.Add("新建箱号", null, MenuXianghao_New_Click);
- _menuXianghao.Items.Add("删除箱号", null, MenuXianghao_Delete_Click);
- _menuXianghao.Items.Add(new ToolStripSeparator());
- _menuXianghao.Items.Add("置顶", null, (s, e) => MoveSelectedRowInGrid(this.advancedDataGridView4, RowMoveAction.Top));
- _menuXianghao.Items.Add("向上移动", null, (s, e) => MoveSelectedRowInGrid(this.advancedDataGridView4, RowMoveAction.Up));
- _menuXianghao.Items.Add("向下移动", null, (s, e) => MoveSelectedRowInGrid(this.advancedDataGridView4, RowMoveAction.Down));
- _menuXianghao.Items.Add("置底", null, (s, e) => MoveSelectedRowInGrid(this.advancedDataGridView4, RowMoveAction.Bottom));
- _menuXianghao.Items.Add("移动到...", null, (s, e) => MoveSelectedRowInGrid(this.advancedDataGridView4, RowMoveAction.To));
- this.advancedDataGridView4.ContextMenuStrip = _menuXianghao;
-
- // 元件菜单(advancedDataGridView5)
- _menuYuanjian = new ContextMenuStrip();
- _menuYuanjian.Items.Add("新建元件", null, MenuYuanjian_New_Click);
- _menuYuanjian.Items.Add("删除元件", null, MenuYuanjian_Delete_Click);
- _menuYuanjian.Items.Add("合并元件", null, MenuYuanjian_Merge_Click);
- _menuYuanjian.Items.Add(new ToolStripSeparator());
- _menuYuanjian.Items.Add("置顶", null, (s, e) => MoveSelectedRowInGrid(this.advancedDataGridView5, RowMoveAction.Top));
- _menuYuanjian.Items.Add("向上移动", null, (s, e) => MoveSelectedRowInGrid(this.advancedDataGridView5, RowMoveAction.Up));
- _menuYuanjian.Items.Add("向下移动", null, (s, e) => MoveSelectedRowInGrid(this.advancedDataGridView5, RowMoveAction.Down));
- _menuYuanjian.Items.Add("置底", null, (s, e) => MoveSelectedRowInGrid(this.advancedDataGridView5, RowMoveAction.Bottom));
- _menuYuanjian.Items.Add("移动到...", null, (s, e) => MoveSelectedRowInGrid(this.advancedDataGridView5, RowMoveAction.To));
- this.advancedDataGridView5.ContextMenuStrip = _menuYuanjian;
- }
-
- private enum RowMoveAction { Top, Up, Down, Bottom, To }
-
- private void MoveSelectedRowInGrid(DataGridView dgv, RowMoveAction action)
- {
- if (dgv == null || string.IsNullOrWhiteSpace(_currentProjectId)) return;
- DataTable table = null;
- System.Action reloadAction = null;
- if (dgv == this.advancedDataGridView5)
- {
- table = _yuanjianTable;
- reloadAction = () => ReloadYuanjianByXianghao(_currentProjectId, _currentTuhao, _currentXianghao);
- }
- else if (dgv == this.advancedDataGridView4)
- {
- table = _xianghaoTable;
- reloadAction = () => ReloadXianghaoByTuhao(_currentProjectId, _currentTuhao);
- }
- else if (dgv == this.advancedDataGridView9)
- {
- table = _tuhaoTable;
- reloadAction = () => ReloadTuhaoByProject(_currentProjectId);
- }
- if (table == null || table.Rows.Count == 0)
- {
- MessageBox.Show(this, "没有数据可移动。", "移动行", MessageBoxButtons.OK, MessageBoxIcon.Information);
- return;
- }
- var dgvRow = GetFirstSelectedRow(dgv);
- if (dgvRow == null)
- {
- MessageBox.Show(this, "请先选择要移动的行。", "移动行", MessageBoxButtons.OK, MessageBoxIcon.Information);
- return;
- }
- int dataCount = dgv.Rows.Count;
- if (dgv.AllowUserToAddRows) dataCount--;
- if (dataCount <= 0) return;
- int oldIndex = dgvRow.Index;
- if (oldIndex >= dataCount) return;
-
- string rememberTuhao = _currentTuhao;
- string rememberXianghao = _currentXianghao;
- int newIndex = -1;
- _isReloading = true;
- try
- {
- dgv.EndEdit();
- newIndex = oldIndex;
- switch (action)
- {
- case RowMoveAction.Top: newIndex = 0; break;
- case RowMoveAction.Up: newIndex = Math.Max(0, oldIndex - 1); break;
- case RowMoveAction.Down: newIndex = Math.Min(dataCount - 1, oldIndex + 1); break;
- case RowMoveAction.Bottom: newIndex = dataCount - 1; break;
- case RowMoveAction.To:
- string input = ShowInputDialog("移动到",
- "请输入目标行号(1-" + dataCount + "):", (oldIndex + 1).ToString());
- if (string.IsNullOrEmpty(input)) { newIndex = -1; return; }
- int target;
- if (!int.TryParse(input.Trim(), out target))
- {
- MessageBox.Show(this, "请输入有效数字。", "移动到", MessageBoxButtons.OK, MessageBoxIcon.Warning);
- newIndex = -1;
- return;
- }
- newIndex = Math.Max(0, Math.Min(dataCount - 1, target - 1));
- break;
- }
- if (newIndex == oldIndex) { newIndex = -1; return; }
-
- DataRow rowToMove = table.Rows[oldIndex];
- object[] savedValues = rowToMove.ItemArray;
- table.Rows.Remove(rowToMove);
- DataRow newRow = table.NewRow();
- newRow.ItemArray = savedValues;
- table.Rows.InsertAt(newRow, newIndex);
-
- if (table.Columns.Contains("序号"))
- {
- for (int i = 0; i < table.Rows.Count; i++) table.Rows[i]["序号"] = (i + 1).ToString();
- }
- if (dgv == this.advancedDataGridView9)
- SaveTableToDatabase(table, _currentProjectId, TuhaoTableName, null, null, true);
- else
- SaveTableToDatabase(table, _currentProjectId, "\"" + table.TableName + "\"", null, null, true);
- }
- catch (Exception ex)
- {
- MessageBox.Show(this, "移动行失败:\n" + ex.Message, "移动行", MessageBoxButtons.OK, MessageBoxIcon.Error);
- newIndex = -1;
- }
- finally
- {
- _isReloading = false;
- if (newIndex >= 0)
- {
- if (dgv == this.advancedDataGridView9)
- SelectRowByValue(this.advancedDataGridView9, "图号", rememberTuhao);
- else if (dgv == this.advancedDataGridView4)
- SelectRowByValue(this.advancedDataGridView4, "箱号", rememberXianghao);
- else if (dgv == this.advancedDataGridView5)
- SelectRowByValue(this.advancedDataGridView5, "序号", (newIndex + 1).ToString());
- }
- }
- }
-
- private void MoveLastRowBelowSelected(DataGridView dgv, DataTable table,
- int afterIndex, string dbTableName, string projectId)
- {
- if (dgv == null || table == null || afterIndex < 0 || table.Rows.Count < 2) return;
- int lastIndex = table.Rows.Count - 1;
- int targetIndex = afterIndex + 1;
- if (targetIndex >= lastIndex) return;
- object[] savedValues = table.Rows[lastIndex].ItemArray;
- table.Rows.RemoveAt(lastIndex);
- DataRow newRow = table.NewRow();
- newRow.ItemArray = savedValues;
- table.Rows.InsertAt(newRow, targetIndex);
- if (table.Columns.Contains("序号"))
- {
- for (int i = 0; i < table.Rows.Count; i++) table.Rows[i]["序号"] = (i + 1).ToString();
- }
- SaveTableToDatabase(table, projectId, dbTableName, null, null, true);
- try { if (targetIndex < dgv.Rows.Count) dgv.FirstDisplayedScrollingRowIndex = targetIndex; } catch { }
- }
-
- // ---------- 图号菜单事件 ----------
-
- private void MenuTuhao_New_Click(object sender, EventArgs e)
- {
- if (string.IsNullOrWhiteSpace(_currentProjectId))
- {
- MessageBox.Show(this, "请先在项目表中双击选择一个项目,再新建图号。",
- "新建图号", MessageBoxButtons.OK, MessageBoxIcon.Information);
- return;
- }
- string newTuhao = "新图号" + GetNextSeqNumber(TuhaoTableName, "图号", _currentProjectId);
- int selectedIndex = GetSelectedRowIndex(this.advancedDataGridView9);
- try
- {
- _isReloading = true;
- SaveAllQuoteTablesIfDirty(false);
- InsertTuhao(_currentProjectId, newTuhao, "", "");
- _xianghaoCache.Clear();
- _yuanjianCache.Clear();
- ReloadTuhaoByProject(_currentProjectId);
- MoveLastRowBelowSelected(this.advancedDataGridView9, _tuhaoTable, selectedIndex, TuhaoTableName, _currentProjectId);
- RecalcAllAfterReload();
- }
- catch (Exception ex)
- {
- MessageBox.Show(this, "新建图号失败:\n" + ex.Message,
- "新建图号", MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- finally
- {
- _currentTuhao = newTuhao;
- SelectRowByValue(this.advancedDataGridView9, "图号", newTuhao);
- _isReloading = false;
- ReloadXianghaoByTuhao(_currentProjectId, newTuhao);
- }
- }
-
- private void MenuTuhao_Delete_Click(object sender, EventArgs e)
- {
- var rows = GetAllSelectedRows(this.advancedDataGridView9);
- if (rows == null || rows.Count == 0)
- {
- MessageBox.Show(this, "请先选择要删除的图号。",
- "删除图号", MessageBoxButtons.OK, MessageBoxIcon.Information);
- return;
- }
- var tuhaos = new List();
- foreach (var r in rows)
- {
- string th = GetCellValueAsString(r, "图号");
- if (!string.IsNullOrWhiteSpace(th) && !tuhaos.Contains(th)) tuhaos.Add(th);
- }
- if (tuhaos.Count == 0)
- {
- MessageBox.Show(this, "选中行没有图号,无法删除。",
- "删除图号", MessageBoxButtons.OK, MessageBoxIcon.Warning);
- return;
- }
- // ★ 收集选中图号行自己的框Handle
- var frameHandles = new List();
- foreach (var r in rows)
- {
- var drv = r.DataBoundItem as DataRowView;
- if (drv != null && drv.Row != null && drv.Row.Table.Columns.Contains("框Handle"))
- {
- object v = drv.Row["框Handle"];
- if (v != null && v != DBNull.Value)
- {
- string h = v.ToString().Trim();
- if (!string.IsNullOrWhiteSpace(h)) frameHandles.Add(h);
- }
- }
- }
- // ★ 收集每个图号下所有箱号和元件的框Handle(级联删框)
- foreach (string tuhao in tuhaos)
- {
- CollectFrameHandlesForTuhao(_currentProjectId, tuhao, frameHandles);
- }
- Log("[MenuTuhao_Delete] 删除图号: " + string.Join(",", tuhaos) + " 收集到框Handle数: " + frameHandles.Count);
- try
- {
- _isReloading = true;
- SaveAllQuoteTablesIfDirty(false);
- foreach (string tuhao in tuhaos)
- {
- DeleteTuhao(_currentProjectId, tuhao);
- if (!string.IsNullOrEmpty(tuhao))
- {
- _xianghaoCache.Remove(tuhao);
- var keysToRemove = new List();
- foreach (var key in _yuanjianCache.Keys)
- if (key.StartsWith(tuhao + "\n")) keysToRemove.Add(key);
- foreach (var key in keysToRemove) _yuanjianCache.Remove(key);
- }
- }
- RenumberTable(_currentProjectId, TuhaoTableName);
- ReloadTuhaoByProject(_currentProjectId);
- RecalcAllAfterReload();
- // ★ 删除所有收集到的框实体(去重)
- var tuhaoDistinct = new HashSet(frameHandles);
- foreach (string h in tuhaoDistinct)
- {
- Log("[MenuTuhao_Delete] 准备删除框Handle: " + h);
- DeleteFrameByHandle(h);
- }
- Log("[MenuTuhao_Delete] 框实体删除完成,共 " + tuhaoDistinct.Count + " 个");
- // ★ 保存DWG,确保删框操作持久化
- SaveCurrentDwg();
- }
- catch (Exception ex)
- {
- MessageBox.Show(this, "删除图号失败:\n" + ex.Message,
- "删除图号", MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- finally { _isReloading = false; }
- }
-
- // ---------- 箱号菜单事件 ----------
-
- private void MenuXianghao_New_Click(object sender, EventArgs e)
- {
- if (string.IsNullOrWhiteSpace(_currentProjectId) || string.IsNullOrWhiteSpace(_currentTuhao))
- {
- MessageBox.Show(this, "请先选择图号,再新建箱号。",
- "新建箱号", MessageBoxButtons.OK, MessageBoxIcon.Information);
- return;
- }
- string rememberTuhao = _currentTuhao;
- int selectedIndex = GetSelectedRowIndex(this.advancedDataGridView4);
- string newXh = "新箱号" + GetXianghaoCount(_currentProjectId, _currentTuhao);
- try
- {
- _isReloading = true;
- SaveAllQuoteTablesIfDirty(false);
- InsertXianghao(_currentProjectId, _currentTuhao, newXh, "", "");
- if (!string.IsNullOrEmpty(rememberTuhao)) _xianghaoCache.Remove(rememberTuhao);
- ReloadXianghaoByTuhao(_currentProjectId, _currentTuhao);
- if (_xianghaoTable != null)
- MoveLastRowBelowSelected(this.advancedDataGridView4, _xianghaoTable, selectedIndex,
- "\"" + _xianghaoTable.TableName + "\"", _currentProjectId);
- RecalcAllAfterReload();
- }
- catch (Exception ex)
- {
- MessageBox.Show(this, "新建箱号失败:\n" + ex.Message,
- "新建箱号", MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- finally
- {
- _currentTuhao = rememberTuhao;
- _currentXianghao = newXh;
- SelectRowByValue(this.advancedDataGridView9, "图号", rememberTuhao);
- SelectRowByValue(this.advancedDataGridView4, "箱号", newXh);
- _isReloading = false;
- ReloadYuanjianByXianghao(_currentProjectId, _currentTuhao, newXh);
- }
- }
-
- private void MenuXianghao_Delete_Click(object sender, EventArgs e)
- {
- var rows = GetAllSelectedRows(this.advancedDataGridView4);
- if (rows == null || rows.Count == 0)
- {
- MessageBox.Show(this, "请先选择要删除的箱号。",
- "删除箱号", MessageBoxButtons.OK, MessageBoxIcon.Information);
- return;
- }
- var xhs = new List();
- foreach (var r in rows)
- {
- string xh = GetCellValueAsString(r, "箱号");
- if (!string.IsNullOrWhiteSpace(xh) && !xhs.Contains(xh)) xhs.Add(xh);
- }
- if (xhs.Count == 0)
- {
- MessageBox.Show(this, "选中行没有箱号,无法删除。",
- "删除箱号", MessageBoxButtons.OK, MessageBoxIcon.Warning);
- return;
- }
- // ★ 收集选中箱号行自己的框Handle
- var frameHandles = new List();
- foreach (var r in rows)
- {
- var drv = r.DataBoundItem as DataRowView;
- if (drv != null && drv.Row != null && drv.Row.Table.Columns.Contains("框Handle"))
- {
- object v = drv.Row["框Handle"];
- if (v != null && v != DBNull.Value)
- {
- string h = v.ToString().Trim();
- if (!string.IsNullOrWhiteSpace(h)) frameHandles.Add(h);
- }
- }
- }
- // ★ 收集每个箱号下元件表的框Handle(级联删框)
- foreach (string xh in xhs)
- {
- CollectFrameHandlesForXianghao(_currentProjectId, _currentTuhao, xh, frameHandles);
- }
- Log("[MenuXianghao_Delete] 删除箱号: " + string.Join(",", xhs) + " 图号=" + _currentTuhao + " 收集到框Handle数: " + frameHandles.Count);
- string rememberTuhao = _currentTuhao;
- try
- {
- _isReloading = true;
- SaveAllQuoteTablesIfDirty(false);
- foreach (string xh in xhs)
- {
- DeleteXianghao(_currentProjectId, _currentTuhao, xh);
- string yjKey = _currentTuhao + "\n" + xh;
- _yuanjianCache.Remove(yjKey);
- }
- string xhTbl = GetXianghaoTableByIndex(_currentProjectId, _currentTuhao);
- if (!string.IsNullOrEmpty(xhTbl))
- RenumberTable(_currentProjectId, "\"" + xhTbl + "\"");
- if (!string.IsNullOrEmpty(_currentTuhao)) _xianghaoCache.Remove(_currentTuhao);
- Log("[MenuXianghao_Delete] 开始 ReloadXianghaoByTuhao...");
- ReloadXianghaoByTuhao(_currentProjectId, _currentTuhao);
- Log("[MenuXianghao_Delete] ReloadXianghaoByTuhao 完成,开始删除框实体...");
- RecalcAllAfterReload();
- // ★ 删除所有收集到的框实体(去重,避免重复删除)
- var distinctHandles = new HashSet(frameHandles);
- foreach (string h in distinctHandles)
- {
- Log("[MenuXianghao_Delete] 准备删除框Handle: " + h);
- DeleteFrameByHandle(h);
- }
- Log("[MenuXianghao_Delete] 框实体删除完成,共 " + distinctHandles.Count + " 个");
- // ★ 保存DWG,确保删框操作持久化
- SaveCurrentDwg();
- }
- catch (Exception ex)
- {
- Log("[MenuXianghao_Delete] 异常: " + ex.Message + "\n" + ex.StackTrace);
- MessageBox.Show(this, "删除箱号失败:\n" + ex.Message,
- "删除箱号", MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- finally
- {
- _currentTuhao = rememberTuhao;
- SelectRowByValue(this.advancedDataGridView9, "图号", rememberTuhao);
- _isReloading = false;
- }
- }
-
- // ---------- 元件菜单事件 ----------
-
- private void MenuYuanjian_New_Click(object sender, EventArgs e)
- {
- if (string.IsNullOrWhiteSpace(_currentProjectId) ||
- string.IsNullOrWhiteSpace(_currentTuhao) ||
- string.IsNullOrWhiteSpace(_currentXianghao))
- {
- MessageBox.Show(this, "请先选择箱号,再新建元件。",
- "新建元件", MessageBoxButtons.OK, MessageBoxIcon.Information);
- return;
- }
- string rememberTuhao = _currentTuhao;
- string rememberXianghao = _currentXianghao;
- int selectedIndex = GetSelectedRowIndex(this.advancedDataGridView5);
- string newName = "新元件" + GetYuanjianCount(_currentProjectId, _currentTuhao, _currentXianghao);
- try
- {
- _isReloading = true;
- SaveAllQuoteTablesIfDirty(false);
- InsertYuanjian(_currentProjectId, _currentTuhao, _currentXianghao, newName);
- string cacheKey = _currentTuhao + "\n" + _currentXianghao;
- _yuanjianCache.Remove(cacheKey);
- ReloadYuanjianByXianghao(_currentProjectId, _currentTuhao, _currentXianghao);
- if (_yuanjianTable != null)
- MoveLastRowBelowSelected(this.advancedDataGridView5, _yuanjianTable, selectedIndex,
- "\"" + _yuanjianTable.TableName + "\"", _currentProjectId);
- RecalcAllAfterReload();
- }
- catch (Exception ex)
- {
- MessageBox.Show(this, "新建元件失败:\n" + ex.Message,
- "新建元件", MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- finally
- {
- _currentTuhao = rememberTuhao;
- _currentXianghao = rememberXianghao;
- SelectRowByValue(this.advancedDataGridView9, "图号", rememberTuhao);
- SelectRowByValue(this.advancedDataGridView4, "箱号", rememberXianghao);
- _isReloading = false;
- }
- }
-
- private void MenuYuanjian_Delete_Click(object sender, EventArgs e)
- {
- if (string.IsNullOrWhiteSpace(_currentProjectId) ||
- string.IsNullOrWhiteSpace(_currentTuhao) ||
- string.IsNullOrWhiteSpace(_currentXianghao))
- {
- MessageBox.Show(this, "请先选择箱号,再删除元件。",
- "删除元件", MessageBoxButtons.OK, MessageBoxIcon.Information);
- return;
- }
- var rows = GetAllSelectedRows(this.advancedDataGridView5);
- if (rows == null || rows.Count == 0)
- {
- MessageBox.Show(this, "请先选择要删除的元件。",
- "删除元件", MessageBoxButtons.OK, MessageBoxIcon.Information);
- return;
- }
- var seqs = new List();
- var frameHandles = new List();
- foreach (var r in rows)
- {
- string seq = GetCellValueAsString(r, "序号");
- if (!string.IsNullOrWhiteSpace(seq) && !seqs.Contains(seq)) seqs.Add(seq);
- // ★ 收集元件行的框Handle
- var drv = r.DataBoundItem as DataRowView;
- if (drv != null && drv.Row != null && drv.Row.Table.Columns.Contains("框Handle"))
- {
- object v = drv.Row["框Handle"];
- if (v != null && v != DBNull.Value)
- {
- string h = v.ToString().Trim();
- if (!string.IsNullOrWhiteSpace(h)) frameHandles.Add(h);
- }
- }
- }
- if (seqs.Count == 0)
- {
- MessageBox.Show(this, "选中行没有序号,无法删除。",
- "删除元件", MessageBoxButtons.OK, MessageBoxIcon.Warning);
- return;
- }
- string rememberTuhao = _currentTuhao;
- string rememberXianghao = _currentXianghao;
- try
- {
- _isReloading = true;
- SaveAllQuoteTablesIfDirty(false);
- foreach (string seq in seqs)
- DeleteYuanjian(_currentProjectId, _currentTuhao, _currentXianghao, seq);
- string realTbl = GetYuanjianTableByIndex(_currentProjectId, _currentTuhao, _currentXianghao);
- if (!string.IsNullOrEmpty(realTbl))
- RenumberTable(_currentProjectId, "\"" + realTbl + "\"");
- string cacheKey = _currentTuhao + "\n" + _currentXianghao;
- _yuanjianCache.Remove(cacheKey);
- ReloadYuanjianByXianghao(_currentProjectId, _currentTuhao, _currentXianghao);
- RecalcAllAfterReload();
- // ★ 删除所有收集到的框实体(去重)
- foreach (string h in new HashSet(frameHandles)) DeleteFrameByHandle(h);
- // ★ 保存DWG,确保删框操作持久化
- SaveCurrentDwg();
- }
- catch (Exception ex)
- {
- MessageBox.Show(this, "删除元件失败:\n" + ex.Message,
- "删除元件", MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- finally
- {
- _currentTuhao = rememberTuhao;
- _currentXianghao = rememberXianghao;
- SelectRowByValue(this.advancedDataGridView9, "图号", rememberTuhao);
- SelectRowByValue(this.advancedDataGridView4, "箱号", rememberXianghao);
- _isReloading = false;
- }
- }
-
- // ============================================================
- // 合并元件:把选中的多行元件合并为一行
- // · 元件名称:所有非空名称直接拼接(去重,不加符号)
- // · 规格:所有非空规格直接拼接(去重,不加符号)
- // · 数量:保持为 1(合并后是一个元件,数量不变)
- // · 其他列(单位/系数/价格):取第一行
- // · 删除被合并的其他行,重新编号,保存刷新
- // ============================================================
- /// 按框Handle集合选中元件表中的行(多选,滚动到第一行)。
- private void SelectYuanjianRowsByFrameHandles(List frameHandles)
- {
- var dgv = this.advancedDataGridView5;
- if (dgv == null || frameHandles == null || frameHandles.Count == 0) return;
- try
- {
- dgv.MultiSelect = true;
- if (dgv.SelectionMode != DataGridViewSelectionMode.RowHeaderSelect &&
- dgv.SelectionMode != DataGridViewSelectionMode.FullRowSelect)
- {
- dgv.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
- }
- dgv.ClearSelection();
- DataGridViewRow first = null;
- foreach (DataGridViewRow row in dgv.Rows)
- {
- var drv = row.DataBoundItem as DataRowView;
- if (drv == null || drv.Row == null) continue;
- if (!drv.Row.Table.Columns.Contains("框Handle")) continue;
- object v = drv.Row["框Handle"];
- string h = v != null && v != DBNull.Value ? v.ToString().Trim() : "";
- if (!string.IsNullOrWhiteSpace(h) && frameHandles.Contains(h))
- {
- row.Selected = true;
- if (first == null) first = row;
- }
- }
- if (first != null && first.DataGridView != null)
- first.DataGridView.FirstDisplayedScrollingRowIndex = Math.Max(0, first.Index);
- }
- catch (Exception ex) { Log("[SelectYuanjianRows] " + ex.Message); }
- }
-
- /// 网页转发的 F1:转到统一入口(焦点在网页时 WinForms 收不到按键)。
- private void OnF1FromBridge()
- {
- try { RunF1Merge(); }
- catch (Exception ex) { Log("[F1桥接] " + ex.Message); }
- }
-
- /// 网页转发的 F2:三个一组配对合并。
- private void OnF2FromBridge()
- {
- try { MergeYuanjianByGroup(3); }
- catch (Exception ex) { Log("[F2桥接] " + ex.Message); }
- }
-
- /// 网页转发的 F3:四个一组配对合并。
- private void OnF3FromBridge()
- {
- try { MergeYuanjianByGroup(4); }
- catch (Exception ex) { Log("[F3桥接] " + ex.Message); }
- }
-
- ///
- /// F1:合并元件表中相邻的两个元件(按序号顺序)。
- /// · 选中 ≥2 行 → 合并前两行
- /// · 选中 1 行 → 与它的下一行合并
- /// · 未选中 → 合并第 1、2 行
- /// 合并时网页 CAD 里的蒙版同步合并(保留行蒙版扩大到并集)。
- ///
- private void MergeAdjacentYuanjianByF1()
- {
- MergeYuanjianByGroup(2);
- }
-
- /// 按 groupSize 分组合并选中元件(F1=两两,F2=三个一组)。
- private void MergeYuanjianByGroup(int groupSize)
- {
- var dgv = this.advancedDataGridView5;
- if (dgv == null) return;
- var rows = GetAllSelectedRows(dgv);
- if (rows == null || rows.Count < groupSize)
- {
- MessageBox.Show(this, "请先选中至少 " + groupSize + " 行元件(扒元件后会自动全选)。", "合并元件",
- MessageBoxButtons.OK, MessageBoxIcon.Information);
- return;
- }
-
- // ★ F1 = 两两配对批量合并(1+2、3+4、5+6...),一次处理完所有选中行;
- // 只想合并单独一对时,只选中那一对两行即可。
- // 合并会刷新表格使行对象失效,所以先记下配对的框Handle,再用 Handle 逐对定位。
- var orderedHandles = new List();
- foreach (var r in rows)
- {
- orderedHandles.Add(GetFrameHandleOfRow(r));
- }
- int groups = orderedHandles.Count / groupSize;
- int merged = 0;
- for (int i = 0; i < groups; i++)
- {
- var groupRows = new List();
- var groupHandles = new List();
- for (int k = 0; k < groupSize; k++)
- {
- string h = orderedHandles[i * groupSize + k];
- if (string.IsNullOrWhiteSpace(h)) { groupRows = null; break; }
- var rowK = FindRowByFrameHandle(dgv, h);
- if (rowK == null) { groupRows = null; break; }
- groupRows.Add(rowK);
- groupHandles.Add(h);
- }
- if (groupRows == null) continue;
- // 组内若含重复行(同句柄)跳过
- if (new HashSet(groupHandles).Count != groupSize) continue;
- MergeYuanjianRows(groupRows);
- merged++;
- }
- Log("[F1批量] " + groupSize + " 个一组配对合并完成: " + merged + "/" + groups + " 组");
- }
-
- /// 读行的框Handle:优先 DataRow("框Handle"可能不在显示列,Cells 读不到)。
- private static string GetFrameHandleOfRow(DataGridViewRow row)
- {
- if (row == null) return "";
- var drv = row.DataBoundItem as DataRowView;
- if (drv != null && drv.Row != null && drv.Row.Table.Columns.Contains("框Handle"))
- {
- object v = drv.Row["框Handle"];
- return v == null || v == DBNull.Value ? "" : v.ToString().Trim();
- }
- return GetCellValueAsString(row, "框Handle");
- }
-
- /// 按框Handle在元件表中找行(找不到返回 null)。
- private DataGridViewRow FindRowByFrameHandle(DataGridView dgv, string frameHandle)
- {
- if (string.IsNullOrWhiteSpace(frameHandle)) return null;
- foreach (DataGridViewRow row in dgv.Rows)
- {
- if (row == null || row.IsNewRow) continue;
- string h = GetFrameHandleOfRow(row);
- if (!string.IsNullOrWhiteSpace(h) && h == frameHandle) return row;
- }
- return null;
- }
-
- /// 合并指定行(按序号排序):第一行为合并目标,其余删除;蒙版同步合并。
- private void MergeYuanjianRows(List rows)
- {
- // 按序号排序(保证合并顺序与表格顺序一致)
- rows.Sort((a, b) =>
- {
- int ia = 0, ib = 0;
- int.TryParse(GetCellValueAsString(a, "序号"), out ia);
- int.TryParse(GetCellValueAsString(b, "序号"), out ib);
- return ia.CompareTo(ib);
- });
-
- // 收集要合并的内容(直接拼接,不加任何符号)
- var names = new List();
- var specs = new List();
- foreach (var r in rows)
- {
- string nm = GetCellValueAsString(r, "元件名称");
- if (!string.IsNullOrWhiteSpace(nm) && !names.Contains(nm)) names.Add(nm);
- string sp = GetCellValueAsString(r, "规格");
- if (!string.IsNullOrWhiteSpace(sp) && !specs.Contains(sp)) specs.Add(sp);
- }
-
- string rememberTuhao = _currentTuhao;
- string rememberXianghao = _currentXianghao;
- string keepHandle = GetFrameHandleOfRow(rows[0]);
- var absorbedHandles = new List();
- for (int i = 1; i < rows.Count; i++)
- {
- string h = GetFrameHandleOfRow(rows[i]);
- if (!string.IsNullOrWhiteSpace(h)) absorbedHandles.Add(h);
- }
-
- try
- {
- _isReloading = true;
- SaveAllQuoteTablesIfDirty(false);
-
- if (_yuanjianTable == null || _yuanjianTable.Rows.Count == 0)
- {
- MessageBox.Show(this, "元件表为空,无法合并。",
- "合并元件", MessageBoxButtons.OK, MessageBoxIcon.Warning);
- return;
- }
-
- // 取出选中行对应的 DataRow
- var dataRows = new List();
- foreach (var dgvRow in rows)
- {
- var drv = dgvRow.DataBoundItem as DataRowView;
- if (drv != null && drv.Row != null) dataRows.Add(drv.Row);
- }
- if (dataRows.Count < 2)
- {
- MessageBox.Show(this, "无法获取选中行的数据,请重试。",
- "合并元件", MessageBoxButtons.OK, MessageBoxIcon.Warning);
- return;
- }
-
- // 第一行作为合并目标,更新名称/规格(直接拼接,不加任何符号)
- // 数量保持为 1(合并后是一个元件)
- DataRow target = dataRows[0];
- if (_yuanjianTable.Columns.Contains("元件名称"))
- target["元件名称"] = string.Join("", names);
- if (_yuanjianTable.Columns.Contains("规格"))
- target["规格"] = string.Join("", specs);
- if (_yuanjianTable.Columns.Contains("数量"))
- target["数量"] = "1";
-
- // 删除其他被合并的行
- for (int i = 1; i < dataRows.Count; i++)
- {
- dataRows[i].Delete();
- }
-
- // 保存到数据库
- string realTbl = GetYuanjianTableByIndex(_currentProjectId, _currentTuhao, _currentXianghao);
- if (!string.IsNullOrEmpty(realTbl))
- {
- SaveTableToDatabase(_yuanjianTable, _currentProjectId,
- "\"" + realTbl + "\"", null, null, true);
- _yuanjianTable.AcceptChanges();
- RenumberTable(_currentProjectId, "\"" + realTbl + "\"");
- }
-
- // ★ 网页 CAD 蒙版同步合并:保留行蒙版扩大到并集,被合并行蒙版移除
- if (!string.IsNullOrWhiteSpace(keepHandle) && absorbedHandles.Count > 0)
- {
- cadbt.CadBridge.MergeMasks(keepHandle, absorbedHandles);
- Log("[MergeYuanjianRows] 蒙版合并: 保留=" + keepHandle);
- }
-
- // 刷新缓存与表格
- string cacheKey = _currentTuhao + "\n" + _currentXianghao;
- _yuanjianCache.Remove(cacheKey);
- ReloadYuanjianByXianghao(_currentProjectId, _currentTuhao, _currentXianghao);
- RecalcAllAfterReload();
- }
- catch (Exception ex)
- {
- MessageBox.Show(this, "合并元件失败:\n" + ex.Message,
- "合并元件", MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- finally
- {
- _currentTuhao = rememberTuhao;
- _currentXianghao = rememberXianghao;
- _isReloading = false;
- // ★ 合并后的行保持选中(连续按 F1 可继续与下一行合并):
- // 延迟到刷新事件链走完再选,否则会被清掉
- if (!string.IsNullOrWhiteSpace(keepHandle))
- {
- var kh = keepHandle;
- BeginInvoke((Action)(() =>
- {
- BeginInvoke((Action)(() =>
- {
- SelectYuanjianRowsByFrameHandles(new List { kh });
- }));
- }));
- }
- }
- }
-
- private void MenuYuanjian_Merge_Click(object sender, EventArgs e)
- {
- if (string.IsNullOrWhiteSpace(_currentProjectId) ||
- string.IsNullOrWhiteSpace(_currentTuhao) ||
- string.IsNullOrWhiteSpace(_currentXianghao))
- {
- MessageBox.Show(this, "请先选择箱号,再合并元件。",
- "合并元件", MessageBoxButtons.OK, MessageBoxIcon.Information);
- return;
- }
- var rows = GetAllSelectedRows(this.advancedDataGridView5);
- if (rows == null || rows.Count < 2)
- {
- MessageBox.Show(this, "请先选择至少两行要合并的元件(按住 Ctrl/Shift 多选)。",
- "合并元件", MessageBoxButtons.OK, MessageBoxIcon.Information);
- return;
- }
- // 按序号排序(保证合并顺序与表格顺序一致)
- rows.Sort((a, b) =>
- {
- int ia = 0, ib = 0;
- int.TryParse(GetCellValueAsString(a, "序号"), out ia);
- int.TryParse(GetCellValueAsString(b, "序号"), out ib);
- return ia.CompareTo(ib);
- });
-
- // 收集要合并的内容(直接拼接,不加任何符号)
- var names = new List();
- var specs = new List();
- foreach (var r in rows)
- {
- string nm = GetCellValueAsString(r, "元件名称");
- if (!string.IsNullOrWhiteSpace(nm) && !names.Contains(nm)) names.Add(nm);
- string sp = GetCellValueAsString(r, "规格");
- if (!string.IsNullOrWhiteSpace(sp) && !specs.Contains(sp)) specs.Add(sp);
- }
-
- string rememberTuhao = _currentTuhao;
- string rememberXianghao = _currentXianghao;
- try
- {
- _isReloading = true;
- SaveAllQuoteTablesIfDirty(false);
-
- if (_yuanjianTable == null || _yuanjianTable.Rows.Count == 0)
- {
- MessageBox.Show(this, "元件表为空,无法合并。",
- "合并元件", MessageBoxButtons.OK, MessageBoxIcon.Warning);
- return;
- }
-
- // 取出选中行对应的 DataRow
- var dataRows = new List();
- foreach (var dgvRow in rows)
- {
- var drv = dgvRow.DataBoundItem as DataRowView;
- if (drv != null && drv.Row != null) dataRows.Add(drv.Row);
- }
- if (dataRows.Count < 2)
- {
- MessageBox.Show(this, "无法获取选中行的数据,请重试。",
- "合并元件", MessageBoxButtons.OK, MessageBoxIcon.Warning);
- return;
- }
-
- // 第一行作为合并目标,更新名称/规格(直接拼接,不加符号)
- // 数量保持为 1(合并后是一个元件)
- DataRow target = dataRows[0];
- if (_yuanjianTable.Columns.Contains("元件名称"))
- target["元件名称"] = string.Join("", names);
- if (_yuanjianTable.Columns.Contains("规格"))
- target["规格"] = string.Join("", specs);
- if (_yuanjianTable.Columns.Contains("数量"))
- target["数量"] = "1";
-
- // ★ 收集被合并行(第2行起)的框Handle,合并后删除这些框
- var mergedFrameHandles = new List();
- if (_yuanjianTable.Columns.Contains("框Handle"))
- {
- for (int i = 1; i < dataRows.Count; i++)
- {
- object v = dataRows[i]["框Handle"];
- if (v != null && v != DBNull.Value)
- {
- string h = v.ToString().Trim();
- if (!string.IsNullOrWhiteSpace(h)) mergedFrameHandles.Add(h);
- }
- }
- }
-
- // 删除其他被合并的行
- for (int i = 1; i < dataRows.Count; i++)
- {
- dataRows[i].Delete();
- }
-
- // 保存到数据库
- string realTbl = GetYuanjianTableByIndex(_currentProjectId, _currentTuhao, _currentXianghao);
- if (!string.IsNullOrEmpty(realTbl))
- {
- SaveTableToDatabase(_yuanjianTable, _currentProjectId,
- "\"" + realTbl + "\"", null, null, true);
- _yuanjianTable.AcceptChanges();
- RenumberTable(_currentProjectId, "\"" + realTbl + "\"");
- }
-
- // ★ 删除被合并行的框实体
- foreach (string h in mergedFrameHandles) DeleteFrameByHandle(h);
- // ★ 保存DWG,确保删框操作持久化
- SaveCurrentDwg();
-
- // 刷新缓存与表格
- string cacheKey = _currentTuhao + "\n" + _currentXianghao;
- _yuanjianCache.Remove(cacheKey);
- ReloadYuanjianByXianghao(_currentProjectId, _currentTuhao, _currentXianghao);
- RecalcAllAfterReload();
- }
- catch (Exception ex)
- {
- MessageBox.Show(this, "合并元件失败:\n" + ex.Message,
- "合并元件", MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- finally
- {
- _currentTuhao = rememberTuhao;
- _currentXianghao = rememberXianghao;
- SelectRowByValue(this.advancedDataGridView9, "图号", rememberTuhao);
- SelectRowByValue(this.advancedDataGridView4, "箱号", rememberXianghao);
- _isReloading = false;
- }
- }
-
- // ============================================================
- // 工具栏:新建项目 / 删除项目 / 导出数据
- // ============================================================
-
- private void toolStripButton5_Click(object sender, EventArgs e)
- {
- // 用自定义对话框收集项目信息字段(无主项目的"新建项目"窗体可用)
- var fields = ShowNewProjectDialog();
- if (fields == null) return;
- try
- {
- int affected = InsertProjectToDatabase(fields);
- if (affected <= 0)
- {
- MessageBox.Show(this, "未写入任何字段,请检查输入。",
- "新建项目", MessageBoxButtons.OK, MessageBoxIcon.Information);
- return;
- }
- ReloadProjectsFromDatabase();
- ApplyPriceFormat(this.advancedDataGridView6, _项目小数位文本);
- }
- catch (Exception ex)
- {
- MessageBox.Show(this, "保存项目失败:\n" + ex.Message,
- "新建项目", MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- }
-
- /// 弹出新建项目窗口,收集项目信息 + 价格格式化配置。
- private Dictionary ShowNewProjectDialog()
- {
- string dbPath = GetDbFullPath(ProjectsDbPath);
- using (var dlg = new 新建项目(dbPath, ProjectsTableName))
- {
- if (dlg.ShowDialog(this) != DialogResult.OK) return null;
- return dlg.GetInputValues();
- }
- }
-
- private void toolStripButton6_Click(object sender, EventArgs e)
- {
- DataGridViewRow row = GetFirstSelectedProjectRow();
- if (row == null)
- {
- MessageBox.Show(this, "请先在项目表格中选择要删除的项目。",
- "删除项目", MessageBoxButtons.OK, MessageBoxIcon.Information);
- return;
- }
- string projectId = GetCellValueAsString(row, "项目编号");
- if (string.IsNullOrWhiteSpace(projectId))
- {
- MessageBox.Show(this, "选中行没有“项目编号”,无法定位要删除的数据库记录。",
- "删除项目", MessageBoxButtons.OK, MessageBoxIcon.Warning);
- return;
- }
- DialogResult dr = MessageBox.Show(this,
- "确定要删除项目编号为 “" + projectId + "” 的项目吗?\n" +
- "该项目下的所有图号/箱号/元件数据也会一并删除!\n此操作不可恢复。",
- "删除项目", MessageBoxButtons.YesNo, MessageBoxIcon.Question,
- MessageBoxDefaultButton.Button2);
- if (dr != DialogResult.Yes) return;
- try
- {
- int affected = DeleteProjectFromDatabase(projectId);
- CascadeDeleteByProject(projectId);
- _currentProjectId = "";
- _currentTuhao = "";
- _currentXianghao = "";
- _xianghaoCache.Clear();
- _yuanjianCache.Clear();
- _tuhaoTable = null;
- ReloadProjectsFromDatabase();
- ReloadTuhaoByProject("");
- }
- catch (Exception ex)
- {
- MessageBox.Show(this, "删除项目失败:\n" + ex.Message,
- "删除项目", MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- }
-
- // ---------- 项目表查找(button28)----------
-
- private void button28_Click(object sender, EventArgs e)
- {
- string field = this.comboBox2.Text == null ? "" : this.comboBox2.Text.Trim();
- string colName = MapSearchFieldToColumn(field);
- if (string.IsNullOrEmpty(colName))
- {
- MessageBox.Show(this,
- "请先在搜索条件下拉框中选择有效的搜索字段(项目名称 / 项目编号 / 客户名称)。",
- "查找", MessageBoxButtons.OK, MessageBoxIcon.Information);
- return;
- }
- string keyword = this.textBox1.Text == null ? "" : this.textBox1.Text.Trim();
- DataTable table = this.advancedDataGridView6.DataSource as DataTable;
- if (table == null)
- {
- MessageBox.Show(this, "项目表暂无数据,无法搜索。", "查找",
- MessageBoxButtons.OK, MessageBoxIcon.Information);
- return;
- }
- if (keyword.Length == 0)
- {
- if (table.DefaultView.RowFilter.Length > 0) table.DefaultView.RowFilter = "";
- return;
- }
- string escaped = EscapeLikeValue(keyword);
- try { table.DefaultView.RowFilter = "[" + colName + "] LIKE '%" + escaped + "%'"; }
- catch (System.Data.SyntaxErrorException ex)
- {
- MessageBox.Show(this, "搜索条件解析失败,请检查输入的关键词。\n详情:" + ex.Message,
- "查找", MessageBoxButtons.OK, MessageBoxIcon.Warning);
- return;
- }
- if (table.DefaultView.Count == 0)
- {
- MessageBox.Show(this, "没有找到 " + field + " 包含 “" + keyword + "” 的项目。",
- "查找", MessageBoxButtons.OK, MessageBoxIcon.Information);
- }
- }
-
- private static string MapSearchFieldToColumn(string field)
- {
- if (string.IsNullOrEmpty(field)) return "";
- string f = field.Replace(" ", "").Trim();
- if (f == "项目名称" || f == "名称") return "项目名称";
- if (f == "项目编号" || f == "编号") return "项目编号";
- if (f == "客户名称" || f == "客户") return "客户名称";
- return "";
- }
-
- private static string EscapeLikeValue(string value)
- {
- if (string.IsNullOrEmpty(value)) return "";
- var sb = new System.Text.StringBuilder(value.Length * 2);
- foreach (char c in value)
- {
- if (c == '\'') sb.Append("''");
- else if (c == '%' || c == '_' || c == '[' || c == ']') sb.Append('[').Append(c).Append(']');
- else sb.Append(c);
- }
- return sb.ToString();
- }
-
- // ---------- 导出数据(toolStripButton1)----------
-
- private void toolStripButton1_Click(object sender, EventArgs e)
- {
- string pid = "";
- try
- {
- var projects = ReadAllProjectsFromDatabase();
- if (projects == null || projects.Count == 0)
- {
- MessageBox.Show(this, "项目列表为空,无项目可导出。",
- "导出项目", MessageBoxButtons.OK, MessageBoxIcon.Information);
- return;
- }
- if (projects.Count == 1)
- {
- pid = projects[0].ContainsKey("项目编号") ? (projects[0]["项目编号"] ?? "").ToString() : "";
- }
- else
- {
- pid = PickProjectDialog(projects);
- if (string.IsNullOrWhiteSpace(pid)) return;
- }
- if (string.IsNullOrWhiteSpace(pid))
- {
- MessageBox.Show(this, "未能确定要导出的项目编号。",
- "导出项目", MessageBoxButtons.OK, MessageBoxIcon.Warning);
- return;
- }
-
- // 先保存当前项目的所有改动
- SaveAllToDatabaseSilent();
-
- string dbPath = GetQuoteDbPath(pid);
- if (!File.Exists(dbPath))
- {
- MessageBox.Show(this, "项目数据库文件不存在:\n" + dbPath,
- "导出项目", MessageBoxButtons.OK, MessageBoxIcon.Warning);
- return;
- }
- var meta = ReadProjectMetaData(pid);
- if (meta == null)
- {
- MessageBox.Show(this, "项目元数据读取失败,项目编号:" + pid,
- "导出项目", MessageBoxButtons.OK, MessageBoxIcon.Warning);
- return;
- }
- string projName = meta.ContainsKey("项目名称") ? (meta["项目名称"] ?? "").ToString() : "";
- string safeName = MakeSafeFileName(projName + "_" + pid);
- string defaultFileName = safeName + "_" + DateTime.Now.ToString("yyyyMMdd") + ".zip";
-
- string initialDir = "";
- try
- {
- string desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
- if (!string.IsNullOrEmpty(desktop) && Directory.Exists(desktop)) initialDir = desktop;
- }
- catch { }
- if (string.IsNullOrEmpty(initialDir))
- {
- try
- {
- string docs = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
- if (!string.IsNullOrEmpty(docs) && Directory.Exists(docs)) initialDir = docs;
- }
- catch { }
- }
-
- // ★ 打包到临时 zip(不弹保存对话框,直接联动主窗口)
- string tempZip = Path.Combine(Path.GetTempPath(), "cadcj_导出_" + Guid.NewGuid().ToString("N") + ".zip");
- string tempDir = Path.Combine(Path.GetTempPath(), "cadcj_导出_" + Guid.NewGuid().ToString("N"));
- Directory.CreateDirectory(tempDir);
- try
- {
- // 复制 db(用 SQL ATTACH 绕开文件锁,兜底 File.Copy)
- string dstDb = Path.Combine(tempDir, "项目" + MakeSafeFileName(pid) + ".db");
- BackupSQLiteDb(dbPath, dstDb);
-
- // 写 meta.json
- var sb = new System.Text.StringBuilder();
- sb.Append("{\n \"项目编号\": \"");
- sb.Append(EscapeJsonString(pid));
- sb.Append("\",\n \"字段\": {");
- bool firstKv = true;
- foreach (var kv in meta)
- {
- if (firstKv) firstKv = false; else sb.Append(",");
- sb.Append("\n \"");
- sb.Append(EscapeJsonString(kv.Key));
- sb.Append("\": \"");
- sb.Append(EscapeJsonString((kv.Value ?? "").ToString()));
- sb.Append("\"");
- }
- sb.Append("\n }\n}");
- File.WriteAllText(Path.Combine(tempDir, "meta.json"), sb.ToString(), new System.Text.UTF8Encoding(false));
-
- // 打包 zip
- if (File.Exists(tempZip)) File.Delete(tempZip);
- System.IO.Compression.ZipFile.CreateFromDirectory(tempDir, tempZip);
-
- // ★ 查找主窗口 exe(cadcj 目录的上级目录)
- string mainExePath = null;
- try
- {
- string pluginDir = Path.GetDirectoryName(
- new System.Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase).LocalPath);
- string parentDir = Path.GetFullPath(Path.Combine(pluginDir, ".."));
- string candidate = Path.Combine(parentDir, "成套报价软件.exe");
- if (File.Exists(candidate)) mainExePath = candidate;
- }
- catch { }
-
- if (!string.IsNullOrEmpty(mainExePath))
- {
- // ★ 启动主窗口并传递 zip 路径,主窗口自动导入并打开项目
- var psi = new System.Diagnostics.ProcessStartInfo
- {
- FileName = mainExePath,
- Arguments = "\"" + tempZip + "\"",
- UseShellExecute = true,
- };
- System.Diagnostics.Process.Start(psi);
- MessageBox.Show(this,
- "已发送到主窗口!\n\n项目:" + projName + " (" + pid + ")\n主程序已打开该项目(若主程序未开会自动启动)。",
- "导出项目", MessageBoxButtons.OK, MessageBoxIcon.Information);
- }
- else
- {
- // ★ 找不到主窗口 exe,退回到保存对话框模式
- using (var sfd = new SaveFileDialog
- {
- Title = "导出项目",
- Filter = "项目包 (*.zip)|*.zip",
- FileName = defaultFileName,
- RestoreDirectory = true,
- })
- {
- if (!string.IsNullOrEmpty(initialDir)) sfd.InitialDirectory = initialDir;
- if (sfd.ShowDialog(this) != DialogResult.OK) return;
- string zipPath = sfd.FileName;
- File.Copy(tempZip, zipPath, true);
- MessageBox.Show(this,
- "导出成功!\n\n项目:" + projName + " (" + pid + ")\n文件:" + zipPath +
- "\n\n(未找到主窗口程序,已保存为zip文件,可手动导入)",
- "导出项目", MessageBoxButtons.OK, MessageBoxIcon.Information);
- }
- }
- }
- finally
- {
- try { Directory.Delete(tempDir, true); } catch { }
- // 临时 zip 不立即删除(主窗口可能正在读取)
- }
- }
- catch (Exception ex)
- {
- MessageBox.Show(this, "导出失败:\n" + ex.Message,
- "导出项目", MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- }
-
- /// 用 SQL ATTACH 复制 SQLite 库,兜底 File.Copy。
- private void BackupSQLiteDb(string srcDbPath, string dstDbPath)
- {
- try { if (File.Exists(dstDbPath)) File.Delete(dstDbPath); } catch { }
- Exception sqlErr = null;
- try
- {
- using (var srcConn = new System.Data.SQLite.SQLiteConnection(
- "Data Source=" + srcDbPath + ";Version=3;Pooling=False;ReadOnly=True;"))
- {
- srcConn.Open();
- using (var att = new System.Data.SQLite.SQLiteCommand("ATTACH DATABASE @path AS dst;", srcConn))
- {
- att.Parameters.AddWithValue("@path", dstDbPath);
- att.ExecuteNonQuery();
- }
- string selAll = "SELECT name, sql FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%';";
- var tables = new List>();
- using (var sel = new System.Data.SQLite.SQLiteCommand(selAll, srcConn))
- using (var rd = sel.ExecuteReader())
- {
- while (rd.Read())
- {
- string tn = rd.IsDBNull(0) ? "" : rd.GetString(0);
- string sql = rd.IsDBNull(1) ? "" : rd.GetString(1);
- if (!string.IsNullOrEmpty(tn)) tables.Add(new KeyValuePair(tn, sql));
- }
- }
- foreach (var kv in tables)
- {
- string tn = kv.Key;
- string sql = kv.Value;
- if (!string.IsNullOrEmpty(sql))
- {
- string dstSql = sql.Replace("CREATE TABLE " + tn, "CREATE TABLE dst." + tn);
- using (var c = new System.Data.SQLite.SQLiteCommand(dstSql, srcConn)) c.ExecuteNonQuery();
- }
- using (var c = new System.Data.SQLite.SQLiteCommand(
- "INSERT INTO dst.\"" + tn + "\" SELECT * FROM main.\"" + tn + "\";", srcConn))
- c.ExecuteNonQuery();
- }
- using (var det = new System.Data.SQLite.SQLiteCommand("DETACH DATABASE dst;", srcConn))
- det.ExecuteNonQuery();
- return;
- }
- }
- catch (Exception ex) { sqlErr = ex; }
- // 兜底:File.Copy
- try { System.Data.SQLite.SQLiteConnection.ClearAllPools(); } catch { }
- try { if (File.Exists(dstDbPath)) File.Delete(dstDbPath); } catch { }
- File.Copy(srcDbPath, dstDbPath, true);
- }
-
- /// 弹出一个简单对话框,让用户从项目列表中选一个项目,返回项目编号。
- private string PickProjectDialog(List> projects)
- {
- try
- {
- using (var dlg = new Form
- {
- Text = "选择要导出的项目",
- StartPosition = FormStartPosition.CenterParent,
- FormBorderStyle = FormBorderStyle.FixedDialog,
- MaximizeBox = false,
- MinimizeBox = false,
- ClientSize = new Size(520, 360),
- })
- {
- var lbl = new Label
- {
- Text = "请选择要导出的项目:",
- Location = new Point(12, 12),
- Size = new Size(496, 23),
- TextAlign = ContentAlignment.MiddleLeft,
- };
- dlg.Controls.Add(lbl);
- var lv = new ListView
- {
- Location = new Point(12, 40),
- Size = new Size(496, 260),
- View = View.Details,
- FullRowSelect = true,
- MultiSelect = false,
- HideSelection = false,
- };
- lv.Columns.Add("项目编号", 100);
- lv.Columns.Add("项目名称", 160);
- lv.Columns.Add("客户名称", 130);
- lv.Columns.Add("项目日期", 90);
- foreach (var p in projects)
- {
- string bh = p.ContainsKey("项目编号") ? (p["项目编号"] ?? "").ToString() : "";
- string mc = p.ContainsKey("项目名称") ? (p["项目名称"] ?? "").ToString() : "";
- string kh = p.ContainsKey("客户名称") ? (p["客户名称"] ?? "").ToString() : "";
- string rq = p.ContainsKey("项目日期") ? (p["项目日期"] ?? "").ToString() : "";
- var item = new ListViewItem(bh);
- item.SubItems.Add(mc);
- item.SubItems.Add(kh);
- item.SubItems.Add(rq);
- lv.Items.Add(item);
- }
- if (lv.Items.Count > 0) lv.Items[0].Selected = true;
- dlg.Controls.Add(lv);
- var btnOk = new Button
- {
- Text = "导出选中项",
- DialogResult = DialogResult.OK,
- Location = new Point(330, 310),
- Size = new Size(85, 28),
- };
- dlg.Controls.Add(btnOk);
- var btnCancel = new Button
- {
- Text = "取消",
- DialogResult = DialogResult.Cancel,
- Location = new Point(425, 310),
- Size = new Size(75, 28),
- };
- dlg.Controls.Add(btnCancel);
- dlg.AcceptButton = btnOk;
- dlg.CancelButton = btnCancel;
- if (dlg.ShowDialog(this) == DialogResult.OK && lv.SelectedItems.Count > 0)
- return lv.SelectedItems[0].Text;
- return "";
- }
- }
- catch { return ""; }
- }
-
- // ============================================================
- // 窗体关闭:回写当前项目的所有改动
- // ============================================================
-
- private void Form3_Disposed(object sender, EventArgs e)
- {
- try { SaveAllToDatabaseSilent(); }
- catch { }
-
- // ★ 取消 CadBridge 事件订阅,避免事件泄漏
- try
- {
- cadbt.CadBridge.EntityErased -= Database_ObjectErased;
- cadbt.CadBridge.PaPicked -= OnPaTextsPicked;
- cadbt.CadBridge.F1Requested -= OnF1FromBridge;
- cadbt.CadBridge.F2Requested -= OnF2FromBridge;
- cadbt.CadBridge.F3Requested -= OnF3FromBridge;
- }
- catch { }
- }
- }
-}
diff --git a/cadbt/cadbt/Plugin/Form3.ui.cs b/cadbt/cadbt/Plugin/Form3.ui.cs
deleted file mode 100644
index f2db1ef..0000000
--- a/cadbt/cadbt/Plugin/Form3.ui.cs
+++ /dev/null
@@ -1,1404 +0,0 @@
-namespace MyApp
-{
- public partial class Form3 : System.Windows.Forms.Form
- {
- /// 必需的设计器变量。
- private System.ComponentModel.IContainer components = null;
-
- /// 清理正在使用的资源。
- protected override void Dispose(bool disposing)
- {
- if (disposing && (components != null))
- {
- components.Dispose();
- }
- base.Dispose(disposing);
- }
-
- #region Windows 窗体设计器生成的代码
-
- private void InitializeComponent()
- {
- this.components = new System.ComponentModel.Container();
-
- this.tabControl2 = new System.Windows.Forms.TabControl();
- this.tabPage3 = new System.Windows.Forms.TabPage();
- this.advancedDataGridView6 = new Zuby.ADGV.AdvancedDataGridView();
- ((System.ComponentModel.ISupportInitialize)(this.advancedDataGridView6)).BeginInit();
- this.panel1 = new System.Windows.Forms.Panel();
- this.button28 = new System.Windows.Forms.Button();
- this.textBox1 = new System.Windows.Forms.TextBox();
- this.comboBox2 = new System.Windows.Forms.ComboBox();
- this.tabPage4 = new System.Windows.Forms.TabPage();
- this.splitContainer2 = new System.Windows.Forms.SplitContainer();
- ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).BeginInit();
- this.advancedDataGridView9 = new Zuby.ADGV.AdvancedDataGridView();
- ((System.ComponentModel.ISupportInitialize)(this.advancedDataGridView9)).BeginInit();
- this.splitContainer3 = new System.Windows.Forms.SplitContainer();
- ((System.ComponentModel.ISupportInitialize)(this.splitContainer3)).BeginInit();
- this.advancedDataGridView4 = new Zuby.ADGV.AdvancedDataGridView();
- ((System.ComponentModel.ISupportInitialize)(this.advancedDataGridView4)).BeginInit();
- this.advancedDataGridView5 = new Zuby.ADGV.AdvancedDataGridView();
- ((System.ComponentModel.ISupportInitialize)(this.advancedDataGridView5)).BeginInit();
- this.toolStrip1 = new System.Windows.Forms.ToolStrip();
- this.toolStripButton1 = new System.Windows.Forms.ToolStripButton();
- this.toolStripButton5 = new System.Windows.Forms.ToolStripButton();
- this.toolStripButton6 = new System.Windows.Forms.ToolStripButton();
- this.toolStripButton2 = new System.Windows.Forms.ToolStripButton();
- this.toolStripButton3 = new System.Windows.Forms.ToolStripButton();
- this.toolStripButton4 = new System.Windows.Forms.ToolStripButton();
- this.toolStripButton7 = new System.Windows.Forms.ToolStripButton();
- this.SuspendLayout();
- //
- // tabControl2
- //
- this.tabControl2.Dock = System.Windows.Forms.DockStyle.Fill;
- this.tabControl2.Alignment = System.Windows.Forms.TabAlignment.Top;
- this.tabControl2.Appearance = System.Windows.Forms.TabAppearance.Normal;
- this.tabControl2.DrawMode = System.Windows.Forms.TabDrawMode.Normal;
- this.tabControl2.HotTrack = false;
- this.tabControl2.ItemSize = new System.Drawing.Size(60, 21);
- this.tabControl2.Multiline = false;
- this.tabControl2.Padding = new System.Drawing.Point(6, 3);
- this.tabControl2.RightToLeftLayout = false;
- this.tabControl2.SizeMode = System.Windows.Forms.TabSizeMode.Fixed;
- this.tabControl2.ShowToolTips = false;
- this.tabControl2.Enabled = true;
- this.tabControl2.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.tabControl2.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.tabControl2.MaximumSize = new System.Drawing.Size(0, 0);
- this.tabControl2.MinimumSize = new System.Drawing.Size(0, 0);
- this.tabControl2.TabIndex = 0;
- this.tabControl2.TabStop = true;
- this.tabControl2.Name = "tabControl2";
-
- //
- // tabPage3
- //
- this.tabPage3.BackColor = System.Drawing.SystemColors.Control;
- this.tabPage3.UseVisualStyleBackColor = true;
- this.tabPage3.BorderStyle = System.Windows.Forms.BorderStyle.None;
- this.tabPage3.AutoScroll = false;
- this.tabPage3.AutoScrollMargin = new System.Drawing.Size(0, 0);
- this.tabPage3.AutoScrollMinSize = new System.Drawing.Size(0, 0);
- this.tabPage3.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Tile;
- this.tabPage3.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.tabPage3.ForeColor = System.Drawing.SystemColors.ControlText;
- this.tabPage3.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.tabPage3.Padding = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.tabPage3.Size = new System.Drawing.Size(479, 717);
- this.tabPage3.Text = "项目";
- this.tabPage3.Name = "tabPage3";
-
- //
- // advancedDataGridView6
- //
- this.advancedDataGridView6.ColumnHeadersDefaultCellStyle.BackColor = System.Drawing.SystemColors.Control;
- this.advancedDataGridView6.ColumnHeadersDefaultCellStyle.ForeColor = System.Drawing.SystemColors.WindowText;
- this.advancedDataGridView6.ColumnHeadersDefaultCellStyle.SelectionBackColor = System.Drawing.SystemColors.Highlight;
- this.advancedDataGridView6.ColumnHeadersDefaultCellStyle.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
- this.advancedDataGridView6.ColumnHeadersDefaultCellStyle.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 1);
- this.advancedDataGridView6.ColumnHeadersDefaultCellStyle.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
- this.advancedDataGridView6.ColumnHeadersDefaultCellStyle.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
- this.advancedDataGridView6.DefaultCellStyle.BackColor = System.Drawing.SystemColors.Window;
- this.advancedDataGridView6.DefaultCellStyle.ForeColor = System.Drawing.SystemColors.ControlText;
- this.advancedDataGridView6.DefaultCellStyle.SelectionBackColor = System.Drawing.SystemColors.Highlight;
- this.advancedDataGridView6.DefaultCellStyle.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
- this.advancedDataGridView6.DefaultCellStyle.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 1);
- this.advancedDataGridView6.DefaultCellStyle.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
- this.advancedDataGridView6.DefaultCellStyle.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
- this.advancedDataGridView6.RowHeadersDefaultCellStyle.BackColor = System.Drawing.SystemColors.Control;
- this.advancedDataGridView6.RowHeadersDefaultCellStyle.ForeColor = System.Drawing.SystemColors.WindowText;
- this.advancedDataGridView6.RowHeadersDefaultCellStyle.SelectionBackColor = System.Drawing.SystemColors.Highlight;
- this.advancedDataGridView6.RowHeadersDefaultCellStyle.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
- this.advancedDataGridView6.RowHeadersDefaultCellStyle.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 1);
- this.advancedDataGridView6.RowHeadersDefaultCellStyle.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
- this.advancedDataGridView6.RowHeadersDefaultCellStyle.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
- this.advancedDataGridView6.Dock = System.Windows.Forms.DockStyle.Fill;
- this.advancedDataGridView6.EnableExcelStyleSelection = true;
- this.advancedDataGridView6.EnableCellPaste = false;
- this.advancedDataGridView6.AllowUserToAddRows = false;
- this.advancedDataGridView6.AllowUserToDeleteRows = true;
- this.advancedDataGridView6.AllowUserToOrderColumns = false;
- this.advancedDataGridView6.AllowUserToResizeColumns = true;
- this.advancedDataGridView6.AllowUserToResizeRows = false;
- this.advancedDataGridView6.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.None;
- this.advancedDataGridView6.AutoSizeRowsMode = System.Windows.Forms.DataGridViewAutoSizeRowsMode.None;
- this.advancedDataGridView6.BackgroundColor = System.Drawing.Color.White;
- this.advancedDataGridView6.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
- this.advancedDataGridView6.CellBorderStyle = System.Windows.Forms.DataGridViewCellBorderStyle.Single;
- this.advancedDataGridView6.ClipboardCopyMode = System.Windows.Forms.DataGridViewClipboardCopyMode.EnableWithAutoHeaderText;
- this.advancedDataGridView6.ColumnHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Raised;
- this.advancedDataGridView6.ColumnHeadersHeight = 25;
- this.advancedDataGridView6.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.EnableResizing;
- this.advancedDataGridView6.ColumnHeadersVisible = true;
- this.advancedDataGridView6.EditMode = System.Windows.Forms.DataGridViewEditMode.EditOnKeystrokeOrF2;
- this.advancedDataGridView6.EnableHeadersVisualStyles = false;
- this.advancedDataGridView6.GridColor = System.Drawing.SystemColors.ControlDark;
- this.advancedDataGridView6.MultiSelect = true;
- this.advancedDataGridView6.ReadOnly = true;
- this.advancedDataGridView6.RowHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Raised;
- this.advancedDataGridView6.RowHeadersVisible = true;
- this.advancedDataGridView6.RowHeadersWidth = 41;
- this.advancedDataGridView6.RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.EnableResizing;
- this.advancedDataGridView6.ScrollBars = System.Windows.Forms.ScrollBars.Both;
- this.advancedDataGridView6.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.RowHeaderSelect;
- this.advancedDataGridView6.ShowCellErrors = true;
- this.advancedDataGridView6.ShowCellToolTips = true;
- this.advancedDataGridView6.ShowEditingIcon = true;
- this.advancedDataGridView6.ShowRowErrors = true;
- this.advancedDataGridView6.StandardTab = false;
- this.advancedDataGridView6.VirtualMode = false;
- this.advancedDataGridView6.Enabled = true;
- this.advancedDataGridView6.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.advancedDataGridView6.MaximumSize = new System.Drawing.Size(0, 0);
- this.advancedDataGridView6.MinimumSize = new System.Drawing.Size(0, 0);
- this.advancedDataGridView6.TabIndex = 1;
- this.advancedDataGridView6.TabStop = true;
- this.advancedDataGridView6.Name = "advancedDataGridView6";
- this.advancedDataGridView6.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView6.Columns[0].Name = "Column2";
- this.advancedDataGridView6.Columns[0].HeaderText = "项目编号";
- this.advancedDataGridView6.Columns[0].Width = 100;
- this.advancedDataGridView6.Columns[0].Visible = true;
- this.advancedDataGridView6.Columns[0].ReadOnly = true;
- this.advancedDataGridView6.Columns[0].Frozen = false;
- this.advancedDataGridView6.Columns[0].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView6.Columns[0].DataPropertyName = "项目编号";
- this.advancedDataGridView6.Columns[0].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView6.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView6.Columns[1].Name = "Column3";
- this.advancedDataGridView6.Columns[1].HeaderText = "项目名称";
- this.advancedDataGridView6.Columns[1].Width = 100;
- this.advancedDataGridView6.Columns[1].Visible = true;
- this.advancedDataGridView6.Columns[1].ReadOnly = true;
- this.advancedDataGridView6.Columns[1].Frozen = false;
- this.advancedDataGridView6.Columns[1].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView6.Columns[1].DataPropertyName = "项目名称";
- this.advancedDataGridView6.Columns[1].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView6.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView6.Columns[2].Name = "";
- this.advancedDataGridView6.Columns[2].HeaderText = "客户名称";
- this.advancedDataGridView6.Columns[2].Width = 100;
- this.advancedDataGridView6.Columns[2].Visible = true;
- this.advancedDataGridView6.Columns[2].ReadOnly = true;
- this.advancedDataGridView6.Columns[2].Frozen = false;
- this.advancedDataGridView6.Columns[2].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView6.Columns[2].DataPropertyName = "客户名称";
- this.advancedDataGridView6.Columns[2].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView6.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView6.Columns[3].Name = "";
- this.advancedDataGridView6.Columns[3].HeaderText = "客户地址";
- this.advancedDataGridView6.Columns[3].Width = 100;
- this.advancedDataGridView6.Columns[3].Visible = true;
- this.advancedDataGridView6.Columns[3].ReadOnly = true;
- this.advancedDataGridView6.Columns[3].Frozen = false;
- this.advancedDataGridView6.Columns[3].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView6.Columns[3].DataPropertyName = "客户地址";
- this.advancedDataGridView6.Columns[3].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView6.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView6.Columns[4].Name = "";
- this.advancedDataGridView6.Columns[4].HeaderText = "联系人";
- this.advancedDataGridView6.Columns[4].Width = 100;
- this.advancedDataGridView6.Columns[4].Visible = true;
- this.advancedDataGridView6.Columns[4].ReadOnly = true;
- this.advancedDataGridView6.Columns[4].Frozen = false;
- this.advancedDataGridView6.Columns[4].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView6.Columns[4].DataPropertyName = "联系人";
- this.advancedDataGridView6.Columns[4].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView6.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView6.Columns[5].Name = "";
- this.advancedDataGridView6.Columns[5].HeaderText = "联系电话";
- this.advancedDataGridView6.Columns[5].Width = 100;
- this.advancedDataGridView6.Columns[5].Visible = true;
- this.advancedDataGridView6.Columns[5].ReadOnly = true;
- this.advancedDataGridView6.Columns[5].Frozen = false;
- this.advancedDataGridView6.Columns[5].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView6.Columns[5].DataPropertyName = "联系电话";
- this.advancedDataGridView6.Columns[5].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView6.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView6.Columns[6].Name = "";
- this.advancedDataGridView6.Columns[6].HeaderText = "项目日期";
- this.advancedDataGridView6.Columns[6].Width = 100;
- this.advancedDataGridView6.Columns[6].Visible = true;
- this.advancedDataGridView6.Columns[6].ReadOnly = true;
- this.advancedDataGridView6.Columns[6].Frozen = false;
- this.advancedDataGridView6.Columns[6].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView6.Columns[6].DataPropertyName = "项目日期";
- this.advancedDataGridView6.Columns[6].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView6.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView6.Columns[7].Name = "";
- this.advancedDataGridView6.Columns[7].HeaderText = "箱柜台数";
- this.advancedDataGridView6.Columns[7].Width = 100;
- this.advancedDataGridView6.Columns[7].Visible = true;
- this.advancedDataGridView6.Columns[7].ReadOnly = true;
- this.advancedDataGridView6.Columns[7].Frozen = false;
- this.advancedDataGridView6.Columns[7].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView6.Columns[7].DataPropertyName = "箱柜台数";
- this.advancedDataGridView6.Columns[7].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView6.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView6.Columns[8].Name = "";
- this.advancedDataGridView6.Columns[8].HeaderText = "成本总价";
- this.advancedDataGridView6.Columns[8].Width = 100;
- this.advancedDataGridView6.Columns[8].Visible = true;
- this.advancedDataGridView6.Columns[8].ReadOnly = true;
- this.advancedDataGridView6.Columns[8].Frozen = false;
- this.advancedDataGridView6.Columns[8].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView6.Columns[8].DataPropertyName = "成本总价";
- this.advancedDataGridView6.Columns[8].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView6.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView6.Columns[9].Name = "";
- this.advancedDataGridView6.Columns[9].HeaderText = "报出总价";
- this.advancedDataGridView6.Columns[9].Width = 100;
- this.advancedDataGridView6.Columns[9].Visible = true;
- this.advancedDataGridView6.Columns[9].ReadOnly = true;
- this.advancedDataGridView6.Columns[9].Frozen = false;
- this.advancedDataGridView6.Columns[9].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView6.Columns[9].DataPropertyName = "报出总价";
- this.advancedDataGridView6.Columns[9].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView6.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView6.Columns[10].Name = "";
- this.advancedDataGridView6.Columns[10].HeaderText = "利润";
- this.advancedDataGridView6.Columns[10].Width = 100;
- this.advancedDataGridView6.Columns[10].Visible = true;
- this.advancedDataGridView6.Columns[10].ReadOnly = true;
- this.advancedDataGridView6.Columns[10].Frozen = false;
- this.advancedDataGridView6.Columns[10].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView6.Columns[10].DataPropertyName = "利润";
- this.advancedDataGridView6.Columns[10].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView6.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView6.Columns[11].Name = "";
- this.advancedDataGridView6.Columns[11].HeaderText = "利润率";
- this.advancedDataGridView6.Columns[11].Width = 100;
- this.advancedDataGridView6.Columns[11].Visible = true;
- this.advancedDataGridView6.Columns[11].ReadOnly = true;
- this.advancedDataGridView6.Columns[11].Frozen = false;
- this.advancedDataGridView6.Columns[11].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView6.Columns[11].DataPropertyName = "利润率";
- this.advancedDataGridView6.Columns[11].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView6.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView6.Columns[12].Name = "";
- this.advancedDataGridView6.Columns[12].HeaderText = "备注";
- this.advancedDataGridView6.Columns[12].Width = 100;
- this.advancedDataGridView6.Columns[12].Visible = true;
- this.advancedDataGridView6.Columns[12].ReadOnly = true;
- this.advancedDataGridView6.Columns[12].Frozen = false;
- this.advancedDataGridView6.Columns[12].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView6.Columns[12].DataPropertyName = "备注";
- this.advancedDataGridView6.Columns[12].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
-
- //
- // panel1
- //
- this.panel1.Dock = System.Windows.Forms.DockStyle.Top;
- this.panel1.AutoSize = false;
- this.panel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowOnly;
- this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.None;
- this.panel1.TabStop = false;
- this.panel1.AutoScroll = false;
- this.panel1.AutoScrollMargin = new System.Drawing.Size(0, 0);
- this.panel1.AutoScrollMinSize = new System.Drawing.Size(0, 0);
- this.panel1.BackColor = System.Drawing.SystemColors.Control;
- this.panel1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Tile;
- this.panel1.Enabled = true;
- this.panel1.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.panel1.ForeColor = System.Drawing.SystemColors.ControlText;
- this.panel1.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.panel1.MaximumSize = new System.Drawing.Size(0, 0);
- this.panel1.MinimumSize = new System.Drawing.Size(0, 0);
- this.panel1.TabIndex = 0;
- this.panel1.Padding = new System.Windows.Forms.Padding(0, 0, 0, 0);
- this.panel1.Size = new System.Drawing.Size(473, 28);
- this.panel1.Location = new System.Drawing.Point(3, 3);
- this.panel1.Name = "panel1";
-
- //
- // button28
- //
- this.button28.Dock = System.Windows.Forms.DockStyle.None;
- this.button28.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowOnly;
- this.button28.DialogResult = System.Windows.Forms.DialogResult.None;
- this.button28.AutoEllipsis = false;
- this.button28.AutoSize = false;
- this.button28.BackColor = System.Drawing.SystemColors.Control;
- this.button28.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
- this.button28.ImageAlign = System.Drawing.ContentAlignment.MiddleCenter;
- this.button28.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
- this.button28.TextImageRelation = System.Windows.Forms.TextImageRelation.Overlay;
- this.button28.UseMnemonic = true;
- this.button28.UseCompatibleTextRendering = false;
- this.button28.UseVisualStyleBackColor = true;
- this.button28.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Tile;
- this.button28.Enabled = true;
- this.button28.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.button28.ForeColor = System.Drawing.SystemColors.ControlText;
- this.button28.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.button28.MaximumSize = new System.Drawing.Size(0, 0);
- this.button28.MinimumSize = new System.Drawing.Size(0, 0);
- this.button28.TabIndex = 2;
- this.button28.TabStop = true;
- this.button28.Padding = new System.Windows.Forms.Padding(0, 0, 0, 0);
- this.button28.Size = new System.Drawing.Size(75, 23);
- this.button28.Location = new System.Drawing.Point(335, 2);
- this.button28.Text = "查找";
- this.button28.Name = "button28";
-
- //
- // textBox1
- //
- this.textBox1.Dock = System.Windows.Forms.DockStyle.None;
- this.textBox1.AcceptsReturn = false;
- this.textBox1.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.None;
- this.textBox1.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.None;
- this.textBox1.CharacterCasing = System.Windows.Forms.CharacterCasing.Normal;
- this.textBox1.Multiline = false;
- this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.None;
- this.textBox1.TextAlign = System.Windows.Forms.HorizontalAlignment.Left;
- this.textBox1.UseSystemPasswordChar = false;
- this.textBox1.AcceptsTab = false;
- this.textBox1.ShortcutsEnabled = true;
- this.textBox1.BackColor = System.Drawing.SystemColors.Window;
- this.textBox1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
- this.textBox1.ForeColor = System.Drawing.SystemColors.WindowText;
- this.textBox1.HideSelection = true;
- this.textBox1.MaxLength = 32767;
- this.textBox1.ReadOnly = false;
- this.textBox1.WordWrap = true;
- this.textBox1.Enabled = true;
- this.textBox1.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.textBox1.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.textBox1.MaximumSize = new System.Drawing.Size(0, 0);
- this.textBox1.MinimumSize = new System.Drawing.Size(0, 0);
- this.textBox1.TabIndex = 1;
- this.textBox1.TabStop = true;
- this.textBox1.Size = new System.Drawing.Size(210, 21);
- this.textBox1.Location = new System.Drawing.Point(119, 4);
- this.textBox1.Name = "textBox1";
-
- //
- // comboBox2
- //
- this.comboBox2.Dock = System.Windows.Forms.DockStyle.None;
- this.comboBox2.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.None;
- this.comboBox2.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.None;
- this.comboBox2.BackColor = System.Drawing.SystemColors.Window;
- this.comboBox2.DrawMode = System.Windows.Forms.DrawMode.Normal;
- this.comboBox2.DropDownWidth = 108;
- this.comboBox2.DropDownHeight = 106;
- this.comboBox2.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
- this.comboBox2.ForeColor = System.Drawing.SystemColors.WindowText;
- this.comboBox2.IntegralHeight = true;
- this.comboBox2.ItemHeight = 12;
- this.comboBox2.MaxDropDownItems = 8;
- this.comboBox2.MaximumSize = new System.Drawing.Size(0, 0);
- this.comboBox2.MinimumSize = new System.Drawing.Size(0, 0);
- this.comboBox2.MaxLength = 0;
- this.comboBox2.Sorted = false;
- this.comboBox2.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDown;
- this.comboBox2.FormattingEnabled = false;
- this.comboBox2.Enabled = true;
- this.comboBox2.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.comboBox2.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.comboBox2.TabIndex = 0;
- this.comboBox2.TabStop = true;
- this.comboBox2.Size = new System.Drawing.Size(108, 20);
- this.comboBox2.Location = new System.Drawing.Point(5, 4);
- this.comboBox2.Text = "项目名称";
- this.comboBox2.Name = "comboBox2";
- this.comboBox2.Items.Add("项目名称");
- this.comboBox2.Items.Add("项目编号");
- this.comboBox2.Items.Add("客户名称");
-
- //
- // tabPage4
- //
- this.tabPage4.BackColor = System.Drawing.SystemColors.Control;
- this.tabPage4.UseVisualStyleBackColor = true;
- this.tabPage4.BorderStyle = System.Windows.Forms.BorderStyle.None;
- this.tabPage4.AutoScroll = false;
- this.tabPage4.AutoScrollMargin = new System.Drawing.Size(0, 0);
- this.tabPage4.AutoScrollMinSize = new System.Drawing.Size(0, 0);
- this.tabPage4.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Tile;
- this.tabPage4.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.tabPage4.ForeColor = System.Drawing.SystemColors.ControlText;
- this.tabPage4.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.tabPage4.Padding = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.tabPage4.Size = new System.Drawing.Size(479, 692);
- this.tabPage4.Text = "报价";
- this.tabPage4.Name = "tabPage4";
-
- //
- // splitContainer2
- //
- this.splitContainer2.Dock = System.Windows.Forms.DockStyle.Fill;
- this.splitContainer2.BorderStyle = System.Windows.Forms.BorderStyle.None;
- this.splitContainer2.FixedPanel = System.Windows.Forms.FixedPanel.None;
- this.splitContainer2.IsSplitterFixed = false;
- this.splitContainer2.Orientation = System.Windows.Forms.Orientation.Horizontal;
- this.splitContainer2.Panel1Collapsed = false;
- this.splitContainer2.Panel2Collapsed = false;
- this.splitContainer2.Panel1MinSize = 25;
- this.splitContainer2.Panel2MinSize = 25;
- this.splitContainer2.SplitterIncrement = 1;
- this.splitContainer2.SplitterWidth = 6;
- this.splitContainer2.TabStop = true;
- this.splitContainer2.BackColor = System.Drawing.SystemColors.Control;
- this.splitContainer2.Enabled = true;
- this.splitContainer2.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.splitContainer2.ForeColor = System.Drawing.SystemColors.ControlText;
- this.splitContainer2.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.splitContainer2.MaximumSize = new System.Drawing.Size(0, 0);
- this.splitContainer2.MinimumSize = new System.Drawing.Size(0, 0);
- this.splitContainer2.TabIndex = 0;
- this.splitContainer2.Name = "splitContainer2";
-
- //
- // advancedDataGridView9
- //
- this.advancedDataGridView9.ColumnHeadersDefaultCellStyle.BackColor = System.Drawing.SystemColors.Control;
- this.advancedDataGridView9.ColumnHeadersDefaultCellStyle.ForeColor = System.Drawing.SystemColors.WindowText;
- this.advancedDataGridView9.ColumnHeadersDefaultCellStyle.SelectionBackColor = System.Drawing.SystemColors.Highlight;
- this.advancedDataGridView9.ColumnHeadersDefaultCellStyle.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
- this.advancedDataGridView9.ColumnHeadersDefaultCellStyle.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 1);
- this.advancedDataGridView9.ColumnHeadersDefaultCellStyle.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
- this.advancedDataGridView9.ColumnHeadersDefaultCellStyle.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
- this.advancedDataGridView9.DefaultCellStyle.BackColor = System.Drawing.SystemColors.Window;
- this.advancedDataGridView9.DefaultCellStyle.ForeColor = System.Drawing.SystemColors.ControlText;
- this.advancedDataGridView9.DefaultCellStyle.SelectionBackColor = System.Drawing.SystemColors.Highlight;
- this.advancedDataGridView9.DefaultCellStyle.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
- this.advancedDataGridView9.DefaultCellStyle.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 1);
- this.advancedDataGridView9.DefaultCellStyle.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
- this.advancedDataGridView9.DefaultCellStyle.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
- this.advancedDataGridView9.RowHeadersDefaultCellStyle.BackColor = System.Drawing.SystemColors.Control;
- this.advancedDataGridView9.RowHeadersDefaultCellStyle.ForeColor = System.Drawing.SystemColors.WindowText;
- this.advancedDataGridView9.RowHeadersDefaultCellStyle.SelectionBackColor = System.Drawing.SystemColors.Highlight;
- this.advancedDataGridView9.RowHeadersDefaultCellStyle.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
- this.advancedDataGridView9.RowHeadersDefaultCellStyle.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 1);
- this.advancedDataGridView9.RowHeadersDefaultCellStyle.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
- this.advancedDataGridView9.RowHeadersDefaultCellStyle.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
- this.advancedDataGridView9.Dock = System.Windows.Forms.DockStyle.Fill;
- this.advancedDataGridView9.EnableExcelStyleSelection = true;
- this.advancedDataGridView9.EnableCellPaste = true;
- this.advancedDataGridView9.AllowUserToAddRows = false;
- this.advancedDataGridView9.AllowUserToDeleteRows = true;
- this.advancedDataGridView9.AllowUserToOrderColumns = false;
- this.advancedDataGridView9.AllowUserToResizeColumns = true;
- this.advancedDataGridView9.AllowUserToResizeRows = false;
- this.advancedDataGridView9.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.None;
- this.advancedDataGridView9.AutoSizeRowsMode = System.Windows.Forms.DataGridViewAutoSizeRowsMode.None;
- this.advancedDataGridView9.BackgroundColor = System.Drawing.Color.White;
- this.advancedDataGridView9.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
- this.advancedDataGridView9.CellBorderStyle = System.Windows.Forms.DataGridViewCellBorderStyle.Single;
- this.advancedDataGridView9.ClipboardCopyMode = System.Windows.Forms.DataGridViewClipboardCopyMode.EnableWithAutoHeaderText;
- this.advancedDataGridView9.ColumnHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Raised;
- this.advancedDataGridView9.ColumnHeadersHeight = 35;
- this.advancedDataGridView9.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.EnableResizing;
- this.advancedDataGridView9.ColumnHeadersVisible = true;
- this.advancedDataGridView9.EditMode = System.Windows.Forms.DataGridViewEditMode.EditOnKeystroke;
- this.advancedDataGridView9.EnableHeadersVisualStyles = false;
- this.advancedDataGridView9.GridColor = System.Drawing.SystemColors.ControlDark;
- this.advancedDataGridView9.MultiSelect = true;
- this.advancedDataGridView9.ReadOnly = false;
- this.advancedDataGridView9.RowHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Raised;
- this.advancedDataGridView9.RowHeadersVisible = true;
- this.advancedDataGridView9.RowHeadersWidth = 41;
- this.advancedDataGridView9.RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.EnableResizing;
- this.advancedDataGridView9.ScrollBars = System.Windows.Forms.ScrollBars.Both;
- this.advancedDataGridView9.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.RowHeaderSelect;
- this.advancedDataGridView9.ShowCellErrors = true;
- this.advancedDataGridView9.ShowCellToolTips = true;
- this.advancedDataGridView9.ShowEditingIcon = true;
- this.advancedDataGridView9.ShowRowErrors = true;
- this.advancedDataGridView9.StandardTab = false;
- this.advancedDataGridView9.VirtualMode = false;
- this.advancedDataGridView9.Enabled = true;
- this.advancedDataGridView9.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.advancedDataGridView9.MaximumSize = new System.Drawing.Size(0, 0);
- this.advancedDataGridView9.MinimumSize = new System.Drawing.Size(0, 0);
- this.advancedDataGridView9.TabIndex = 0;
- this.advancedDataGridView9.TabStop = true;
- this.advancedDataGridView9.Name = "advancedDataGridView9";
- this.advancedDataGridView9.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView9.Columns[0].Name = "";
- this.advancedDataGridView9.Columns[0].HeaderText = "序号";
- this.advancedDataGridView9.Columns[0].Width = 35;
- this.advancedDataGridView9.Columns[0].Visible = true;
- this.advancedDataGridView9.Columns[0].ReadOnly = false;
- this.advancedDataGridView9.Columns[0].Frozen = true;
- this.advancedDataGridView9.Columns[0].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None;
- this.advancedDataGridView9.Columns[0].DataPropertyName = "序号";
- this.advancedDataGridView9.Columns[0].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView9.Columns[0].DefaultCellStyle.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
- this.advancedDataGridView9.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView9.Columns[1].Name = "";
- this.advancedDataGridView9.Columns[1].HeaderText = "图号";
- this.advancedDataGridView9.Columns[1].Width = 100;
- this.advancedDataGridView9.Columns[1].Visible = true;
- this.advancedDataGridView9.Columns[1].ReadOnly = false;
- this.advancedDataGridView9.Columns[1].Frozen = false;
- this.advancedDataGridView9.Columns[1].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView9.Columns[1].DataPropertyName = "图号";
- this.advancedDataGridView9.Columns[1].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView9.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView9.Columns[2].Name = "";
- this.advancedDataGridView9.Columns[2].HeaderText = "图名";
- this.advancedDataGridView9.Columns[2].Width = 100;
- this.advancedDataGridView9.Columns[2].Visible = true;
- this.advancedDataGridView9.Columns[2].ReadOnly = false;
- this.advancedDataGridView9.Columns[2].Frozen = false;
- this.advancedDataGridView9.Columns[2].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView9.Columns[2].DataPropertyName = "图名";
- this.advancedDataGridView9.Columns[2].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView9.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView9.Columns[3].Name = "";
- this.advancedDataGridView9.Columns[3].HeaderText = "台数";
- this.advancedDataGridView9.Columns[3].Width = 35;
- this.advancedDataGridView9.Columns[3].Visible = true;
- this.advancedDataGridView9.Columns[3].ReadOnly = false;
- this.advancedDataGridView9.Columns[3].Frozen = false;
- this.advancedDataGridView9.Columns[3].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView9.Columns[3].DataPropertyName = "台数";
- this.advancedDataGridView9.Columns[3].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView9.Columns[3].DefaultCellStyle.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
- this.advancedDataGridView9.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView9.Columns[4].Name = "";
- this.advancedDataGridView9.Columns[4].HeaderText = "箱柜数量";
- this.advancedDataGridView9.Columns[4].Width = 35;
- this.advancedDataGridView9.Columns[4].Visible = true;
- this.advancedDataGridView9.Columns[4].ReadOnly = false;
- this.advancedDataGridView9.Columns[4].Frozen = false;
- this.advancedDataGridView9.Columns[4].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView9.Columns[4].DataPropertyName = "箱柜数量";
- this.advancedDataGridView9.Columns[4].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView9.Columns[4].DefaultCellStyle.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
- this.advancedDataGridView9.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView9.Columns[5].Name = "";
- this.advancedDataGridView9.Columns[5].HeaderText = "单价";
- this.advancedDataGridView9.Columns[5].Width = 100;
- this.advancedDataGridView9.Columns[5].Visible = true;
- this.advancedDataGridView9.Columns[5].ReadOnly = false;
- this.advancedDataGridView9.Columns[5].Frozen = false;
- this.advancedDataGridView9.Columns[5].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView9.Columns[5].DataPropertyName = "单价";
- this.advancedDataGridView9.Columns[5].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView9.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView9.Columns[6].Name = "";
- this.advancedDataGridView9.Columns[6].HeaderText = "总价";
- this.advancedDataGridView9.Columns[6].Width = 100;
- this.advancedDataGridView9.Columns[6].Visible = true;
- this.advancedDataGridView9.Columns[6].ReadOnly = false;
- this.advancedDataGridView9.Columns[6].Frozen = false;
- this.advancedDataGridView9.Columns[6].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView9.Columns[6].DataPropertyName = "总价";
- this.advancedDataGridView9.Columns[6].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView9.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView9.Columns[7].Name = "";
- this.advancedDataGridView9.Columns[7].HeaderText = "成本总价";
- this.advancedDataGridView9.Columns[7].Width = 100;
- this.advancedDataGridView9.Columns[7].Visible = true;
- this.advancedDataGridView9.Columns[7].ReadOnly = false;
- this.advancedDataGridView9.Columns[7].Frozen = false;
- this.advancedDataGridView9.Columns[7].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView9.Columns[7].DataPropertyName = "成本总价";
- this.advancedDataGridView9.Columns[7].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView9.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView9.Columns[8].Name = "";
- this.advancedDataGridView9.Columns[8].HeaderText = "毛利";
- this.advancedDataGridView9.Columns[8].Width = 100;
- this.advancedDataGridView9.Columns[8].Visible = true;
- this.advancedDataGridView9.Columns[8].ReadOnly = false;
- this.advancedDataGridView9.Columns[8].Frozen = false;
- this.advancedDataGridView9.Columns[8].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView9.Columns[8].DataPropertyName = "毛利";
- this.advancedDataGridView9.Columns[8].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView9.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView9.Columns[9].Name = "";
- this.advancedDataGridView9.Columns[9].HeaderText = "毛利率";
- this.advancedDataGridView9.Columns[9].Width = 100;
- this.advancedDataGridView9.Columns[9].Visible = true;
- this.advancedDataGridView9.Columns[9].ReadOnly = false;
- this.advancedDataGridView9.Columns[9].Frozen = false;
- this.advancedDataGridView9.Columns[9].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView9.Columns[9].DataPropertyName = "毛利率";
- this.advancedDataGridView9.Columns[9].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
-
- //
- // splitContainer3
- //
- this.splitContainer3.Dock = System.Windows.Forms.DockStyle.Fill;
- this.splitContainer3.BorderStyle = System.Windows.Forms.BorderStyle.None;
- this.splitContainer3.FixedPanel = System.Windows.Forms.FixedPanel.None;
- this.splitContainer3.IsSplitterFixed = false;
- this.splitContainer3.Orientation = System.Windows.Forms.Orientation.Horizontal;
- this.splitContainer3.Panel1Collapsed = false;
- this.splitContainer3.Panel2Collapsed = false;
- this.splitContainer3.Panel1MinSize = 25;
- this.splitContainer3.Panel2MinSize = 25;
- this.splitContainer3.SplitterIncrement = 1;
- this.splitContainer3.SplitterWidth = 6;
- this.splitContainer3.TabStop = true;
- this.splitContainer3.BackColor = System.Drawing.SystemColors.Control;
- this.splitContainer3.Enabled = true;
- this.splitContainer3.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.splitContainer3.ForeColor = System.Drawing.SystemColors.ControlText;
- this.splitContainer3.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.splitContainer3.MaximumSize = new System.Drawing.Size(0, 0);
- this.splitContainer3.MinimumSize = new System.Drawing.Size(0, 0);
- this.splitContainer3.TabIndex = 0;
- this.splitContainer3.Name = "splitContainer3";
-
- //
- // advancedDataGridView4
- //
- this.advancedDataGridView4.ColumnHeadersDefaultCellStyle.BackColor = System.Drawing.SystemColors.Control;
- this.advancedDataGridView4.ColumnHeadersDefaultCellStyle.ForeColor = System.Drawing.SystemColors.WindowText;
- this.advancedDataGridView4.ColumnHeadersDefaultCellStyle.SelectionBackColor = System.Drawing.SystemColors.Highlight;
- this.advancedDataGridView4.ColumnHeadersDefaultCellStyle.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
- this.advancedDataGridView4.ColumnHeadersDefaultCellStyle.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 1);
- this.advancedDataGridView4.ColumnHeadersDefaultCellStyle.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
- this.advancedDataGridView4.ColumnHeadersDefaultCellStyle.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
- this.advancedDataGridView4.DefaultCellStyle.BackColor = System.Drawing.SystemColors.Window;
- this.advancedDataGridView4.DefaultCellStyle.ForeColor = System.Drawing.SystemColors.ControlText;
- this.advancedDataGridView4.DefaultCellStyle.SelectionBackColor = System.Drawing.SystemColors.Highlight;
- this.advancedDataGridView4.DefaultCellStyle.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
- this.advancedDataGridView4.DefaultCellStyle.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 1);
- this.advancedDataGridView4.DefaultCellStyle.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
- this.advancedDataGridView4.DefaultCellStyle.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
- this.advancedDataGridView4.RowHeadersDefaultCellStyle.BackColor = System.Drawing.SystemColors.Control;
- this.advancedDataGridView4.RowHeadersDefaultCellStyle.ForeColor = System.Drawing.SystemColors.WindowText;
- this.advancedDataGridView4.RowHeadersDefaultCellStyle.SelectionBackColor = System.Drawing.SystemColors.Highlight;
- this.advancedDataGridView4.RowHeadersDefaultCellStyle.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
- this.advancedDataGridView4.RowHeadersDefaultCellStyle.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 1);
- this.advancedDataGridView4.RowHeadersDefaultCellStyle.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
- this.advancedDataGridView4.RowHeadersDefaultCellStyle.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
- this.advancedDataGridView4.Dock = System.Windows.Forms.DockStyle.Fill;
- this.advancedDataGridView4.EnableExcelStyleSelection = true;
- this.advancedDataGridView4.EnableCellPaste = true;
- this.advancedDataGridView4.AllowUserToAddRows = false;
- this.advancedDataGridView4.AllowUserToDeleteRows = true;
- this.advancedDataGridView4.AllowUserToOrderColumns = false;
- this.advancedDataGridView4.AllowUserToResizeColumns = true;
- this.advancedDataGridView4.AllowUserToResizeRows = false;
- this.advancedDataGridView4.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.None;
- this.advancedDataGridView4.AutoSizeRowsMode = System.Windows.Forms.DataGridViewAutoSizeRowsMode.None;
- this.advancedDataGridView4.BackgroundColor = System.Drawing.Color.White;
- this.advancedDataGridView4.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
- this.advancedDataGridView4.CellBorderStyle = System.Windows.Forms.DataGridViewCellBorderStyle.Single;
- this.advancedDataGridView4.ClipboardCopyMode = System.Windows.Forms.DataGridViewClipboardCopyMode.EnableWithAutoHeaderText;
- this.advancedDataGridView4.ColumnHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Raised;
- this.advancedDataGridView4.ColumnHeadersHeight = 35;
- this.advancedDataGridView4.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.EnableResizing;
- this.advancedDataGridView4.ColumnHeadersVisible = true;
- this.advancedDataGridView4.EditMode = System.Windows.Forms.DataGridViewEditMode.EditOnKeystroke;
- this.advancedDataGridView4.EnableHeadersVisualStyles = false;
- this.advancedDataGridView4.GridColor = System.Drawing.SystemColors.ControlDark;
- this.advancedDataGridView4.MultiSelect = true;
- this.advancedDataGridView4.ReadOnly = false;
- this.advancedDataGridView4.RowHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Raised;
- this.advancedDataGridView4.RowHeadersVisible = true;
- this.advancedDataGridView4.RowHeadersWidth = 41;
- this.advancedDataGridView4.RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.EnableResizing;
- this.advancedDataGridView4.ScrollBars = System.Windows.Forms.ScrollBars.Both;
- this.advancedDataGridView4.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.RowHeaderSelect;
- this.advancedDataGridView4.ShowCellErrors = true;
- this.advancedDataGridView4.ShowCellToolTips = true;
- this.advancedDataGridView4.ShowEditingIcon = true;
- this.advancedDataGridView4.ShowRowErrors = true;
- this.advancedDataGridView4.StandardTab = false;
- this.advancedDataGridView4.VirtualMode = false;
- this.advancedDataGridView4.Enabled = true;
- this.advancedDataGridView4.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.advancedDataGridView4.MaximumSize = new System.Drawing.Size(0, 0);
- this.advancedDataGridView4.MinimumSize = new System.Drawing.Size(0, 0);
- this.advancedDataGridView4.TabIndex = 0;
- this.advancedDataGridView4.TabStop = true;
- this.advancedDataGridView4.Name = "advancedDataGridView4";
- this.advancedDataGridView4.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView4.Columns[0].Name = "";
- this.advancedDataGridView4.Columns[0].HeaderText = "序号";
- this.advancedDataGridView4.Columns[0].Width = 35;
- this.advancedDataGridView4.Columns[0].Visible = true;
- this.advancedDataGridView4.Columns[0].ReadOnly = false;
- this.advancedDataGridView4.Columns[0].Frozen = false;
- this.advancedDataGridView4.Columns[0].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView4.Columns[0].DataPropertyName = "序号";
- this.advancedDataGridView4.Columns[0].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView4.Columns[0].DefaultCellStyle.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
- this.advancedDataGridView4.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView4.Columns[1].Name = "";
- this.advancedDataGridView4.Columns[1].HeaderText = "箱号";
- this.advancedDataGridView4.Columns[1].Width = 150;
- this.advancedDataGridView4.Columns[1].Visible = true;
- this.advancedDataGridView4.Columns[1].ReadOnly = false;
- this.advancedDataGridView4.Columns[1].Frozen = false;
- this.advancedDataGridView4.Columns[1].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView4.Columns[1].DataPropertyName = "箱号";
- this.advancedDataGridView4.Columns[1].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView4.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView4.Columns[2].Name = "";
- this.advancedDataGridView4.Columns[2].HeaderText = "箱名";
- this.advancedDataGridView4.Columns[2].Width = 150;
- this.advancedDataGridView4.Columns[2].Visible = true;
- this.advancedDataGridView4.Columns[2].ReadOnly = false;
- this.advancedDataGridView4.Columns[2].Frozen = false;
- this.advancedDataGridView4.Columns[2].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView4.Columns[2].DataPropertyName = "箱名";
- this.advancedDataGridView4.Columns[2].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView4.Columns[2].DefaultCellStyle.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
- this.advancedDataGridView4.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView4.Columns[3].Name = "";
- this.advancedDataGridView4.Columns[3].HeaderText = "型号";
- this.advancedDataGridView4.Columns[3].Width = 150;
- this.advancedDataGridView4.Columns[3].Visible = true;
- this.advancedDataGridView4.Columns[3].ReadOnly = false;
- this.advancedDataGridView4.Columns[3].Frozen = false;
- this.advancedDataGridView4.Columns[3].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView4.Columns[3].DataPropertyName = "型号";
- this.advancedDataGridView4.Columns[3].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView4.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView4.Columns[4].Name = "";
- this.advancedDataGridView4.Columns[4].HeaderText = "规格";
- this.advancedDataGridView4.Columns[4].Width = 150;
- this.advancedDataGridView4.Columns[4].Visible = true;
- this.advancedDataGridView4.Columns[4].ReadOnly = false;
- this.advancedDataGridView4.Columns[4].Frozen = false;
- this.advancedDataGridView4.Columns[4].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView4.Columns[4].DataPropertyName = "规格";
- this.advancedDataGridView4.Columns[4].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView4.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView4.Columns[5].Name = "";
- this.advancedDataGridView4.Columns[5].HeaderText = "单位";
- this.advancedDataGridView4.Columns[5].Width = 35;
- this.advancedDataGridView4.Columns[5].Visible = true;
- this.advancedDataGridView4.Columns[5].ReadOnly = false;
- this.advancedDataGridView4.Columns[5].Frozen = false;
- this.advancedDataGridView4.Columns[5].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView4.Columns[5].DataPropertyName = "单位";
- this.advancedDataGridView4.Columns[5].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView4.Columns[5].DefaultCellStyle.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
- this.advancedDataGridView4.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView4.Columns[6].Name = "";
- this.advancedDataGridView4.Columns[6].HeaderText = "数量";
- this.advancedDataGridView4.Columns[6].Width = 45;
- this.advancedDataGridView4.Columns[6].Visible = true;
- this.advancedDataGridView4.Columns[6].ReadOnly = false;
- this.advancedDataGridView4.Columns[6].Frozen = false;
- this.advancedDataGridView4.Columns[6].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView4.Columns[6].DataPropertyName = "数量";
- this.advancedDataGridView4.Columns[6].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView4.Columns[6].DefaultCellStyle.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
- this.advancedDataGridView4.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView4.Columns[7].Name = "";
- this.advancedDataGridView4.Columns[7].HeaderText = "单台成本";
- this.advancedDataGridView4.Columns[7].Width = 100;
- this.advancedDataGridView4.Columns[7].Visible = true;
- this.advancedDataGridView4.Columns[7].ReadOnly = false;
- this.advancedDataGridView4.Columns[7].Frozen = false;
- this.advancedDataGridView4.Columns[7].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView4.Columns[7].DataPropertyName = "单台成本";
- this.advancedDataGridView4.Columns[7].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView4.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView4.Columns[8].Name = "";
- this.advancedDataGridView4.Columns[8].HeaderText = "成本价";
- this.advancedDataGridView4.Columns[8].Width = 100;
- this.advancedDataGridView4.Columns[8].Visible = true;
- this.advancedDataGridView4.Columns[8].ReadOnly = false;
- this.advancedDataGridView4.Columns[8].Frozen = false;
- this.advancedDataGridView4.Columns[8].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView4.Columns[8].DataPropertyName = "成本价";
- this.advancedDataGridView4.Columns[8].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView4.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView4.Columns[9].Name = "";
- this.advancedDataGridView4.Columns[9].HeaderText = "单台报出";
- this.advancedDataGridView4.Columns[9].Width = 100;
- this.advancedDataGridView4.Columns[9].Visible = true;
- this.advancedDataGridView4.Columns[9].ReadOnly = false;
- this.advancedDataGridView4.Columns[9].Frozen = false;
- this.advancedDataGridView4.Columns[9].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView4.Columns[9].DataPropertyName = "单台报出";
- this.advancedDataGridView4.Columns[9].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView4.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView4.Columns[10].Name = "";
- this.advancedDataGridView4.Columns[10].HeaderText = "报出价";
- this.advancedDataGridView4.Columns[10].Width = 100;
- this.advancedDataGridView4.Columns[10].Visible = true;
- this.advancedDataGridView4.Columns[10].ReadOnly = false;
- this.advancedDataGridView4.Columns[10].Frozen = false;
- this.advancedDataGridView4.Columns[10].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView4.Columns[10].DataPropertyName = "报出价";
- this.advancedDataGridView4.Columns[10].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView4.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView4.Columns[11].Name = "";
- this.advancedDataGridView4.Columns[11].HeaderText = "利润";
- this.advancedDataGridView4.Columns[11].Width = 100;
- this.advancedDataGridView4.Columns[11].Visible = true;
- this.advancedDataGridView4.Columns[11].ReadOnly = false;
- this.advancedDataGridView4.Columns[11].Frozen = false;
- this.advancedDataGridView4.Columns[11].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView4.Columns[11].DataPropertyName = "利润";
- this.advancedDataGridView4.Columns[11].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView4.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView4.Columns[12].Name = "";
- this.advancedDataGridView4.Columns[12].HeaderText = "利润率";
- this.advancedDataGridView4.Columns[12].Width = 100;
- this.advancedDataGridView4.Columns[12].Visible = true;
- this.advancedDataGridView4.Columns[12].ReadOnly = false;
- this.advancedDataGridView4.Columns[12].Frozen = false;
- this.advancedDataGridView4.Columns[12].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView4.Columns[12].DataPropertyName = "利润率";
- this.advancedDataGridView4.Columns[12].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView4.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView4.Columns[13].Name = "";
- this.advancedDataGridView4.Columns[13].HeaderText = "毛利率";
- this.advancedDataGridView4.Columns[13].Width = 100;
- this.advancedDataGridView4.Columns[13].Visible = true;
- this.advancedDataGridView4.Columns[13].ReadOnly = false;
- this.advancedDataGridView4.Columns[13].Frozen = false;
- this.advancedDataGridView4.Columns[13].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView4.Columns[13].DataPropertyName = "毛利率";
- this.advancedDataGridView4.Columns[13].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView4.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView4.Columns[14].Name = "";
- this.advancedDataGridView4.Columns[14].HeaderText = "箱柜类型";
- this.advancedDataGridView4.Columns[14].Width = 100;
- this.advancedDataGridView4.Columns[14].Visible = true;
- this.advancedDataGridView4.Columns[14].ReadOnly = false;
- this.advancedDataGridView4.Columns[14].Frozen = false;
- this.advancedDataGridView4.Columns[14].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView4.Columns[14].DataPropertyName = "箱柜类型";
- this.advancedDataGridView4.Columns[14].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView4.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView4.Columns[15].Name = "";
- this.advancedDataGridView4.Columns[15].HeaderText = "备注";
- this.advancedDataGridView4.Columns[15].Width = 100;
- this.advancedDataGridView4.Columns[15].Visible = true;
- this.advancedDataGridView4.Columns[15].ReadOnly = false;
- this.advancedDataGridView4.Columns[15].Frozen = false;
- this.advancedDataGridView4.Columns[15].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView4.Columns[15].DataPropertyName = "备注";
- this.advancedDataGridView4.Columns[15].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView4.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView4.Columns[16].Name = "";
- this.advancedDataGridView4.Columns[16].HeaderText = "图纸";
- this.advancedDataGridView4.Columns[16].Width = 100;
- this.advancedDataGridView4.Columns[16].Visible = true;
- this.advancedDataGridView4.Columns[16].ReadOnly = false;
- this.advancedDataGridView4.Columns[16].Frozen = false;
- this.advancedDataGridView4.Columns[16].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView4.Columns[16].DataPropertyName = "图纸";
- this.advancedDataGridView4.Columns[16].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
-
- //
- // advancedDataGridView5
- //
- this.advancedDataGridView5.ColumnHeadersDefaultCellStyle.BackColor = System.Drawing.SystemColors.Control;
- this.advancedDataGridView5.ColumnHeadersDefaultCellStyle.ForeColor = System.Drawing.SystemColors.WindowText;
- this.advancedDataGridView5.ColumnHeadersDefaultCellStyle.SelectionBackColor = System.Drawing.SystemColors.Highlight;
- this.advancedDataGridView5.ColumnHeadersDefaultCellStyle.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
- this.advancedDataGridView5.ColumnHeadersDefaultCellStyle.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 1);
- this.advancedDataGridView5.ColumnHeadersDefaultCellStyle.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
- this.advancedDataGridView5.ColumnHeadersDefaultCellStyle.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
- this.advancedDataGridView5.DefaultCellStyle.BackColor = System.Drawing.SystemColors.Window;
- this.advancedDataGridView5.DefaultCellStyle.ForeColor = System.Drawing.SystemColors.ControlText;
- this.advancedDataGridView5.DefaultCellStyle.SelectionBackColor = System.Drawing.SystemColors.Highlight;
- this.advancedDataGridView5.DefaultCellStyle.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
- this.advancedDataGridView5.DefaultCellStyle.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 1);
- this.advancedDataGridView5.DefaultCellStyle.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
- this.advancedDataGridView5.DefaultCellStyle.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
- this.advancedDataGridView5.RowHeadersDefaultCellStyle.BackColor = System.Drawing.SystemColors.Control;
- this.advancedDataGridView5.RowHeadersDefaultCellStyle.ForeColor = System.Drawing.SystemColors.WindowText;
- this.advancedDataGridView5.RowHeadersDefaultCellStyle.SelectionBackColor = System.Drawing.SystemColors.Highlight;
- this.advancedDataGridView5.RowHeadersDefaultCellStyle.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
- this.advancedDataGridView5.RowHeadersDefaultCellStyle.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 1);
- this.advancedDataGridView5.RowHeadersDefaultCellStyle.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
- this.advancedDataGridView5.RowHeadersDefaultCellStyle.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
- this.advancedDataGridView5.Dock = System.Windows.Forms.DockStyle.Fill;
- this.advancedDataGridView5.EnableExcelStyleSelection = true;
- this.advancedDataGridView5.EnableCellPaste = true;
- this.advancedDataGridView5.AllowUserToAddRows = false;
- this.advancedDataGridView5.AllowUserToDeleteRows = true;
- this.advancedDataGridView5.AllowUserToOrderColumns = false;
- this.advancedDataGridView5.AllowUserToResizeColumns = true;
- this.advancedDataGridView5.AllowUserToResizeRows = false;
- this.advancedDataGridView5.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.None;
- this.advancedDataGridView5.AutoSizeRowsMode = System.Windows.Forms.DataGridViewAutoSizeRowsMode.None;
- this.advancedDataGridView5.BackgroundColor = System.Drawing.Color.White;
- this.advancedDataGridView5.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
- this.advancedDataGridView5.CellBorderStyle = System.Windows.Forms.DataGridViewCellBorderStyle.Single;
- this.advancedDataGridView5.ClipboardCopyMode = System.Windows.Forms.DataGridViewClipboardCopyMode.EnableWithAutoHeaderText;
- this.advancedDataGridView5.ColumnHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Raised;
- this.advancedDataGridView5.ColumnHeadersHeight = 35;
- this.advancedDataGridView5.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.EnableResizing;
- this.advancedDataGridView5.ColumnHeadersVisible = true;
- this.advancedDataGridView5.EditMode = System.Windows.Forms.DataGridViewEditMode.EditOnKeystroke;
- this.advancedDataGridView5.EnableHeadersVisualStyles = false;
- this.advancedDataGridView5.GridColor = System.Drawing.SystemColors.ControlDark;
- this.advancedDataGridView5.MultiSelect = true;
- this.advancedDataGridView5.ReadOnly = false;
- this.advancedDataGridView5.RowHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Raised;
- this.advancedDataGridView5.RowHeadersVisible = true;
- this.advancedDataGridView5.RowHeadersWidth = 41;
- this.advancedDataGridView5.RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.EnableResizing;
- this.advancedDataGridView5.ScrollBars = System.Windows.Forms.ScrollBars.Both;
- this.advancedDataGridView5.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.RowHeaderSelect;
- this.advancedDataGridView5.ShowCellErrors = true;
- this.advancedDataGridView5.ShowCellToolTips = true;
- this.advancedDataGridView5.ShowEditingIcon = true;
- this.advancedDataGridView5.ShowRowErrors = true;
- this.advancedDataGridView5.StandardTab = false;
- this.advancedDataGridView5.VirtualMode = false;
- this.advancedDataGridView5.Enabled = true;
- this.advancedDataGridView5.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.advancedDataGridView5.MaximumSize = new System.Drawing.Size(0, 0);
- this.advancedDataGridView5.MinimumSize = new System.Drawing.Size(0, 0);
- this.advancedDataGridView5.TabIndex = 0;
- this.advancedDataGridView5.TabStop = true;
- this.advancedDataGridView5.Name = "advancedDataGridView5";
- this.advancedDataGridView5.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView5.Columns[0].Name = "";
- this.advancedDataGridView5.Columns[0].HeaderText = "序号";
- this.advancedDataGridView5.Columns[0].Width = 35;
- this.advancedDataGridView5.Columns[0].Visible = true;
- this.advancedDataGridView5.Columns[0].ReadOnly = false;
- this.advancedDataGridView5.Columns[0].Frozen = false;
- this.advancedDataGridView5.Columns[0].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView5.Columns[0].DataPropertyName = "序号";
- this.advancedDataGridView5.Columns[0].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView5.Columns[0].DefaultCellStyle.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
- this.advancedDataGridView5.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView5.Columns[1].Name = "";
- this.advancedDataGridView5.Columns[1].HeaderText = "元件名称";
- this.advancedDataGridView5.Columns[1].Width = 150;
- this.advancedDataGridView5.Columns[1].Visible = true;
- this.advancedDataGridView5.Columns[1].ReadOnly = false;
- this.advancedDataGridView5.Columns[1].Frozen = false;
- this.advancedDataGridView5.Columns[1].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView5.Columns[1].DataPropertyName = "元件名称";
- this.advancedDataGridView5.Columns[1].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView5.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView5.Columns[2].Name = "";
- this.advancedDataGridView5.Columns[2].HeaderText = "规格";
- this.advancedDataGridView5.Columns[2].Width = 150;
- this.advancedDataGridView5.Columns[2].Visible = true;
- this.advancedDataGridView5.Columns[2].ReadOnly = false;
- this.advancedDataGridView5.Columns[2].Frozen = false;
- this.advancedDataGridView5.Columns[2].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView5.Columns[2].DataPropertyName = "规格";
- this.advancedDataGridView5.Columns[2].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView5.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView5.Columns[3].Name = "";
- this.advancedDataGridView5.Columns[3].HeaderText = "单位";
- this.advancedDataGridView5.Columns[3].Width = 35;
- this.advancedDataGridView5.Columns[3].Visible = true;
- this.advancedDataGridView5.Columns[3].ReadOnly = false;
- this.advancedDataGridView5.Columns[3].Frozen = false;
- this.advancedDataGridView5.Columns[3].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView5.Columns[3].DataPropertyName = "单位";
- this.advancedDataGridView5.Columns[3].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView5.Columns[3].DefaultCellStyle.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
- this.advancedDataGridView5.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView5.Columns[4].Name = "";
- this.advancedDataGridView5.Columns[4].HeaderText = "数量";
- this.advancedDataGridView5.Columns[4].Width = 40;
- this.advancedDataGridView5.Columns[4].Visible = true;
- this.advancedDataGridView5.Columns[4].ReadOnly = false;
- this.advancedDataGridView5.Columns[4].Frozen = false;
- this.advancedDataGridView5.Columns[4].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView5.Columns[4].DataPropertyName = "数量";
- this.advancedDataGridView5.Columns[4].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView5.Columns[4].DefaultCellStyle.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
- this.advancedDataGridView5.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView5.Columns[5].Name = "";
- this.advancedDataGridView5.Columns[5].HeaderText = "表价";
- this.advancedDataGridView5.Columns[5].Width = 100;
- this.advancedDataGridView5.Columns[5].Visible = true;
- this.advancedDataGridView5.Columns[5].ReadOnly = false;
- this.advancedDataGridView5.Columns[5].Frozen = false;
- this.advancedDataGridView5.Columns[5].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView5.Columns[5].DataPropertyName = "表价";
- this.advancedDataGridView5.Columns[5].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView5.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView5.Columns[6].Name = "";
- this.advancedDataGridView5.Columns[6].HeaderText = "采购单价";
- this.advancedDataGridView5.Columns[6].Width = 100;
- this.advancedDataGridView5.Columns[6].Visible = true;
- this.advancedDataGridView5.Columns[6].ReadOnly = false;
- this.advancedDataGridView5.Columns[6].Frozen = false;
- this.advancedDataGridView5.Columns[6].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView5.Columns[6].DataPropertyName = "采购单价";
- this.advancedDataGridView5.Columns[6].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView5.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView5.Columns[7].Name = "";
- this.advancedDataGridView5.Columns[7].HeaderText = "采购系数";
- this.advancedDataGridView5.Columns[7].Width = 100;
- this.advancedDataGridView5.Columns[7].Visible = true;
- this.advancedDataGridView5.Columns[7].ReadOnly = false;
- this.advancedDataGridView5.Columns[7].Frozen = false;
- this.advancedDataGridView5.Columns[7].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView5.Columns[7].DataPropertyName = "采购系数";
- this.advancedDataGridView5.Columns[7].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView5.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView5.Columns[8].Name = "";
- this.advancedDataGridView5.Columns[8].HeaderText = "采购价";
- this.advancedDataGridView5.Columns[8].Width = 100;
- this.advancedDataGridView5.Columns[8].Visible = true;
- this.advancedDataGridView5.Columns[8].ReadOnly = false;
- this.advancedDataGridView5.Columns[8].Frozen = false;
- this.advancedDataGridView5.Columns[8].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView5.Columns[8].DataPropertyName = "采购价";
- this.advancedDataGridView5.Columns[8].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView5.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView5.Columns[9].Name = "";
- this.advancedDataGridView5.Columns[9].HeaderText = "报出单价";
- this.advancedDataGridView5.Columns[9].Width = 100;
- this.advancedDataGridView5.Columns[9].Visible = true;
- this.advancedDataGridView5.Columns[9].ReadOnly = false;
- this.advancedDataGridView5.Columns[9].Frozen = false;
- this.advancedDataGridView5.Columns[9].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView5.Columns[9].DataPropertyName = "报出单价";
- this.advancedDataGridView5.Columns[9].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView5.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView5.Columns[10].Name = "";
- this.advancedDataGridView5.Columns[10].HeaderText = "报出系数";
- this.advancedDataGridView5.Columns[10].Width = 100;
- this.advancedDataGridView5.Columns[10].Visible = true;
- this.advancedDataGridView5.Columns[10].ReadOnly = false;
- this.advancedDataGridView5.Columns[10].Frozen = false;
- this.advancedDataGridView5.Columns[10].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView5.Columns[10].DataPropertyName = "报出系数";
- this.advancedDataGridView5.Columns[10].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView5.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView5.Columns[11].Name = "";
- this.advancedDataGridView5.Columns[11].HeaderText = "报出价";
- this.advancedDataGridView5.Columns[11].Width = 100;
- this.advancedDataGridView5.Columns[11].Visible = true;
- this.advancedDataGridView5.Columns[11].ReadOnly = false;
- this.advancedDataGridView5.Columns[11].Frozen = false;
- this.advancedDataGridView5.Columns[11].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView5.Columns[11].DataPropertyName = "报出价";
- this.advancedDataGridView5.Columns[11].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView5.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView5.Columns[12].Name = "";
- this.advancedDataGridView5.Columns[12].HeaderText = "图纸规格";
- this.advancedDataGridView5.Columns[12].Width = 100;
- this.advancedDataGridView5.Columns[12].Visible = true;
- this.advancedDataGridView5.Columns[12].ReadOnly = false;
- this.advancedDataGridView5.Columns[12].Frozen = false;
- this.advancedDataGridView5.Columns[12].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView5.Columns[12].DataPropertyName = "图纸规格";
- this.advancedDataGridView5.Columns[12].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView5.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView5.Columns[13].Name = "";
- this.advancedDataGridView5.Columns[13].HeaderText = "品牌";
- this.advancedDataGridView5.Columns[13].Width = 100;
- this.advancedDataGridView5.Columns[13].Visible = true;
- this.advancedDataGridView5.Columns[13].ReadOnly = false;
- this.advancedDataGridView5.Columns[13].Frozen = false;
- this.advancedDataGridView5.Columns[13].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView5.Columns[13].DataPropertyName = "品牌";
- this.advancedDataGridView5.Columns[13].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView5.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView5.Columns[14].Name = "";
- this.advancedDataGridView5.Columns[14].HeaderText = "系列";
- this.advancedDataGridView5.Columns[14].Width = 100;
- this.advancedDataGridView5.Columns[14].Visible = true;
- this.advancedDataGridView5.Columns[14].ReadOnly = false;
- this.advancedDataGridView5.Columns[14].Frozen = false;
- this.advancedDataGridView5.Columns[14].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView5.Columns[14].DataPropertyName = "系列";
- this.advancedDataGridView5.Columns[14].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView5.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView5.Columns[15].Name = "";
- this.advancedDataGridView5.Columns[15].HeaderText = "类型";
- this.advancedDataGridView5.Columns[15].Width = 100;
- this.advancedDataGridView5.Columns[15].Visible = true;
- this.advancedDataGridView5.Columns[15].ReadOnly = false;
- this.advancedDataGridView5.Columns[15].Frozen = false;
- this.advancedDataGridView5.Columns[15].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView5.Columns[15].DataPropertyName = "类型";
- this.advancedDataGridView5.Columns[15].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.advancedDataGridView5.Columns.Add(new System.Windows.Forms.DataGridViewTextBoxColumn());
- this.advancedDataGridView5.Columns[16].Name = "";
- this.advancedDataGridView5.Columns[16].HeaderText = "备注";
- this.advancedDataGridView5.Columns[16].Width = 100;
- this.advancedDataGridView5.Columns[16].Visible = true;
- this.advancedDataGridView5.Columns[16].ReadOnly = false;
- this.advancedDataGridView5.Columns[16].Frozen = false;
- this.advancedDataGridView5.Columns[16].AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.NotSet;
- this.advancedDataGridView5.Columns[16].DataPropertyName = "备注";
- this.advancedDataGridView5.Columns[16].SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
-
- //
- // toolStrip1
- //
- this.toolStrip1.Dock = System.Windows.Forms.DockStyle.Top;
- this.toolStrip1.AutoSize = true;
- this.toolStrip1.AllowItemReorder = false;
- this.toolStrip1.AllowMerge = true;
- this.toolStrip1.BackColor = System.Drawing.SystemColors.Control;
- this.toolStrip1.CanOverflow = true;
- this.toolStrip1.Font = new System.Drawing.Font("Microsoft YaHei UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.toolStrip1.GripStyle = System.Windows.Forms.ToolStripGripStyle.Visible;
- this.toolStrip1.GripMargin = new System.Windows.Forms.Padding(2, 2, 2, 2);
- this.toolStrip1.ImageScalingSize = new System.Drawing.Size(16, 16);
- this.toolStrip1.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.HorizontalStackWithOverflow;
- this.toolStrip1.Stretch = false;
- this.toolStrip1.RenderMode = System.Windows.Forms.ToolStripRenderMode.ManagerRenderMode;
- this.toolStrip1.ShowItemToolTips = true;
- this.toolStrip1.TabStop = false;
- this.toolStrip1.TextDirection = System.Windows.Forms.ToolStripTextDirection.Horizontal;
- this.toolStrip1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Tile;
- this.toolStrip1.Enabled = true;
- this.toolStrip1.Margin = new System.Windows.Forms.Padding(0, 0, 0, 0);
- this.toolStrip1.MaximumSize = new System.Drawing.Size(0, 0);
- this.toolStrip1.MinimumSize = new System.Drawing.Size(0, 0);
- this.toolStrip1.TabIndex = 1;
- this.toolStrip1.Padding = new System.Windows.Forms.Padding(0, 0, 1, 0);
- this.toolStrip1.Size = new System.Drawing.Size(487, 25);
- this.toolStrip1.Location = new System.Drawing.Point(0, 0);
- this.toolStrip1.Name = "toolStrip1";
-
- //
- // toolStripButton1
- //
- this.toolStripButton1.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
- this.toolStripButton1.ToolTipText = "导出数据";
- this.toolStripButton1.Size = new System.Drawing.Size(60, 22);
- this.toolStripButton1.Text = "导出数据";
- this.toolStripButton1.Name = "toolStripButton1";
-
- //
- // toolStripButton5
- //
- this.toolStripButton5.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
- this.toolStripButton5.ToolTipText = "新建项目";
- this.toolStripButton5.Size = new System.Drawing.Size(60, 22);
- this.toolStripButton5.Text = "新建项目";
- this.toolStripButton5.Name = "toolStripButton5";
-
- //
- // toolStripButton6
- //
- this.toolStripButton6.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
- this.toolStripButton6.ToolTipText = "删除项目";
- this.toolStripButton6.Size = new System.Drawing.Size(60, 22);
- this.toolStripButton6.Text = "删除项目";
- this.toolStripButton6.Name = "toolStripButton6";
-
- //
- // toolStripButton2
- //
- this.toolStripButton2.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
- this.toolStripButton2.ToolTipText = "扒图号";
- this.toolStripButton2.Size = new System.Drawing.Size(48, 22);
- this.toolStripButton2.Text = "扒图号";
- this.toolStripButton2.Name = "toolStripButton2";
-
- //
- // toolStripButton3
- //
- this.toolStripButton3.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
- this.toolStripButton3.ToolTipText = "扒箱号";
- this.toolStripButton3.Size = new System.Drawing.Size(48, 22);
- this.toolStripButton3.Text = "扒箱号";
- this.toolStripButton3.Name = "toolStripButton3";
-
- //
- // toolStripButton4
- //
- this.toolStripButton4.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
- this.toolStripButton4.ToolTipText = "扒元件";
- this.toolStripButton4.Size = new System.Drawing.Size(48, 22);
- this.toolStripButton4.Text = "扒元件";
- this.toolStripButton4.Name = "toolStripButton4";
-
- //
- // toolStripButton7
- //
- this.toolStripButton7.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
- this.toolStripButton7.ImageTransparentColor = System.Drawing.Color.Magenta;
- this.toolStripButton7.Size = new System.Drawing.Size(36, 22);
- this.toolStripButton7.Text = "设置";
- this.toolStripButton7.Name = "toolStripButton7";
-
- // Form3
- this.Controls.AddRange(new System.Windows.Forms.Control[] {
- this.tabControl2,
- this.toolStrip1,
- });
- // tabControl2
- this.tabControl2.Controls.AddRange(new System.Windows.Forms.Control[] {
- this.tabPage3,
- this.tabPage4,
- });
- // tabPage3
- this.tabPage3.Controls.AddRange(new System.Windows.Forms.Control[] {
- this.advancedDataGridView6,
- this.panel1,
- });
- // panel1
- this.panel1.Controls.AddRange(new System.Windows.Forms.Control[] {
- this.button28,
- this.textBox1,
- this.comboBox2,
- });
- // tabPage4
- this.tabPage4.Controls.AddRange(new System.Windows.Forms.Control[] {
- this.splitContainer2,
- });
- // Panel1
- this.splitContainer2.Panel1.Controls.AddRange(new System.Windows.Forms.Control[] {
- this.advancedDataGridView9,
- });
- // Panel2
- this.splitContainer2.Panel2.Controls.AddRange(new System.Windows.Forms.Control[] {
- this.splitContainer3,
- });
- // Panel1
- this.splitContainer3.Panel1.Controls.AddRange(new System.Windows.Forms.Control[] {
- this.advancedDataGridView4,
- });
- // Panel2
- this.splitContainer3.Panel2.Controls.AddRange(new System.Windows.Forms.Control[] {
- this.advancedDataGridView5,
- });
- // toolStrip1
- this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
- this.toolStripButton1,
- this.toolStripButton5,
- this.toolStripButton6,
- this.toolStripButton2,
- this.toolStripButton3,
- this.toolStripButton4,
- this.toolStripButton7,
- });
- //
- // Form3
- //
- this.Dock = System.Windows.Forms.DockStyle.None;
- this.AutoScroll = false;
- this.AutoSize = false;
- this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowOnly;
- this.AutoValidate = System.Windows.Forms.AutoValidate.EnablePreventFocusChange;
- this.BackColor = System.Drawing.SystemColors.Control;
- this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Sizable;
- this.ControlBox = true;
- this.HelpButton = false;
- this.IsMdiContainer = false;
- this.KeyPreview = false;
- this.MaximumSize = new System.Drawing.Size(0, 0);
- this.MinimumSize = new System.Drawing.Size(0, 0);
- this.MaximizeBox = true;
- this.MinimizeBox = true;
- this.Opacity = 1;
- this.RightToLeftLayout = false;
- this.ShowInTaskbar = true;
- this.ShowIcon = true;
- this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Auto;
- this.StartPosition = System.Windows.Forms.FormStartPosition.WindowsDefaultLocation;
- this.TopMost = false;
- this.WindowState = System.Windows.Forms.FormWindowState.Normal;
- this.AutoScrollMargin = new System.Drawing.Size(0, 0);
- this.AutoScrollMinSize = new System.Drawing.Size(0, 0);
- this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Tile;
- this.Enabled = true;
- this.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.ForeColor = System.Drawing.SystemColors.ControlText;
- this.Padding = new System.Windows.Forms.Padding(0, 0, 0, 0);
- this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
- this.Size = new System.Drawing.Size(503, 785);
- this.Text = "Form3";
- this.Name = "Form3";
- ((System.ComponentModel.ISupportInitialize)(this.advancedDataGridView6)).EndInit();
- ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).EndInit();
- ((System.ComponentModel.ISupportInitialize)(this.advancedDataGridView9)).EndInit();
- ((System.ComponentModel.ISupportInitialize)(this.splitContainer3)).EndInit();
- ((System.ComponentModel.ISupportInitialize)(this.advancedDataGridView4)).EndInit();
- ((System.ComponentModel.ISupportInitialize)(this.advancedDataGridView5)).EndInit();
- this.ResumeLayout(false);
- this.PerformLayout();
- this.splitContainer2.SplitterDistance = 173;
- this.splitContainer3.SplitterDistance = 239;
-
- // === DataGridView Excel 风格选中效果 ===
-
- // === SQLite 设计时数据绑定(由设计器注入) ===
- // 在 Form.Load 事件中加载所有绑定数据
- this.Load += (sender, e) => LoadAllSqliteData();
- }
-
- #endregion
-
- private System.Windows.Forms.TabControl tabControl2;
- private System.Windows.Forms.TabPage tabPage3;
- private Zuby.ADGV.AdvancedDataGridView advancedDataGridView6;
- private System.Windows.Forms.Panel panel1;
- private System.Windows.Forms.Button button28;
- private System.Windows.Forms.TextBox textBox1;
- private System.Windows.Forms.ComboBox comboBox2;
- private System.Windows.Forms.TabPage tabPage4;
- private System.Windows.Forms.SplitContainer splitContainer2;
- private Zuby.ADGV.AdvancedDataGridView advancedDataGridView9;
- private System.Windows.Forms.SplitContainer splitContainer3;
- private Zuby.ADGV.AdvancedDataGridView advancedDataGridView4;
- private Zuby.ADGV.AdvancedDataGridView advancedDataGridView5;
- private System.Windows.Forms.ToolStrip toolStrip1;
- private System.Windows.Forms.ToolStripButton toolStripButton1;
- private System.Windows.Forms.ToolStripButton toolStripButton5;
- private System.Windows.Forms.ToolStripButton toolStripButton6;
- private System.Windows.Forms.ToolStripButton toolStripButton2;
- private System.Windows.Forms.ToolStripButton toolStripButton3;
- private System.Windows.Forms.ToolStripButton toolStripButton4;
- private System.Windows.Forms.ToolStripButton toolStripButton7;
-
- /// 加载所有 SQLite 设计数据绑定。
- private void LoadAllSqliteData()
- {
- // cadbt 宿主为 x86 进程,引用的是 x86 版 System.Data.SQLite.dll,
- // 无需 AutoCAD 插件版的 64 位检查,直接加载。
- try { LoadSqliteData_advancedDataGridView6(); } catch (System.Exception ex_advancedDataGridView6) { System.Windows.Forms.MessageBox.Show("加载数据失败 (advancedDataGridView6): " + ex_advancedDataGridView6.Message); }
- }
-
- /// 为 advancedDataGridView6 加载 SQLite 数据(由设计器生成)。
- private void LoadSqliteData_advancedDataGridView6()
- {
- // ★ 数据库路径:优先用插件真实目录(_baseDir 在 Form3.cs,注册表/CodeBase 解析),
- // 在 CAD 中加载时 BaseDirectory 指向 CAD 安装目录会找不到库
- string dbPath = System.IO.Path.Combine(
- GetPluginBaseDirForUi(), @"sjk\advancedDataGridView6Table.db");
- if (!System.IO.File.Exists(dbPath))
- {
- // ★ 静默跳过(不弹窗):构造函数里的 Load 事件已用正确路径重新加载
- System.Diagnostics.Debug.WriteLine("找不到数据库文件: " + dbPath);
- return;
- }
-
- string connStr = "Data Source=" + dbPath + ";Version=3;busy_timeout=3000;";
- var table = new System.Data.DataTable();
- using (var conn = new System.Data.SQLite.SQLiteConnection(connStr))
- {
- conn.Open();
- string sql = @"SELECT * FROM advancedDataGridView6Table";
- using (var adapter = new System.Data.SQLite.SQLiteDataAdapter(sql, conn))
- {
- adapter.Fill(table);
- }
- }
-
- this.advancedDataGridView6.AutoGenerateColumns = false;
- // KeepCustomColumns=true:设计器中自定义的列不会被覆盖,
- // 数据库列通过 DataPropertyName 与控件列关联。
- // 若列名与数据库列名相同,运行时会自动绑定数据。
- this.advancedDataGridView6.DataSource = table;
- }
-
- ///
- /// ui.cs 侧获取插件目录:复用 Form3.cs 的 _baseDir
- /// (partial 类同字段;_baseDir 在 Form3.cs 中由注册表/CodeBase 解析)
- ///
- private string GetPluginBaseDirForUi()
- {
- return _baseDir;
- }
- }
-}
diff --git a/cadbt/cadbt/Plugin/PaTypes.cs b/cadbt/cadbt/Plugin/PaTypes.cs
deleted file mode 100644
index 3c4e287..0000000
--- a/cadbt/cadbt/Plugin/PaTypes.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-// ============================================================
-// 扒图数据类型(与原 cadcj 插件 / 网页端 cadbridge.ts 保持一致)
-// ============================================================
-using System.Collections.Generic;
-
-namespace MyApp
-{
- ///
- /// 扒数据模式:图号/箱号/元件
- ///
- public enum PaMode
- {
- Tuhao, // 扒图号
- Xianghao, // 扒箱号
- Yuanjian // 扒元件
- }
-
- ///
- /// 扒图结果:一条文本 + 它对应的彩色框的 Handle(句柄字符串)
- /// 用于关联表格数据行与网页 CAD 框实体,实现点击行定位、删除行删框。
- /// ★ TextHandle:源文本实体自身的 Handle,用于判断"是否同一个文本"。
- ///
- public class PaTextResult
- {
- public string Text;
- public string FrameHandle;
- public string TextHandle = "";
- }
-}
diff --git a/cadbt/cadbt/Plugin/新建项目.cs b/cadbt/cadbt/Plugin/新建项目.cs
deleted file mode 100644
index 494c388..0000000
--- a/cadbt/cadbt/Plugin/新建项目.cs
+++ /dev/null
@@ -1,132 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Windows.Forms;
-
-namespace MyApp
-{
- ///
- /// 新建项目 窗口(简化版,不依赖企业信息)。
- /// UI 布局见 新建项目.ui.cs,本文件只含交互逻辑。
- ///
- public partial class 新建项目 : Form
- {
- // 价格格式化选项(与主项目 价格格式化.cs 保持一致)
- private static readonly string[] 小数位选项 =
- {
- "保留整数", "保留1位小数", "保留2位小数", "保留3位小数",
- "保留4位小数", "保留5位小数", "保留6位小数"
- };
- private static readonly string[] 取整方式选项 =
- {
- "不取整", "四舍五入", "四舍五入到角", "四舍五入到元",
- "四舍五入到十元", "向上取整到元", "最近5元", "最近10元"
- };
-
- private readonly string _dbPath;
- private readonly string _tableName;
-
- public 新建项目() : this(null, null) { }
-
- /// 带数据库路径的构造函数(用于自动生成项目编号)。
- public 新建项目(string dbPath, string tableName)
- {
- InitializeComponent();
- _dbPath = dbPath;
- _tableName = tableName;
- InitPriceFormatCombos();
- this.Load += 新建项目_Load;
- }
-
- private void InitPriceFormatCombos()
- {
- cmb单台价格.Items.Clear();
- cmb单台价格.Items.AddRange(小数位选项);
- cmb项目总价.Items.Clear();
- cmb项目总价.Items.AddRange(小数位选项);
- comboBox1.Items.Clear();
- comboBox1.Items.AddRange(取整方式选项);
- comboBox2.Items.Clear();
- comboBox2.Items.AddRange(取整方式选项);
- }
-
- private void 新建项目_Load(object sender, EventArgs e)
- {
- FillAutoFields();
- }
-
- /// 自动填充项目日期(当天)和项目编号(yyyyMMdd+3位序号)。
- private void FillAutoFields()
- {
- DateTime today = DateTime.Today;
- txt项目日期.Text = today.ToString("yyyy-MM-dd");
-
- string datePart = today.ToString("yyyyMMdd");
- int seq = GetNextSeqForDate(datePart);
- txt项目编号.Text = datePart + seq.ToString("000");
- txt项目编号.ReadOnly = true;
- txt项目编号.TabStop = false;
- txt项目编号.BackColor = System.Drawing.SystemColors.Control;
- }
-
- /// 查数据库当天最大序号+1,失败返回1。
- private int GetNextSeqForDate(string datePart)
- {
- if (string.IsNullOrEmpty(datePart) ||
- string.IsNullOrEmpty(_dbPath) ||
- string.IsNullOrEmpty(_tableName) ||
- !System.IO.File.Exists(_dbPath))
- {
- return 1;
- }
- try
- {
- string connStr = "Data Source=" + _dbPath + ";Version=3;";
- using (var conn = new System.Data.SQLite.SQLiteConnection(connStr))
- {
- conn.Open();
- string sql =
- "SELECT MAX(CAST(SUBSTR(项目编号, 9) AS INTEGER)) " +
- "FROM " + _tableName + " " +
- "WHERE SUBSTR(项目编号, 1, 8) = '" + datePart + "';";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- object result = cmd.ExecuteScalar();
- if (result == null || result == DBNull.Value) return 1;
- int maxSeq;
- if (int.TryParse(result.ToString(), out maxSeq)) return maxSeq + 1;
- return 1;
- }
- }
- }
- catch { return 1; }
- }
-
- /// 收集对话框字段,以列名为键返回(供 Form3 写入数据库)。
- public Dictionary GetInputValues()
- {
- var values = new Dictionary();
- AddIfNotEmpty(values, "项目编号", txt项目编号.Text);
- AddIfNotEmpty(values, "项目日期", txt项目日期.Text);
- AddIfNotEmpty(values, "项目名称", txt项目名称.Text);
- AddIfNotEmpty(values, "客户名称", txt客户名称.Text);
- AddIfNotEmpty(values, "客户地址", txt客户地址.Text);
- AddIfNotEmpty(values, "联系人", txt联系人.Text);
- AddIfNotEmpty(values, "联系电话", txt联系电话.Text);
- AddIfNotEmpty(values, "备注", txt备注.Text);
- AddIfNotEmpty(values, "成套厂名称", txt成套厂名称.Text);
- AddIfNotEmpty(values, "成套厂地址", txt成套厂地址.Text);
- AddIfNotEmpty(values, "成套厂联系人", txt成套厂联系人.Text);
- AddIfNotEmpty(values, "成套厂联系电话", txt成套厂联系电话.Text);
- values["单台小数位"] = (cmb单台价格.SelectedItem ?? cmb单台价格.Text ?? "").ToString();
- values["项目小数位"] = (cmb项目总价.SelectedItem ?? cmb项目总价.Text ?? "").ToString();
- values["单台取整方式"] = (comboBox1.SelectedItem ?? comboBox1.Text ?? "").ToString();
- values["项目取整方式"] = (comboBox2.SelectedItem ?? comboBox2.Text ?? "").ToString();
- return values;
- }
-
- private static void AddIfNotEmpty(Dictionary dict, string key, string value)
- {
- if (!string.IsNullOrWhiteSpace(value)) dict[key] = value.Trim();
- }
- }
-}
diff --git a/cadbt/cadbt/Plugin/新建项目.ui.cs b/cadbt/cadbt/Plugin/新建项目.ui.cs
deleted file mode 100644
index 37aeee3..0000000
--- a/cadbt/cadbt/Plugin/新建项目.ui.cs
+++ /dev/null
@@ -1,1337 +0,0 @@
-namespace MyApp
-{
- public partial class 新建项目 : System.Windows.Forms.Form
- {
- /// 必需的设计器变量。
- private System.ComponentModel.IContainer components = null;
-
- /// 清理正在使用的资源。
- protected override void Dispose(bool disposing)
- {
- if (disposing && (components != null))
- {
- components.Dispose();
- }
- base.Dispose(disposing);
- }
-
- #region Windows 窗体设计器生成的代码
-
- private void InitializeComponent()
- {
- this.components = new System.ComponentModel.Container();
-
- this.lbl项目编号 = new System.Windows.Forms.Label();
- this.txt项目编号 = new System.Windows.Forms.TextBox();
- this.lbl项目日期 = new System.Windows.Forms.Label();
- this.txt项目日期 = new System.Windows.Forms.TextBox();
- this.lbl项目名称 = new System.Windows.Forms.Label();
- this.txt项目名称 = new System.Windows.Forms.TextBox();
- this.lbl客户名称 = new System.Windows.Forms.Label();
- this.txt客户名称 = new System.Windows.Forms.TextBox();
- this.btn选择客户 = new System.Windows.Forms.Button();
- this.lbl客户地址 = new System.Windows.Forms.Label();
- this.txt客户地址 = new System.Windows.Forms.TextBox();
- this.lbl联系人 = new System.Windows.Forms.Label();
- this.txt联系人 = new System.Windows.Forms.TextBox();
- this.lbl联系电话 = new System.Windows.Forms.Label();
- this.txt联系电话 = new System.Windows.Forms.TextBox();
- this.lbl成套厂名称 = new System.Windows.Forms.Label();
- this.txt成套厂名称 = new System.Windows.Forms.TextBox();
- this.lbl成套厂地址 = new System.Windows.Forms.Label();
- this.txt成套厂地址 = new System.Windows.Forms.TextBox();
- this.lbl成套厂联系人 = new System.Windows.Forms.Label();
- this.txt成套厂联系人 = new System.Windows.Forms.TextBox();
- this.lbl成套厂联系电话 = new System.Windows.Forms.Label();
- this.txt成套厂联系电话 = new System.Windows.Forms.TextBox();
- this.lbl报出方式 = new System.Windows.Forms.Label();
- this.cmb报出方式 = new System.Windows.Forms.ComboBox();
- this.lbl箱柜模板 = new System.Windows.Forms.Label();
- this.cmb箱柜模板 = new System.Windows.Forms.ComboBox();
- this.lbl单台价格 = new System.Windows.Forms.Label();
- this.cmb单台价格 = new System.Windows.Forms.ComboBox();
- this.lbl项目总价 = new System.Windows.Forms.Label();
- this.lbl备注 = new System.Windows.Forms.Label();
- this.txt备注 = new System.Windows.Forms.TextBox();
- this.btn确定 = new System.Windows.Forms.Button();
- this.btn取消 = new System.Windows.Forms.Button();
- this.comboBox1 = new System.Windows.Forms.ComboBox();
- this.label1 = new System.Windows.Forms.Label();
- this.label2 = new System.Windows.Forms.Label();
- this.comboBox2 = new System.Windows.Forms.ComboBox();
- this.cmb项目总价 = new System.Windows.Forms.ComboBox();
- this.SuspendLayout();
- //
- // lbl项目编号
- //
- this.lbl项目编号.Dock = System.Windows.Forms.DockStyle.None;
- this.lbl项目编号.AutoSize = false;
- this.lbl项目编号.AutoEllipsis = false;
- this.lbl项目编号.BorderStyle = System.Windows.Forms.BorderStyle.None;
- this.lbl项目编号.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
- this.lbl项目编号.ImageAlign = System.Drawing.ContentAlignment.MiddleCenter;
- this.lbl项目编号.LiveSetting = System.Windows.Forms.Automation.AutomationLiveSetting.Off;
- this.lbl项目编号.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
- this.lbl项目编号.UseCompatibleTextRendering = false;
- this.lbl项目编号.UseMnemonic = true;
- this.lbl项目编号.BackColor = System.Drawing.SystemColors.Control;
- this.lbl项目编号.Enabled = true;
- this.lbl项目编号.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.lbl项目编号.ForeColor = System.Drawing.SystemColors.ControlText;
- this.lbl项目编号.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
- this.lbl项目编号.MaximumSize = new System.Drawing.Size(0, 0);
- this.lbl项目编号.MinimumSize = new System.Drawing.Size(0, 0);
- this.lbl项目编号.TabIndex = 0;
- this.lbl项目编号.Padding = new System.Windows.Forms.Padding(0, 0, 0, 0);
- this.lbl项目编号.Size = new System.Drawing.Size(70, 23);
- this.lbl项目编号.Location = new System.Drawing.Point(20, 25);
- this.lbl项目编号.Text = "项目编号:";
- this.lbl项目编号.Name = "lbl项目编号";
-
- //
- // txt项目编号
- //
- this.txt项目编号.Dock = System.Windows.Forms.DockStyle.None;
- this.txt项目编号.AcceptsReturn = false;
- this.txt项目编号.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.None;
- this.txt项目编号.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.None;
- this.txt项目编号.CharacterCasing = System.Windows.Forms.CharacterCasing.Normal;
- this.txt项目编号.Multiline = false;
- this.txt项目编号.ScrollBars = System.Windows.Forms.ScrollBars.None;
- this.txt项目编号.TextAlign = System.Windows.Forms.HorizontalAlignment.Left;
- this.txt项目编号.UseSystemPasswordChar = false;
- this.txt项目编号.AcceptsTab = false;
- this.txt项目编号.ShortcutsEnabled = true;
- this.txt项目编号.BackColor = System.Drawing.SystemColors.Window;
- this.txt项目编号.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
- this.txt项目编号.ForeColor = System.Drawing.SystemColors.WindowText;
- this.txt项目编号.HideSelection = true;
- this.txt项目编号.MaxLength = 32767;
- this.txt项目编号.ReadOnly = false;
- this.txt项目编号.WordWrap = true;
- this.txt项目编号.Enabled = true;
- this.txt项目编号.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.txt项目编号.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.txt项目编号.MaximumSize = new System.Drawing.Size(0, 0);
- this.txt项目编号.MinimumSize = new System.Drawing.Size(0, 0);
- this.txt项目编号.TabIndex = 0;
- this.txt项目编号.TabStop = true;
- this.txt项目编号.Size = new System.Drawing.Size(220, 21);
- this.txt项目编号.Location = new System.Drawing.Point(95, 25);
- this.txt项目编号.Name = "txt项目编号";
-
- //
- // lbl项目日期
- //
- this.lbl项目日期.Dock = System.Windows.Forms.DockStyle.None;
- this.lbl项目日期.AutoSize = false;
- this.lbl项目日期.AutoEllipsis = false;
- this.lbl项目日期.BorderStyle = System.Windows.Forms.BorderStyle.None;
- this.lbl项目日期.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
- this.lbl项目日期.ImageAlign = System.Drawing.ContentAlignment.MiddleCenter;
- this.lbl项目日期.LiveSetting = System.Windows.Forms.Automation.AutomationLiveSetting.Off;
- this.lbl项目日期.TextAlign = System.Drawing.ContentAlignment.TopLeft;
- this.lbl项目日期.UseCompatibleTextRendering = false;
- this.lbl项目日期.UseMnemonic = true;
- this.lbl项目日期.BackColor = System.Drawing.SystemColors.Control;
- this.lbl项目日期.Enabled = true;
- this.lbl项目日期.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.lbl项目日期.ForeColor = System.Drawing.SystemColors.ControlText;
- this.lbl项目日期.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
- this.lbl项目日期.MaximumSize = new System.Drawing.Size(0, 0);
- this.lbl项目日期.MinimumSize = new System.Drawing.Size(0, 0);
- this.lbl项目日期.TabIndex = 1;
- this.lbl项目日期.Padding = new System.Windows.Forms.Padding(0, 0, 0, 0);
- this.lbl项目日期.Size = new System.Drawing.Size(70, 18);
- this.lbl项目日期.Location = new System.Drawing.Point(380, 28);
- this.lbl项目日期.Text = "项目日期:";
- this.lbl项目日期.Name = "lbl项目日期";
-
- //
- // txt项目日期
- //
- this.txt项目日期.Dock = System.Windows.Forms.DockStyle.None;
- this.txt项目日期.AcceptsReturn = false;
- this.txt项目日期.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.None;
- this.txt项目日期.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.None;
- this.txt项目日期.CharacterCasing = System.Windows.Forms.CharacterCasing.Normal;
- this.txt项目日期.Multiline = false;
- this.txt项目日期.ScrollBars = System.Windows.Forms.ScrollBars.None;
- this.txt项目日期.TextAlign = System.Windows.Forms.HorizontalAlignment.Left;
- this.txt项目日期.UseSystemPasswordChar = false;
- this.txt项目日期.AcceptsTab = false;
- this.txt项目日期.ShortcutsEnabled = true;
- this.txt项目日期.BackColor = System.Drawing.SystemColors.Window;
- this.txt项目日期.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
- this.txt项目日期.ForeColor = System.Drawing.SystemColors.WindowText;
- this.txt项目日期.HideSelection = true;
- this.txt项目日期.MaxLength = 32767;
- this.txt项目日期.ReadOnly = false;
- this.txt项目日期.WordWrap = true;
- this.txt项目日期.Enabled = true;
- this.txt项目日期.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.txt项目日期.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.txt项目日期.MaximumSize = new System.Drawing.Size(0, 0);
- this.txt项目日期.MinimumSize = new System.Drawing.Size(0, 0);
- this.txt项目日期.TabIndex = 1;
- this.txt项目日期.TabStop = true;
- this.txt项目日期.Size = new System.Drawing.Size(210, 21);
- this.txt项目日期.Location = new System.Drawing.Point(455, 25);
- this.txt项目日期.Name = "txt项目日期";
-
- //
- // lbl项目名称
- //
- this.lbl项目名称.Dock = System.Windows.Forms.DockStyle.None;
- this.lbl项目名称.AutoSize = false;
- this.lbl项目名称.AutoEllipsis = false;
- this.lbl项目名称.BorderStyle = System.Windows.Forms.BorderStyle.None;
- this.lbl项目名称.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
- this.lbl项目名称.ImageAlign = System.Drawing.ContentAlignment.MiddleCenter;
- this.lbl项目名称.LiveSetting = System.Windows.Forms.Automation.AutomationLiveSetting.Off;
- this.lbl项目名称.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
- this.lbl项目名称.UseCompatibleTextRendering = false;
- this.lbl项目名称.UseMnemonic = true;
- this.lbl项目名称.BackColor = System.Drawing.SystemColors.Control;
- this.lbl项目名称.Enabled = true;
- this.lbl项目名称.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.lbl项目名称.ForeColor = System.Drawing.SystemColors.ControlText;
- this.lbl项目名称.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
- this.lbl项目名称.MaximumSize = new System.Drawing.Size(0, 0);
- this.lbl项目名称.MinimumSize = new System.Drawing.Size(0, 0);
- this.lbl项目名称.TabIndex = 2;
- this.lbl项目名称.Padding = new System.Windows.Forms.Padding(0, 0, 0, 0);
- this.lbl项目名称.Size = new System.Drawing.Size(70, 23);
- this.lbl项目名称.Location = new System.Drawing.Point(20, 55);
- this.lbl项目名称.Text = "项目名称:";
- this.lbl项目名称.Name = "lbl项目名称";
-
- //
- // txt项目名称
- //
- this.txt项目名称.Dock = System.Windows.Forms.DockStyle.None;
- this.txt项目名称.AcceptsReturn = false;
- this.txt项目名称.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.None;
- this.txt项目名称.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.None;
- this.txt项目名称.CharacterCasing = System.Windows.Forms.CharacterCasing.Normal;
- this.txt项目名称.Multiline = false;
- this.txt项目名称.ScrollBars = System.Windows.Forms.ScrollBars.None;
- this.txt项目名称.TextAlign = System.Windows.Forms.HorizontalAlignment.Left;
- this.txt项目名称.UseSystemPasswordChar = false;
- this.txt项目名称.AcceptsTab = false;
- this.txt项目名称.ShortcutsEnabled = true;
- this.txt项目名称.BackColor = System.Drawing.SystemColors.Window;
- this.txt项目名称.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
- this.txt项目名称.ForeColor = System.Drawing.SystemColors.WindowText;
- this.txt项目名称.HideSelection = true;
- this.txt项目名称.MaxLength = 32767;
- this.txt项目名称.ReadOnly = false;
- this.txt项目名称.WordWrap = true;
- this.txt项目名称.Enabled = true;
- this.txt项目名称.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.txt项目名称.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.txt项目名称.MaximumSize = new System.Drawing.Size(0, 0);
- this.txt项目名称.MinimumSize = new System.Drawing.Size(0, 0);
- this.txt项目名称.TabIndex = 2;
- this.txt项目名称.TabStop = true;
- this.txt项目名称.Size = new System.Drawing.Size(570, 21);
- this.txt项目名称.Location = new System.Drawing.Point(95, 55);
- this.txt项目名称.Name = "txt项目名称";
-
- //
- // lbl客户名称
- //
- this.lbl客户名称.Dock = System.Windows.Forms.DockStyle.None;
- this.lbl客户名称.AutoSize = false;
- this.lbl客户名称.AutoEllipsis = false;
- this.lbl客户名称.BorderStyle = System.Windows.Forms.BorderStyle.None;
- this.lbl客户名称.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
- this.lbl客户名称.ImageAlign = System.Drawing.ContentAlignment.MiddleCenter;
- this.lbl客户名称.LiveSetting = System.Windows.Forms.Automation.AutomationLiveSetting.Off;
- this.lbl客户名称.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
- this.lbl客户名称.UseCompatibleTextRendering = false;
- this.lbl客户名称.UseMnemonic = true;
- this.lbl客户名称.BackColor = System.Drawing.SystemColors.Control;
- this.lbl客户名称.Enabled = true;
- this.lbl客户名称.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.lbl客户名称.ForeColor = System.Drawing.SystemColors.ControlText;
- this.lbl客户名称.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
- this.lbl客户名称.MaximumSize = new System.Drawing.Size(0, 0);
- this.lbl客户名称.MinimumSize = new System.Drawing.Size(0, 0);
- this.lbl客户名称.TabIndex = 3;
- this.lbl客户名称.Padding = new System.Windows.Forms.Padding(0, 0, 0, 0);
- this.lbl客户名称.Size = new System.Drawing.Size(70, 23);
- this.lbl客户名称.Location = new System.Drawing.Point(20, 85);
- this.lbl客户名称.Text = "客户名称:";
- this.lbl客户名称.Name = "lbl客户名称";
-
- //
- // txt客户名称
- //
- this.txt客户名称.Dock = System.Windows.Forms.DockStyle.None;
- this.txt客户名称.AcceptsReturn = false;
- this.txt客户名称.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.None;
- this.txt客户名称.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.None;
- this.txt客户名称.CharacterCasing = System.Windows.Forms.CharacterCasing.Normal;
- this.txt客户名称.Multiline = false;
- this.txt客户名称.ScrollBars = System.Windows.Forms.ScrollBars.None;
- this.txt客户名称.TextAlign = System.Windows.Forms.HorizontalAlignment.Left;
- this.txt客户名称.UseSystemPasswordChar = false;
- this.txt客户名称.AcceptsTab = false;
- this.txt客户名称.ShortcutsEnabled = true;
- this.txt客户名称.BackColor = System.Drawing.SystemColors.Window;
- this.txt客户名称.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
- this.txt客户名称.ForeColor = System.Drawing.SystemColors.WindowText;
- this.txt客户名称.HideSelection = true;
- this.txt客户名称.MaxLength = 32767;
- this.txt客户名称.ReadOnly = false;
- this.txt客户名称.WordWrap = true;
- this.txt客户名称.Enabled = true;
- this.txt客户名称.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.txt客户名称.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.txt客户名称.MaximumSize = new System.Drawing.Size(0, 0);
- this.txt客户名称.MinimumSize = new System.Drawing.Size(0, 0);
- this.txt客户名称.TabIndex = 3;
- this.txt客户名称.TabStop = true;
- this.txt客户名称.Size = new System.Drawing.Size(479, 21);
- this.txt客户名称.Location = new System.Drawing.Point(95, 85);
- this.txt客户名称.Name = "txt客户名称";
-
- //
- // btn选择客户
- //
- this.btn选择客户.Dock = System.Windows.Forms.DockStyle.None;
- this.btn选择客户.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowOnly;
- this.btn选择客户.DialogResult = System.Windows.Forms.DialogResult.None;
- this.btn选择客户.AutoEllipsis = false;
- this.btn选择客户.AutoSize = false;
- this.btn选择客户.BackColor = System.Drawing.SystemColors.Control;
- this.btn选择客户.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
- this.btn选择客户.ImageAlign = System.Drawing.ContentAlignment.MiddleCenter;
- this.btn选择客户.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
- this.btn选择客户.TextImageRelation = System.Windows.Forms.TextImageRelation.Overlay;
- this.btn选择客户.UseMnemonic = true;
- this.btn选择客户.UseCompatibleTextRendering = false;
- this.btn选择客户.UseVisualStyleBackColor = true;
- this.btn选择客户.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Tile;
- this.btn选择客户.Enabled = true;
- this.btn选择客户.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.btn选择客户.ForeColor = System.Drawing.SystemColors.ControlText;
- this.btn选择客户.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.btn选择客户.MaximumSize = new System.Drawing.Size(0, 0);
- this.btn选择客户.MinimumSize = new System.Drawing.Size(0, 0);
- this.btn选择客户.TabIndex = 4;
- this.btn选择客户.TabStop = true;
- this.btn选择客户.Padding = new System.Windows.Forms.Padding(0, 0, 0, 0);
- this.btn选择客户.Size = new System.Drawing.Size(85, 23);
- this.btn选择客户.Location = new System.Drawing.Point(580, 85);
- this.btn选择客户.Text = "选择客户";
- this.btn选择客户.Name = "btn选择客户";
-
- //
- // lbl客户地址
- //
- this.lbl客户地址.Dock = System.Windows.Forms.DockStyle.None;
- this.lbl客户地址.AutoSize = false;
- this.lbl客户地址.AutoEllipsis = false;
- this.lbl客户地址.BorderStyle = System.Windows.Forms.BorderStyle.None;
- this.lbl客户地址.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
- this.lbl客户地址.ImageAlign = System.Drawing.ContentAlignment.MiddleCenter;
- this.lbl客户地址.LiveSetting = System.Windows.Forms.Automation.AutomationLiveSetting.Off;
- this.lbl客户地址.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
- this.lbl客户地址.UseCompatibleTextRendering = false;
- this.lbl客户地址.UseMnemonic = true;
- this.lbl客户地址.BackColor = System.Drawing.SystemColors.Control;
- this.lbl客户地址.Enabled = true;
- this.lbl客户地址.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.lbl客户地址.ForeColor = System.Drawing.SystemColors.ControlText;
- this.lbl客户地址.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
- this.lbl客户地址.MaximumSize = new System.Drawing.Size(0, 0);
- this.lbl客户地址.MinimumSize = new System.Drawing.Size(0, 0);
- this.lbl客户地址.TabIndex = 5;
- this.lbl客户地址.Padding = new System.Windows.Forms.Padding(0, 0, 0, 0);
- this.lbl客户地址.Size = new System.Drawing.Size(70, 23);
- this.lbl客户地址.Location = new System.Drawing.Point(20, 115);
- this.lbl客户地址.Text = "客户地址:";
- this.lbl客户地址.Name = "lbl客户地址";
-
- //
- // txt客户地址
- //
- this.txt客户地址.Dock = System.Windows.Forms.DockStyle.None;
- this.txt客户地址.AcceptsReturn = false;
- this.txt客户地址.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.None;
- this.txt客户地址.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.None;
- this.txt客户地址.CharacterCasing = System.Windows.Forms.CharacterCasing.Normal;
- this.txt客户地址.Multiline = false;
- this.txt客户地址.ScrollBars = System.Windows.Forms.ScrollBars.None;
- this.txt客户地址.TextAlign = System.Windows.Forms.HorizontalAlignment.Left;
- this.txt客户地址.UseSystemPasswordChar = false;
- this.txt客户地址.AcceptsTab = false;
- this.txt客户地址.ShortcutsEnabled = true;
- this.txt客户地址.BackColor = System.Drawing.SystemColors.Window;
- this.txt客户地址.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
- this.txt客户地址.ForeColor = System.Drawing.SystemColors.WindowText;
- this.txt客户地址.HideSelection = true;
- this.txt客户地址.MaxLength = 32767;
- this.txt客户地址.ReadOnly = false;
- this.txt客户地址.WordWrap = true;
- this.txt客户地址.Enabled = true;
- this.txt客户地址.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.txt客户地址.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.txt客户地址.MaximumSize = new System.Drawing.Size(0, 0);
- this.txt客户地址.MinimumSize = new System.Drawing.Size(0, 0);
- this.txt客户地址.TabIndex = 5;
- this.txt客户地址.TabStop = true;
- this.txt客户地址.Size = new System.Drawing.Size(570, 21);
- this.txt客户地址.Location = new System.Drawing.Point(95, 115);
- this.txt客户地址.Name = "txt客户地址";
-
- //
- // lbl联系人
- //
- this.lbl联系人.Dock = System.Windows.Forms.DockStyle.None;
- this.lbl联系人.AutoSize = false;
- this.lbl联系人.AutoEllipsis = false;
- this.lbl联系人.BorderStyle = System.Windows.Forms.BorderStyle.None;
- this.lbl联系人.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
- this.lbl联系人.ImageAlign = System.Drawing.ContentAlignment.MiddleCenter;
- this.lbl联系人.LiveSetting = System.Windows.Forms.Automation.AutomationLiveSetting.Off;
- this.lbl联系人.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
- this.lbl联系人.UseCompatibleTextRendering = false;
- this.lbl联系人.UseMnemonic = true;
- this.lbl联系人.BackColor = System.Drawing.SystemColors.Control;
- this.lbl联系人.Enabled = true;
- this.lbl联系人.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.lbl联系人.ForeColor = System.Drawing.SystemColors.ControlText;
- this.lbl联系人.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
- this.lbl联系人.MaximumSize = new System.Drawing.Size(0, 0);
- this.lbl联系人.MinimumSize = new System.Drawing.Size(0, 0);
- this.lbl联系人.TabIndex = 6;
- this.lbl联系人.Padding = new System.Windows.Forms.Padding(0, 0, 0, 0);
- this.lbl联系人.Size = new System.Drawing.Size(60, 23);
- this.lbl联系人.Location = new System.Drawing.Point(30, 145);
- this.lbl联系人.Text = "联系人:";
- this.lbl联系人.Name = "lbl联系人";
-
- //
- // txt联系人
- //
- this.txt联系人.Dock = System.Windows.Forms.DockStyle.None;
- this.txt联系人.AcceptsReturn = false;
- this.txt联系人.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.None;
- this.txt联系人.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.None;
- this.txt联系人.CharacterCasing = System.Windows.Forms.CharacterCasing.Normal;
- this.txt联系人.Multiline = false;
- this.txt联系人.ScrollBars = System.Windows.Forms.ScrollBars.None;
- this.txt联系人.TextAlign = System.Windows.Forms.HorizontalAlignment.Left;
- this.txt联系人.UseSystemPasswordChar = false;
- this.txt联系人.AcceptsTab = false;
- this.txt联系人.ShortcutsEnabled = true;
- this.txt联系人.BackColor = System.Drawing.SystemColors.Window;
- this.txt联系人.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
- this.txt联系人.ForeColor = System.Drawing.SystemColors.WindowText;
- this.txt联系人.HideSelection = true;
- this.txt联系人.MaxLength = 32767;
- this.txt联系人.ReadOnly = false;
- this.txt联系人.WordWrap = true;
- this.txt联系人.Enabled = true;
- this.txt联系人.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.txt联系人.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.txt联系人.MaximumSize = new System.Drawing.Size(0, 0);
- this.txt联系人.MinimumSize = new System.Drawing.Size(0, 0);
- this.txt联系人.TabIndex = 6;
- this.txt联系人.TabStop = true;
- this.txt联系人.Size = new System.Drawing.Size(220, 21);
- this.txt联系人.Location = new System.Drawing.Point(95, 145);
- this.txt联系人.Name = "txt联系人";
-
- //
- // lbl联系电话
- //
- this.lbl联系电话.Dock = System.Windows.Forms.DockStyle.None;
- this.lbl联系电话.AutoSize = false;
- this.lbl联系电话.AutoEllipsis = false;
- this.lbl联系电话.BorderStyle = System.Windows.Forms.BorderStyle.None;
- this.lbl联系电话.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
- this.lbl联系电话.ImageAlign = System.Drawing.ContentAlignment.MiddleCenter;
- this.lbl联系电话.LiveSetting = System.Windows.Forms.Automation.AutomationLiveSetting.Off;
- this.lbl联系电话.TextAlign = System.Drawing.ContentAlignment.TopLeft;
- this.lbl联系电话.UseCompatibleTextRendering = false;
- this.lbl联系电话.UseMnemonic = true;
- this.lbl联系电话.BackColor = System.Drawing.SystemColors.Control;
- this.lbl联系电话.Enabled = true;
- this.lbl联系电话.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.lbl联系电话.ForeColor = System.Drawing.SystemColors.ControlText;
- this.lbl联系电话.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
- this.lbl联系电话.MaximumSize = new System.Drawing.Size(0, 0);
- this.lbl联系电话.MinimumSize = new System.Drawing.Size(0, 0);
- this.lbl联系电话.TabIndex = 7;
- this.lbl联系电话.Padding = new System.Windows.Forms.Padding(0, 0, 0, 0);
- this.lbl联系电话.Size = new System.Drawing.Size(70, 21);
- this.lbl联系电话.Location = new System.Drawing.Point(380, 145);
- this.lbl联系电话.Text = "联系电话:";
- this.lbl联系电话.Name = "lbl联系电话";
-
- //
- // txt联系电话
- //
- this.txt联系电话.Dock = System.Windows.Forms.DockStyle.None;
- this.txt联系电话.AcceptsReturn = false;
- this.txt联系电话.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.None;
- this.txt联系电话.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.None;
- this.txt联系电话.CharacterCasing = System.Windows.Forms.CharacterCasing.Normal;
- this.txt联系电话.Multiline = false;
- this.txt联系电话.ScrollBars = System.Windows.Forms.ScrollBars.None;
- this.txt联系电话.TextAlign = System.Windows.Forms.HorizontalAlignment.Left;
- this.txt联系电话.UseSystemPasswordChar = false;
- this.txt联系电话.AcceptsTab = false;
- this.txt联系电话.ShortcutsEnabled = true;
- this.txt联系电话.BackColor = System.Drawing.SystemColors.Window;
- this.txt联系电话.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
- this.txt联系电话.ForeColor = System.Drawing.SystemColors.WindowText;
- this.txt联系电话.HideSelection = true;
- this.txt联系电话.MaxLength = 32767;
- this.txt联系电话.ReadOnly = false;
- this.txt联系电话.WordWrap = true;
- this.txt联系电话.Enabled = true;
- this.txt联系电话.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.txt联系电话.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.txt联系电话.MaximumSize = new System.Drawing.Size(0, 0);
- this.txt联系电话.MinimumSize = new System.Drawing.Size(0, 0);
- this.txt联系电话.TabIndex = 7;
- this.txt联系电话.TabStop = true;
- this.txt联系电话.Size = new System.Drawing.Size(210, 21);
- this.txt联系电话.Location = new System.Drawing.Point(455, 145);
- this.txt联系电话.Name = "txt联系电话";
-
- //
- // lbl成套厂名称
- //
- this.lbl成套厂名称.Dock = System.Windows.Forms.DockStyle.None;
- this.lbl成套厂名称.AutoSize = false;
- this.lbl成套厂名称.AutoEllipsis = false;
- this.lbl成套厂名称.BorderStyle = System.Windows.Forms.BorderStyle.None;
- this.lbl成套厂名称.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
- this.lbl成套厂名称.ImageAlign = System.Drawing.ContentAlignment.MiddleCenter;
- this.lbl成套厂名称.LiveSetting = System.Windows.Forms.Automation.AutomationLiveSetting.Off;
- this.lbl成套厂名称.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
- this.lbl成套厂名称.UseCompatibleTextRendering = false;
- this.lbl成套厂名称.UseMnemonic = true;
- this.lbl成套厂名称.BackColor = System.Drawing.SystemColors.Control;
- this.lbl成套厂名称.Enabled = true;
- this.lbl成套厂名称.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.lbl成套厂名称.ForeColor = System.Drawing.SystemColors.ControlText;
- this.lbl成套厂名称.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
- this.lbl成套厂名称.MaximumSize = new System.Drawing.Size(0, 0);
- this.lbl成套厂名称.MinimumSize = new System.Drawing.Size(0, 0);
- this.lbl成套厂名称.TabIndex = 8;
- this.lbl成套厂名称.Padding = new System.Windows.Forms.Padding(0, 0, 0, 0);
- this.lbl成套厂名称.Size = new System.Drawing.Size(80, 23);
- this.lbl成套厂名称.Location = new System.Drawing.Point(10, 175);
- this.lbl成套厂名称.Text = "成套厂名称:";
- this.lbl成套厂名称.Name = "lbl成套厂名称";
-
- //
- // txt成套厂名称
- //
- this.txt成套厂名称.Dock = System.Windows.Forms.DockStyle.None;
- this.txt成套厂名称.AcceptsReturn = false;
- this.txt成套厂名称.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.None;
- this.txt成套厂名称.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.None;
- this.txt成套厂名称.CharacterCasing = System.Windows.Forms.CharacterCasing.Normal;
- this.txt成套厂名称.Multiline = false;
- this.txt成套厂名称.ScrollBars = System.Windows.Forms.ScrollBars.None;
- this.txt成套厂名称.TextAlign = System.Windows.Forms.HorizontalAlignment.Left;
- this.txt成套厂名称.UseSystemPasswordChar = false;
- this.txt成套厂名称.AcceptsTab = false;
- this.txt成套厂名称.ShortcutsEnabled = true;
- this.txt成套厂名称.BackColor = System.Drawing.SystemColors.Window;
- this.txt成套厂名称.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
- this.txt成套厂名称.ForeColor = System.Drawing.SystemColors.WindowText;
- this.txt成套厂名称.HideSelection = true;
- this.txt成套厂名称.MaxLength = 32767;
- this.txt成套厂名称.ReadOnly = false;
- this.txt成套厂名称.WordWrap = true;
- this.txt成套厂名称.Enabled = true;
- this.txt成套厂名称.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.txt成套厂名称.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.txt成套厂名称.MaximumSize = new System.Drawing.Size(0, 0);
- this.txt成套厂名称.MinimumSize = new System.Drawing.Size(0, 0);
- this.txt成套厂名称.TabIndex = 8;
- this.txt成套厂名称.TabStop = true;
- this.txt成套厂名称.Size = new System.Drawing.Size(570, 21);
- this.txt成套厂名称.Location = new System.Drawing.Point(95, 175);
- this.txt成套厂名称.Name = "txt成套厂名称";
-
- //
- // lbl成套厂地址
- //
- this.lbl成套厂地址.Dock = System.Windows.Forms.DockStyle.None;
- this.lbl成套厂地址.AutoSize = false;
- this.lbl成套厂地址.AutoEllipsis = false;
- this.lbl成套厂地址.BorderStyle = System.Windows.Forms.BorderStyle.None;
- this.lbl成套厂地址.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
- this.lbl成套厂地址.ImageAlign = System.Drawing.ContentAlignment.MiddleCenter;
- this.lbl成套厂地址.LiveSetting = System.Windows.Forms.Automation.AutomationLiveSetting.Off;
- this.lbl成套厂地址.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
- this.lbl成套厂地址.UseCompatibleTextRendering = false;
- this.lbl成套厂地址.UseMnemonic = true;
- this.lbl成套厂地址.BackColor = System.Drawing.SystemColors.Control;
- this.lbl成套厂地址.Enabled = true;
- this.lbl成套厂地址.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.lbl成套厂地址.ForeColor = System.Drawing.SystemColors.ControlText;
- this.lbl成套厂地址.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
- this.lbl成套厂地址.MaximumSize = new System.Drawing.Size(0, 0);
- this.lbl成套厂地址.MinimumSize = new System.Drawing.Size(0, 0);
- this.lbl成套厂地址.TabIndex = 9;
- this.lbl成套厂地址.Padding = new System.Windows.Forms.Padding(0, 0, 0, 0);
- this.lbl成套厂地址.Size = new System.Drawing.Size(80, 23);
- this.lbl成套厂地址.Location = new System.Drawing.Point(10, 205);
- this.lbl成套厂地址.Text = "成套厂地址:";
- this.lbl成套厂地址.Name = "lbl成套厂地址";
-
- //
- // txt成套厂地址
- //
- this.txt成套厂地址.Dock = System.Windows.Forms.DockStyle.None;
- this.txt成套厂地址.AcceptsReturn = false;
- this.txt成套厂地址.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.None;
- this.txt成套厂地址.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.None;
- this.txt成套厂地址.CharacterCasing = System.Windows.Forms.CharacterCasing.Normal;
- this.txt成套厂地址.Multiline = false;
- this.txt成套厂地址.ScrollBars = System.Windows.Forms.ScrollBars.None;
- this.txt成套厂地址.TextAlign = System.Windows.Forms.HorizontalAlignment.Left;
- this.txt成套厂地址.UseSystemPasswordChar = false;
- this.txt成套厂地址.AcceptsTab = false;
- this.txt成套厂地址.ShortcutsEnabled = true;
- this.txt成套厂地址.BackColor = System.Drawing.SystemColors.Window;
- this.txt成套厂地址.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
- this.txt成套厂地址.ForeColor = System.Drawing.SystemColors.WindowText;
- this.txt成套厂地址.HideSelection = true;
- this.txt成套厂地址.MaxLength = 32767;
- this.txt成套厂地址.ReadOnly = false;
- this.txt成套厂地址.WordWrap = true;
- this.txt成套厂地址.Enabled = true;
- this.txt成套厂地址.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.txt成套厂地址.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.txt成套厂地址.MaximumSize = new System.Drawing.Size(0, 0);
- this.txt成套厂地址.MinimumSize = new System.Drawing.Size(0, 0);
- this.txt成套厂地址.TabIndex = 9;
- this.txt成套厂地址.TabStop = true;
- this.txt成套厂地址.Size = new System.Drawing.Size(570, 21);
- this.txt成套厂地址.Location = new System.Drawing.Point(95, 205);
- this.txt成套厂地址.Name = "txt成套厂地址";
-
- //
- // lbl成套厂联系人
- //
- this.lbl成套厂联系人.Dock = System.Windows.Forms.DockStyle.None;
- this.lbl成套厂联系人.AutoSize = false;
- this.lbl成套厂联系人.AutoEllipsis = false;
- this.lbl成套厂联系人.BorderStyle = System.Windows.Forms.BorderStyle.None;
- this.lbl成套厂联系人.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
- this.lbl成套厂联系人.ImageAlign = System.Drawing.ContentAlignment.MiddleCenter;
- this.lbl成套厂联系人.LiveSetting = System.Windows.Forms.Automation.AutomationLiveSetting.Off;
- this.lbl成套厂联系人.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
- this.lbl成套厂联系人.UseCompatibleTextRendering = false;
- this.lbl成套厂联系人.UseMnemonic = true;
- this.lbl成套厂联系人.BackColor = System.Drawing.SystemColors.Control;
- this.lbl成套厂联系人.Enabled = true;
- this.lbl成套厂联系人.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.lbl成套厂联系人.ForeColor = System.Drawing.SystemColors.ControlText;
- this.lbl成套厂联系人.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
- this.lbl成套厂联系人.MaximumSize = new System.Drawing.Size(0, 0);
- this.lbl成套厂联系人.MinimumSize = new System.Drawing.Size(0, 0);
- this.lbl成套厂联系人.TabIndex = 10;
- this.lbl成套厂联系人.Padding = new System.Windows.Forms.Padding(0, 0, 0, 0);
- this.lbl成套厂联系人.Size = new System.Drawing.Size(60, 23);
- this.lbl成套厂联系人.Location = new System.Drawing.Point(30, 235);
- this.lbl成套厂联系人.Text = "联系人:";
- this.lbl成套厂联系人.Name = "lbl成套厂联系人";
-
- //
- // txt成套厂联系人
- //
- this.txt成套厂联系人.Dock = System.Windows.Forms.DockStyle.None;
- this.txt成套厂联系人.AcceptsReturn = false;
- this.txt成套厂联系人.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.None;
- this.txt成套厂联系人.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.None;
- this.txt成套厂联系人.CharacterCasing = System.Windows.Forms.CharacterCasing.Normal;
- this.txt成套厂联系人.Multiline = false;
- this.txt成套厂联系人.ScrollBars = System.Windows.Forms.ScrollBars.None;
- this.txt成套厂联系人.TextAlign = System.Windows.Forms.HorizontalAlignment.Left;
- this.txt成套厂联系人.UseSystemPasswordChar = false;
- this.txt成套厂联系人.AcceptsTab = false;
- this.txt成套厂联系人.ShortcutsEnabled = true;
- this.txt成套厂联系人.BackColor = System.Drawing.SystemColors.Window;
- this.txt成套厂联系人.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
- this.txt成套厂联系人.ForeColor = System.Drawing.SystemColors.WindowText;
- this.txt成套厂联系人.HideSelection = true;
- this.txt成套厂联系人.MaxLength = 32767;
- this.txt成套厂联系人.ReadOnly = false;
- this.txt成套厂联系人.WordWrap = true;
- this.txt成套厂联系人.Enabled = true;
- this.txt成套厂联系人.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.txt成套厂联系人.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.txt成套厂联系人.MaximumSize = new System.Drawing.Size(0, 0);
- this.txt成套厂联系人.MinimumSize = new System.Drawing.Size(0, 0);
- this.txt成套厂联系人.TabIndex = 10;
- this.txt成套厂联系人.TabStop = true;
- this.txt成套厂联系人.Size = new System.Drawing.Size(220, 21);
- this.txt成套厂联系人.Location = new System.Drawing.Point(95, 235);
- this.txt成套厂联系人.Name = "txt成套厂联系人";
-
- //
- // lbl成套厂联系电话
- //
- this.lbl成套厂联系电话.Dock = System.Windows.Forms.DockStyle.None;
- this.lbl成套厂联系电话.AutoSize = false;
- this.lbl成套厂联系电话.AutoEllipsis = false;
- this.lbl成套厂联系电话.BorderStyle = System.Windows.Forms.BorderStyle.None;
- this.lbl成套厂联系电话.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
- this.lbl成套厂联系电话.ImageAlign = System.Drawing.ContentAlignment.MiddleCenter;
- this.lbl成套厂联系电话.LiveSetting = System.Windows.Forms.Automation.AutomationLiveSetting.Off;
- this.lbl成套厂联系电话.TextAlign = System.Drawing.ContentAlignment.TopLeft;
- this.lbl成套厂联系电话.UseCompatibleTextRendering = false;
- this.lbl成套厂联系电话.UseMnemonic = true;
- this.lbl成套厂联系电话.BackColor = System.Drawing.SystemColors.Control;
- this.lbl成套厂联系电话.Enabled = true;
- this.lbl成套厂联系电话.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.lbl成套厂联系电话.ForeColor = System.Drawing.SystemColors.ControlText;
- this.lbl成套厂联系电话.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
- this.lbl成套厂联系电话.MaximumSize = new System.Drawing.Size(0, 0);
- this.lbl成套厂联系电话.MinimumSize = new System.Drawing.Size(0, 0);
- this.lbl成套厂联系电话.TabIndex = 11;
- this.lbl成套厂联系电话.Padding = new System.Windows.Forms.Padding(0, 0, 0, 0);
- this.lbl成套厂联系电话.Size = new System.Drawing.Size(70, 21);
- this.lbl成套厂联系电话.Location = new System.Drawing.Point(380, 235);
- this.lbl成套厂联系电话.Text = "联系电话:";
- this.lbl成套厂联系电话.Name = "lbl成套厂联系电话";
-
- //
- // txt成套厂联系电话
- //
- this.txt成套厂联系电话.Dock = System.Windows.Forms.DockStyle.None;
- this.txt成套厂联系电话.AcceptsReturn = false;
- this.txt成套厂联系电话.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.None;
- this.txt成套厂联系电话.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.None;
- this.txt成套厂联系电话.CharacterCasing = System.Windows.Forms.CharacterCasing.Normal;
- this.txt成套厂联系电话.Multiline = false;
- this.txt成套厂联系电话.ScrollBars = System.Windows.Forms.ScrollBars.None;
- this.txt成套厂联系电话.TextAlign = System.Windows.Forms.HorizontalAlignment.Left;
- this.txt成套厂联系电话.UseSystemPasswordChar = false;
- this.txt成套厂联系电话.AcceptsTab = false;
- this.txt成套厂联系电话.ShortcutsEnabled = true;
- this.txt成套厂联系电话.BackColor = System.Drawing.SystemColors.Window;
- this.txt成套厂联系电话.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
- this.txt成套厂联系电话.ForeColor = System.Drawing.SystemColors.WindowText;
- this.txt成套厂联系电话.HideSelection = true;
- this.txt成套厂联系电话.MaxLength = 32767;
- this.txt成套厂联系电话.ReadOnly = false;
- this.txt成套厂联系电话.WordWrap = true;
- this.txt成套厂联系电话.Enabled = true;
- this.txt成套厂联系电话.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.txt成套厂联系电话.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.txt成套厂联系电话.MaximumSize = new System.Drawing.Size(0, 0);
- this.txt成套厂联系电话.MinimumSize = new System.Drawing.Size(0, 0);
- this.txt成套厂联系电话.TabIndex = 11;
- this.txt成套厂联系电话.TabStop = true;
- this.txt成套厂联系电话.Size = new System.Drawing.Size(210, 21);
- this.txt成套厂联系电话.Location = new System.Drawing.Point(455, 232);
- this.txt成套厂联系电话.Name = "txt成套厂联系电话";
-
- //
- // lbl报出方式
- //
- this.lbl报出方式.Dock = System.Windows.Forms.DockStyle.None;
- this.lbl报出方式.AutoSize = false;
- this.lbl报出方式.AutoEllipsis = false;
- this.lbl报出方式.BorderStyle = System.Windows.Forms.BorderStyle.None;
- this.lbl报出方式.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
- this.lbl报出方式.ImageAlign = System.Drawing.ContentAlignment.MiddleCenter;
- this.lbl报出方式.LiveSetting = System.Windows.Forms.Automation.AutomationLiveSetting.Off;
- this.lbl报出方式.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
- this.lbl报出方式.UseCompatibleTextRendering = false;
- this.lbl报出方式.UseMnemonic = true;
- this.lbl报出方式.BackColor = System.Drawing.SystemColors.Control;
- this.lbl报出方式.Enabled = true;
- this.lbl报出方式.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.lbl报出方式.ForeColor = System.Drawing.SystemColors.ControlText;
- this.lbl报出方式.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
- this.lbl报出方式.MaximumSize = new System.Drawing.Size(0, 0);
- this.lbl报出方式.MinimumSize = new System.Drawing.Size(0, 0);
- this.lbl报出方式.TabIndex = 12;
- this.lbl报出方式.Padding = new System.Windows.Forms.Padding(0, 0, 0, 0);
- this.lbl报出方式.Size = new System.Drawing.Size(70, 23);
- this.lbl报出方式.Location = new System.Drawing.Point(20, 265);
- this.lbl报出方式.Text = "报出方式:";
- this.lbl报出方式.Name = "lbl报出方式";
-
- //
- // cmb报出方式
- //
- this.cmb报出方式.Dock = System.Windows.Forms.DockStyle.None;
- this.cmb报出方式.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.None;
- this.cmb报出方式.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.None;
- this.cmb报出方式.BackColor = System.Drawing.SystemColors.Window;
- this.cmb报出方式.DrawMode = System.Windows.Forms.DrawMode.Normal;
- this.cmb报出方式.DropDownWidth = 200;
- this.cmb报出方式.DropDownHeight = 106;
- this.cmb报出方式.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
- this.cmb报出方式.ForeColor = System.Drawing.SystemColors.WindowText;
- this.cmb报出方式.IntegralHeight = true;
- this.cmb报出方式.ItemHeight = 12;
- this.cmb报出方式.MaxDropDownItems = 8;
- this.cmb报出方式.MaximumSize = new System.Drawing.Size(0, 0);
- this.cmb报出方式.MinimumSize = new System.Drawing.Size(0, 0);
- this.cmb报出方式.MaxLength = 0;
- this.cmb报出方式.Sorted = false;
- this.cmb报出方式.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDown;
- this.cmb报出方式.FormattingEnabled = false;
- this.cmb报出方式.Enabled = true;
- this.cmb报出方式.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.cmb报出方式.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.cmb报出方式.TabIndex = 12;
- this.cmb报出方式.TabStop = true;
- this.cmb报出方式.Size = new System.Drawing.Size(220, 20);
- this.cmb报出方式.Location = new System.Drawing.Point(95, 265);
- this.cmb报出方式.Text = "报出价=表价*采购系数*报出系数";
- this.cmb报出方式.Name = "cmb报出方式";
-
- //
- // lbl箱柜模板
- //
- this.lbl箱柜模板.Dock = System.Windows.Forms.DockStyle.None;
- this.lbl箱柜模板.AutoSize = false;
- this.lbl箱柜模板.AutoEllipsis = false;
- this.lbl箱柜模板.BorderStyle = System.Windows.Forms.BorderStyle.None;
- this.lbl箱柜模板.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
- this.lbl箱柜模板.ImageAlign = System.Drawing.ContentAlignment.MiddleCenter;
- this.lbl箱柜模板.LiveSetting = System.Windows.Forms.Automation.AutomationLiveSetting.Off;
- this.lbl箱柜模板.TextAlign = System.Drawing.ContentAlignment.TopLeft;
- this.lbl箱柜模板.UseCompatibleTextRendering = false;
- this.lbl箱柜模板.UseMnemonic = true;
- this.lbl箱柜模板.BackColor = System.Drawing.SystemColors.Control;
- this.lbl箱柜模板.Enabled = true;
- this.lbl箱柜模板.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.lbl箱柜模板.ForeColor = System.Drawing.SystemColors.ControlText;
- this.lbl箱柜模板.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
- this.lbl箱柜模板.MaximumSize = new System.Drawing.Size(0, 0);
- this.lbl箱柜模板.MinimumSize = new System.Drawing.Size(0, 0);
- this.lbl箱柜模板.TabIndex = 13;
- this.lbl箱柜模板.Padding = new System.Windows.Forms.Padding(0, 0, 0, 0);
- this.lbl箱柜模板.Size = new System.Drawing.Size(70, 20);
- this.lbl箱柜模板.Location = new System.Drawing.Point(380, 265);
- this.lbl箱柜模板.Text = "箱柜模板:";
- this.lbl箱柜模板.Name = "lbl箱柜模板";
-
- //
- // cmb箱柜模板
- //
- this.cmb箱柜模板.Dock = System.Windows.Forms.DockStyle.None;
- this.cmb箱柜模板.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.None;
- this.cmb箱柜模板.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.None;
- this.cmb箱柜模板.BackColor = System.Drawing.SystemColors.Window;
- this.cmb箱柜模板.DrawMode = System.Windows.Forms.DrawMode.Normal;
- this.cmb箱柜模板.DropDownWidth = 200;
- this.cmb箱柜模板.DropDownHeight = 106;
- this.cmb箱柜模板.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
- this.cmb箱柜模板.ForeColor = System.Drawing.SystemColors.WindowText;
- this.cmb箱柜模板.IntegralHeight = true;
- this.cmb箱柜模板.ItemHeight = 12;
- this.cmb箱柜模板.MaxDropDownItems = 8;
- this.cmb箱柜模板.MaximumSize = new System.Drawing.Size(0, 0);
- this.cmb箱柜模板.MinimumSize = new System.Drawing.Size(0, 0);
- this.cmb箱柜模板.MaxLength = 0;
- this.cmb箱柜模板.Sorted = false;
- this.cmb箱柜模板.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDown;
- this.cmb箱柜模板.FormattingEnabled = false;
- this.cmb箱柜模板.Enabled = true;
- this.cmb箱柜模板.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.cmb箱柜模板.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.cmb箱柜模板.TabIndex = 13;
- this.cmb箱柜模板.TabStop = true;
- this.cmb箱柜模板.Size = new System.Drawing.Size(210, 20);
- this.cmb箱柜模板.Location = new System.Drawing.Point(455, 262);
- this.cmb箱柜模板.Name = "cmb箱柜模板";
-
- //
- // lbl单台价格
- //
- this.lbl单台价格.Dock = System.Windows.Forms.DockStyle.None;
- this.lbl单台价格.AutoSize = false;
- this.lbl单台价格.AutoEllipsis = false;
- this.lbl单台价格.BorderStyle = System.Windows.Forms.BorderStyle.None;
- this.lbl单台价格.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
- this.lbl单台价格.ImageAlign = System.Drawing.ContentAlignment.MiddleCenter;
- this.lbl单台价格.LiveSetting = System.Windows.Forms.Automation.AutomationLiveSetting.Off;
- this.lbl单台价格.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
- this.lbl单台价格.UseCompatibleTextRendering = false;
- this.lbl单台价格.UseMnemonic = true;
- this.lbl单台价格.BackColor = System.Drawing.SystemColors.Control;
- this.lbl单台价格.Enabled = true;
- this.lbl单台价格.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.lbl单台价格.ForeColor = System.Drawing.SystemColors.ControlText;
- this.lbl单台价格.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
- this.lbl单台价格.MaximumSize = new System.Drawing.Size(0, 0);
- this.lbl单台价格.MinimumSize = new System.Drawing.Size(0, 0);
- this.lbl单台价格.TabIndex = 14;
- this.lbl单台价格.Padding = new System.Windows.Forms.Padding(0, 0, 0, 0);
- this.lbl单台价格.Size = new System.Drawing.Size(70, 23);
- this.lbl单台价格.Location = new System.Drawing.Point(20, 293);
- this.lbl单台价格.Text = "单台价格:";
- this.lbl单台价格.Name = "lbl单台价格";
-
- //
- // cmb单台价格
- //
- this.cmb单台价格.Dock = System.Windows.Forms.DockStyle.None;
- this.cmb单台价格.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.None;
- this.cmb单台价格.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.None;
- this.cmb单台价格.BackColor = System.Drawing.SystemColors.Window;
- this.cmb单台价格.DrawMode = System.Windows.Forms.DrawMode.Normal;
- this.cmb单台价格.DropDownWidth = 200;
- this.cmb单台价格.DropDownHeight = 106;
- this.cmb单台价格.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
- this.cmb单台价格.ForeColor = System.Drawing.SystemColors.WindowText;
- this.cmb单台价格.IntegralHeight = true;
- this.cmb单台价格.ItemHeight = 12;
- this.cmb单台价格.MaxDropDownItems = 8;
- this.cmb单台价格.MaximumSize = new System.Drawing.Size(0, 0);
- this.cmb单台价格.MinimumSize = new System.Drawing.Size(0, 0);
- this.cmb单台价格.MaxLength = 0;
- this.cmb单台价格.Sorted = false;
- this.cmb单台价格.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDown;
- this.cmb单台价格.FormattingEnabled = false;
- this.cmb单台价格.Enabled = true;
- this.cmb单台价格.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.cmb单台价格.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.cmb单台价格.TabIndex = 14;
- this.cmb单台价格.TabStop = true;
- this.cmb单台价格.Size = new System.Drawing.Size(220, 20);
- this.cmb单台价格.Location = new System.Drawing.Point(95, 293);
- this.cmb单台价格.Text = "保留整数";
- this.cmb单台价格.Name = "cmb单台价格";
-
- //
- // lbl项目总价
- //
- this.lbl项目总价.Dock = System.Windows.Forms.DockStyle.None;
- this.lbl项目总价.AutoSize = false;
- this.lbl项目总价.AutoEllipsis = false;
- this.lbl项目总价.BorderStyle = System.Windows.Forms.BorderStyle.None;
- this.lbl项目总价.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
- this.lbl项目总价.ImageAlign = System.Drawing.ContentAlignment.MiddleCenter;
- this.lbl项目总价.LiveSetting = System.Windows.Forms.Automation.AutomationLiveSetting.Off;
- this.lbl项目总价.TextAlign = System.Drawing.ContentAlignment.TopLeft;
- this.lbl项目总价.UseCompatibleTextRendering = false;
- this.lbl项目总价.UseMnemonic = true;
- this.lbl项目总价.BackColor = System.Drawing.SystemColors.Control;
- this.lbl项目总价.Enabled = true;
- this.lbl项目总价.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.lbl项目总价.ForeColor = System.Drawing.SystemColors.ControlText;
- this.lbl项目总价.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
- this.lbl项目总价.MaximumSize = new System.Drawing.Size(0, 0);
- this.lbl项目总价.MinimumSize = new System.Drawing.Size(0, 0);
- this.lbl项目总价.TabIndex = 15;
- this.lbl项目总价.Padding = new System.Windows.Forms.Padding(0, 0, 0, 0);
- this.lbl项目总价.Size = new System.Drawing.Size(70, 20);
- this.lbl项目总价.Location = new System.Drawing.Point(379, 293);
- this.lbl项目总价.Text = "项目总价:";
- this.lbl项目总价.Name = "lbl项目总价";
-
- //
- // lbl备注
- //
- this.lbl备注.Dock = System.Windows.Forms.DockStyle.None;
- this.lbl备注.AutoSize = false;
- this.lbl备注.AutoEllipsis = false;
- this.lbl备注.BorderStyle = System.Windows.Forms.BorderStyle.None;
- this.lbl备注.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
- this.lbl备注.ImageAlign = System.Drawing.ContentAlignment.MiddleCenter;
- this.lbl备注.LiveSetting = System.Windows.Forms.Automation.AutomationLiveSetting.Off;
- this.lbl备注.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
- this.lbl备注.UseCompatibleTextRendering = false;
- this.lbl备注.UseMnemonic = true;
- this.lbl备注.BackColor = System.Drawing.SystemColors.Control;
- this.lbl备注.Enabled = true;
- this.lbl备注.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.lbl备注.ForeColor = System.Drawing.SystemColors.ControlText;
- this.lbl备注.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
- this.lbl备注.MaximumSize = new System.Drawing.Size(0, 0);
- this.lbl备注.MinimumSize = new System.Drawing.Size(0, 0);
- this.lbl备注.TabIndex = 16;
- this.lbl备注.Padding = new System.Windows.Forms.Padding(0, 0, 0, 0);
- this.lbl备注.Size = new System.Drawing.Size(46, 23);
- this.lbl备注.Location = new System.Drawing.Point(44, 352);
- this.lbl备注.Text = "备注:";
- this.lbl备注.Name = "lbl备注";
-
- //
- // txt备注
- //
- this.txt备注.Dock = System.Windows.Forms.DockStyle.None;
- this.txt备注.AcceptsReturn = false;
- this.txt备注.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.None;
- this.txt备注.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.None;
- this.txt备注.CharacterCasing = System.Windows.Forms.CharacterCasing.Normal;
- this.txt备注.Multiline = true;
- this.txt备注.ScrollBars = System.Windows.Forms.ScrollBars.None;
- this.txt备注.TextAlign = System.Windows.Forms.HorizontalAlignment.Left;
- this.txt备注.UseSystemPasswordChar = false;
- this.txt备注.AcceptsTab = false;
- this.txt备注.ShortcutsEnabled = true;
- this.txt备注.BackColor = System.Drawing.SystemColors.Window;
- this.txt备注.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
- this.txt备注.ForeColor = System.Drawing.SystemColors.WindowText;
- this.txt备注.HideSelection = true;
- this.txt备注.MaxLength = 32767;
- this.txt备注.ReadOnly = false;
- this.txt备注.WordWrap = true;
- this.txt备注.Enabled = true;
- this.txt备注.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.txt备注.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.txt备注.MaximumSize = new System.Drawing.Size(0, 0);
- this.txt备注.MinimumSize = new System.Drawing.Size(0, 0);
- this.txt备注.TabIndex = 16;
- this.txt备注.TabStop = true;
- this.txt备注.Size = new System.Drawing.Size(570, 80);
- this.txt备注.Location = new System.Drawing.Point(95, 352);
- this.txt备注.Name = "txt备注";
-
- //
- // btn确定
- //
- this.btn确定.Dock = System.Windows.Forms.DockStyle.None;
- this.btn确定.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowOnly;
- this.btn确定.DialogResult = System.Windows.Forms.DialogResult.OK;
- this.btn确定.AutoEllipsis = false;
- this.btn确定.AutoSize = false;
- this.btn确定.BackColor = System.Drawing.SystemColors.Control;
- this.btn确定.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
- this.btn确定.ImageAlign = System.Drawing.ContentAlignment.MiddleCenter;
- this.btn确定.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
- this.btn确定.TextImageRelation = System.Windows.Forms.TextImageRelation.Overlay;
- this.btn确定.UseMnemonic = true;
- this.btn确定.UseCompatibleTextRendering = false;
- this.btn确定.UseVisualStyleBackColor = true;
- this.btn确定.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Tile;
- this.btn确定.Enabled = true;
- this.btn确定.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.btn确定.ForeColor = System.Drawing.SystemColors.ControlText;
- this.btn确定.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.btn确定.MaximumSize = new System.Drawing.Size(0, 0);
- this.btn确定.MinimumSize = new System.Drawing.Size(0, 0);
- this.btn确定.TabIndex = 17;
- this.btn确定.TabStop = true;
- this.btn确定.Padding = new System.Windows.Forms.Padding(0, 0, 0, 0);
- this.btn确定.Size = new System.Drawing.Size(100, 28);
- this.btn确定.Location = new System.Drawing.Point(455, 449);
- this.btn确定.Text = "确定";
- this.btn确定.Name = "btn确定";
-
- //
- // btn取消
- //
- this.btn取消.Dock = System.Windows.Forms.DockStyle.None;
- this.btn取消.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowOnly;
- this.btn取消.DialogResult = System.Windows.Forms.DialogResult.Cancel;
- this.btn取消.AutoEllipsis = false;
- this.btn取消.AutoSize = false;
- this.btn取消.BackColor = System.Drawing.SystemColors.Control;
- this.btn取消.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
- this.btn取消.ImageAlign = System.Drawing.ContentAlignment.MiddleCenter;
- this.btn取消.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
- this.btn取消.TextImageRelation = System.Windows.Forms.TextImageRelation.Overlay;
- this.btn取消.UseMnemonic = true;
- this.btn取消.UseCompatibleTextRendering = false;
- this.btn取消.UseVisualStyleBackColor = true;
- this.btn取消.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Tile;
- this.btn取消.Enabled = true;
- this.btn取消.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.btn取消.ForeColor = System.Drawing.SystemColors.ControlText;
- this.btn取消.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.btn取消.MaximumSize = new System.Drawing.Size(0, 0);
- this.btn取消.MinimumSize = new System.Drawing.Size(0, 0);
- this.btn取消.TabIndex = 18;
- this.btn取消.TabStop = true;
- this.btn取消.Padding = new System.Windows.Forms.Padding(0, 0, 0, 0);
- this.btn取消.Size = new System.Drawing.Size(100, 28);
- this.btn取消.Location = new System.Drawing.Point(565, 449);
- this.btn取消.Text = "取消";
- this.btn取消.Name = "btn取消";
-
- //
- // comboBox1
- //
- this.comboBox1.Dock = System.Windows.Forms.DockStyle.None;
- this.comboBox1.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.None;
- this.comboBox1.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.None;
- this.comboBox1.BackColor = System.Drawing.SystemColors.Window;
- this.comboBox1.DrawMode = System.Windows.Forms.DrawMode.Normal;
- this.comboBox1.DropDownWidth = 210;
- this.comboBox1.DropDownHeight = 106;
- this.comboBox1.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
- this.comboBox1.ForeColor = System.Drawing.SystemColors.WindowText;
- this.comboBox1.IntegralHeight = true;
- this.comboBox1.ItemHeight = 12;
- this.comboBox1.MaxDropDownItems = 8;
- this.comboBox1.MaximumSize = new System.Drawing.Size(0, 0);
- this.comboBox1.MinimumSize = new System.Drawing.Size(0, 0);
- this.comboBox1.MaxLength = 0;
- this.comboBox1.Sorted = false;
- this.comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDown;
- this.comboBox1.FormattingEnabled = false;
- this.comboBox1.Enabled = true;
- this.comboBox1.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.comboBox1.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.comboBox1.TabIndex = 14;
- this.comboBox1.TabStop = true;
- this.comboBox1.Size = new System.Drawing.Size(210, 20);
- this.comboBox1.Location = new System.Drawing.Point(455, 322);
- this.comboBox1.Text = "四舍五入";
- this.comboBox1.Name = "comboBox1";
-
- //
- // label1
- //
- this.label1.Dock = System.Windows.Forms.DockStyle.None;
- this.label1.AutoSize = false;
- this.label1.AutoEllipsis = false;
- this.label1.BorderStyle = System.Windows.Forms.BorderStyle.None;
- this.label1.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
- this.label1.ImageAlign = System.Drawing.ContentAlignment.MiddleCenter;
- this.label1.LiveSetting = System.Windows.Forms.Automation.AutomationLiveSetting.Off;
- this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
- this.label1.UseCompatibleTextRendering = false;
- this.label1.UseMnemonic = true;
- this.label1.BackColor = System.Drawing.SystemColors.Control;
- this.label1.Enabled = true;
- this.label1.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.label1.ForeColor = System.Drawing.SystemColors.ControlText;
- this.label1.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
- this.label1.MaximumSize = new System.Drawing.Size(0, 0);
- this.label1.MinimumSize = new System.Drawing.Size(0, 0);
- this.label1.TabIndex = 14;
- this.label1.Padding = new System.Windows.Forms.Padding(0, 0, 0, 0);
- this.label1.Size = new System.Drawing.Size(70, 23);
- this.label1.Location = new System.Drawing.Point(19, 320);
- this.label1.Text = "单台取整:";
- this.label1.Name = "label1";
-
- //
- // label2
- //
- this.label2.Dock = System.Windows.Forms.DockStyle.None;
- this.label2.AutoSize = false;
- this.label2.AutoEllipsis = false;
- this.label2.BorderStyle = System.Windows.Forms.BorderStyle.None;
- this.label2.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
- this.label2.ImageAlign = System.Drawing.ContentAlignment.MiddleCenter;
- this.label2.LiveSetting = System.Windows.Forms.Automation.AutomationLiveSetting.Off;
- this.label2.TextAlign = System.Drawing.ContentAlignment.TopLeft;
- this.label2.UseCompatibleTextRendering = false;
- this.label2.UseMnemonic = true;
- this.label2.BackColor = System.Drawing.SystemColors.Control;
- this.label2.Enabled = true;
- this.label2.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.label2.ForeColor = System.Drawing.SystemColors.ControlText;
- this.label2.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
- this.label2.MaximumSize = new System.Drawing.Size(0, 0);
- this.label2.MinimumSize = new System.Drawing.Size(0, 0);
- this.label2.TabIndex = 15;
- this.label2.Padding = new System.Windows.Forms.Padding(0, 0, 0, 0);
- this.label2.Size = new System.Drawing.Size(70, 20);
- this.label2.Location = new System.Drawing.Point(379, 324);
- this.label2.Text = "项目取整:";
- this.label2.Name = "label2";
-
- //
- // comboBox2
- //
- this.comboBox2.Dock = System.Windows.Forms.DockStyle.None;
- this.comboBox2.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.None;
- this.comboBox2.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.None;
- this.comboBox2.BackColor = System.Drawing.SystemColors.Window;
- this.comboBox2.DrawMode = System.Windows.Forms.DrawMode.Normal;
- this.comboBox2.DropDownWidth = 220;
- this.comboBox2.DropDownHeight = 106;
- this.comboBox2.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
- this.comboBox2.ForeColor = System.Drawing.SystemColors.WindowText;
- this.comboBox2.IntegralHeight = true;
- this.comboBox2.ItemHeight = 12;
- this.comboBox2.MaxDropDownItems = 8;
- this.comboBox2.MaximumSize = new System.Drawing.Size(0, 0);
- this.comboBox2.MinimumSize = new System.Drawing.Size(0, 0);
- this.comboBox2.MaxLength = 0;
- this.comboBox2.Sorted = false;
- this.comboBox2.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDown;
- this.comboBox2.FormattingEnabled = false;
- this.comboBox2.Enabled = true;
- this.comboBox2.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.comboBox2.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.comboBox2.TabIndex = 14;
- this.comboBox2.TabStop = true;
- this.comboBox2.Size = new System.Drawing.Size(220, 20);
- this.comboBox2.Location = new System.Drawing.Point(95, 324);
- this.comboBox2.Text = "四舍五入";
- this.comboBox2.Name = "comboBox2";
-
- //
- // cmb项目总价
- //
- this.cmb项目总价.Dock = System.Windows.Forms.DockStyle.None;
- this.cmb项目总价.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.None;
- this.cmb项目总价.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.None;
- this.cmb项目总价.BackColor = System.Drawing.SystemColors.Window;
- this.cmb项目总价.DrawMode = System.Windows.Forms.DrawMode.Normal;
- this.cmb项目总价.DropDownWidth = 200;
- this.cmb项目总价.DropDownHeight = 106;
- this.cmb项目总价.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
- this.cmb项目总价.ForeColor = System.Drawing.SystemColors.WindowText;
- this.cmb项目总价.IntegralHeight = true;
- this.cmb项目总价.ItemHeight = 12;
- this.cmb项目总价.MaxDropDownItems = 8;
- this.cmb项目总价.MaximumSize = new System.Drawing.Size(0, 0);
- this.cmb项目总价.MinimumSize = new System.Drawing.Size(0, 0);
- this.cmb项目总价.MaxLength = 0;
- this.cmb项目总价.Sorted = false;
- this.cmb项目总价.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDown;
- this.cmb项目总价.FormattingEnabled = false;
- this.cmb项目总价.Enabled = true;
- this.cmb项目总价.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.cmb项目总价.Margin = new System.Windows.Forms.Padding(3, 3, 3, 3);
- this.cmb项目总价.TabIndex = 14;
- this.cmb项目总价.TabStop = true;
- this.cmb项目总价.Size = new System.Drawing.Size(210, 20);
- this.cmb项目总价.Location = new System.Drawing.Point(455, 290);
- this.cmb项目总价.Text = "保留整数";
- this.cmb项目总价.Name = "cmb项目总价";
-
- // 新建项目
- this.Controls.AddRange(new System.Windows.Forms.Control[] {
- this.lbl项目编号,
- this.txt项目编号,
- this.lbl项目日期,
- this.txt项目日期,
- this.lbl项目名称,
- this.txt项目名称,
- this.lbl客户名称,
- this.txt客户名称,
- this.btn选择客户,
- this.lbl客户地址,
- this.txt客户地址,
- this.lbl联系人,
- this.txt联系人,
- this.lbl联系电话,
- this.txt联系电话,
- this.lbl成套厂名称,
- this.txt成套厂名称,
- this.lbl成套厂地址,
- this.txt成套厂地址,
- this.lbl成套厂联系人,
- this.txt成套厂联系人,
- this.lbl成套厂联系电话,
- this.txt成套厂联系电话,
- this.lbl报出方式,
- this.cmb报出方式,
- this.lbl箱柜模板,
- this.cmb箱柜模板,
- this.lbl单台价格,
- this.cmb单台价格,
- this.lbl项目总价,
- this.lbl备注,
- this.txt备注,
- this.btn确定,
- this.btn取消,
- this.comboBox1,
- this.label1,
- this.label2,
- this.comboBox2,
- this.cmb项目总价,
- });
- //
- // 新建项目
- //
- this.Dock = System.Windows.Forms.DockStyle.None;
- this.AutoScroll = false;
- this.AutoSize = false;
- this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowOnly;
- this.AutoValidate = System.Windows.Forms.AutoValidate.EnablePreventFocusChange;
- this.BackColor = System.Drawing.SystemColors.Control;
- this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
- this.ControlBox = true;
- this.HelpButton = false;
- this.IsMdiContainer = false;
- this.KeyPreview = false;
- this.MaximumSize = new System.Drawing.Size(0, 0);
- this.MinimumSize = new System.Drawing.Size(0, 0);
- this.MaximizeBox = false;
- this.MinimizeBox = false;
- this.Opacity = 1;
- this.RightToLeftLayout = false;
- this.ShowInTaskbar = true;
- this.ShowIcon = true;
- this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Auto;
- this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
- this.TopMost = false;
- this.WindowState = System.Windows.Forms.FormWindowState.Normal;
- this.AutoScrollMargin = new System.Drawing.Size(0, 0);
- this.AutoScrollMinSize = new System.Drawing.Size(0, 0);
- this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Tile;
- this.Enabled = true;
- this.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- this.ForeColor = System.Drawing.SystemColors.ControlText;
- this.Padding = new System.Windows.Forms.Padding(0, 0, 0, 0);
- this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
- this.Size = new System.Drawing.Size(700, 538);
- this.Text = "新建项目";
- this.Name = "新建项目";
- this.ResumeLayout(false);
- this.PerformLayout();
- }
-
- #endregion
-
- private System.Windows.Forms.Label lbl项目编号;
- private System.Windows.Forms.TextBox txt项目编号;
- private System.Windows.Forms.Label lbl项目日期;
- private System.Windows.Forms.TextBox txt项目日期;
- private System.Windows.Forms.Label lbl项目名称;
- private System.Windows.Forms.TextBox txt项目名称;
- private System.Windows.Forms.Label lbl客户名称;
- private System.Windows.Forms.TextBox txt客户名称;
- private System.Windows.Forms.Button btn选择客户;
- private System.Windows.Forms.Label lbl客户地址;
- private System.Windows.Forms.TextBox txt客户地址;
- private System.Windows.Forms.Label lbl联系人;
- private System.Windows.Forms.TextBox txt联系人;
- private System.Windows.Forms.Label lbl联系电话;
- private System.Windows.Forms.TextBox txt联系电话;
- private System.Windows.Forms.Label lbl成套厂名称;
- private System.Windows.Forms.TextBox txt成套厂名称;
- private System.Windows.Forms.Label lbl成套厂地址;
- private System.Windows.Forms.TextBox txt成套厂地址;
- private System.Windows.Forms.Label lbl成套厂联系人;
- private System.Windows.Forms.TextBox txt成套厂联系人;
- private System.Windows.Forms.Label lbl成套厂联系电话;
- private System.Windows.Forms.TextBox txt成套厂联系电话;
- private System.Windows.Forms.Label lbl报出方式;
- private System.Windows.Forms.ComboBox cmb报出方式;
- private System.Windows.Forms.Label lbl箱柜模板;
- private System.Windows.Forms.ComboBox cmb箱柜模板;
- private System.Windows.Forms.Label lbl单台价格;
- private System.Windows.Forms.ComboBox cmb单台价格;
- private System.Windows.Forms.Label lbl项目总价;
- private System.Windows.Forms.Label lbl备注;
- private System.Windows.Forms.TextBox txt备注;
- private System.Windows.Forms.Button btn确定;
- private System.Windows.Forms.Button btn取消;
- private System.Windows.Forms.ComboBox comboBox1;
- private System.Windows.Forms.Label label1;
- private System.Windows.Forms.Label label2;
- private System.Windows.Forms.ComboBox comboBox2;
- private System.Windows.Forms.ComboBox cmb项目总价;
- }
-}
diff --git a/cadbt/cadbt/Program.cs b/cadbt/cadbt/Program.cs
deleted file mode 100644
index f041c15..0000000
--- a/cadbt/cadbt/Program.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 由SharpDevelop创建。
- * 用户: 099978
- * 日期: 2026-09-04
- * 时间: 12:24
- *
- * 要改变这种模板请点击 工具|选项|代码编写|编辑标准头文件
- */
-using System;
-using System.Windows.Forms;
-
-namespace cadbt
-{
- ///
- /// Class with program entry point.
- ///
- internal sealed class Program
- {
- ///
- /// Program entry point.
- ///
- [STAThread]
- private static void Main(string[] args)
- {
- // 单实例保护:重复启动时激活已有实例并退出,避免残留多个进程
- bool createdNew;
- using (var mutex = new System.Threading.Mutex(true, "cadbt_SingleInstance", out createdNew))
- {
- if (!createdNew)
- {
- MessageBox.Show("cadbt 已在运行中。", "cadbt",
- MessageBoxButtons.OK, MessageBoxIcon.Information);
- return;
- }
- Application.EnableVisualStyles();
- Application.SetCompatibleTextRenderingDefault(false);
- Application.Run(new MainForm());
- GC.KeepAlive(mutex);
- }
- }
-
- }
-}
diff --git a/cadbt/cadbt/Properties/AssemblyInfo.cs b/cadbt/cadbt/Properties/AssemblyInfo.cs
deleted file mode 100644
index a0a3c60..0000000
--- a/cadbt/cadbt/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-#region Using directives
-
-using System;
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-#endregion
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("cadbt")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("cadbt")]
-[assembly: AssemblyCopyright("Copyright 2026")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// This sets the default COM visibility of types in the assembly to invisible.
-// If you need to expose a type to COM, use [ComVisible(true)] on that type.
-[assembly: ComVisible(false)]
-
-// The assembly version has following format :
-//
-// Major.Minor.Build.Revision
-//
-// You can specify all the values or you can use the default the Revision and
-// Build Numbers by using the '*' as shown below:
-[assembly: AssemblyVersion("1.0.*")]
diff --git a/cadbt/cadbt/app.config b/cadbt/cadbt/app.config
deleted file mode 100644
index f6ecaf5..0000000
--- a/cadbt/cadbt/app.config
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/cadbt/cadbt/app.manifest b/cadbt/cadbt/app.manifest
deleted file mode 100644
index 6d88151..0000000
--- a/cadbt/cadbt/app.manifest
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
- true
-
-
-
diff --git a/cadbt/cadbt/cadbt.csproj b/cadbt/cadbt/cadbt.csproj
deleted file mode 100644
index d9fcca4..0000000
--- a/cadbt/cadbt/cadbt.csproj
+++ /dev/null
@@ -1,147 +0,0 @@
-
-
-
- {0A91D57B-B279-4672-9440-78088D022EB1}
- {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- Debug
- AnyCPU
- WinExe
- cadbt
- cadbt
- v4.8
- Properties
- x86
- app.manifest
-
-
- bin\Debug\
- True
- Full
- False
- True
- DEBUG;TRACE
-
-
- bin\Release\
- False
- None
- True
- False
- TRACE
-
-
- True
-
-
-
- 4.0
-
-
-
- 3.5
-
-
-
- 3.5
-
-
-
-
-
- 3.5
-
-
- 3.5
-
-
-
-
- C:\Program Files (x86)\SharpDevelop\5.2\bin\Smart.CustomComponents.dll
- True
-
-
- C:\Program Files (x86)\SharpDevelop\5.2\bin\WeifenLuo.WinFormsUI.Docking.dll
- True
-
-
- C:\Program Files (x86)\SharpDevelop\5.2\bin\WeifenLuo.WinFormsUI.Docking.ThemeVS2015.dll
- True
-
-
- C:\Program Files (x86)\SharpDevelop\5.2\bin\System.Data.SQLite.dll
- True
-
-
- C:\Program Files (x86)\SharpDevelop\5.2\bin\log4net.dll
- True
-
-
- C:\Program Files (x86)\SharpDevelop\5.2\bin\System.Resources.Extensions.dll
- True
-
-
- C:\Program Files (x86)\SharpDevelop\5.2\bin\System.Memory.dll
- True
-
-
- C:\Program Files (x86)\SharpDevelop\5.2\bin\System.Runtime.CompilerServices.Unsafe.dll
- True
-
-
- C:\Program Files (x86)\SharpDevelop\5.2\bin\System.Numerics.Vectors.dll
- True
-
-
- libs\AdvancedDataGridView.dll
- True
-
-
- libs\webview2\Microsoft.Web.WebView2.Core.dll
- True
-
-
- libs\webview2\Microsoft.Web.WebView2.WinForms.dll
- True
-
-
-
-
-
- MainForm.cs
-
-
- MainForm.cs
-
-
-
-
-
-
- Form3.cs
-
-
-
-
- 新建项目.cs
-
-
-
- CadViewerWindow.cs
-
-
-
- QuoteWindow.cs
-
-
-
-
-
-
-
-
- WebView2Loader.dll
- PreserveNewest
-
-
-
-
\ No newline at end of file
diff --git a/cadbt/cadbt/lib/Smart.CustomComponents.dll b/cadbt/cadbt/lib/Smart.CustomComponents.dll
deleted file mode 100644
index 717c96b..0000000
Binary files a/cadbt/cadbt/lib/Smart.CustomComponents.dll and /dev/null differ
diff --git a/cadbt/cadbt/libs/AdvancedDataGridView.dll b/cadbt/cadbt/libs/AdvancedDataGridView.dll
deleted file mode 100644
index f520283..0000000
Binary files a/cadbt/cadbt/libs/AdvancedDataGridView.dll and /dev/null differ
diff --git a/cadbt/cadbt/libs/webview2/Microsoft.Web.WebView2.Core.dll b/cadbt/cadbt/libs/webview2/Microsoft.Web.WebView2.Core.dll
deleted file mode 100644
index 4a27877..0000000
Binary files a/cadbt/cadbt/libs/webview2/Microsoft.Web.WebView2.Core.dll and /dev/null differ
diff --git a/cadbt/cadbt/libs/webview2/Microsoft.Web.WebView2.WinForms.dll b/cadbt/cadbt/libs/webview2/Microsoft.Web.WebView2.WinForms.dll
deleted file mode 100644
index 21caf04..0000000
Binary files a/cadbt/cadbt/libs/webview2/Microsoft.Web.WebView2.WinForms.dll and /dev/null differ
diff --git a/cadbt/cadbt/libs/webview2/WebView2Loader.dll b/cadbt/cadbt/libs/webview2/WebView2Loader.dll
deleted file mode 100644
index a8565ba..0000000
Binary files a/cadbt/cadbt/libs/webview2/WebView2Loader.dll and /dev/null differ
diff --git a/ghj/MainForm.Designer.cs b/ghj/MainForm.Designer.cs
deleted file mode 100644
index dcf54ff..0000000
--- a/ghj/MainForm.Designer.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 由SharpDevelop创建。
- * 用户: 099978
- * 日期: 2026-09-28
- * 时间: 13:00
- *
- * 要改变这种模板请点击 工具|选项|代码编写|编辑标准头文件
- */
-namespace ghj
-{
- partial class MainForm
- {
- ///
- /// Designer variable used to keep track of non-visual components.
- ///
- private System.ComponentModel.IContainer components = null;
-
- ///
- /// Disposes resources used by the form.
- ///
- /// true if managed resources should be disposed; otherwise, false.
- protected override void Dispose(bool disposing)
- {
- if (disposing) {
- if (components != null) {
- components.Dispose();
- }
- }
- base.Dispose(disposing);
- }
-
- ///
- /// This method is required for Windows Forms designer support.
- /// Do not change the method contents inside the source code editor. The Forms designer might
- /// not be able to load this method if it was changed manually.
- ///
- private void InitializeComponent()
- {
- //
- // MainForm
- //
- this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.Text = "ghj";
- this.Name = "MainForm";
- }
- }
-}
diff --git a/ghj/MainForm.cs b/ghj/MainForm.cs
deleted file mode 100644
index 087ae95..0000000
--- a/ghj/MainForm.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 由SharpDevelop创建。
- * 用户: 099978
- * 日期: 2026-09-28
- * 时间: 13:00
- *
- * 要改变这种模板请点击 工具|选项|代码编写|编辑标准头文件
- */
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Windows.Forms;
-
-namespace ghj
-{
- ///
- /// Description of MainForm.
- ///
- public partial class MainForm : Form
- {
- public MainForm()
- {
- //
- // The InitializeComponent() call is required for Windows Forms designer support.
- //
- InitializeComponent();
-
- //
- // TODO: Add constructor code after the InitializeComponent() call.
- //
- }
- }
-}
diff --git a/ghj/Program.cs b/ghj/Program.cs
deleted file mode 100644
index 80d5687..0000000
--- a/ghj/Program.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 由SharpDevelop创建。
- * 用户: 099978
- * 日期: 2026-09-28
- * 时间: 13:00
- *
- * 要改变这种模板请点击 工具|选项|代码编写|编辑标准头文件
- */
-using System;
-using System.Windows.Forms;
-
-namespace ghj
-{
- ///
- /// Class with program entry point.
- ///
- internal sealed class Program
- {
- ///
- /// Program entry point.
- ///
- [STAThread]
- private static void Main(string[] args)
- {
- Application.EnableVisualStyles();
- Application.SetCompatibleTextRenderingDefault(false);
- Application.Run(new MainForm());
- }
-
- }
-}
diff --git a/ghj/Properties/AssemblyInfo.cs b/ghj/Properties/AssemblyInfo.cs
deleted file mode 100644
index 3fb9ecc..0000000
--- a/ghj/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-#region Using directives
-
-using System;
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-#endregion
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("ghj")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("ghj")]
-[assembly: AssemblyCopyright("Copyright 2026")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// This sets the default COM visibility of types in the assembly to invisible.
-// If you need to expose a type to COM, use [ComVisible(true)] on that type.
-[assembly: ComVisible(false)]
-
-// The assembly version has following format :
-//
-// Major.Minor.Build.Revision
-//
-// You can specify all the values or you can use the default the Revision and
-// Build Numbers by using the '*' as shown below:
-[assembly: AssemblyVersion("1.0.*")]
diff --git a/ghj/app.config b/ghj/app.config
deleted file mode 100644
index f6ecaf5..0000000
--- a/ghj/app.config
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/ghj/app.manifest b/ghj/app.manifest
deleted file mode 100644
index 6d88151..0000000
--- a/ghj/app.manifest
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
- true
-
-
-
diff --git a/ghj/ghj.csproj b/ghj/ghj.csproj
deleted file mode 100644
index c64f235..0000000
--- a/ghj/ghj.csproj
+++ /dev/null
@@ -1,67 +0,0 @@
-
-
-
- {C9E28D5E-B911-4F7C-9C9D-75EBD3250694}
- {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- Debug
- AnyCPU
- WinExe
- ghj
- ghj
- v4.8
- Properties
- x86
- app.manifest
-
-
- bin\Debug\
- True
- Full
- False
- True
- DEBUG;TRACE
-
-
- bin\Release\
- False
- None
- True
- False
- TRACE
-
-
- True
-
-
-
- 4.0
-
-
-
- 3.5
-
-
-
- 3.5
-
-
-
-
-
- 3.5
-
-
-
-
-
- MainForm.cs
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/pdfbt/.zcode/plans/plan-sess_102a5996-c0fe-48a9-b058-69b91506b2b8.md b/pdfbt/.zcode/plans/plan-sess_102a5996-c0fe-48a9-b058-69b91506b2b8.md
deleted file mode 100644
index a7cefa0..0000000
--- a/pdfbt/.zcode/plans/plan-sess_102a5996-c0fe-48a9-b058-69b91506b2b8.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# 新增 UApiPro(uapis.cn) 通用文字识别引擎(第五个 OCR 引擎)
-
-## 已确认的接口细节(官方文档 + 官网已核实)
-- 端点:`POST https://uapis.cn/api/v1/image/ocr`,multipart/form-data
-- 鉴权:`X-API-Key: `(uapis.cn/console 邮箱注册即生成,免费积分 4积分/次,限速 4QPS)
-- 请求字段:`image_base64`(纯 base64 或 DataURI)+ `need_location="true"`(返回坐标)+ `enable_cls="true"`(方向校正)
-- 响应:`words_result[]{words, location{left,top,width,height}, score}` ——**每行带位置和置信度**,结构与百度OCR几乎一致
-- 布尔参数是字符串形式;图片 ≤10MB
-
-## 修改文件
-
-### 1. 新增 UapisOcrClient.cs
-- multipart/form-data 手工拼装(net48 无 MultipartFormDataContent)
-- words_result 解析 → OcrItem(location 像素坐标直接用,score 保留供图形符号过滤用)
-- 错误处理:HTTP 错误体 {code,message} 与业务 code 非 200 双查
-- Key 存 baidu_ocr.json 的 uapis_api_key
-
-### 2. OcrClient.cs 路由加 "uapis"
-- 新增 _uapis 成员 + StatusChanged 转发 + LoadConfig 注入 Key + RecognizeAsync 路由
-
-### 3. OcrSettingsForm 第四个引擎选项
-- 下拉加"UApiPro 通用OCR(免费积分/带位置)";选中显示 UApiPro Key 输入行;保存 uapis_api_key
-
-### 4. csproj 注册 → 编译 → 关闭重启 → 交付说明
-
-## 说明
-- 该引擎带 score 置信度,图形符号过滤(<0.8 短串拦截、<0.55 长文本兜底)对它自动生效
-- 4QPS 限速对人工框选节奏完全够用;免费积分计费
-- 五引擎格局:百度(内置Key即用)/ 智谱GLM / 千帆PaddleOCR-VL / UApiPro,外加本地GPU rapidocr 已退役
\ No newline at end of file
diff --git a/pdfbt/DockWindows/QuoteWindow.Designer.cs b/pdfbt/DockWindows/QuoteWindow.Designer.cs
deleted file mode 100644
index 4774ff4..0000000
--- a/pdfbt/DockWindows/QuoteWindow.Designer.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-namespace pdfbt.DockWindows
-{
- partial class QuoteWindow
- {
- private System.ComponentModel.IContainer components = null;
-
- protected override void Dispose(bool disposing)
- {
- if (disposing && (components != null)) components.Dispose();
- base.Dispose(disposing);
- }
-
- #region Designer generated code
-
- private void InitializeComponent()
- {
- this.SuspendLayout();
- //
- // QuoteWindow
- //
- this.Name = "QuoteWindow";
- this.ResumeLayout(false);
- }
-
- #endregion
- }
-}
diff --git a/pdfbt/DockWindows/QuoteWindow.cs b/pdfbt/DockWindows/QuoteWindow.cs
deleted file mode 100644
index 7d7fc03..0000000
--- a/pdfbt/DockWindows/QuoteWindow.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-// ============================================================
-// 停靠窗口:报价插件工具栏(左侧)
-// 把 cadcj 的 Form3 报价界面作为子控件嵌入(TopLevel=false)。
-// ============================================================
-using System.Windows.Forms;
-
-namespace pdfbt.DockWindows
-{
- /// 停靠窗口:报价插件工具栏(DockState.DockLeft)。
- public partial class QuoteWindow : WeifenLuo.WinFormsUI.Docking.DockContent
- {
- public QuoteWindow()
- {
- InitializeComponent();
- Text = "报价工具";
- TabText = "报价工具";
-
- var form = new MyApp.Form3();
- form.TopLevel = false;
- form.FormBorderStyle = FormBorderStyle.None;
- form.Dock = DockStyle.Fill;
- Controls.Add(form);
- form.Show();
- }
- }
-}
diff --git a/pdfbt/MainForm.Designer.cs b/pdfbt/MainForm.Designer.cs
deleted file mode 100644
index 79cc738..0000000
--- a/pdfbt/MainForm.Designer.cs
+++ /dev/null
@@ -1,71 +0,0 @@
-namespace pdfbt
-{
- partial class MainForm
- {
- ///
- /// Designer variable used to keep track of non-visual components.
- ///
- private System.ComponentModel.IContainer components = null;
-
- ///
- /// Disposes resources used by the form.
- ///
- /// true if managed resources should be disposed; otherwise, false.
- protected override void Dispose(bool disposing)
- {
- if (disposing) {
- if (components != null) {
- components.Dispose();
- }
- }
- base.Dispose(disposing);
- }
-
- ///
- /// This method is required for Windows Forms designer support.
- /// Do not change the method contents inside the source code editor.
- ///
- private void InitializeComponent()
- {
- Smart.CustomComponents.DockWindows.DockWindowItem dockWindowItem1 = new Smart.CustomComponents.DockWindows.DockWindowItem();
- Smart.CustomComponents.DockWindows.DockWindowItem dockWindowItem2 = new Smart.CustomComponents.DockWindows.DockWindowItem();
- this.dockSurface1 = new Smart.CustomComponents.DockSurface();
- this.SuspendLayout();
- //
- // dockSurface1
- //
- this.dockSurface1.Dock = System.Windows.Forms.DockStyle.Fill;
- this.dockSurface1.DockBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(238)))), ((int)(((byte)(238)))), ((int)(((byte)(242)))));
- dockWindowItem1.ClassName = "QuoteWindow";
- dockWindowItem1.DefaultWidth = 440;
- dockWindowItem1.ShowCloseButton = false;
- dockWindowItem1.Title = "报价工具";
- dockWindowItem2.ClassName = "PdfViewerWindow";
- dockWindowItem2.DockState = WeifenLuo.WinFormsUI.Docking.DockState.Document;
- dockWindowItem2.ShowCloseButton = false;
- dockWindowItem2.Title = "PDF 查看器";
- this.dockSurface1.DockWindows.Add(dockWindowItem1);
- this.dockSurface1.DockWindows.Add(dockWindowItem2);
- this.dockSurface1.Location = new System.Drawing.Point(0, 0);
- this.dockSurface1.Name = "dockSurface1";
- this.dockSurface1.Padding = new System.Windows.Forms.Padding(6);
- this.dockSurface1.ShowAutoHideContentOnHover = false;
- this.dockSurface1.Size = new System.Drawing.Size(1184, 661);
- this.dockSurface1.TabIndex = 0;
- //
- // MainForm
- //
- this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 18F);
- this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(1184, 661);
- this.Controls.Add(this.dockSurface1);
- this.Name = "MainForm";
- this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
- this.Text = "PDF 扒图";
- this.ResumeLayout(false);
-
- }
-
- private Smart.CustomComponents.DockSurface dockSurface1;
- }
-}
diff --git a/pdfbt/MainForm.DockWindows.cs b/pdfbt/MainForm.DockWindows.cs
deleted file mode 100644
index 76ed75b..0000000
--- a/pdfbt/MainForm.DockWindows.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-// 本文件由『生成停靠窗口代码』自动生成格式参考手写,集合变更后请同步刷新。
-using System;
-using WeifenLuo.WinFormsUI.Docking;
-
-namespace pdfbt
-{
- public partial class MainForm
- {
- void CreateDockWindows_dockSurface1()
- {
- var dockSurface1 = this.dockSurface1 as Smart.CustomComponents.DockSurface;
- if (dockSurface1 == null) return;
- dockSurface1.EnsureDefaultTheme(); // 必须:Show 前保证有效主题
-
- var quote = new pdfbt.DockWindows.QuoteWindow();
- quote.CloseButtonVisible = false;
- quote.TabText = "报价工具";
- quote.Text = "报价工具";
- quote.Show(dockSurface1, DockState.DockLeft);
-
- var viewer = new pdfbt.PdfViewerWindow();
- viewer.CloseButtonVisible = false;
- viewer.TabText = "PDF 查看器";
- viewer.Text = "PDF 查看器";
- viewer.Show(dockSurface1, DockState.Document);
- }
- }
-}
diff --git a/pdfbt/MainForm.cs b/pdfbt/MainForm.cs
deleted file mode 100644
index 762c334..0000000
--- a/pdfbt/MainForm.cs
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * MainForm:主窗体(报价工具 + PDF 查看器)
- * 由 cadbt 改造:WebView2 网页 CAD → pdfium 原生 PDF 查看 + 框选 OCR
- */
-using System;
-using System.IO;
-using System.Windows.Forms;
-using 成套报价软件; // ★ A1:OCR/PDF 基础设施已链接共享主项目源码(类型在 成套报价软件 命名空间)
-namespace pdfbt
-{
- public partial class MainForm : Form
- {
- public MainForm()
- {
- InitializeComponent();
- CreateDockWindows_dockSurface1();
-
- // ★ 全局 F1/F2/F3 过滤器:焦点在任何 WinForms 控件上都触发元件合并
- // (与 cadbt 一致,两路都汇聚到 PdfBridge.F*Requested)
- Application.AddMessageFilter(new F1MessageFilter());
- FormClosed += (s, e) => Application.RemoveMessageFilter(f1Filter);
-
- // ★ Umi-OCR 预热:已装本体且当前引擎为 umi 时,主程序一启动就静默拉起
- // (--hide 托盘),不等首次框选;后台线程跑,不拖慢窗口出现
- System.Threading.ThreadPool.QueueUserWorkItem(_ =>
- {
- try
- {
- if (File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "baidu_ocr.json")))
- {
- var jsv = new System.Web.Script.Serialization.JavaScriptSerializer()
- .Deserialize>(
- File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "baidu_ocr.json")));
- string eng = jsv != null && jsv.ContainsKey("engine") ? jsv["engine"] : "baidu";
- if (eng == "umi" && UmiOcrHost.IsInstalled) UmiOcrLauncher.EnsureRunning(); // ★ A1:启停已拆到 UmiOcrLauncher(主项目共享版)
- }
- }
- catch { }
- });
- }
-
- private readonly F1MessageFilter f1Filter = new F1MessageFilter();
-
- ///
- /// 把 F1/F2/F3 按键(0x70/0x71/0x72)转成 PdfBridge 事件。
- /// ★ 焦点在报价插件(Form3)树内时不触发——那条路径由 Form3.ProcessCmdKey
- /// 处理,此处再触发会双跑一次(F1 合并两遍:第一遍成功、第二遍弹
- /// "请先选中至少2行"的误提示)。
- ///
- private class F1MessageFilter : IMessageFilter
- {
- public bool PreFilterMessage(ref Message m)
- {
- const int WM_KEYDOWN = 0x0100;
- bool isFKey = m.Msg == WM_KEYDOWN &&
- ((int)m.WParam == 0x70 || (int)m.WParam == 0x71 || (int)m.WParam == 0x72);
- if (!isFKey) return false;
-
- // 焦点控件在 Form3 树内 → 交给 Form3.ProcessCmdKey,跳过
- try
- {
- var focused = Control.FromHandle(m.HWnd);
- for (var c = focused; c != null; c = c.Parent)
- {
- if (c is MyApp.Form3) return false;
- }
- }
- catch { }
-
- int key = (int)m.WParam;
- try
- {
- if (key == 0x70) PdfBridge.RaiseF1();
- else if (key == 0x71) PdfBridge.RaiseF2();
- else if (key == 0x72) PdfBridge.RaiseF3();
- }
- catch { }
- return false;
- }
- }
- }
-}
diff --git a/pdfbt/MainForm.resx b/pdfbt/MainForm.resx
deleted file mode 100644
index 1af7de1..0000000
--- a/pdfbt/MainForm.resx
+++ /dev/null
@@ -1,120 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 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
-
-
\ No newline at end of file
diff --git a/pdfbt/PdfBridge.cs b/pdfbt/PdfBridge.cs
deleted file mode 100644
index 9ecef9c..0000000
--- a/pdfbt/PdfBridge.cs
+++ /dev/null
@@ -1,148 +0,0 @@
-// ============================================================
-// PdfBridge:报价插件(Form3)与 PDF 查看器之间的桥
-// 与 cadbt 的 CadBridge 保持相同的 API 形状:
-// · 下行(Form3→查看器):SendPaCommand / ZoomToFrameHandle /
-// DeleteFramesByHandles / MergeMasks / ClearHighlight
-// · 上行(查看器→Form3):PaPicked / EntityErased / PaExited /
-// F1/F2/F3Requested
-// 扒图逻辑:用户在 PDF 上框选 → 裁剪 → OCR 工作进程识别 →
-// 按 CAD 版语义组装 results(正向逐条/反向合并) → PaPicked
-// → Form3 入表格;查看器在框选位置画彩色蒙版框。
-// ============================================================
-using System;
-using System.Collections.Generic;
-
-namespace pdfbt
-{
- public static class PdfBridge
- {
- private static PdfViewerWindow _viewer;
-
- /// PDF 查看器是否已挂载且打开了文档。
- public static bool IsViewerReady
- {
- get { return _viewer != null && _viewer.IsDocumentOpen; }
- }
-
- /// 扒图连续模式当前是否激活(供 ESC 全局过滤判断)。
- public static bool PickModeActive
- {
- get { return _viewer != null && _viewer.PickModeActive; }
- }
-
- /// 兼容 CadBridge:查看器中蒙版被外部删除(当前无触发源,保留事件形状)。
- public static event Action EntityErased;
-
- /// 框选识别完成一批(图号/箱号/元件)。
- public static event Action> PaPicked;
-
- /// 用户按 ESC 退出连续扒图模式。
- public static event Action PaExited;
-
- /// 用户按 F1 —— 元件两两合并。
- public static event Action F1Requested;
-
- /// 用户按 F2 —— 元件三个一组合并。
- public static event Action F2Requested;
-
- /// 用户按 F3 —— 元件四个一组合并。
- public static event Action F3Requested;
-
- /// 把 PDF 查看器挂到桥上(查看器构造时调用一次)。
- public static void Attach(PdfViewerWindow viewer)
- {
- _viewer = viewer;
- }
-
- // ------------------------------------------------------------
- // 查看器 → Form3 的上行事件触发(仅查看器调用)
- // ------------------------------------------------------------
-
- public static void RaisePaPicked(MyApp.PaMode mode, List results)
- {
- if (PaPicked != null) PaPicked(mode, results);
- }
-
- public static void RaisePaExited()
- {
- if (PaExited != null) PaExited();
- }
-
- public static void RaiseEntityErased(string handle)
- {
- if (!string.IsNullOrWhiteSpace(handle) && EntityErased != null)
- EntityErased(handle);
- }
-
- public static void RaiseF1() { if (F1Requested != null) F1Requested(); }
- public static void RaiseF2() { if (F2Requested != null) F2Requested(); }
- public static void RaiseF3() { if (F3Requested != null) F3Requested(); }
-
- // ------------------------------------------------------------
- // Form3 → 查看器的下行命令
- // ------------------------------------------------------------
-
- ///
- /// 发送扒图命令。接受原 CAD 命令名(CADPATU/CADPAXH/CADPAYJ/CADPACL)
- /// 或网页命令名(patu/paxh/payj/pacl)。
- ///
- public static void SendPaCommand(string cmd)
- {
- if (string.IsNullOrWhiteSpace(cmd)) return;
- string c = cmd.Trim().ToUpperInvariant();
- int mode = 0;
- if (c == "CADPATU" || c == "PATU") mode = 0;
- else if (c == "CADPAXH" || c == "PAXH") mode = 1;
- else if (c == "CADPAYJ" || c == "PAYJ") mode = 2;
- else if (c == "CADPACL" || c == "PACL")
- {
- ClearHighlight();
- return;
- }
- else return;
-
- if (_viewer == null) return;
- _viewer.StartPick(mode);
- }
-
- /// 定位到指定 Handle 的蒙版框(点击表格行定位)。
- public static void ZoomToFrameHandle(string handle)
- {
- if (string.IsNullOrWhiteSpace(handle) || _viewer == null) return;
- _viewer.ZoomToFrame(handle);
- }
-
- /// 批量删除指定 Handle 的蒙版(删表格行联动删框)。
- public static void DeleteFramesByHandles(IEnumerable handles)
- {
- if (handles == null || _viewer == null) return;
- var list = new List();
- foreach (string h in handles)
- if (!string.IsNullOrWhiteSpace(h)) list.Add(h);
- if (list.Count == 0) return;
- _viewer.DeleteFrames(list);
- }
-
- ///
- /// 合并蒙版:保留 keep 的蒙版并扩大到所有 removes 蒙版的并集,
- /// 被合并行的蒙版移除(元件合并时蒙版同步合并)。
- ///
- public static void MergeMasks(string keep, IEnumerable removes)
- {
- if (string.IsNullOrWhiteSpace(keep) || _viewer == null) return;
- var list = new List();
- if (removes != null)
- foreach (string h in removes)
- if (!string.IsNullOrWhiteSpace(h) && h != keep) list.Add(h);
- if (list.Count == 0) return;
- _viewer.MergeMasks(keep, list);
- }
-
- /// 清除所有高亮。
- public static void ClearHighlight()
- {
- if (_viewer == null) return;
- _viewer.ClearHighlight();
- }
- }
-}
diff --git a/pdfbt/PdfViewerWindow.cs b/pdfbt/PdfViewerWindow.cs
deleted file mode 100644
index 4c36065..0000000
--- a/pdfbt/PdfViewerWindow.cs
+++ /dev/null
@@ -1,1400 +0,0 @@
-// ============================================================
-// PdfViewerWindow:停靠窗口(中央文档区)—— PDF 查看 + 框选 OCR 扒图
-// · pdfium 渲染;单画布自管理滚动偏移 + 双缓冲 → 拖动/滚动无闪烁
-// · 框选(仿 CAD 窗选语义):
-// 正向(左→右) = 逐条:每个识别文本一个彩色蒙版框、各自 Handle
-// 反向(右→左) = 合并:整块一个蒙版框、共享 Handle(Form3 拼接为一条规格)
-// · ★ 框选区域按 300DPI 高清重渲染后交 Windows 内置 OCR(PowerShell 桥)
-// —— 与屏幕缩放无关,任意缩放下识别质量一致,单次 ~0.1-0.3s
-// · 结果按"列分组、列内从上到下"排序(与 CAD 版 PaTextSelector 一致)
-// · 蒙版持久化:.pdfmask.json,重开 PDF 自动恢复
-// · ZoomToFrame/DeleteFrames/MergeMasks 供 PdfBridge 联动表格
-// ============================================================
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Drawing.Drawing2D;
-using System.IO;
-using System.Linq;
-using System.Threading.Tasks;
-using System.Web.Script.Serialization;
-using 成套报价软件; // ★ A1:OCR/PDF 基础设施已链接共享主项目源码(类型在 成套报价软件 命名空间)
-using System.Windows.Forms;
-using WeifenLuo.WinFormsUI.Docking;
-
-namespace pdfbt
-{
- /// 一个已绘制的蒙版框。
- public class PdfMaskItem
- {
- public string Handle; // 唯一编号 "M1"...
- public string TextHandle; // 稳定文本标识(页+粗化位置),用于判重
- public int Page; // 0 基页码
- public RectangleF RectPt; // 页面坐标(PDF 点)
- public int Mode; // 0=图号 1=箱号 2=元件
-
- public Color Color
- {
- get { return MaskColor(Mode); }
- }
-
- public static Color MaskColor(int mode)
- {
- switch (mode)
- {
- case 0: return Color.FromArgb(220, 40, 40); // 图号 红
- case 1: return Color.FromArgb(30, 110, 220); // 箱号 蓝
- default: return Color.FromArgb(20, 150, 90); // 元件 绿
- }
- }
- }
-
- /// PDF 查看器停靠窗口(DockState.Document)。
- public class PdfViewerWindow : DockContent
- {
- // ---------- 子控件 ----------
- private ToolStrip _toolbar;
- private ToolStripButton _btnOpen;
- private ToolStripButton _btnPrev, _btnNext;
- private ToolStripLabel _lblPage;
- private ToolStripButton _btnZoomOut, _btnZoomIn, _btnFitWidth, _btnFitPage;
- private ToolStripLabel _lblZoom;
- private ToolStripLabel _lblMode;
- private StatusStrip _status;
- private ToolStripStatusLabel _statusLeft, _statusOcr;
- private ViewerCanvas _canvas;
- private HScrollBar _hsb;
- private VScrollBar _vsb;
-
- // ---------- 文档状态 ----------
- private PdfDocument _doc;
- private float _zoom = 1.0f; // 1.0 = 96dpi 视觉尺寸
- private float _dpiFactor = 96f / 72f; // 像素/点 基准,构造时按实际 DPI 校准
- private int _pageIndex;
- private float _pxPerPt; // 当前页实际渲染比例(等比上限修正后)
-
- // ---------- 滚动/平移 ----------
- private int _scrollX, _scrollY; // 页面位图相对视口原点偏移(≥0)
- private bool _panning;
- private Point _panStart;
- private int _panScrollX, _panScrollY;
-
- // ---------- 扒图状态 ----------
- private int _pickMode = -1; // -1=未激活 0/1/2
- private bool _picking;
- private Point _pickStart; // 画布客户区坐标
- private Rectangle _rubber;
- private int _ocrBusyCount;
- private bool _ocrErrorShown;
-
- // ---------- 蒙版 ----------
- private List _masks = new List();
- private HashSet _highlight = new HashSet();
- private int _handleCounter = 1;
- private List _sessionPicked = new List();
- private string _maskSavePath;
-
- // ★ 缩放卡顿修复(2026-10-01):光栅化转后台线程的两根支柱
- private static readonly object PdfRenderGate = new object(); // pdfium 非线程安全,所有渲染/文档操作全局互斥
- private volatile int _renderGen; // 渲染代数:每次发起渲染+1,过期结果直接丢弃
-
- private OcrClient _ocr;
- private readonly JavaScriptSerializer _json = new JavaScriptSerializer();
-
- private EventHandler _btnOcrcfg_Click;
-
- /// OCR 设置:打开设计器窗体 OcrSettingsForm。
- private void ShowOcrSettings()
- {
- using (var f = new OcrSettingsForm(_ocr))
- {
- f.ShowDialog(this);
- }
- }
- private Timer _highlightTimer;
-
- private const int MAX_RENDER_DIM = 8192; // 单边渲染像素上限(等比)
- private const int OCR_MAX_DIM = 4000; // OCR 区域单边像素上限
- private const float OCR_DPI = 300f; // OCR 渲染分辨率
-
- public bool IsDocumentOpen
- {
- get { return _doc != null && _doc.IsOpen; }
- }
-
- public bool PickModeActive
- {
- get { return _pickMode >= 0; }
- }
-
- public PdfViewerWindow()
- {
- BuildUi();
- Text = "PDF 查看器";
- TabText = "PDF 查看器";
- PdfBridge.Attach(this);
- AllowDrop = true;
- DragEnter += (s, e) =>
- {
- if (e.Data.GetDataPresent(DataFormats.FileDrop))
- e.Effect = DragDropEffects.Copy;
- };
- DragDrop += (s, e) =>
- {
- var files = e.Data.GetData(DataFormats.FileDrop) as string[];
- if (files != null && files.Length > 0)
- OpenPdf(files[0]);
- };
-
- _ocr = new OcrClient();
- _ocr.StatusChanged += msg =>
- {
- if (InvokeRequired) BeginInvoke((Action)(() => _statusOcr.Text = msg));
- else _statusOcr.Text = msg;
- };
-
- try
- {
- using (var g = CreateGraphics())
- _dpiFactor = g.DpiX / 72f;
- }
- catch { }
- }
-
- // ============================================================
- // UI 构建
- // ============================================================
- private void BuildUi()
- {
- _toolbar = new ToolStrip();
- _toolbar.GripStyle = ToolStripGripStyle.Hidden;
- _toolbar.RenderMode = ToolStripRenderMode.System;
-
- _btnOpen = new ToolStripButton("打开PDF");
- _btnOpen.Click += (s, e) => ShowOpenDialog();
- _btnPrev = new ToolStripButton("◀");
- _btnPrev.Click += (s, e) => SetPage(_pageIndex - 1);
- _lblPage = new ToolStripLabel("0 / 0");
- _btnNext = new ToolStripButton("▶");
- _btnNext.Click += (s, e) => SetPage(_pageIndex + 1);
- _btnZoomOut = new ToolStripButton("-");
- _btnZoomOut.Click += (s, e) => SetZoom(_zoom / 1.25f);
- _lblZoom = new ToolStripLabel("100%");
- _btnZoomIn = new ToolStripButton("+");
- _btnZoomIn.Click += (s, e) => SetZoom(_zoom * 1.25f);
- _btnFitWidth = new ToolStripButton("适合宽度");
- _btnFitWidth.Click += (s, e) => FitWidth();
- _btnFitPage = new ToolStripButton("适合整页");
- _btnFitPage.Click += (s, e) => FitPage();
- _lblMode = new ToolStripLabel("");
- _lblMode.ForeColor = Color.Firebrick;
- _lblMode.Font = new Font(_lblMode.Font, FontStyle.Bold);
-
- _toolbar.Items.Add(_btnOpen);
- var _btnOcrCfg = new ToolStripButton("OCR设置");
- _btnOcrcfg_Click = delegate { ShowOcrSettings(); };
- _btnOcrCfg.Click += _btnOcrcfg_Click;
- _toolbar.Items.Add(_btnOcrCfg);
- _toolbar.Items.Add(new ToolStripSeparator());
- _toolbar.Items.Add(_btnPrev);
- _toolbar.Items.Add(_lblPage);
- _toolbar.Items.Add(_btnNext);
- _toolbar.Items.Add(new ToolStripSeparator());
- _toolbar.Items.Add(_btnZoomOut);
- _toolbar.Items.Add(_lblZoom);
- _toolbar.Items.Add(_btnZoomIn);
- _toolbar.Items.Add(_btnFitWidth);
- _toolbar.Items.Add(_btnFitPage);
- _toolbar.Items.Add(new ToolStripSeparator());
- _toolbar.Items.Add(_lblMode);
-
- _status = new StatusStrip();
- _statusLeft = new ToolStripStatusLabel("请打开 PDF 图纸(或直接拖入窗口)");
- _statusLeft.Spring = true;
- _statusLeft.TextAlign = ContentAlignment.MiddleLeft;
- _statusOcr = new ToolStripStatusLabel("OCR 未启动");
- _status.Items.Add(_statusLeft);
- _status.Items.Add(_statusOcr);
-
- _canvas = new ViewerCanvas();
- _canvas.Dock = DockStyle.Fill;
- _canvas.BackColor = Color.FromArgb(70, 70, 74);
-
- _hsb = new HScrollBar();
- _hsb.Dock = DockStyle.Bottom;
- _hsb.SmallChange = 30;
- _hsb.LargeChange = 120;
- _vsb = new VScrollBar();
- _vsb.Dock = DockStyle.Right;
- _vsb.SmallChange = 30;
- _vsb.LargeChange = 120;
- _hsb.ValueChanged += (s, e) => { _scrollX = _hsb.Value; _canvas.Invalidate(); };
- _vsb.ValueChanged += (s, e) => { _scrollY = _vsb.Value; _canvas.Invalidate(); };
-
- // 布局顺序(Dock 逆序处理):toolbar(Top) → status(Bottom) → hsb(Bottom) → vsb(Right) → canvas(Fill)
- Controls.Add(_canvas);
- Controls.Add(_vsb);
- Controls.Add(_hsb);
- Controls.Add(_status);
- Controls.Add(_toolbar);
-
- _canvas.MouseDown += CanvasMouseDown;
- _canvas.MouseMove += CanvasMouseMove;
- _canvas.MouseUp += CanvasMouseUp;
- _canvas.MouseWheel += CanvasMouseWheel;
- _canvas.OriginProvider = () => PageOrigin;
- _canvas.Resize += (s, e) => { UpdateScrollbars(); _canvas.Invalidate(); };
-
- _highlightTimer = new Timer();
- _highlightTimer.Interval = 3000;
- _highlightTimer.Tick += (s, e) =>
- {
- _highlightTimer.Stop();
- _highlight.Clear();
- RefreshMasks();
- };
- }
-
- private void ShowOpenDialog()
- {
- using (var dlg = new OpenFileDialog())
- {
- dlg.Filter = "PDF 文件 (*.pdf)|*.pdf|所有文件 (*.*)|*.*";
- dlg.Title = "打开 PDF 图纸";
- if (dlg.ShowDialog(this) == DialogResult.OK)
- OpenPdf(dlg.FileName);
- }
- }
-
- // ============================================================
- // 打开 / 渲染 / 导航
- // ============================================================
-
- public void OpenPdf(string path)
- {
- if (string.IsNullOrEmpty(path) || !File.Exists(path))
- {
- MessageBox.Show(this, "文件不存在: " + path, "打开 PDF");
- return;
- }
- try
- {
- // ★ 先把当前 PDF 关掉再开新的(用户要求的机制)——
- // 旧文档(含后备缓冲/页句柄/掩码状态)先释放,也避免两份大 PDF 同时占内存
- if (_doc != null)
- {
- _renderGen++; // 作废所有在途后台渲染
- lock (PdfRenderGate) { _doc.Dispose(); } // 与后台渲染互斥,等它出锁再释放
- _doc = null;
- }
-
- var doc = new PdfDocument();
- doc.Open(path, null);
- _doc = doc;
- _pageIndex = 0;
- _scrollX = 0; _scrollY = 0;
- _canvas.SetPage(null, 1f); // 清掉上一份 PDF 的位图,白底等新页(渲染已异步)
-
- _maskSavePath = path + ".pdfmask.json";
- LoadMasks();
-
- Text = Path.GetFileName(path);
- TabText = Path.GetFileName(path);
- _statusLeft.Text = path + " · " + _doc.PageCount + " 页";
-
- // ★ 强制重绘:SetZoom 在新旧 PDF 页宽相同(工程图同为 A4/A3 很常见)时
- // 算出相同缩放会直接 return,不触发 RenderCurrentPage——画布停留在
- // 第一份 PDF 的位图上("换 PDF 显示不变"的元凶)。先把缩放置为无效值,
- // FitWidth→SetZoom 必然视为变化,强制渲染新文档。
- _zoom = -1f;
- FitWidth();
- UpdateNavUi();
- }
- catch (Exception ex)
- {
- MessageBox.Show(this, ex.Message, "打开 PDF 失败",
- MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- }
-
- private float MaxZoom
- {
- get
- {
- if (!IsDocumentOpen) return 8f;
- float maxSide = Math.Max(_doc.PageWidthPt[_pageIndex], _doc.PageHeightPt[_pageIndex]);
- if (maxSide <= 0) return 8f;
- return Math.Min(8f, MAX_RENDER_DIM / maxSide / _dpiFactor);
- }
- }
-
- private void SetPage(int index)
- {
- if (!IsDocumentOpen) return;
- if (index < 0) index = 0;
- if (index > _doc.PageCount - 1) index = _doc.PageCount - 1;
- if (index == _pageIndex && _canvas.Page != null) return;
- _pageIndex = index;
- _scrollX = 0; _scrollY = 0;
- RenderCurrentPage(clearPage: true); // 翻页:清旧页位图,白底等新页
- UpdateNavUi();
- }
-
- private void UpdateNavUi()
- {
- _lblPage.Text = IsDocumentOpen
- ? (_pageIndex + 1) + " / " + _doc.PageCount
- : "0 / 0";
- }
-
- private void SetZoom(float zoom)
- {
- zoom = Math.Max(0.05f, Math.Min(MaxZoom, zoom));
- if (Math.Abs(zoom - _zoom) < 0.001f) return;
- _zoom = zoom;
- _lblZoom.Text = (int)Math.Round(_zoom * 100) + "%";
- RenderCurrentPage();
- }
-
- private void FitWidth()
- {
- if (!IsDocumentOpen) return;
- float pageWpt = _doc.PageWidthPt[_pageIndex];
- int avail = _canvas.ClientSize.Width - (int)_dpiFactor * 16;
- if (pageWpt <= 0 || avail <= 0) return;
- SetZoom(avail / (pageWpt * _dpiFactor));
- }
-
- private void FitPage()
- {
- if (!IsDocumentOpen) return;
- float pageWpt = _doc.PageWidthPt[_pageIndex];
- float pageHpt = _doc.PageHeightPt[_pageIndex];
- int availW = _canvas.ClientSize.Width - (int)_dpiFactor * 16;
- int availH = _canvas.ClientSize.Height - (int)_dpiFactor * 16;
- if (pageWpt <= 0 || pageHpt <= 0) return;
- float z = Math.Min(availW / (pageWpt * _dpiFactor), availH / (pageHpt * _dpiFactor));
- SetZoom(Math.Max(0.05f, z));
- }
-
- /// 异步重渲染当前页(等比限制在 MAX_RENDER_DIM 内)。
- /// ★ 缩放卡顿修复(2026-10-01):原来 UI 线程同步光栅化整页,大幅面工程图每档滚轮
- /// 冻结数百毫秒~秒级。现在:视图比例立即生效+旧位图拉伸过渡帧(滚轮即时反馈),
- /// 光栅化转后台线程;连续触发用代数令牌只落最后一档,过期任务连渲染都不做。
- private void RenderCurrentPage(bool clearPage = false)
- {
- if (!IsDocumentOpen)
- {
- _canvas.SetPage(null, 1f);
- UpdateScrollbars();
- _canvas.Invalidate();
- return;
- }
-
- float scale = _zoom * _dpiFactor;
- float maxSide = Math.Max(_doc.PageWidthPt[_pageIndex], _doc.PageHeightPt[_pageIndex]);
- if (maxSide > 0 && scale * maxSide > MAX_RENDER_DIM)
- scale = MAX_RENDER_DIM / maxSide; // ★ 等比降档,保持长宽比
- _pxPerPt = scale;
-
- if (clearPage)
- {
- // 翻页/换文档:旧页位图直接清掉(画布白底),避免"上一页拉伸"的错觉
- _canvas.SetPage(null, scale);
- }
- else
- {
- // 缩放:保留旧位图按新比例拉伸显示(过渡帧),高清渲染完成后自动替换
- _canvas.SetViewScale(scale);
- }
- UpdateScrollbars();
- _canvas.Invalidate();
-
- int gen = ++_renderGen;
- int page = _pageIndex;
- var doc = _doc;
- System.Threading.Tasks.Task.Factory.StartNew(() =>
- {
- lock (PdfRenderGate) // pdfium 非线程安全:与 OCR 渲染/文档开关全局互斥
- {
- if (gen != _renderGen || doc != _doc) return null; // 过期:不再光栅化
- return doc.RenderPage(page, scale);
- }
- }).ContinueWith(t =>
- {
- var bmp = t.Result;
- // 回 UI 线程后复核:期间又缩放/翻页/换文档/窗口销毁 → 丢弃结果
- if (gen != _renderGen || doc != _doc || page != _pageIndex || IsDisposed)
- {
- if (bmp != null) bmp.Dispose();
- return;
- }
- if (bmp == null)
- {
- _statusLeft.Text = "页面渲染失败";
- return;
- }
- _canvas.SetPage(bmp, scale);
- _canvas.Masks = CurrentPageMasks();
- UpdateScrollbars();
- _canvas.Invalidate();
- }, TaskScheduler.FromCurrentSynchronizationContext());
- }
-
- private List CurrentPageMasks()
- {
- var list = new List();
- foreach (var m in _masks)
- if (m.Page == _pageIndex) list.Add(m);
- return list;
- }
-
- private void RefreshMasks()
- {
- _canvas.Masks = CurrentPageMasks();
- _canvas.Highlight = _highlight;
- _canvas.Invalidate();
- }
-
- // ============================================================
- // 滚动条 / 偏移
- // ============================================================
-
- /// 页面位图按当前视图比例(ViewScale)的显示尺寸。
- /// 过渡帧拉伸期间与位图实际尺寸不同,滚动范围/原点/居中都必须用它。
- private Size PageViewSize
- {
- get
- {
- var p = _canvas.Page;
- if (p == null) return Size.Empty;
- float st = _canvas.ViewScale;
- return new Size((int)Math.Round(p.Width * st), (int)Math.Round(p.Height * st));
- }
- }
-
- private void UpdateScrollbars()
- {
- var view = PageViewSize;
- int clientW = _canvas.ClientSize.Width;
- int clientH = _canvas.ClientSize.Height;
- int pageW = view.Width;
- int pageH = view.Height;
-
- int maxX = Math.Max(0, pageW - clientW);
- int maxY = Math.Max(0, pageH - clientH);
- _scrollX = Clamp(_scrollX, 0, maxX);
- _scrollY = Clamp(_scrollY, 0, maxY);
-
- _hsb.Enabled = maxX > 0;
- _vsb.Enabled = maxY > 0;
- // Maximum 需含 LargeChange 补偿,否则最大值滚不到底
- _hsb.LargeChange = Math.Max(10, Math.Min(clientW, maxX + 10));
- _hsb.Maximum = maxX + _hsb.LargeChange - 1;
- _hsb.Value = Clamp(_hsb.Value, 0, Math.Max(0, _hsb.Maximum - _hsb.LargeChange + 1));
- if (_hsb.Value != _scrollX) _hsb.Value = _scrollX;
- _vsb.LargeChange = Math.Max(10, Math.Min(clientH, maxY + 10));
- _vsb.Maximum = maxY + _vsb.LargeChange - 1;
- _vsb.Value = Clamp(_vsb.Value, 0, Math.Max(0, _vsb.Maximum - _vsb.LargeChange + 1));
- if (_vsb.Value != _scrollY) _vsb.Value = _scrollY;
- }
-
- private static int Clamp(int v, int lo, int hi)
- {
- if (hi < lo) hi = lo;
- return v < lo ? lo : (v > hi ? hi : v);
- }
-
- /// 页面位图在画布上的绘制原点(小于视口时居中)。按视图尺寸(含过渡帧拉伸)计算。
- private Point PageOrigin
- {
- get
- {
- var view = PageViewSize;
- if (view.IsEmpty) return Point.Empty;
- int dx = view.Width <= _canvas.ClientSize.Width
- ? (_canvas.ClientSize.Width - view.Width) / 2 : -_scrollX;
- int dy = view.Height <= _canvas.ClientSize.Height
- ? (_canvas.ClientSize.Height - view.Height) / 2 : -_scrollY;
- return new Point(dx, dy);
- }
- }
-
- // ============================================================
- // 鼠标交互
- // ============================================================
-
- private void CanvasMouseDown(object sender, MouseEventArgs e)
- {
- _canvas.Focus();
- if (e.Button == MouseButtons.Middle)
- {
- _panStart = e.Location;
- _panScrollX = _scrollX;
- _panScrollY = _scrollY;
- _panning = true;
- return;
- }
- if (e.Button == MouseButtons.Right)
- {
- // ★ 扒图会话中右键循环切换模式(与网页 CAD 版一致):
- // 图号→箱号→元件→退出;无会话时忽略
- if (_pickMode >= 0)
- {
- _picking = false;
- _canvas.Rubber = Rectangle.Empty;
- if (_pickMode == 0) StartPick(1);
- else if (_pickMode == 1) StartPick(2);
- else
- {
- ExitPickMode();
- PdfBridge.RaisePaExited();
- }
- }
- return;
- }
- if (e.Button == MouseButtons.Left && _pickMode >= 0 && IsDocumentOpen)
- {
- _picking = true;
- _pickStart = e.Location;
- _rubber = new Rectangle(e.Location, Size.Empty);
- }
- }
-
- private void CanvasMouseMove(object sender, MouseEventArgs e)
- {
- if (_panning)
- {
- var view = PageViewSize; // 视图尺寸(与滚动条范围一致)
- int maxX = Math.Max(0, view.Width - _canvas.ClientSize.Width);
- int maxY = Math.Max(0, view.Height - _canvas.ClientSize.Height);
- _scrollX = Clamp(_panScrollX - (e.X - _panStart.X), 0, maxX);
- _scrollY = Clamp(_panScrollY - (e.Y - _panStart.Y), 0, maxY);
- SyncScrollbars();
- _canvas.Invalidate();
- return;
- }
- if (_picking)
- {
- _rubber = Rectangle.FromLTRB(
- Math.Min(_pickStart.X, e.X), Math.Min(_pickStart.Y, e.Y),
- Math.Max(_pickStart.X, e.X), Math.Max(_pickStart.Y, e.Y));
- _canvas.Rubber = _rubber;
- _canvas.RubberMerge = _pickStart.X > e.X; // 反向拖拽 = 合并
- _canvas.Invalidate();
- }
- }
-
- private void CanvasMouseUp(object sender, MouseEventArgs e)
- {
- if (e.Button == MouseButtons.Middle) { _panning = false; return; }
-
- if (e.Button == MouseButtons.Left && _picking)
- {
- _picking = false;
- _canvas.Rubber = Rectangle.Empty;
- var rect = _rubber;
- _rubber = Rectangle.Empty;
- _canvas.Invalidate();
-
- if (rect.Width < 5 || rect.Height < 5) return; // 误点忽略
- bool merge = _pickStart.X > e.X; // 反向 = 合并
- RunPickOcr(rect, merge);
- }
- }
-
- private void CanvasMouseWheel(object sender, MouseEventArgs e)
- {
- var hme = e as HandledMouseEventArgs;
- if ((Control.ModifierKeys & Keys.Control) != 0)
- {
- if (hme != null) hme.Handled = true;
- if (!IsDocumentOpen) return;
- // 以鼠标为中心缩放:记住鼠标处页面点,缩放后滚回
- var origin = PageOrigin;
- float ptX = (e.X - origin.X) / _pxPerPt;
- float ptY = (e.Y - origin.Y) / _pxPerPt;
- SetZoom(e.Delta > 0 ? _zoom * 1.2f : _zoom / 1.2f);
- _scrollX = Clamp((int)(ptX * _pxPerPt) - e.X, 0, int.MaxValue);
- _scrollY = Clamp((int)(ptY * _pxPerPt) - e.Y, 0, int.MaxValue);
- UpdateScrollbars();
- SyncScrollbars();
- _canvas.Invalidate();
- }
- else
- {
- if (hme != null) hme.Handled = true;
- int pageH = PageViewSize.Height; // 视图尺寸(过渡帧拉伸期间跟随缩放)
- int maxY = Math.Max(0, pageH - _canvas.ClientSize.Height);
- _scrollY = Clamp(_scrollY - e.Delta, 0, maxY);
- SyncScrollbars();
- _canvas.Invalidate();
- }
- }
-
- private void SyncScrollbars()
- {
- if (_hsb.Value != _scrollX && _scrollX <= _hsb.Maximum) _hsb.Value = _scrollX;
- if (_vsb.Value != _scrollY && _scrollY <= _vsb.Maximum) _vsb.Value = _scrollY;
- }
-
- // ============================================================
- // 扒图:框选 → 高清重渲染 → OCR → 组装结果 + 蒙版
- // ============================================================
-
- public void StartPick(int mode)
- {
- if (!IsDocumentOpen)
- {
- _statusLeft.Text = "请先打开 PDF 图纸,再点扒图按钮";
- return;
- }
- _pickMode = mode;
- _highlight.Clear();
- RefreshMasks();
- string[] names = { "扒图号", "扒箱号", "扒元件" };
- _lblMode.Text = names[mode] + ":框选中(左→右逐条 / 右→左合并),ESC 退出";
- _canvas.Cursor = Cursors.Cross;
- _statusLeft.Text = "框选识别:正向拖拽=逐条,反向拖拽=合并,ESC 退出";
- }
-
- public void ExitPickMode()
- {
- _pickMode = -1;
- _picking = false;
- _lblMode.Text = "";
- _canvas.Cursor = Cursors.Default;
- _canvas.Rubber = Rectangle.Empty;
- _canvas.Invalidate();
- _statusLeft.Text = "已退出扒图模式";
- }
-
- protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
- {
- if (keyData == Keys.Escape && _pickMode >= 0)
- {
- ExitPickMode();
- PdfBridge.RaisePaExited();
- return true;
- }
- return base.ProcessCmdKey(ref msg, keyData);
- }
-
- ///
- /// 框选完成:客户区矩形 → 页面pt矩形 → 300DPI 高清重渲染 → OCR。
- /// ★ 与屏幕缩放无关:任意缩放下识别质量一致。
- ///
- private void RunPickOcr(Rectangle rectClient, bool merge)
- {
- if (!IsDocumentOpen) return;
- var origin = PageOrigin;
- // 客户区 → 页面pt
- float x0 = (rectClient.Left - origin.X) / _pxPerPt;
- float y0 = (rectClient.Top - origin.Y) / _pxPerPt;
- float x1 = (rectClient.Right - origin.X) / _pxPerPt;
- float y1 = (rectClient.Bottom - origin.Y) / _pxPerPt;
- var rectPt = RectangleF.FromLTRB(
- Math.Min(x0, x1), Math.Min(y0, y1), Math.Max(x0, x1), Math.Max(y0, y1));
-
- // OCR 渲染分辨率:300DPI,单边超限降档;不低于当前屏幕渲染比例
- float ocrScale = OCR_DPI / 72f;
- float maxSidePt = Math.Max(rectPt.Width, rectPt.Height);
- if (maxSidePt > 0 && maxSidePt * ocrScale > OCR_MAX_DIM)
- ocrScale = OCR_MAX_DIM / maxSidePt;
- if (ocrScale < _pxPerPt) ocrScale = _pxPerPt;
-
- Bitmap crop;
- try
- {
- lock (PdfRenderGate) // pdfium 非线程安全:与后台缩放渲染互斥
- {
- crop = _doc.RenderRegion(_pageIndex, rectPt, ocrScale);
- }
- }
- catch (Exception ex)
- {
- _statusLeft.Text = "框选区域渲染失败: " + ex.Message;
- return;
- }
- if (crop == null || crop.Width < 4 || crop.Height < 4) return;
-
- // Umi-OCR 本地引擎:识别前确保本体已安装且服务在线(懒启动,首次约几秒)
- if (_ocr.Engine == "umi")
- {
- try
- {
- _statusLeft.Text = "正在启动 Umi-OCR 本地引擎…";
- if (!UmiOcrLauncher.EnsureRunning()) // ★ A1:启停已拆到 UmiOcrLauncher(主项目共享版)
- {
- _statusLeft.Text = "Umi-OCR 服务启动超时(本体已安装),请稍后重试或检查 Umi-OCR 窗口";
- crop.Dispose();
- return;
- }
- }
- catch (Exception exUmi)
- {
- _statusLeft.Text = exUmi.Message;
- MessageBox.Show(this, exUmi.Message, "Umi-OCR", MessageBoxButtons.OK, MessageBoxIcon.Information);
- crop.Dispose();
- return;
- }
- }
-
- int mode = _pickMode;
- _ocrBusyCount++;
- UpdateOcrStatus();
- var sw = System.Diagnostics.Stopwatch.StartNew();
-
- _ocr.RecognizeAsync(crop, 30000).ContinueWith(t =>
- {
- _ocrBusyCount--;
- UpdateOcrStatus();
- try
- {
- var items = t.Result;
- // crop 传入过滤层(图形符号墨水/笔画判定用)
- HandleOcrResult(mode, items, rectPt, merge, ocrScale, sw.ElapsedMilliseconds, crop);
- }
- catch (Exception ex)
- {
- // t.Result 抛的 AggregateException 消息恒为"发生一个或多个错误",解包取根因
- Exception root = ex is AggregateException ? ((AggregateException)ex).GetBaseException() : ex;
- string msg = "OCR 识别失败: " + root.Message;
- _statusLeft.Text = msg;
- if (!_ocrErrorShown)
- {
- _ocrErrorShown = true;
- MessageBox.Show(this, msg + "\r\n\r\n下次框选时将自动重启 OCR。",
- "OCR", MessageBoxButtons.OK, MessageBoxIcon.Warning);
- }
- }
- finally
- {
- crop.Dispose();
- }
- }, TaskScheduler.FromCurrentSynchronizationContext());
- }
-
- private void UpdateOcrStatus()
- {
- if (_ocrBusyCount > 0)
- _statusOcr.Text = "OCR 识别中…(" + _ocrBusyCount + " 个框)";
- else
- _statusOcr.Text = "OCR 空闲";
- }
-
- ///
- /// 高风险短串:2-4 字符、含 ASCII 字母、非纯数字、不含汉字。
- /// (X1/M4/KI 这类图形误读高发形态;纯数字数量、汉字、长规格不受此门约束)
- ///
- private static bool IsShortLetterText(string s)
- {
- if (string.IsNullOrEmpty(s) || s.Length < 2 || s.Length > 4) return false;
- bool hasLetter = false;
- foreach (char c in s)
- {
- if (c >= 0x4E00 && c <= 0x9FFF) return false; // 含汉字不适用
- if (!char.IsDigit(c))
- {
- if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) hasLetter = true;
- // 其他字符(如 -)允许出现
- }
- }
- return hasLetter;
- }
-
- ///
- /// 图形误读判定(基于裁剪图 bbox 区域的笔画特征):
- /// · 百度置信度 <0.8(真短标注通常 >0.9;GLM Score=1 跳过,由下面两条兜底)
- /// · 墨水密度 ≥22%(前景=亮度<140;粗线符号 15-60%,文字 5-15%)
- /// · 水平行程中位数 ≥8px(粗笔画;文字笔画 2-5px@300DPI)
- /// 三条任一命中即判图形。
- ///
- private static bool IsGraphicMisread(OcrItem it, Bitmap crop)
- {
- if (it.Score > 0f && it.Score < 0.8f) return true;
- if (crop == null) return false;
- return StrokeMetrics(crop, it.Bounds);
- }
-
- /// 计算 bbox 区域墨水密度与水平行程中位数,超限返回 true。
- private static bool StrokeMetrics(Bitmap crop, RectangleF boundsF)
- {
- var r = Rectangle.Round(boundsF);
- r.Intersect(new Rectangle(0, 0, crop.Width, crop.Height));
- if (r.Width < 4 || r.Height < 4) return false;
-
- var data = crop.LockBits(r,
- System.Drawing.Imaging.ImageLockMode.ReadOnly,
- System.Drawing.Imaging.PixelFormat.Format32bppArgb);
- int fg = 0, total = 0;
- var runs = new List();
- try
- {
- var buf = new byte[r.Width * 4];
- for (int y = 0; y < r.Height; y++)
- {
- System.Runtime.InteropServices.Marshal.Copy(
- new IntPtr(data.Scan0.ToInt64() + y * data.Stride), buf, 0, buf.Length);
- int run = 0;
- for (int x = 0; x < r.Width; x++)
- {
- byte b = buf[x * 4], g = buf[x * 4 + 1], rr = buf[x * 4 + 2];
- int lum = (rr * 299 + g * 587 + b * 114) / 1000;
- if (lum < 140) { fg++; run++; }
- else { if (run >= 2) runs.Add(run); run = 0; }
- }
- if (run >= 2) runs.Add(run);
- total += r.Width;
- }
- }
- finally
- {
- crop.UnlockBits(data);
- }
- if (total == 0) return false;
- float density = (float)fg / total;
- if (density >= 0.22f) return true;
- if (runs.Count == 0) return false;
- runs.Sort();
- float strokeMedian = runs[runs.Count / 2];
- return strokeMedian >= 8;
- }
-
- /// 过滤丢弃记录(exe 旁 filter.log,便于调阈值);失败静默。
- private static void FilterLog(string msg)
- {
- try
- {
- File.AppendAllText(
- Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "filter.log"),
- DateTime.Now.ToString("HH:mm:ss.fff") + " " + msg + "\r\n");
- }
- catch { }
- }
-
- ///
- /// 剥离图形符号字符:电气图纸上的小三角(▲▼◀▶△)、箭头、制表线、
- /// 杂项符号等被 OCR 误当文字的内容。剥完只剩空白 → 整条丢弃(调用处判断)。
- /// ★ 只删明确的符号区段,不碰正常文字/标点/工程符号(-/.×x#等)。
- ///
- private static string RemoveSymbolJunk(string s)
- {
- if (string.IsNullOrEmpty(s)) return s;
- bool changed = false;
- var sb = new System.Text.StringBuilder(s.Length);
- foreach (char c in s)
- {
- if (IsJunkSymbolChar(c)) { changed = true; continue; }
- sb.Append(c);
- }
- if (!changed) return s;
- string r = sb.ToString().Trim();
- while (r.Contains(" ")) r = r.Replace(" ", " ");
- return r;
- }
-
- /// 图形符号字符判定(几何图形/箭头/制表线/杂项符号/零宽字符)。
- private static bool IsJunkSymbolChar(char c)
- {
- int u = c;
- if (u >= 0x25A0 && u <= 0x25FF) return true; // ▲△■□●○◤◥ 等
- if (u >= 0x2190 && u <= 0x21FF) return true; // ←↑→↓↖↗↘↙ 等箭头
- if (u >= 0x2500 && u <= 0x257F) return true; // ─│┌┐└┘├┤┬┴┼ 制表线
- if (u >= 0x2600 && u <= 0x27BF) return true; // ★☆※§ 等杂项
- if (u == 0xFE0F || u == 0x200B || u == 0x200D) return true; // 变体/零宽
- return false;
- }
-
- /// Windows OCR 符号归一化:间隔号/全角/Unicode 连字符 → 半角工程符号。
- private static string NormalizeOcrText(string s) {
- if (string.IsNullOrEmpty(s)) return s;
- s = s.Replace(" · ", "-").Replace(" - ", "-").Replace(" / ", "/");
- s = s.Replace('\u00B7', '-'); // 间隔号·
- s = s.Replace('\uFF0D', '-'); // 全角-
- s = s.Replace('\uFF0F', '/'); // 全角/
- s = s.Replace('\u2010', '-').Replace('\u2011', '-')
- .Replace('\u2012', '-').Replace('\u2013', '-')
- .Replace('\u2014', '-').Replace('\u2212', '-');
- return s.Trim();
- }
-
- /// OCR 完成:按 CAD 语义组装 results + 画蒙版 + 通知 Form3。
- private void HandleOcrResult(int mode, List items,
- RectangleF rectPt, bool merge, float ocrScale, long elapsedMs, Bitmap crop)
- {
- var valid = new List();
- foreach (var it in items)
- {
- string norm = NormalizeOcrText(it.Text);
- norm = RemoveSymbolJunk(norm); // ★ 剥离图形符号字符(▲等)
- if (string.IsNullOrWhiteSpace(norm)) continue;
- // ★ 电气图形符号被 OCR 误读成文字的特征过滤:
- // 1) 剥完只剩 1 个非数字非汉字的字符(如图形认成 "A"/"M") → 丢
- // 2) 低置信度(<0.55,百度引擎给出;GLM 恒为 1 不受影响) → 丢
- // 3) 短文本(2-3字符,非纯数字)+ 近方形框 → 圆圈/三角等图形符号误读
- // (真实横排文字宽高比 >1.4,图形外接框宽≈高;纯数字与汉字单字保护)
- if (norm.Length == 1 && !char.IsDigit(norm[0]) &&
- !(norm[0] >= 0x4E00 && norm[0] <= 0x9FFF)) continue;
- if (it.Score > 0f && it.Score < 0.55f) continue;
- if (norm.Length >= 2 && norm.Length <= 3)
- {
- bool allDigits = true;
- foreach (char c in norm) if (!char.IsDigit(c)) { allDigits = false; break; }
- if (!allDigits)
- {
- var b = it.Bounds;
- if (b.Height > 4)
- {
- float ratio = b.Width / b.Height;
- if (ratio >= 0.7f && ratio <= 1.4f) continue;
- }
- }
- }
- // 4) ★ 短串(2-4字符,含字母)+ 图形笔画特征 → 线圈/方框等粗线符号误读
- // (如 X|X 绕组符号认成 "X1":横宽与真文字一样,靠墨水密度/笔画宽度区分)
- if (IsShortLetterText(norm) && IsGraphicMisread(it, crop))
- {
- FilterLog("丢弃疑似图形符号 '" + norm + "' score=" +
- it.Score.ToString("0.00") + " 密度/笔画超限");
- continue;
- }
- it.Text = norm;
- valid.Add(it);
- }
- if (valid.Count == 0)
- {
- _statusLeft.Text = "未识别到文字 —— 可放大视图或调整框选范围后重试 (" + elapsedMs + "ms)";
- return;
- }
-
- // 列分组、列内从上到下(与 CAD 版 PaTextSelector 顺序语义一致)
- valid = SortByColumns(valid);
-
- var results = new List();
- string mergeHandle = null;
-
- foreach (var it in valid)
- {
- // 裁剪图像素 → 页面点
- RectangleF b = it.Bounds;
- RectangleF boxPt = new RectangleF(
- rectPt.X + b.X / ocrScale,
- rectPt.Y + b.Y / ocrScale,
- b.Width / ocrScale, b.Height / ocrScale);
- string textHandle = FindOrBuildTextHandle(_pageIndex, boxPt);
-
- string frameHandle;
- if (merge)
- {
- if (mergeHandle == null)
- {
- mergeHandle = NewHandle();
- _masks.Add(new PdfMaskItem
- {
- Handle = mergeHandle,
- TextHandle = BuildTextHandle(_pageIndex, rectPt),
- Page = _pageIndex,
- RectPt = rectPt,
- Mode = mode
- });
- }
- frameHandle = mergeHandle;
- }
- else
- {
- frameHandle = NewHandle();
- _masks.Add(new PdfMaskItem
- {
- Handle = frameHandle,
- TextHandle = textHandle,
- Page = _pageIndex,
- RectPt = boxPt,
- Mode = mode
- });
- }
-
- results.Add(new MyApp.PaTextResult
- {
- Text = it.Text.Trim(),
- FrameHandle = frameHandle,
- TextHandle = textHandle
- });
- }
-
- SaveMasks();
- RefreshMasks();
- _statusLeft.Text = "识别到 " + valid.Count + " 条文本(" + elapsedMs + "ms)" +
- (merge ? ",合并模式,已拼为一条规格" : "") + ",已入表格并画框";
- _ocrErrorShown = false;
-
- PdfBridge.RaisePaPicked((MyApp.PaMode)mode, results);
- }
-
- /// 按"列分组、列内从上到下"排序(阅读顺序)。
- private static List SortByColumns(List items)
- {
- var byX = items.OrderBy(i => i.Bounds.X).ToList();
- var columns = new List>();
- foreach (var it in byX)
- {
- bool placed = false;
- foreach (var col in columns)
- {
- float colLeft = col.Min(c => c.Bounds.Left);
- float colRight = col.Max(c => c.Bounds.Right);
- float itMid = it.Bounds.Left + it.Bounds.Width / 2f;
- if (itMid >= colLeft - 2 && itMid <= colRight + 2)
- {
- col.Add(it);
- placed = true;
- break;
- }
- }
- if (!placed) columns.Add(new List { it });
- }
- var result = new List();
- foreach (var col in columns)
- result.AddRange(col.OrderBy(c => c.Bounds.Y).ThenBy(c => c.Bounds.X));
- return result;
- }
-
- private string NewHandle()
- {
- return "M" + (_handleCounter++);
- }
-
- /// 稳定文本标识:页码 + 中心点(10pt 网格) + 尺寸(5pt 网格)。
- private static string BuildTextHandle(int page, RectangleF rectPt)
- {
- float cx = rectPt.X + rectPt.Width / 2f;
- float cy = rectPt.Y + rectPt.Height / 2f;
- return "P" + page
- + "@" + (int)Math.Round(cx / 10.0) + "," + (int)Math.Round(cy / 10.0)
- + "|" + (int)Math.Round(rectPt.Width / 5.0) + "x" + (int)Math.Round(rectPt.Height / 5.0);
- }
-
- /// 会话内复用:同页 IoU>0.5 的旧框 → 沿用其 TextHandle。
- private string FindOrBuildTextHandle(int page, RectangleF rectPt)
- {
- foreach (var m in _sessionPicked)
- {
- if (m.Page != page) continue;
- RectangleF a = m.RectPt;
- RectangleF inter = RectangleF.Intersect(a, rectPt);
- if (inter.Width <= 0 || inter.Height <= 0) continue;
- float interArea = inter.Width * inter.Height;
- float union = a.Width * a.Height + rectPt.Width * rectPt.Height - interArea;
- if (union > 0 && interArea / union > 0.5f)
- {
- m.RectPt = rectPt;
- return m.TextHandle;
- }
- }
- string th = BuildTextHandle(page, rectPt);
- _sessionPicked.Add(new PdfMaskItem
- {
- Handle = "",
- TextHandle = th,
- Page = page,
- RectPt = rectPt
- });
- return th;
- }
-
- // ============================================================
- // 桥联动:定位 / 删框 / 合并 / 高亮
- // ============================================================
-
- public void ZoomToFrame(string handle)
- {
- PdfMaskItem m = null;
- foreach (var k in _masks)
- if (k.Handle == handle) { m = k; break; }
- if (m == null) return;
-
- if (m.Page != _pageIndex)
- {
- _pageIndex = m.Page;
- RenderCurrentPage(clearPage: true); // 跨页定位:清旧页位图
- UpdateNavUi();
- }
- // 框太小看不清时放大到框宽约 300px
- float pxw = m.RectPt.Width * _pxPerPt;
- if (pxw < 300)
- {
- float want = (300f / m.RectPt.Width) / _dpiFactor;
- SetZoom(Math.Min(MaxZoom, want));
- }
-
- float cx = (m.RectPt.X + m.RectPt.Width / 2f) * _pxPerPt;
- float cy = (m.RectPt.Y + m.RectPt.Height / 2f) * _pxPerPt;
- var view = PageViewSize; // 视图尺寸(过渡帧拉伸期间按当前视图比例算滚动范围)
- _scrollX = Clamp((int)cx - _canvas.ClientSize.Width / 2, 0, Math.Max(0, view.Width - _canvas.ClientSize.Width));
- _scrollY = Clamp((int)cy - _canvas.ClientSize.Height / 2, 0, Math.Max(0, view.Height - _canvas.ClientSize.Height));
- UpdateScrollbars();
- SyncScrollbars();
-
- _highlight.Clear();
- _highlight.Add(handle);
- RefreshMasks();
- _highlightTimer.Stop();
- _highlightTimer.Start();
- }
-
- public void DeleteFrames(List handles)
- {
- if (handles == null || handles.Count == 0) return;
- bool changed = false;
- foreach (string h in handles)
- {
- int n = _masks.RemoveAll(m => m.Handle == h);
- if (n > 0) changed = true;
- _highlight.Remove(h);
- }
- if (changed)
- {
- SaveMasks();
- RefreshMasks();
- }
- }
-
- public void MergeMasks(string keep, List removes)
- {
- PdfMaskItem k = null;
- foreach (var m in _masks)
- if (m.Handle == keep) { k = m; break; }
- if (k == null) return;
- bool changed = false;
- foreach (string h in removes)
- {
- PdfMaskItem r = _masks.FirstOrDefault(m => m.Handle == h);
- if (r == null) continue;
- float l = Math.Min(k.RectPt.Left, r.RectPt.Left);
- float t = Math.Min(k.RectPt.Top, r.RectPt.Top);
- float rr = Math.Max(k.RectPt.Right, r.RectPt.Right);
- float b = Math.Max(k.RectPt.Bottom, r.RectPt.Bottom);
- k.RectPt = RectangleF.FromLTRB(l, t, rr, b);
- _masks.Remove(r);
- changed = true;
- }
- if (changed)
- {
- SaveMasks();
- RefreshMasks();
- }
- }
-
- public void ClearHighlight()
- {
- _highlight.Clear();
- RefreshMasks();
- }
-
- // ============================================================
- // 蒙版持久化
- // ============================================================
-
- private void SaveMasks()
- {
- if (string.IsNullOrEmpty(_maskSavePath)) return;
- try
- {
- var data = new
- {
- counter = _handleCounter,
- masks = _masks.Select(m => new
- {
- handle = m.Handle,
- textHandle = m.TextHandle,
- page = m.Page,
- mode = m.Mode,
- rect = new[] { m.RectPt.X, m.RectPt.Y, m.RectPt.Width, m.RectPt.Height }
- }).ToArray()
- };
- File.WriteAllText(_maskSavePath, _json.Serialize(data));
- }
- catch { }
- }
-
- private void LoadMasks()
- {
- _masks = new List();
- _sessionPicked = new List();
- _highlight.Clear();
- _handleCounter = 1;
- if (string.IsNullOrEmpty(_maskSavePath) || !File.Exists(_maskSavePath)) return;
- try
- {
- var data = _json.Deserialize>(File.ReadAllText(_maskSavePath));
- if (data == null) return;
- if (data.ContainsKey("counter"))
- _handleCounter = Convert.ToInt32(data["counter"]);
- var arr = data.ContainsKey("masks") ? data["masks"] as System.Collections.ArrayList : null;
- if (arr != null)
- {
- foreach (Dictionary m in arr)
- {
- var rect = m["rect"] as System.Collections.ArrayList;
- var item = new PdfMaskItem
- {
- Handle = Convert.ToString(m["handle"]),
- TextHandle = Convert.ToString(m["textHandle"]),
- Page = Convert.ToInt32(m["page"]),
- Mode = Convert.ToInt32(m["mode"]),
- RectPt = new RectangleF(
- Convert.ToSingle(rect[0]), Convert.ToSingle(rect[1]),
- Convert.ToSingle(rect[2]), Convert.ToSingle(rect[3]))
- };
- _masks.Add(item);
- _sessionPicked.Add(item);
- }
- }
- }
- catch { }
- }
-
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- try { if (_ocr != null) _ocr.Dispose(); } catch { }
- try
- {
- if (_doc != null)
- {
- _renderGen++; // 作废在途后台渲染
- lock (PdfRenderGate) { _doc.Dispose(); } // 与后台渲染互斥后释放
- }
- }
- catch { }
- // Umi-OCR:只停由本程序启动的实例(用户自己开的 Umi-OCR 不动)
- try { UmiOcrLauncher.StopIfStartedByUs(); } catch { } // ★ A1:启停已拆到 UmiOcrLauncher(主项目共享版)
- }
- base.Dispose(disposing);
- }
-
- // ============================================================
- // 内部画布:位图 + 蒙版 + 橡皮筋(同一双缓冲绘制,无闪烁)
- // ============================================================
- private class ViewerCanvas : Control
- {
- private Bitmap _page;
- public float PxPerPt = 1f;
- /// 视图比例/位图实际比例(缩放过渡帧>1 或 <1:位图待拉伸;高清渲染落图后回 1)。
- public float ViewScale = 1f;
- public List Masks = new List();
- public HashSet Highlight = new HashSet();
- public Rectangle Rubber = Rectangle.Empty;
- public bool RubberMerge;
-
- public ViewerCanvas()
- {
- SetStyle(ControlStyles.AllPaintingInWmPaint
- | ControlStyles.OptimizedDoubleBuffer
- | ControlStyles.UserPaint
- | ControlStyles.ResizeRedraw, true);
- Cursor = Cursors.Default;
- TabStop = true;
- }
-
- public Bitmap Page
- {
- get { return _page; }
- }
-
- public void SetPage(Bitmap bmp, float pxPerPt)
- {
- if (_page != null && _page != bmp) _page.Dispose();
- _page = bmp;
- PxPerPt = pxPerPt;
- ViewScale = 1f; // 新位图即视图比例
- Invalidate();
- }
-
- /// 缩放过渡帧:不换位图,只把视图比例改为 viewPxPerPt(旧位图按 ViewScale 拉伸显示),
- /// 后台高清渲染完成 SetPage 后自动复位。位图未就绪时忽略。
- public void SetViewScale(float viewPxPerPt)
- {
- if (_page == null || PxPerPt <= 0) return;
- float st = viewPxPerPt / PxPerPt;
- if (Math.Abs(st - ViewScale) < 0.001f) return;
- ViewScale = st;
- Invalidate();
- }
-
- protected override void OnPaint(PaintEventArgs e)
- {
- var g = e.Graphics;
- g.Clear(BackColor);
- if (_page == null) return;
-
- var origin = GetOrigin();
- // ★ 过渡帧:位图按 ViewScale 拉伸绘制(1:1 时与原 DrawImage 完全等价);
- // 大图拉伸用 Bilinear(默认 HighQualityBicubic 更慢,过渡帧求即时反馈)
- bool stretching = Math.Abs(ViewScale - 1f) > 0.001f;
- if (stretching) g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Bilinear;
- g.DrawImage(_page, origin.X, origin.Y,
- _page.Width * ViewScale, _page.Height * ViewScale);
-
- float vpp = PxPerPt * ViewScale; // 当前视图比例(蒙版换算用)
-
- // 蒙版框(页面pt → 屏幕)
- foreach (var m in Masks)
- {
- var rect = new RectangleF(
- origin.X + m.RectPt.X * vpp,
- origin.Y + m.RectPt.Y * vpp,
- m.RectPt.Width * vpp, m.RectPt.Height * vpp);
- if (rect.Width < 1 || rect.Height < 1) continue;
- bool hl = Highlight.Contains(m.Handle);
- using (var fill = new SolidBrush(Color.FromArgb(70, m.Color)))
- g.FillRectangle(fill, rect);
- using (var pen = new Pen(m.Color, hl ? 4f : 2f))
- g.DrawRectangle(pen, rect.X, rect.Y, rect.Width, rect.Height);
- if (hl)
- {
- using (var pen2 = new Pen(Color.FromArgb(120, Color.Gold), 7f))
- g.DrawRectangle(pen2, rect.X - 3, rect.Y - 3,
- rect.Width + 6, rect.Height + 6);
- }
- }
-
- // 橡皮筋
- if (Rubber.Width > 0 && Rubber.Height > 0)
- {
- Color rc = RubberMerge ? Color.OrangeRed : Color.RoyalBlue;
- using (var fill = new SolidBrush(Color.FromArgb(40, rc)))
- g.FillRectangle(fill, Rubber);
- using (var pen = new Pen(rc, 1.5f) { DashStyle = DashStyle.Dash })
- g.DrawRectangle(pen, Rubber.X, Rubber.Y, Rubber.Width, Rubber.Height);
- }
- base.OnPaint(e);
- }
-
- /// 宿主注入的原点计算(避免画布反查滚动状态)。
- public Func OriginProvider;
-
- private Point GetOrigin()
- {
- return OriginProvider != null ? OriginProvider() : Point.Empty;
- }
-
- protected override bool IsInputKey(Keys keyData)
- {
- // 方向键给画布(避免被父容器抢去切焦点)
- if ((keyData & Keys.KeyCode) == Keys.Left ||
- (keyData & Keys.KeyCode) == Keys.Right ||
- (keyData & Keys.KeyCode) == Keys.Up ||
- (keyData & Keys.KeyCode) == Keys.Down)
- return true;
- return base.IsInputKey(keyData);
- }
-
- protected override void OnPaintBackground(PaintEventArgs e)
- {
- // 全部在 OnPaint 绘制(双缓冲)
- }
- }
- }
-}
diff --git a/pdfbt/Plugin/Form3.Designer.cs b/pdfbt/Plugin/Form3.Designer.cs
deleted file mode 100644
index f2db03c..0000000
--- a/pdfbt/Plugin/Form3.Designer.cs
+++ /dev/null
@@ -1,1321 +0,0 @@
-namespace MyApp
-{
- public partial class Form3 : System.Windows.Forms.Form
- {
- /// 必需的设计器变量。
- private System.ComponentModel.IContainer components = null;
-
- /// 清理正在使用的资源。
- protected override void Dispose(bool disposing)
- {
- if (disposing && (components != null))
- {
- components.Dispose();
- }
- base.Dispose(disposing);
- }
-
- #region Windows 窗体设计器生成的代码
-
- private void InitializeComponent()
- {
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle3 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle4 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle5 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle6 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle7 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle8 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle9 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle10 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle11 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle12 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle13 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle14 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle15 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle16 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle17 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle18 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle19 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle20 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle21 = new System.Windows.Forms.DataGridViewCellStyle();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle22 = new System.Windows.Forms.DataGridViewCellStyle();
- this.tabControl2 = new System.Windows.Forms.TabControl();
- this.tabPage3 = new System.Windows.Forms.TabPage();
- this.advancedDataGridView6 = new Zuby.ADGV.AdvancedDataGridView();
- this.dataGridViewTextBoxColumn1 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn2 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn3 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn4 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn5 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn6 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn7 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn8 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn9 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn10 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn11 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn12 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn13 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.panel1 = new System.Windows.Forms.Panel();
- this.button28 = new System.Windows.Forms.Button();
- this.textBox1 = new System.Windows.Forms.TextBox();
- this.comboBox2 = new System.Windows.Forms.ComboBox();
- this.tabPage4 = new System.Windows.Forms.TabPage();
- this.splitContainer2 = new System.Windows.Forms.SplitContainer();
- this.advancedDataGridView9 = new Zuby.ADGV.AdvancedDataGridView();
- this.dataGridViewTextBoxColumn14 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn15 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn16 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn17 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn18 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn19 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn20 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn21 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn22 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn23 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.splitContainer3 = new System.Windows.Forms.SplitContainer();
- this.advancedDataGridView4 = new Zuby.ADGV.AdvancedDataGridView();
- this.dataGridViewTextBoxColumn24 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn25 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn26 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn27 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn28 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn29 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn30 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn31 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn32 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn33 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn34 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn35 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn36 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn37 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn38 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn39 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn40 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.advancedDataGridView5 = new Zuby.ADGV.AdvancedDataGridView();
- this.dataGridViewTextBoxColumn41 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn42 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn43 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn44 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn45 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn46 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn47 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn48 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn49 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn50 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn51 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn52 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn53 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn54 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn55 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn56 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.dataGridViewTextBoxColumn57 = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.toolStrip1 = new System.Windows.Forms.ToolStrip();
- this.toolStripButton1 = new System.Windows.Forms.ToolStripButton();
- this.toolStripButton5 = new System.Windows.Forms.ToolStripButton();
- this.toolStripButton6 = new System.Windows.Forms.ToolStripButton();
- this.toolStripButton2 = new System.Windows.Forms.ToolStripButton();
- this.toolStripButton3 = new System.Windows.Forms.ToolStripButton();
- this.toolStripButton4 = new System.Windows.Forms.ToolStripButton();
- this.toolStripButton7 = new System.Windows.Forms.ToolStripButton();
- this.tabControl2.SuspendLayout();
- this.tabPage3.SuspendLayout();
- ((System.ComponentModel.ISupportInitialize)(this.advancedDataGridView6)).BeginInit();
- this.panel1.SuspendLayout();
- this.tabPage4.SuspendLayout();
- ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).BeginInit();
- this.splitContainer2.Panel1.SuspendLayout();
- this.splitContainer2.Panel2.SuspendLayout();
- this.splitContainer2.SuspendLayout();
- ((System.ComponentModel.ISupportInitialize)(this.advancedDataGridView9)).BeginInit();
- ((System.ComponentModel.ISupportInitialize)(this.splitContainer3)).BeginInit();
- this.splitContainer3.Panel1.SuspendLayout();
- this.splitContainer3.Panel2.SuspendLayout();
- this.splitContainer3.SuspendLayout();
- ((System.ComponentModel.ISupportInitialize)(this.advancedDataGridView4)).BeginInit();
- ((System.ComponentModel.ISupportInitialize)(this.advancedDataGridView5)).BeginInit();
- this.toolStrip1.SuspendLayout();
- this.SuspendLayout();
- //
- // tabControl2
- //
- this.tabControl2.Controls.Add(this.tabPage3);
- this.tabControl2.Controls.Add(this.tabPage4);
- this.tabControl2.Dock = System.Windows.Forms.DockStyle.Fill;
- this.tabControl2.Font = new System.Drawing.Font("宋体", 9F);
- this.tabControl2.ItemSize = new System.Drawing.Size(60, 21);
- this.tabControl2.Location = new System.Drawing.Point(0, 31);
- this.tabControl2.Name = "tabControl2";
- this.tabControl2.SelectedIndex = 0;
- this.tabControl2.Size = new System.Drawing.Size(540, 838);
- this.tabControl2.SizeMode = System.Windows.Forms.TabSizeMode.Fixed;
- this.tabControl2.TabIndex = 0;
- //
- // tabPage3
- //
- this.tabPage3.BackColor = System.Drawing.Color.Transparent;
- this.tabPage3.Controls.Add(this.advancedDataGridView6);
- this.tabPage3.Controls.Add(this.panel1);
- this.tabPage3.Font = new System.Drawing.Font("宋体", 9F);
- this.tabPage3.ForeColor = System.Drawing.SystemColors.ControlText;
- this.tabPage3.Location = new System.Drawing.Point(4, 25);
- this.tabPage3.Name = "tabPage3";
- this.tabPage3.Padding = new System.Windows.Forms.Padding(3);
- this.tabPage3.Size = new System.Drawing.Size(473, 669);
- this.tabPage3.TabIndex = 0;
- this.tabPage3.Text = "项目";
- this.tabPage3.UseVisualStyleBackColor = true;
- //
- // advancedDataGridView6
- //
- this.advancedDataGridView6.AllowUserToAddRows = false;
- this.advancedDataGridView6.AllowUserToResizeRows = false;
- this.advancedDataGridView6.BackgroundColor = System.Drawing.Color.White;
- dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
- dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Control;
- dataGridViewCellStyle1.Font = new System.Drawing.Font("宋体", 9F);
- dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.WindowText;
- dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Control;
- dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.WindowText;
- dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
- this.advancedDataGridView6.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1;
- this.advancedDataGridView6.ColumnHeadersHeight = 25;
- this.advancedDataGridView6.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
- this.dataGridViewTextBoxColumn1,
- this.dataGridViewTextBoxColumn2,
- this.dataGridViewTextBoxColumn3,
- this.dataGridViewTextBoxColumn4,
- this.dataGridViewTextBoxColumn5,
- this.dataGridViewTextBoxColumn6,
- this.dataGridViewTextBoxColumn7,
- this.dataGridViewTextBoxColumn8,
- this.dataGridViewTextBoxColumn9,
- this.dataGridViewTextBoxColumn10,
- this.dataGridViewTextBoxColumn11,
- this.dataGridViewTextBoxColumn12,
- this.dataGridViewTextBoxColumn13});
- //
- // dataGridViewTextBoxColumn1
- //
- this.dataGridViewTextBoxColumn1.DataPropertyName = "项目编号";
- this.dataGridViewTextBoxColumn1.HeaderText = "项目编号";
- this.dataGridViewTextBoxColumn1.Name = "dataGridViewTextBoxColumn1";
- this.dataGridViewTextBoxColumn1.ReadOnly = true;
- this.dataGridViewTextBoxColumn1.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn1.Width = 100;
- //
- // dataGridViewTextBoxColumn2
- //
- this.dataGridViewTextBoxColumn2.DataPropertyName = "项目名称";
- this.dataGridViewTextBoxColumn2.HeaderText = "项目名称";
- this.dataGridViewTextBoxColumn2.Name = "dataGridViewTextBoxColumn2";
- this.dataGridViewTextBoxColumn2.ReadOnly = true;
- this.dataGridViewTextBoxColumn2.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn2.Width = 100;
- //
- // dataGridViewTextBoxColumn3
- //
- this.dataGridViewTextBoxColumn3.DataPropertyName = "客户名称";
- this.dataGridViewTextBoxColumn3.HeaderText = "客户名称";
- this.dataGridViewTextBoxColumn3.Name = "dataGridViewTextBoxColumn3";
- this.dataGridViewTextBoxColumn3.ReadOnly = true;
- this.dataGridViewTextBoxColumn3.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn3.Width = 100;
- //
- // dataGridViewTextBoxColumn4
- //
- this.dataGridViewTextBoxColumn4.DataPropertyName = "客户地址";
- this.dataGridViewTextBoxColumn4.HeaderText = "客户地址";
- this.dataGridViewTextBoxColumn4.Name = "dataGridViewTextBoxColumn4";
- this.dataGridViewTextBoxColumn4.ReadOnly = true;
- this.dataGridViewTextBoxColumn4.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn4.Width = 100;
- //
- // dataGridViewTextBoxColumn5
- //
- this.dataGridViewTextBoxColumn5.DataPropertyName = "联系人";
- this.dataGridViewTextBoxColumn5.HeaderText = "联系人";
- this.dataGridViewTextBoxColumn5.Name = "dataGridViewTextBoxColumn5";
- this.dataGridViewTextBoxColumn5.ReadOnly = true;
- this.dataGridViewTextBoxColumn5.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn5.Width = 100;
- //
- // dataGridViewTextBoxColumn6
- //
- this.dataGridViewTextBoxColumn6.DataPropertyName = "联系电话";
- this.dataGridViewTextBoxColumn6.HeaderText = "联系电话";
- this.dataGridViewTextBoxColumn6.Name = "dataGridViewTextBoxColumn6";
- this.dataGridViewTextBoxColumn6.ReadOnly = true;
- this.dataGridViewTextBoxColumn6.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn6.Width = 100;
- //
- // dataGridViewTextBoxColumn7
- //
- this.dataGridViewTextBoxColumn7.DataPropertyName = "项目日期";
- this.dataGridViewTextBoxColumn7.HeaderText = "项目日期";
- this.dataGridViewTextBoxColumn7.Name = "dataGridViewTextBoxColumn7";
- this.dataGridViewTextBoxColumn7.ReadOnly = true;
- this.dataGridViewTextBoxColumn7.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn7.Width = 100;
- //
- // dataGridViewTextBoxColumn8
- //
- this.dataGridViewTextBoxColumn8.DataPropertyName = "箱柜台数";
- this.dataGridViewTextBoxColumn8.HeaderText = "箱柜台数";
- this.dataGridViewTextBoxColumn8.Name = "dataGridViewTextBoxColumn8";
- this.dataGridViewTextBoxColumn8.ReadOnly = true;
- this.dataGridViewTextBoxColumn8.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn8.Width = 100;
- //
- // dataGridViewTextBoxColumn9
- //
- this.dataGridViewTextBoxColumn9.DataPropertyName = "成本总价";
- this.dataGridViewTextBoxColumn9.HeaderText = "成本总价";
- this.dataGridViewTextBoxColumn9.Name = "dataGridViewTextBoxColumn9";
- this.dataGridViewTextBoxColumn9.ReadOnly = true;
- this.dataGridViewTextBoxColumn9.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn9.Width = 100;
- //
- // dataGridViewTextBoxColumn10
- //
- this.dataGridViewTextBoxColumn10.DataPropertyName = "报出总价";
- this.dataGridViewTextBoxColumn10.HeaderText = "报出总价";
- this.dataGridViewTextBoxColumn10.Name = "dataGridViewTextBoxColumn10";
- this.dataGridViewTextBoxColumn10.ReadOnly = true;
- this.dataGridViewTextBoxColumn10.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn10.Width = 100;
- //
- // dataGridViewTextBoxColumn11
- //
- this.dataGridViewTextBoxColumn11.DataPropertyName = "利润";
- this.dataGridViewTextBoxColumn11.HeaderText = "利润";
- this.dataGridViewTextBoxColumn11.Name = "dataGridViewTextBoxColumn11";
- this.dataGridViewTextBoxColumn11.ReadOnly = true;
- this.dataGridViewTextBoxColumn11.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn11.Width = 100;
- //
- // dataGridViewTextBoxColumn12
- //
- this.dataGridViewTextBoxColumn12.DataPropertyName = "利润率";
- this.dataGridViewTextBoxColumn12.HeaderText = "利润率";
- this.dataGridViewTextBoxColumn12.Name = "dataGridViewTextBoxColumn12";
- this.dataGridViewTextBoxColumn12.ReadOnly = true;
- this.dataGridViewTextBoxColumn12.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn12.Width = 100;
- //
- // dataGridViewTextBoxColumn13
- //
- this.dataGridViewTextBoxColumn13.DataPropertyName = "备注";
- this.dataGridViewTextBoxColumn13.HeaderText = "备注";
- this.dataGridViewTextBoxColumn13.Name = "dataGridViewTextBoxColumn13";
- this.dataGridViewTextBoxColumn13.ReadOnly = true;
- this.dataGridViewTextBoxColumn13.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn13.Width = 100;
- dataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
- dataGridViewCellStyle2.BackColor = System.Drawing.SystemColors.Window;
- dataGridViewCellStyle2.Font = new System.Drawing.Font("宋体", 9F);
- dataGridViewCellStyle2.ForeColor = System.Drawing.SystemColors.ControlText;
- dataGridViewCellStyle2.SelectionBackColor = System.Drawing.SystemColors.Window;
- dataGridViewCellStyle2.SelectionForeColor = System.Drawing.SystemColors.ControlText;
- dataGridViewCellStyle2.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
- this.advancedDataGridView6.DefaultCellStyle = dataGridViewCellStyle2;
- this.advancedDataGridView6.Dock = System.Windows.Forms.DockStyle.Fill;
- this.advancedDataGridView6.EnableHeadersVisualStyles = false;
- this.advancedDataGridView6.Location = new System.Drawing.Point(3, 31);
- this.advancedDataGridView6.Name = "advancedDataGridView6";
- this.advancedDataGridView6.ReadOnly = true;
- this.advancedDataGridView6.RightToLeft = System.Windows.Forms.RightToLeft.No;
- dataGridViewCellStyle3.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
- dataGridViewCellStyle3.BackColor = System.Drawing.SystemColors.Control;
- dataGridViewCellStyle3.Font = new System.Drawing.Font("宋体", 9F);
- dataGridViewCellStyle3.ForeColor = System.Drawing.SystemColors.WindowText;
- dataGridViewCellStyle3.SelectionBackColor = System.Drawing.SystemColors.Control;
- dataGridViewCellStyle3.SelectionForeColor = System.Drawing.SystemColors.WindowText;
- dataGridViewCellStyle3.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
- this.advancedDataGridView6.RowHeadersDefaultCellStyle = dataGridViewCellStyle3;
- this.advancedDataGridView6.Size = new System.Drawing.Size(467, 635);
- this.advancedDataGridView6.TabIndex = 1;
- //
- // panel1
- //
- this.panel1.BackColor = System.Drawing.SystemColors.Control;
- this.panel1.Controls.Add(this.button28);
- this.panel1.Controls.Add(this.textBox1);
- this.panel1.Controls.Add(this.comboBox2);
- this.panel1.Dock = System.Windows.Forms.DockStyle.Top;
- this.panel1.Font = new System.Drawing.Font("宋体", 9F);
- this.panel1.ForeColor = System.Drawing.SystemColors.ControlText;
- this.panel1.Location = new System.Drawing.Point(3, 3);
- this.panel1.Name = "panel1";
- this.panel1.Size = new System.Drawing.Size(467, 28);
- this.panel1.TabIndex = 0;
- //
- // button28
- //
- this.button28.BackColor = System.Drawing.SystemColors.Control;
- this.button28.Font = new System.Drawing.Font("宋体", 9F);
- this.button28.ForeColor = System.Drawing.SystemColors.ControlText;
- this.button28.Location = new System.Drawing.Point(335, 2);
- this.button28.Name = "button28";
- this.button28.Size = new System.Drawing.Size(75, 23);
- this.button28.TabIndex = 2;
- this.button28.Text = "查找";
- this.button28.UseVisualStyleBackColor = true;
- //
- // textBox1
- //
- this.textBox1.BackColor = System.Drawing.SystemColors.Window;
- this.textBox1.Font = new System.Drawing.Font("宋体", 9F);
- this.textBox1.ForeColor = System.Drawing.SystemColors.WindowText;
- this.textBox1.Location = new System.Drawing.Point(119, 4);
- this.textBox1.Name = "textBox1";
- this.textBox1.Size = new System.Drawing.Size(210, 28);
- this.textBox1.TabIndex = 1;
- //
- // comboBox2
- //
- this.comboBox2.BackColor = System.Drawing.SystemColors.Window;
- this.comboBox2.DropDownWidth = 108;
- this.comboBox2.Font = new System.Drawing.Font("宋体", 9F);
- this.comboBox2.ForeColor = System.Drawing.SystemColors.WindowText;
- this.comboBox2.ItemHeight = 18;
- this.comboBox2.Items.AddRange(new object[] {
- "项目名称",
- "项目编号",
- "客户名称"});
- this.comboBox2.Location = new System.Drawing.Point(5, 4);
- this.comboBox2.Name = "comboBox2";
- this.comboBox2.Size = new System.Drawing.Size(108, 26);
- this.comboBox2.TabIndex = 0;
- this.comboBox2.Text = "项目名称";
- //
- // tabPage4
- //
- this.tabPage4.BackColor = System.Drawing.Color.Transparent;
- this.tabPage4.Controls.Add(this.splitContainer2);
- this.tabPage4.Font = new System.Drawing.Font("宋体", 9F);
- this.tabPage4.ForeColor = System.Drawing.SystemColors.ControlText;
- this.tabPage4.Location = new System.Drawing.Point(4, 25);
- this.tabPage4.Name = "tabPage4";
- this.tabPage4.Padding = new System.Windows.Forms.Padding(3);
- this.tabPage4.Size = new System.Drawing.Size(532, 809);
- this.tabPage4.TabIndex = 1;
- this.tabPage4.Text = "报价";
- this.tabPage4.UseVisualStyleBackColor = true;
- //
- // splitContainer2
- //
- this.splitContainer2.BackColor = System.Drawing.SystemColors.Control;
- this.splitContainer2.Dock = System.Windows.Forms.DockStyle.Fill;
- this.splitContainer2.Font = new System.Drawing.Font("宋体", 9F);
- this.splitContainer2.ForeColor = System.Drawing.SystemColors.ControlText;
- this.splitContainer2.Location = new System.Drawing.Point(3, 3);
- this.splitContainer2.Name = "splitContainer2";
- this.splitContainer2.Orientation = System.Windows.Forms.Orientation.Horizontal;
- //
- // splitContainer2.Panel1
- //
- this.splitContainer2.Panel1.Controls.Add(this.advancedDataGridView9);
- //
- // splitContainer2.Panel2
- //
- this.splitContainer2.Panel2.Controls.Add(this.splitContainer3);
- this.splitContainer2.Size = new System.Drawing.Size(526, 803);
- this.splitContainer2.SplitterDistance = 254;
- this.splitContainer2.SplitterWidth = 6;
- this.splitContainer2.TabIndex = 0;
- //
- // advancedDataGridView9
- //
- this.advancedDataGridView9.AllowUserToAddRows = false;
- this.advancedDataGridView9.AllowUserToResizeRows = false;
- this.advancedDataGridView9.BackgroundColor = System.Drawing.Color.White;
- dataGridViewCellStyle4.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
- dataGridViewCellStyle4.BackColor = System.Drawing.SystemColors.Control;
- dataGridViewCellStyle4.Font = new System.Drawing.Font("宋体", 9F);
- dataGridViewCellStyle4.ForeColor = System.Drawing.SystemColors.WindowText;
- dataGridViewCellStyle4.SelectionBackColor = System.Drawing.SystemColors.Control;
- dataGridViewCellStyle4.SelectionForeColor = System.Drawing.SystemColors.WindowText;
- dataGridViewCellStyle4.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
- this.advancedDataGridView9.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle4;
- this.advancedDataGridView9.ColumnHeadersHeight = 35;
- this.advancedDataGridView9.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
- this.dataGridViewTextBoxColumn14,
- this.dataGridViewTextBoxColumn15,
- this.dataGridViewTextBoxColumn16,
- this.dataGridViewTextBoxColumn17,
- this.dataGridViewTextBoxColumn18,
- this.dataGridViewTextBoxColumn19,
- this.dataGridViewTextBoxColumn20,
- this.dataGridViewTextBoxColumn21,
- this.dataGridViewTextBoxColumn22,
- this.dataGridViewTextBoxColumn23});
- //
- // dataGridViewTextBoxColumn14
- //
- this.dataGridViewTextBoxColumn14.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None;
- this.dataGridViewTextBoxColumn14.DataPropertyName = "序号";
- dataGridViewCellStyle13.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
- this.dataGridViewTextBoxColumn14.DefaultCellStyle = dataGridViewCellStyle13;
- this.dataGridViewTextBoxColumn14.Frozen = true;
- this.dataGridViewTextBoxColumn14.HeaderText = "序号";
- this.dataGridViewTextBoxColumn14.Name = "dataGridViewTextBoxColumn14";
- this.dataGridViewTextBoxColumn14.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn14.Width = 35;
- //
- // dataGridViewTextBoxColumn15
- //
- this.dataGridViewTextBoxColumn15.DataPropertyName = "图号";
- this.dataGridViewTextBoxColumn15.HeaderText = "图号";
- this.dataGridViewTextBoxColumn15.Name = "dataGridViewTextBoxColumn15";
- this.dataGridViewTextBoxColumn15.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn15.Width = 100;
- //
- // dataGridViewTextBoxColumn16
- //
- this.dataGridViewTextBoxColumn16.DataPropertyName = "图名";
- this.dataGridViewTextBoxColumn16.HeaderText = "图名";
- this.dataGridViewTextBoxColumn16.Name = "dataGridViewTextBoxColumn16";
- this.dataGridViewTextBoxColumn16.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn16.Width = 100;
- //
- // dataGridViewTextBoxColumn17
- //
- this.dataGridViewTextBoxColumn17.DataPropertyName = "台数";
- dataGridViewCellStyle14.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
- this.dataGridViewTextBoxColumn17.DefaultCellStyle = dataGridViewCellStyle14;
- this.dataGridViewTextBoxColumn17.HeaderText = "台数";
- this.dataGridViewTextBoxColumn17.Name = "dataGridViewTextBoxColumn17";
- this.dataGridViewTextBoxColumn17.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn17.Width = 35;
- //
- // dataGridViewTextBoxColumn18
- //
- this.dataGridViewTextBoxColumn18.DataPropertyName = "箱柜数量";
- dataGridViewCellStyle15.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
- this.dataGridViewTextBoxColumn18.DefaultCellStyle = dataGridViewCellStyle15;
- this.dataGridViewTextBoxColumn18.HeaderText = "箱柜数量";
- this.dataGridViewTextBoxColumn18.Name = "dataGridViewTextBoxColumn18";
- this.dataGridViewTextBoxColumn18.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn18.Width = 35;
- //
- // dataGridViewTextBoxColumn19
- //
- this.dataGridViewTextBoxColumn19.DataPropertyName = "单价";
- this.dataGridViewTextBoxColumn19.HeaderText = "单价";
- this.dataGridViewTextBoxColumn19.Name = "dataGridViewTextBoxColumn19";
- this.dataGridViewTextBoxColumn19.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn19.Width = 100;
- //
- // dataGridViewTextBoxColumn20
- //
- this.dataGridViewTextBoxColumn20.DataPropertyName = "总价";
- this.dataGridViewTextBoxColumn20.HeaderText = "总价";
- this.dataGridViewTextBoxColumn20.Name = "dataGridViewTextBoxColumn20";
- this.dataGridViewTextBoxColumn20.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn20.Width = 100;
- //
- // dataGridViewTextBoxColumn21
- //
- this.dataGridViewTextBoxColumn21.DataPropertyName = "成本总价";
- this.dataGridViewTextBoxColumn21.HeaderText = "成本总价";
- this.dataGridViewTextBoxColumn21.Name = "dataGridViewTextBoxColumn21";
- this.dataGridViewTextBoxColumn21.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn21.Width = 100;
- //
- // dataGridViewTextBoxColumn22
- //
- this.dataGridViewTextBoxColumn22.DataPropertyName = "毛利";
- this.dataGridViewTextBoxColumn22.HeaderText = "毛利";
- this.dataGridViewTextBoxColumn22.Name = "dataGridViewTextBoxColumn22";
- this.dataGridViewTextBoxColumn22.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn22.Width = 100;
- //
- // dataGridViewTextBoxColumn23
- //
- this.dataGridViewTextBoxColumn23.DataPropertyName = "毛利率";
- this.dataGridViewTextBoxColumn23.HeaderText = "毛利率";
- this.dataGridViewTextBoxColumn23.Name = "dataGridViewTextBoxColumn23";
- this.dataGridViewTextBoxColumn23.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn23.Width = 100;
- dataGridViewCellStyle5.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
- dataGridViewCellStyle5.BackColor = System.Drawing.SystemColors.Window;
- dataGridViewCellStyle5.Font = new System.Drawing.Font("宋体", 9F);
- dataGridViewCellStyle5.ForeColor = System.Drawing.SystemColors.ControlText;
- dataGridViewCellStyle5.SelectionBackColor = System.Drawing.SystemColors.Window;
- dataGridViewCellStyle5.SelectionForeColor = System.Drawing.SystemColors.ControlText;
- dataGridViewCellStyle5.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
- this.advancedDataGridView9.DefaultCellStyle = dataGridViewCellStyle5;
- this.advancedDataGridView9.Dock = System.Windows.Forms.DockStyle.Fill;
- this.advancedDataGridView9.EditMode = System.Windows.Forms.DataGridViewEditMode.EditOnKeystroke;
- this.advancedDataGridView9.EnableCellPaste = true;
- this.advancedDataGridView9.EnableHeadersVisualStyles = false;
- this.advancedDataGridView9.Location = new System.Drawing.Point(0, 0);
- this.advancedDataGridView9.Name = "advancedDataGridView9";
- this.advancedDataGridView9.RightToLeft = System.Windows.Forms.RightToLeft.No;
- dataGridViewCellStyle6.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
- dataGridViewCellStyle6.BackColor = System.Drawing.SystemColors.Control;
- dataGridViewCellStyle6.Font = new System.Drawing.Font("宋体", 9F);
- dataGridViewCellStyle6.ForeColor = System.Drawing.SystemColors.WindowText;
- dataGridViewCellStyle6.SelectionBackColor = System.Drawing.SystemColors.Control;
- dataGridViewCellStyle6.SelectionForeColor = System.Drawing.SystemColors.WindowText;
- dataGridViewCellStyle6.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
- this.advancedDataGridView9.RowHeadersDefaultCellStyle = dataGridViewCellStyle6;
- this.advancedDataGridView9.Size = new System.Drawing.Size(526, 254);
- this.advancedDataGridView9.TabIndex = 0;
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- // splitContainer3
- //
- this.splitContainer3.BackColor = System.Drawing.SystemColors.Control;
- this.splitContainer3.Dock = System.Windows.Forms.DockStyle.Fill;
- this.splitContainer3.Font = new System.Drawing.Font("宋体", 9F);
- this.splitContainer3.ForeColor = System.Drawing.SystemColors.ControlText;
- this.splitContainer3.Location = new System.Drawing.Point(0, 0);
- this.splitContainer3.Name = "splitContainer3";
- this.splitContainer3.Orientation = System.Windows.Forms.Orientation.Horizontal;
- //
- // splitContainer3.Panel1
- //
- this.splitContainer3.Panel1.Controls.Add(this.advancedDataGridView4);
- //
- // splitContainer3.Panel2
- //
- this.splitContainer3.Panel2.Controls.Add(this.advancedDataGridView5);
- this.splitContainer3.Size = new System.Drawing.Size(526, 543);
- this.splitContainer3.SplitterDistance = 265;
- this.splitContainer3.SplitterWidth = 6;
- this.splitContainer3.TabIndex = 0;
- //
- // advancedDataGridView4
- //
- this.advancedDataGridView4.AllowUserToAddRows = false;
- this.advancedDataGridView4.AllowUserToResizeRows = false;
- this.advancedDataGridView4.BackgroundColor = System.Drawing.Color.White;
- dataGridViewCellStyle7.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
- dataGridViewCellStyle7.BackColor = System.Drawing.SystemColors.Control;
- dataGridViewCellStyle7.Font = new System.Drawing.Font("宋体", 9F);
- dataGridViewCellStyle7.ForeColor = System.Drawing.SystemColors.WindowText;
- dataGridViewCellStyle7.SelectionBackColor = System.Drawing.SystemColors.Control;
- dataGridViewCellStyle7.SelectionForeColor = System.Drawing.SystemColors.WindowText;
- dataGridViewCellStyle7.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
- this.advancedDataGridView4.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle7;
- this.advancedDataGridView4.ColumnHeadersHeight = 35;
- this.advancedDataGridView4.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
- this.dataGridViewTextBoxColumn24,
- this.dataGridViewTextBoxColumn25,
- this.dataGridViewTextBoxColumn26,
- this.dataGridViewTextBoxColumn27,
- this.dataGridViewTextBoxColumn28,
- this.dataGridViewTextBoxColumn29,
- this.dataGridViewTextBoxColumn30,
- this.dataGridViewTextBoxColumn31,
- this.dataGridViewTextBoxColumn32,
- this.dataGridViewTextBoxColumn33,
- this.dataGridViewTextBoxColumn34,
- this.dataGridViewTextBoxColumn35,
- this.dataGridViewTextBoxColumn36,
- this.dataGridViewTextBoxColumn37,
- this.dataGridViewTextBoxColumn38,
- this.dataGridViewTextBoxColumn39,
- this.dataGridViewTextBoxColumn40});
- //
- // dataGridViewTextBoxColumn24
- //
- this.dataGridViewTextBoxColumn24.DataPropertyName = "序号";
- dataGridViewCellStyle16.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
- this.dataGridViewTextBoxColumn24.DefaultCellStyle = dataGridViewCellStyle16;
- this.dataGridViewTextBoxColumn24.HeaderText = "序号";
- this.dataGridViewTextBoxColumn24.Name = "dataGridViewTextBoxColumn24";
- this.dataGridViewTextBoxColumn24.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn24.Width = 35;
- //
- // dataGridViewTextBoxColumn25
- //
- this.dataGridViewTextBoxColumn25.DataPropertyName = "箱号";
- this.dataGridViewTextBoxColumn25.HeaderText = "箱号";
- this.dataGridViewTextBoxColumn25.Name = "dataGridViewTextBoxColumn25";
- this.dataGridViewTextBoxColumn25.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn25.Width = 150;
- //
- // dataGridViewTextBoxColumn26
- //
- this.dataGridViewTextBoxColumn26.DataPropertyName = "箱名";
- dataGridViewCellStyle17.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
- this.dataGridViewTextBoxColumn26.DefaultCellStyle = dataGridViewCellStyle17;
- this.dataGridViewTextBoxColumn26.HeaderText = "箱名";
- this.dataGridViewTextBoxColumn26.Name = "dataGridViewTextBoxColumn26";
- this.dataGridViewTextBoxColumn26.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn26.Width = 150;
- //
- // dataGridViewTextBoxColumn27
- //
- this.dataGridViewTextBoxColumn27.DataPropertyName = "型号";
- this.dataGridViewTextBoxColumn27.HeaderText = "型号";
- this.dataGridViewTextBoxColumn27.Name = "dataGridViewTextBoxColumn27";
- this.dataGridViewTextBoxColumn27.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn27.Width = 150;
- //
- // dataGridViewTextBoxColumn28
- //
- this.dataGridViewTextBoxColumn28.DataPropertyName = "规格";
- this.dataGridViewTextBoxColumn28.HeaderText = "规格";
- this.dataGridViewTextBoxColumn28.Name = "dataGridViewTextBoxColumn28";
- this.dataGridViewTextBoxColumn28.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn28.Width = 150;
- //
- // dataGridViewTextBoxColumn29
- //
- this.dataGridViewTextBoxColumn29.DataPropertyName = "单位";
- dataGridViewCellStyle18.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
- this.dataGridViewTextBoxColumn29.DefaultCellStyle = dataGridViewCellStyle18;
- this.dataGridViewTextBoxColumn29.HeaderText = "单位";
- this.dataGridViewTextBoxColumn29.Name = "dataGridViewTextBoxColumn29";
- this.dataGridViewTextBoxColumn29.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn29.Width = 35;
- //
- // dataGridViewTextBoxColumn30
- //
- this.dataGridViewTextBoxColumn30.DataPropertyName = "数量";
- dataGridViewCellStyle19.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
- this.dataGridViewTextBoxColumn30.DefaultCellStyle = dataGridViewCellStyle19;
- this.dataGridViewTextBoxColumn30.HeaderText = "数量";
- this.dataGridViewTextBoxColumn30.Name = "dataGridViewTextBoxColumn30";
- this.dataGridViewTextBoxColumn30.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn30.Width = 45;
- //
- // dataGridViewTextBoxColumn31
- //
- this.dataGridViewTextBoxColumn31.DataPropertyName = "单台成本";
- this.dataGridViewTextBoxColumn31.HeaderText = "单台成本";
- this.dataGridViewTextBoxColumn31.Name = "dataGridViewTextBoxColumn31";
- this.dataGridViewTextBoxColumn31.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn31.Width = 100;
- //
- // dataGridViewTextBoxColumn32
- //
- this.dataGridViewTextBoxColumn32.DataPropertyName = "成本价";
- this.dataGridViewTextBoxColumn32.HeaderText = "成本价";
- this.dataGridViewTextBoxColumn32.Name = "dataGridViewTextBoxColumn32";
- this.dataGridViewTextBoxColumn32.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn32.Width = 100;
- //
- // dataGridViewTextBoxColumn33
- //
- this.dataGridViewTextBoxColumn33.DataPropertyName = "单台报出";
- this.dataGridViewTextBoxColumn33.HeaderText = "单台报出";
- this.dataGridViewTextBoxColumn33.Name = "dataGridViewTextBoxColumn33";
- this.dataGridViewTextBoxColumn33.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn33.Width = 100;
- //
- // dataGridViewTextBoxColumn34
- //
- this.dataGridViewTextBoxColumn34.DataPropertyName = "报出价";
- this.dataGridViewTextBoxColumn34.HeaderText = "报出价";
- this.dataGridViewTextBoxColumn34.Name = "dataGridViewTextBoxColumn34";
- this.dataGridViewTextBoxColumn34.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn34.Width = 100;
- //
- // dataGridViewTextBoxColumn35
- //
- this.dataGridViewTextBoxColumn35.DataPropertyName = "利润";
- this.dataGridViewTextBoxColumn35.HeaderText = "利润";
- this.dataGridViewTextBoxColumn35.Name = "dataGridViewTextBoxColumn35";
- this.dataGridViewTextBoxColumn35.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn35.Width = 100;
- //
- // dataGridViewTextBoxColumn36
- //
- this.dataGridViewTextBoxColumn36.DataPropertyName = "利润率";
- this.dataGridViewTextBoxColumn36.HeaderText = "利润率";
- this.dataGridViewTextBoxColumn36.Name = "dataGridViewTextBoxColumn36";
- this.dataGridViewTextBoxColumn36.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn36.Width = 100;
- //
- // dataGridViewTextBoxColumn37
- //
- this.dataGridViewTextBoxColumn37.DataPropertyName = "毛利率";
- this.dataGridViewTextBoxColumn37.HeaderText = "毛利率";
- this.dataGridViewTextBoxColumn37.Name = "dataGridViewTextBoxColumn37";
- this.dataGridViewTextBoxColumn37.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn37.Width = 100;
- //
- // dataGridViewTextBoxColumn38
- //
- this.dataGridViewTextBoxColumn38.DataPropertyName = "箱柜类型";
- this.dataGridViewTextBoxColumn38.HeaderText = "箱柜类型";
- this.dataGridViewTextBoxColumn38.Name = "dataGridViewTextBoxColumn38";
- this.dataGridViewTextBoxColumn38.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn38.Width = 100;
- //
- // dataGridViewTextBoxColumn39
- //
- this.dataGridViewTextBoxColumn39.DataPropertyName = "备注";
- this.dataGridViewTextBoxColumn39.HeaderText = "备注";
- this.dataGridViewTextBoxColumn39.Name = "dataGridViewTextBoxColumn39";
- this.dataGridViewTextBoxColumn39.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn39.Width = 100;
- //
- // dataGridViewTextBoxColumn40
- //
- this.dataGridViewTextBoxColumn40.DataPropertyName = "图纸";
- this.dataGridViewTextBoxColumn40.HeaderText = "图纸";
- this.dataGridViewTextBoxColumn40.Name = "dataGridViewTextBoxColumn40";
- this.dataGridViewTextBoxColumn40.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn40.Width = 100;
- dataGridViewCellStyle8.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
- dataGridViewCellStyle8.BackColor = System.Drawing.SystemColors.Window;
- dataGridViewCellStyle8.Font = new System.Drawing.Font("宋体", 9F);
- dataGridViewCellStyle8.ForeColor = System.Drawing.SystemColors.ControlText;
- dataGridViewCellStyle8.SelectionBackColor = System.Drawing.SystemColors.Window;
- dataGridViewCellStyle8.SelectionForeColor = System.Drawing.SystemColors.ControlText;
- dataGridViewCellStyle8.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
- this.advancedDataGridView4.DefaultCellStyle = dataGridViewCellStyle8;
- this.advancedDataGridView4.Dock = System.Windows.Forms.DockStyle.Fill;
- this.advancedDataGridView4.EditMode = System.Windows.Forms.DataGridViewEditMode.EditOnKeystroke;
- this.advancedDataGridView4.EnableCellPaste = true;
- this.advancedDataGridView4.EnableHeadersVisualStyles = false;
- this.advancedDataGridView4.Location = new System.Drawing.Point(0, 0);
- this.advancedDataGridView4.Name = "advancedDataGridView4";
- this.advancedDataGridView4.RightToLeft = System.Windows.Forms.RightToLeft.No;
- dataGridViewCellStyle9.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
- dataGridViewCellStyle9.BackColor = System.Drawing.SystemColors.Control;
- dataGridViewCellStyle9.Font = new System.Drawing.Font("宋体", 9F);
- dataGridViewCellStyle9.ForeColor = System.Drawing.SystemColors.WindowText;
- dataGridViewCellStyle9.SelectionBackColor = System.Drawing.SystemColors.Control;
- dataGridViewCellStyle9.SelectionForeColor = System.Drawing.SystemColors.WindowText;
- dataGridViewCellStyle9.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
- this.advancedDataGridView4.RowHeadersDefaultCellStyle = dataGridViewCellStyle9;
- this.advancedDataGridView4.Size = new System.Drawing.Size(526, 265);
- this.advancedDataGridView4.TabIndex = 0;
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- // advancedDataGridView5
- //
- this.advancedDataGridView5.AllowUserToAddRows = false;
- this.advancedDataGridView5.AllowUserToResizeRows = false;
- this.advancedDataGridView5.BackgroundColor = System.Drawing.Color.White;
- dataGridViewCellStyle10.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
- dataGridViewCellStyle10.BackColor = System.Drawing.SystemColors.Control;
- dataGridViewCellStyle10.Font = new System.Drawing.Font("宋体", 9F);
- dataGridViewCellStyle10.ForeColor = System.Drawing.SystemColors.WindowText;
- dataGridViewCellStyle10.SelectionBackColor = System.Drawing.SystemColors.Control;
- dataGridViewCellStyle10.SelectionForeColor = System.Drawing.SystemColors.WindowText;
- dataGridViewCellStyle10.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
- this.advancedDataGridView5.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle10;
- this.advancedDataGridView5.ColumnHeadersHeight = 35;
- this.advancedDataGridView5.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
- this.dataGridViewTextBoxColumn41,
- this.dataGridViewTextBoxColumn42,
- this.dataGridViewTextBoxColumn43,
- this.dataGridViewTextBoxColumn44,
- this.dataGridViewTextBoxColumn45,
- this.dataGridViewTextBoxColumn46,
- this.dataGridViewTextBoxColumn47,
- this.dataGridViewTextBoxColumn48,
- this.dataGridViewTextBoxColumn49,
- this.dataGridViewTextBoxColumn50,
- this.dataGridViewTextBoxColumn51,
- this.dataGridViewTextBoxColumn52,
- this.dataGridViewTextBoxColumn53,
- this.dataGridViewTextBoxColumn54,
- this.dataGridViewTextBoxColumn55,
- this.dataGridViewTextBoxColumn56,
- this.dataGridViewTextBoxColumn57});
- //
- // dataGridViewTextBoxColumn41
- //
- this.dataGridViewTextBoxColumn41.DataPropertyName = "序号";
- dataGridViewCellStyle20.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
- this.dataGridViewTextBoxColumn41.DefaultCellStyle = dataGridViewCellStyle20;
- this.dataGridViewTextBoxColumn41.HeaderText = "序号";
- this.dataGridViewTextBoxColumn41.Name = "dataGridViewTextBoxColumn41";
- this.dataGridViewTextBoxColumn41.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn41.Width = 35;
- //
- // dataGridViewTextBoxColumn42
- //
- this.dataGridViewTextBoxColumn42.DataPropertyName = "元件名称";
- this.dataGridViewTextBoxColumn42.HeaderText = "元件名称";
- this.dataGridViewTextBoxColumn42.Name = "dataGridViewTextBoxColumn42";
- this.dataGridViewTextBoxColumn42.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn42.Width = 150;
- //
- // dataGridViewTextBoxColumn43
- //
- this.dataGridViewTextBoxColumn43.DataPropertyName = "规格";
- this.dataGridViewTextBoxColumn43.HeaderText = "规格";
- this.dataGridViewTextBoxColumn43.Name = "dataGridViewTextBoxColumn43";
- this.dataGridViewTextBoxColumn43.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn43.Width = 150;
- //
- // dataGridViewTextBoxColumn44
- //
- this.dataGridViewTextBoxColumn44.DataPropertyName = "单位";
- dataGridViewCellStyle21.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
- this.dataGridViewTextBoxColumn44.DefaultCellStyle = dataGridViewCellStyle21;
- this.dataGridViewTextBoxColumn44.HeaderText = "单位";
- this.dataGridViewTextBoxColumn44.Name = "dataGridViewTextBoxColumn44";
- this.dataGridViewTextBoxColumn44.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn44.Width = 35;
- //
- // dataGridViewTextBoxColumn45
- //
- this.dataGridViewTextBoxColumn45.DataPropertyName = "数量";
- dataGridViewCellStyle22.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
- this.dataGridViewTextBoxColumn45.DefaultCellStyle = dataGridViewCellStyle22;
- this.dataGridViewTextBoxColumn45.HeaderText = "数量";
- this.dataGridViewTextBoxColumn45.Name = "dataGridViewTextBoxColumn45";
- this.dataGridViewTextBoxColumn45.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn45.Width = 40;
- //
- // dataGridViewTextBoxColumn46
- //
- this.dataGridViewTextBoxColumn46.DataPropertyName = "表价";
- this.dataGridViewTextBoxColumn46.HeaderText = "表价";
- this.dataGridViewTextBoxColumn46.Name = "dataGridViewTextBoxColumn46";
- this.dataGridViewTextBoxColumn46.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn46.Width = 100;
- //
- // dataGridViewTextBoxColumn47
- //
- this.dataGridViewTextBoxColumn47.DataPropertyName = "采购单价";
- this.dataGridViewTextBoxColumn47.HeaderText = "采购单价";
- this.dataGridViewTextBoxColumn47.Name = "dataGridViewTextBoxColumn47";
- this.dataGridViewTextBoxColumn47.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn47.Width = 100;
- //
- // dataGridViewTextBoxColumn48
- //
- this.dataGridViewTextBoxColumn48.DataPropertyName = "采购系数";
- this.dataGridViewTextBoxColumn48.HeaderText = "采购系数";
- this.dataGridViewTextBoxColumn48.Name = "dataGridViewTextBoxColumn48";
- this.dataGridViewTextBoxColumn48.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn48.Width = 100;
- //
- // dataGridViewTextBoxColumn49
- //
- this.dataGridViewTextBoxColumn49.DataPropertyName = "采购价";
- this.dataGridViewTextBoxColumn49.HeaderText = "采购价";
- this.dataGridViewTextBoxColumn49.Name = "dataGridViewTextBoxColumn49";
- this.dataGridViewTextBoxColumn49.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn49.Width = 100;
- //
- // dataGridViewTextBoxColumn50
- //
- this.dataGridViewTextBoxColumn50.DataPropertyName = "报出单价";
- this.dataGridViewTextBoxColumn50.HeaderText = "报出单价";
- this.dataGridViewTextBoxColumn50.Name = "dataGridViewTextBoxColumn50";
- this.dataGridViewTextBoxColumn50.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn50.Width = 100;
- //
- // dataGridViewTextBoxColumn51
- //
- this.dataGridViewTextBoxColumn51.DataPropertyName = "报出系数";
- this.dataGridViewTextBoxColumn51.HeaderText = "报出系数";
- this.dataGridViewTextBoxColumn51.Name = "dataGridViewTextBoxColumn51";
- this.dataGridViewTextBoxColumn51.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn51.Width = 100;
- //
- // dataGridViewTextBoxColumn52
- //
- this.dataGridViewTextBoxColumn52.DataPropertyName = "报出价";
- this.dataGridViewTextBoxColumn52.HeaderText = "报出价";
- this.dataGridViewTextBoxColumn52.Name = "dataGridViewTextBoxColumn52";
- this.dataGridViewTextBoxColumn52.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn52.Width = 100;
- //
- // dataGridViewTextBoxColumn53
- //
- this.dataGridViewTextBoxColumn53.DataPropertyName = "图纸规格";
- this.dataGridViewTextBoxColumn53.HeaderText = "图纸规格";
- this.dataGridViewTextBoxColumn53.Name = "dataGridViewTextBoxColumn53";
- this.dataGridViewTextBoxColumn53.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn53.Width = 100;
- //
- // dataGridViewTextBoxColumn54
- //
- this.dataGridViewTextBoxColumn54.DataPropertyName = "品牌";
- this.dataGridViewTextBoxColumn54.HeaderText = "品牌";
- this.dataGridViewTextBoxColumn54.Name = "dataGridViewTextBoxColumn54";
- this.dataGridViewTextBoxColumn54.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn54.Width = 100;
- //
- // dataGridViewTextBoxColumn55
- //
- this.dataGridViewTextBoxColumn55.DataPropertyName = "系列";
- this.dataGridViewTextBoxColumn55.HeaderText = "系列";
- this.dataGridViewTextBoxColumn55.Name = "dataGridViewTextBoxColumn55";
- this.dataGridViewTextBoxColumn55.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn55.Width = 100;
- //
- // dataGridViewTextBoxColumn56
- //
- this.dataGridViewTextBoxColumn56.DataPropertyName = "类型";
- this.dataGridViewTextBoxColumn56.HeaderText = "类型";
- this.dataGridViewTextBoxColumn56.Name = "dataGridViewTextBoxColumn56";
- this.dataGridViewTextBoxColumn56.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn56.Width = 100;
- //
- // dataGridViewTextBoxColumn57
- //
- this.dataGridViewTextBoxColumn57.DataPropertyName = "备注";
- this.dataGridViewTextBoxColumn57.HeaderText = "备注";
- this.dataGridViewTextBoxColumn57.Name = "dataGridViewTextBoxColumn57";
- this.dataGridViewTextBoxColumn57.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
- this.dataGridViewTextBoxColumn57.Width = 100;
- dataGridViewCellStyle11.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
- dataGridViewCellStyle11.BackColor = System.Drawing.SystemColors.Window;
- dataGridViewCellStyle11.Font = new System.Drawing.Font("宋体", 9F);
- dataGridViewCellStyle11.ForeColor = System.Drawing.SystemColors.ControlText;
- dataGridViewCellStyle11.SelectionBackColor = System.Drawing.SystemColors.Window;
- dataGridViewCellStyle11.SelectionForeColor = System.Drawing.SystemColors.ControlText;
- dataGridViewCellStyle11.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
- this.advancedDataGridView5.DefaultCellStyle = dataGridViewCellStyle11;
- this.advancedDataGridView5.Dock = System.Windows.Forms.DockStyle.Fill;
- this.advancedDataGridView5.EditMode = System.Windows.Forms.DataGridViewEditMode.EditOnKeystroke;
- this.advancedDataGridView5.EnableCellPaste = true;
- this.advancedDataGridView5.EnableHeadersVisualStyles = false;
- this.advancedDataGridView5.Location = new System.Drawing.Point(0, 0);
- this.advancedDataGridView5.Name = "advancedDataGridView5";
- this.advancedDataGridView5.RightToLeft = System.Windows.Forms.RightToLeft.No;
- dataGridViewCellStyle12.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
- dataGridViewCellStyle12.BackColor = System.Drawing.SystemColors.Control;
- dataGridViewCellStyle12.Font = new System.Drawing.Font("宋体", 9F);
- dataGridViewCellStyle12.ForeColor = System.Drawing.SystemColors.WindowText;
- dataGridViewCellStyle12.SelectionBackColor = System.Drawing.SystemColors.Control;
- dataGridViewCellStyle12.SelectionForeColor = System.Drawing.SystemColors.WindowText;
- dataGridViewCellStyle12.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
- this.advancedDataGridView5.RowHeadersDefaultCellStyle = dataGridViewCellStyle12;
- this.advancedDataGridView5.Size = new System.Drawing.Size(526, 272);
- this.advancedDataGridView5.TabIndex = 0;
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- // toolStrip1
- //
- this.toolStrip1.BackColor = System.Drawing.SystemColors.Control;
- this.toolStrip1.Font = new System.Drawing.Font("Microsoft YaHei UI", 9F);
- this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
- this.toolStripButton1,
- this.toolStripButton5,
- this.toolStripButton6,
- this.toolStripButton2,
- this.toolStripButton3,
- this.toolStripButton4,
- this.toolStripButton7});
- this.toolStrip1.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.HorizontalStackWithOverflow;
- this.toolStrip1.Location = new System.Drawing.Point(0, 0);
- this.toolStrip1.Name = "toolStrip1";
- this.toolStrip1.Size = new System.Drawing.Size(540, 31);
- this.toolStrip1.TabIndex = 1;
- //
- // toolStripButton1
- //
- this.toolStripButton1.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
- this.toolStripButton1.Name = "toolStripButton1";
- this.toolStripButton1.Size = new System.Drawing.Size(86, 28);
- this.toolStripButton1.Text = "导出数据";
- this.toolStripButton1.ToolTipText = "导出数据";
- //
- // toolStripButton5
- //
- this.toolStripButton5.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
- this.toolStripButton5.Name = "toolStripButton5";
- this.toolStripButton5.Size = new System.Drawing.Size(86, 28);
- this.toolStripButton5.Text = "新建项目";
- this.toolStripButton5.ToolTipText = "新建项目";
- //
- // toolStripButton6
- //
- this.toolStripButton6.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
- this.toolStripButton6.Name = "toolStripButton6";
- this.toolStripButton6.Size = new System.Drawing.Size(86, 28);
- this.toolStripButton6.Text = "删除项目";
- this.toolStripButton6.ToolTipText = "删除项目";
- //
- // toolStripButton2
- //
- this.toolStripButton2.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
- this.toolStripButton2.Name = "toolStripButton2";
- this.toolStripButton2.Size = new System.Drawing.Size(68, 28);
- this.toolStripButton2.Text = "扒图号";
- this.toolStripButton2.ToolTipText = "扒图号";
- //
- // toolStripButton3
- //
- this.toolStripButton3.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
- this.toolStripButton3.Name = "toolStripButton3";
- this.toolStripButton3.Size = new System.Drawing.Size(68, 28);
- this.toolStripButton3.Text = "扒箱号";
- this.toolStripButton3.ToolTipText = "扒箱号";
- //
- // toolStripButton4
- //
- this.toolStripButton4.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
- this.toolStripButton4.Name = "toolStripButton4";
- this.toolStripButton4.Size = new System.Drawing.Size(68, 28);
- this.toolStripButton4.Text = "扒元件";
- this.toolStripButton4.ToolTipText = "扒元件";
- //
- // toolStripButton7
- //
- this.toolStripButton7.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
- this.toolStripButton7.ImageTransparentColor = System.Drawing.Color.Magenta;
- this.toolStripButton7.Name = "toolStripButton7";
- this.toolStripButton7.Size = new System.Drawing.Size(50, 28);
- this.toolStripButton7.Text = "设置";
- //
- // Form3
- //
- this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
- this.AutoValidate = System.Windows.Forms.AutoValidate.EnablePreventFocusChange;
- this.BackColor = System.Drawing.SystemColors.Control;
- this.ClientSize = new System.Drawing.Size(540, 869);
- this.Controls.Add(this.tabControl2);
- this.Controls.Add(this.toolStrip1);
- this.Font = new System.Drawing.Font("宋体", 9F);
- this.ForeColor = System.Drawing.SystemColors.ControlText;
- this.Name = "Form3";
- this.Text = "Form3";
- this.tabControl2.ResumeLayout(false);
- this.tabPage3.ResumeLayout(false);
- ((System.ComponentModel.ISupportInitialize)(this.advancedDataGridView6)).EndInit();
- this.panel1.ResumeLayout(false);
- this.panel1.PerformLayout();
- this.tabPage4.ResumeLayout(false);
- this.splitContainer2.Panel1.ResumeLayout(false);
- this.splitContainer2.Panel2.ResumeLayout(false);
- ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).EndInit();
- this.splitContainer2.ResumeLayout(false);
- ((System.ComponentModel.ISupportInitialize)(this.advancedDataGridView9)).EndInit();
- this.splitContainer3.Panel1.ResumeLayout(false);
- this.splitContainer3.Panel2.ResumeLayout(false);
- ((System.ComponentModel.ISupportInitialize)(this.splitContainer3)).EndInit();
- this.splitContainer3.ResumeLayout(false);
- ((System.ComponentModel.ISupportInitialize)(this.advancedDataGridView4)).EndInit();
- ((System.ComponentModel.ISupportInitialize)(this.advancedDataGridView5)).EndInit();
- this.toolStrip1.ResumeLayout(false);
- this.toolStrip1.PerformLayout();
- this.ResumeLayout(false);
- this.PerformLayout();
-
- }
-
- #endregion
-
- private System.Windows.Forms.TabControl tabControl2;
- private System.Windows.Forms.TabPage tabPage3;
- private Zuby.ADGV.AdvancedDataGridView advancedDataGridView6;
- private System.Windows.Forms.Panel panel1;
- private System.Windows.Forms.Button button28;
- private System.Windows.Forms.TextBox textBox1;
- private System.Windows.Forms.ComboBox comboBox2;
- private System.Windows.Forms.TabPage tabPage4;
- private System.Windows.Forms.SplitContainer splitContainer2;
- private Zuby.ADGV.AdvancedDataGridView advancedDataGridView9;
- private System.Windows.Forms.SplitContainer splitContainer3;
- private Zuby.ADGV.AdvancedDataGridView advancedDataGridView4;
- private Zuby.ADGV.AdvancedDataGridView advancedDataGridView5;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn1;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn2;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn3;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn4;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn5;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn6;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn7;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn8;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn9;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn10;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn11;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn12;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn13;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn14;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn15;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn16;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn17;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn18;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn19;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn20;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn21;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn22;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn23;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn24;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn25;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn26;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn27;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn28;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn29;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn30;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn31;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn32;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn33;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn34;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn35;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn36;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn37;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn38;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn39;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn40;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn41;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn42;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn43;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn44;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn45;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn46;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn47;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn48;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn49;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn50;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn51;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn52;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn53;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn54;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn55;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn56;
- private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn57;
- private System.Windows.Forms.ToolStrip toolStrip1;
- private System.Windows.Forms.ToolStripButton toolStripButton1;
- private System.Windows.Forms.ToolStripButton toolStripButton5;
- private System.Windows.Forms.ToolStripButton toolStripButton6;
- private System.Windows.Forms.ToolStripButton toolStripButton2;
- private System.Windows.Forms.ToolStripButton toolStripButton3;
- private System.Windows.Forms.ToolStripButton toolStripButton4;
- private System.Windows.Forms.ToolStripButton toolStripButton7;
-
- /// 加载所有 SQLite 设计数据绑定。
- private void LoadAllSqliteData()
- {
- // cadbt 宿主为 x86 进程,引用的是 x86 版 System.Data.SQLite.dll,
- // 无需 AutoCAD 插件版的 64 位检查,直接加载。
- try { LoadSqliteData_advancedDataGridView6(); } catch (System.Exception ex_advancedDataGridView6) { System.Windows.Forms.MessageBox.Show("加载数据失败 (advancedDataGridView6): " + ex_advancedDataGridView6.Message); }
- }
-
- /// 为 advancedDataGridView6 加载 SQLite 数据(由设计器生成)。
- private void LoadSqliteData_advancedDataGridView6()
- {
- // ★ 数据库路径:优先用插件真实目录(_baseDir 在 Form3.cs,注册表/CodeBase 解析),
- // 在 CAD 中加载时 BaseDirectory 指向 CAD 安装目录会找不到库
- string dbPath = System.IO.Path.Combine(
- GetPluginBaseDirForUi(), @"sjk\advancedDataGridView6Table.db");
- if (!System.IO.File.Exists(dbPath))
- {
- // ★ 静默跳过(不弹窗):构造函数里的 Load 事件已用正确路径重新加载
- System.Diagnostics.Debug.WriteLine("找不到数据库文件: " + dbPath);
- return;
- }
-
- string connStr = "Data Source=" + dbPath + ";Version=3;busy_timeout=3000;";
- var table = new System.Data.DataTable();
- using (var conn = new System.Data.SQLite.SQLiteConnection(connStr))
- {
- conn.Open();
- string sql = @"SELECT * FROM advancedDataGridView6Table";
- using (var adapter = new System.Data.SQLite.SQLiteDataAdapter(sql, conn))
- {
- adapter.Fill(table);
- }
- }
-
- this.advancedDataGridView6.AutoGenerateColumns = false;
- // KeepCustomColumns=true:设计器中自定义的列不会被覆盖,
- // 数据库列通过 DataPropertyName 与控件列关联。
- // 若列名与数据库列名相同,运行时会自动绑定数据。
- this.advancedDataGridView6.DataSource = table;
- }
-
- ///
- /// ui.cs 侧获取插件目录:复用 Form3.cs 的 _baseDir
- /// (partial 类同字段;_baseDir 在 Form3.cs 中由注册表/CodeBase 解析)
- ///
- private string GetPluginBaseDirForUi()
- {
- return _baseDir;
- }
- }
-}
diff --git a/pdfbt/Plugin/Form3.cs b/pdfbt/Plugin/Form3.cs
deleted file mode 100644
index 69a2287..0000000
--- a/pdfbt/Plugin/Form3.cs
+++ /dev/null
@@ -1,6882 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Data;
-using System.Drawing;
-using System.IO;
-using System.Windows.Forms;
-using Microsoft.Win32;
-using Zuby.ADGV;
-
-namespace MyApp
-{
- ///
- /// Form3 的交互逻辑(CAD 2018 插件报价窗口)。
- /// 功能与主项目报价页面一致:项目表 + 图号/箱号/元件三级联动 + 公式重算 + 右键菜单 + 项目导出。
- /// UI 布局定义见 Form3.ui.cs。数据库独立存放在 cadcj\sjk\ 目录。
- ///
- public partial class Form3
- {
- // ============================================================
- // 数据库路径与表名常量(独立于主项目,存放在 cadcj\sjk\ 下)
- // ============================================================
-
- private const string ProjectsDbPath = @"sjk\advancedDataGridView6Table.db";
- private const string ProjectsTableName = "advancedDataGridView6Table";
- private const string QuoteDbDir = @"sjk\bjb";
- private const string TuhaoTableName = "advancedDataGridView9Table";
- private const string ProjectInfoTableName = "项目信息";
- private const string IndexTableName = "表索引";
-
- private const string CadRegPath = @"SOFTWARE\Autodesk\AutoCAD\R22.0\ACAD-1001:804\Apps\CADCJ";
-
- ///
- /// 插件所在目录(cadcj)。优先从注册表读取 CAD 自动加载的 DLL 路径(最可靠),
- /// 然后尝试 CodeBase / Location,最后兜底 BaseDirectory(可能是 CAD 目录,会报错)。
- ///
- private static readonly string _baseDir = GetPluginBaseDir();
-
- private static string GetPluginBaseDir()
- {
- // ★ 方案0(standalone 版):exe 所在目录即数据根
- // (不再读 AutoCAD 注册表——旧 cadcj 注册表残留在客户机上会把数据指向已删除的目录)
- try
- {
- var baseDir0 = AppDomain.CurrentDomain.BaseDirectory;
- if (!string.IsNullOrEmpty(baseDir0) && Directory.Exists(baseDir0))
- {
- WriteDebugLog("[GetPluginBaseDir] BaseDirectory 成功: " + baseDir0);
- return baseDir0;
- }
- }
- catch (Exception ex) { WriteDebugLog("[GetPluginBaseDir] BaseDirectory 异常: " + ex.Message); }
-
- // ★ 方案1(历史保留):从注册表读取 CAD 自动加载配置的 MODULE 路径
- try
- {
- using (var key = Registry.LocalMachine.OpenSubKey(CadRegPath))
- {
- if (key != null)
- {
- var module = key.GetValue("MODULE") as string;
- if (!string.IsNullOrEmpty(module))
- {
- var dir = Path.GetDirectoryName(module);
- if (!string.IsNullOrEmpty(dir) && Directory.Exists(dir))
- {
- WriteDebugLog("[GetPluginBaseDir] 注册表方案成功: " + dir);
- return dir;
- }
- }
- }
- }
- }
- catch (Exception ex) { WriteDebugLog("[GetPluginBaseDir] 注册表方案异常: " + ex.Message); }
-
- // ★ 方案2:CodeBase(不受 shadow copy 影响)
- try
- {
- var codeBase = System.Reflection.Assembly.GetExecutingAssembly().CodeBase;
- WriteDebugLog("[GetPluginBaseDir] CodeBase=" + codeBase);
- if (!string.IsNullOrEmpty(codeBase))
- {
- var localPath = new Uri(codeBase).LocalPath;
- var dir = Path.GetDirectoryName(localPath);
- if (!string.IsNullOrEmpty(dir) && Directory.Exists(dir))
- {
- WriteDebugLog("[GetPluginBaseDir] CodeBase方案成功: " + dir);
- return dir;
- }
- }
- }
- catch (Exception ex) { WriteDebugLog("[GetPluginBaseDir] CodeBase方案异常: " + ex.Message); }
-
- // ★ 方案3:Location
- try
- {
- var loc = System.Reflection.Assembly.GetExecutingAssembly().Location;
- WriteDebugLog("[GetPluginBaseDir] Location=" + loc);
- if (!string.IsNullOrEmpty(loc))
- {
- var dir = Path.GetDirectoryName(loc);
- if (!string.IsNullOrEmpty(dir) && Directory.Exists(dir))
- {
- WriteDebugLog("[GetPluginBaseDir] Location方案成功: " + dir);
- return dir;
- }
- }
- }
- catch (Exception ex) { WriteDebugLog("[GetPluginBaseDir] Location方案异常: " + ex.Message); }
-
- // ★ 方案4(最后兜底):BaseDirectory(CAD 目录,数据库会找不到)
- var fallback = AppDomain.CurrentDomain.BaseDirectory;
- WriteDebugLog("[GetPluginBaseDir] ⚠ 兜底BaseDirectory=" + fallback + " (数据库会找不到!)");
- return fallback;
- }
-
- private static void WriteDebugLog(string msg)
- {
- try
- {
- var logDir = Path.Combine(
- Path.GetDirectoryName(
- new Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase).LocalPath),
- "sjk");
- if (!Directory.Exists(logDir)) logDir = Path.GetTempPath();
- var logPath = Path.Combine(logDir, "form3_path_debug.log");
- File.AppendAllText(logPath,
- "[" + DateTime.Now.ToString("HH:mm:ss") + "] " + msg + Environment.NewLine);
- }
- catch { }
- }
-
- // ============================================================
- // 当前层级选中状态(联动核心)
- // ============================================================
-
- private string _currentProjectId = "";
- private string _currentTuhao = "";
- private string _currentXianghao = "";
- private bool _isReloading = false;
- private bool _isRecalculating = false;
- private DateTime _lastRecalcTime = DateTime.MinValue;
-
- // 价格显示格式化配置(每个项目独立,随项目信息表加载)
- private string _单台小数位文本 = "保留2位小数";
- private string _单台取整方式 = "不取整";
- private string _项目小数位文本 = "保留2位小数";
- private string _项目取整方式 = "不取整";
-
- // 当前各表的内存数据(用于关闭/切换时回写数据库)
- private DataTable _tuhaoTable;
- private DataTable _xianghaoTable;
- private DataTable _yuanjianTable;
-
- // 内存缓存:切换图号/箱号时不丢编辑,点保存才写库
- private Dictionary _xianghaoCache = new Dictionary();
- private Dictionary _yuanjianCache = new Dictionary();
-
- // 右键菜单组件(运行时创建,不在设计器 XML 里)
- private ContextMenuStrip _menuTuhao;
- private ContextMenuStrip _menuXianghao;
- private ContextMenuStrip _menuYuanjian;
-
- private static readonly string[] ProjectInfoColumns =
- {
- "项目编号", "项目名称", "客户名称", "客户地址",
- "联系人", "联系电话", "项目日期", "备注",
- "成套厂名称", "成套厂地址", "成套厂联系人", "成套厂联系电话",
- "单台小数位", "单台取整方式", "项目小数位", "项目取整方式"
- };
-
- /// 公式计算列集合(只包含程序算出来的价格列)。
- private static readonly HashSet s_公式列集合 =
- new HashSet(StringComparer.OrdinalIgnoreCase)
- {
- "表价", "采购单价", "采购价", "报出单价", "报出价",
- "单台成本", "成本价", "单台报出", "利润",
- "单价", "总价", "成本总价", "毛利",
- "成本总价", "报出总价", "利润"
- };
-
- /// 构造函数:初始化 UI 并绑定事件。
- public Form3()
- {
- InitializeComponent();
-
- // ★ ADGV 右键多选保持(消息钩子版):右键点已选中的行不清空多选集合。
- // 原做法是项目内子类 AdgvKeepMulti 覆写 WndProc——但"设计器+项目内自定义类型"
- // 在 SharpDevelop 设计时解析是死结,故改回 DLL 类型+NativeWindow 钩子(语义一致)。
- _keepMultiHooks = new System.Collections.Generic.List();
- HookKeepMulti(advancedDataGridView6);
- HookKeepMulti(advancedDataGridView9);
- HookKeepMulti(advancedDataGridView4);
- HookKeepMulti(advancedDataGridView5);
-
- // ★ 立即创建数据库(不依赖 Load 事件,UserControl 嵌入 PaletteSet 时 Load 可能延迟)
- try
- {
- Log("[Form3] _baseDir = " + _baseDir);
- Log("[Form3] ProjectsDbPath = " + GetDbFullPath(ProjectsDbPath));
- EnsureProjectDbExists(GetDbFullPath(ProjectsDbPath));
- Log("[Form3] 数据库创建/验证成功");
- }
- catch (System.Exception ex)
- {
- Log("[Form3] 数据库创建失败: " + ex.Message);
- }
-
- // ★ 诊断:后续初始化步骤逐步打点(定位面板空白问题)
- try
- {
- Log("[Form3.init] 开始双缓冲设置");
- EnableDoubleBuffered(this.advancedDataGridView6);
- EnableDoubleBuffered(this.advancedDataGridView9);
- EnableDoubleBuffered(this.advancedDataGridView4);
- EnableDoubleBuffered(this.advancedDataGridView5);
- Log("[Form3.init] 双缓冲完成");
-
- ApplyReadOnlyColumns(this.advancedDataGridView6, new string[] {
- "项目编号", "项目名称", "客户名称", "客户地址", "联系人", "联系电话",
- "项目日期", "箱柜台数", "成本总价", "报出总价", "利润", "利润率", "备注"
- });
- ApplyReadOnlyColumns(this.advancedDataGridView9, new string[] {
- "序号", "箱柜数量", "单价", "总价", "成本总价", "毛利", "毛利率"
- });
- ApplyReadOnlyColumns(this.advancedDataGridView4, new string[] {
- "序号", "单台成本", "成本价", "单台报出", "报出价", "利润", "利润率", "毛利率"
- });
- ApplyReadOnlyColumns(this.advancedDataGridView5, new string[] {
- "序号", "采购单价", "采购价", "报出单价", "报出价"
- });
- Log("[Form3.init] 只读列完成");
-
- // 工具栏按钮事件
- this.toolStripButton1.Click += toolStripButton1_Click;
- this.toolStripButton5.Click += toolStripButton5_Click;
- this.toolStripButton6.Click += toolStripButton6_Click;
- this.toolStripButton2.Click += (s, e) => SendCadPaCommand("CADPATU");
- this.toolStripButton3.Click += (s, e) => SendCadPaCommand("CADPAXH");
- this.toolStripButton4.Click += (s, e) => SendCadPaCommand("CADPAYJ");
- this.toolStripButton7.Click += (s, e) => ShowDeepSeekSettings();
- Log("[Form3.init] 工具栏事件完成");
-
- this.button28.Click += button28_Click;
- this.advancedDataGridView6.CellDoubleClick += advancedDataGridView6_CellDoubleClick;
-
- this.advancedDataGridView9.SelectionChanged += advancedDataGridView9_SelectionChanged;
- this.advancedDataGridView4.SelectionChanged += advancedDataGridView4_SelectionChanged;
- this.advancedDataGridView5.SelectionChanged += advancedDataGridView5_SelectionChanged;
-
- this.advancedDataGridView9.CellClick += Grid_CellClick_Zoom;
- this.advancedDataGridView4.CellClick += Grid_CellClick_Zoom;
- this.advancedDataGridView5.CellClick += Grid_CellClick_Zoom;
-
- this.advancedDataGridView5.CellValueChanged += Yuanjian_CellValueChanged;
- this.advancedDataGridView4.CurrentCellDirtyStateChanged += Grid_DirtyStateChanged;
- this.advancedDataGridView4.CellValueChanged += Xianghao_CellValueChanged;
- this.advancedDataGridView9.CurrentCellDirtyStateChanged += Grid_DirtyStateChanged;
- this.advancedDataGridView9.CellValueChanged += Tuhao_CellValueChanged;
-
- this.advancedDataGridView5.CellEndEdit += Grid_CellEndEdit;
- this.advancedDataGridView4.CellEndEdit += Grid_CellEndEdit;
- this.advancedDataGridView9.CellEndEdit += Grid_CellEndEdit;
-
- this.advancedDataGridView5.DataError += (s, e) => { e.Cancel = true; };
- this.advancedDataGridView4.DataError += (s, e) => { e.Cancel = true; };
- this.advancedDataGridView9.DataError += (s, e) => { e.Cancel = true; };
- this.advancedDataGridView6.DataError += (s, e) => { e.Cancel = true; };
-
- this.advancedDataGridView9.MouseDown += Grid_MouseDown_KeepMultiSelect;
- this.advancedDataGridView4.MouseDown += Grid_MouseDown_KeepMultiSelect;
- this.advancedDataGridView5.MouseDown += Grid_MouseDown_KeepMultiSelect;
-
- this.advancedDataGridView9.KeyDown += Grid_KeyDown_Delete;
- this.advancedDataGridView4.KeyDown += Grid_KeyDown_Delete;
- this.advancedDataGridView5.KeyDown += Grid_KeyDown_Delete;
- Log("[Form3.init] 表格事件完成");
-
- BuildContextMenus();
- Log("[Form3.init] 右键菜单完成");
-
- this.Disposed += Form3_Disposed;
-
- this.Load += (s, e) =>
- {
- try
- {
- EnsureProjectDbExists(GetDbFullPath(ProjectsDbPath));
- ReloadProjectsFromDatabase();
- ApplyPriceFormat(this.advancedDataGridView6, _项目小数位文本);
- this.advancedDataGridView9.DataSource = null;
- this.advancedDataGridView4.DataSource = null;
- this.advancedDataGridView5.DataSource = null;
- Log("[Form3.Load] 初始化完成");
- }
- catch (System.Exception ex)
- {
- Log("[Form3.Load] 初始化异常: " + ex.Message);
- }
-
- try
- {
- // 网页 CAD 桥:订阅实体删除事件(用户在网页里删框时联动删行)
- pdfbt.PdfBridge.EntityErased -= Database_ObjectErased;
- pdfbt.PdfBridge.EntityErased += Database_ObjectErased;
- // 网页 CAD 桥:订阅扒图结果事件(框选完成立即插入表格)
- pdfbt.PdfBridge.PaPicked -= OnPaTextsPicked;
- pdfbt.PdfBridge.PaPicked += OnPaTextsPicked;
- // 网页 CAD 桥:F1/F2 元件合并(焦点在网页时按键由网页转发)
- pdfbt.PdfBridge.F1Requested -= OnF1FromBridge;
- pdfbt.PdfBridge.F1Requested += OnF1FromBridge;
- pdfbt.PdfBridge.F2Requested -= OnF2FromBridge;
- pdfbt.PdfBridge.F2Requested += OnF2FromBridge;
- pdfbt.PdfBridge.F3Requested -= OnF3FromBridge;
- pdfbt.PdfBridge.F3Requested += OnF3FromBridge;
- }
- catch (System.Exception ex)
- {
- Log("[Form3.Load] 订阅CadBridge事件失败: " + ex.Message);
- }
- };
- Log("[Form3.init] 构造函数全部完成 ✓");
- }
- catch (System.Exception ex)
- {
- Log("[Form3.init] ⚠ 初始化异常: " + ex.ToString());
- }
- }
-
- ///
- /// ★ 网页 CAD 中实体被删除时触发。如果删除的是 __CADCJ_PA_FRAME 图层上的扒图框,
- /// 通过 Handle 查找当前项目下的图号表/箱号表/元件表对应行,同步删除。
- ///
- private void Database_ObjectErased(string handle)
- {
- try
- {
- if (string.IsNullOrWhiteSpace(handle)) return;
- // ★ 如果正在通过表格删除(_isReloading=true),跳过网页 CAD 事件触发的删除
- // 避免表格删除和 CAD 事件删除互相干扰导致蒙版/数据不一致
- if (_isReloading) return;
-
- Log("[ObjectErased] 触发! Handle=" + handle);
-
- this.BeginInvoke((Action)(() =>
- {
- try
- {
- // 再次检查(异步执行时状态可能已变化)
- if (_isReloading) { Log("[ObjectErased] _isReloading=true,跳过"); return; }
- DeleteRowsByFrameHandle(handle);
- }
- catch (System.Exception ex)
- {
- Log("[ObjectErased.BeginInvoke] 异常: " + ex.Message);
- }
- }));
- }
- catch (System.Exception ex)
- {
- Log("[ObjectErased] 异常: " + ex.Message);
- }
- }
-
- ///
- /// 根据框Handle在当前项目的图号表/箱号表/元件表中删除对应数据行。
- ///
- private void DeleteRowsByFrameHandle(string frameHandle)
- {
- if (string.IsNullOrWhiteSpace(frameHandle)) return;
- if (string.IsNullOrWhiteSpace(_currentProjectId)) { Log("[DeleteRowsByFrameHandle] _currentProjectId 为空,放弃"); return; }
- _isReloading = true;
- try
- {
- string dbPath = GetQuoteDbPath(_currentProjectId);
- if (!File.Exists(dbPath)) { Log("[DeleteRowsByFrameHandle] 数据库不存在: " + dbPath); return; }
-
- bool deleted = false;
- string deletedTuhao = null;
- string deletedXianghao = null;
- // ★ 收集级联删除的框Handle(图号→箱号→元件,删除数据时同步删蒙版)
- var cascadeFrames = new List();
-
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
-
- // 1) 图号表
- using (var sel = new System.Data.SQLite.SQLiteCommand(
- "SELECT 图号 FROM " + TuhaoTableName + " WHERE 框Handle=@fh;", conn))
- {
- sel.Parameters.AddWithValue("@fh", frameHandle);
- using (var reader = sel.ExecuteReader())
- {
- if (reader.Read())
- {
- deletedTuhao = reader.IsDBNull(0) ? "" : reader.GetString(0);
- Log("[DeleteRowsByFrameHandle] 命中图号表: " + deletedTuhao);
- }
- }
- }
- if (!string.IsNullOrWhiteSpace(deletedTuhao))
- {
- // ★ 删除图号前,先收集该图号下所有箱号和元件的框Handle(级联删蒙版)
- CollectFrameHandlesForTuhao(_currentProjectId, deletedTuhao, cascadeFrames);
- DeleteTuhao(_currentProjectId, deletedTuhao);
- deleted = true;
- }
-
- if (!deleted)
- {
- // 2) 箱号表:通过表索引找到所有箱号表,逐个查
- List allXhTables = new List();
- using (var selIdx = new System.Data.SQLite.SQLiteCommand(
- "SELECT 实际表名, 图号 FROM 表索引 WHERE 类型='箱号';", conn))
- using (var rIdx = selIdx.ExecuteReader())
- {
- while (rIdx.Read())
- {
- string realTbl = rIdx.IsDBNull(0) ? "" : rIdx.GetString(0);
- string th = rIdx.IsDBNull(1) ? "" : rIdx.GetString(1);
- if (!string.IsNullOrWhiteSpace(realTbl))
- allXhTables.Add(realTbl + "|" + th);
- }
- }
- Log("[DeleteRowsByFrameHandle] 箱号表数量: " + allXhTables.Count);
- foreach (string info in allXhTables)
- {
- string[] parts = info.Split('|');
- string realTbl = parts[0];
- string th = parts.Length > 1 ? parts[1] : "";
- using (var sel = new System.Data.SQLite.SQLiteCommand(
- "SELECT 箱号 FROM \"" + realTbl + "\" WHERE 框Handle=@fh;", conn))
- {
- sel.Parameters.AddWithValue("@fh", frameHandle);
- using (var reader = sel.ExecuteReader())
- {
- if (reader.Read())
- {
- deletedTuhao = th;
- deletedXianghao = reader.IsDBNull(0) ? "" : reader.GetString(0);
- Log("[DeleteRowsByFrameHandle] 命中箱号表: 图号=" + th + " 箱号=" + deletedXianghao);
- break;
- }
- }
- }
- if (!string.IsNullOrWhiteSpace(deletedXianghao)) break;
- }
- if (!string.IsNullOrWhiteSpace(deletedXianghao))
- {
- // ★ 删除箱号前,先收集该箱号下元件表的框Handle(级联删蒙版)
- CollectFrameHandlesForXianghao(_currentProjectId, deletedTuhao, deletedXianghao, cascadeFrames);
- DeleteXianghao(_currentProjectId, deletedTuhao, deletedXianghao);
- deleted = true;
- }
- }
-
- if (!deleted)
- {
- // 3) 元件表:通过表索引找到所有元件表,逐个查
- List allYjTables = new List();
- using (var selIdx = new System.Data.SQLite.SQLiteCommand(
- "SELECT 实际表名, 图号, 箱号 FROM 表索引 WHERE 类型='元件';", conn))
- using (var rIdx = selIdx.ExecuteReader())
- {
- while (rIdx.Read())
- {
- string realTbl = rIdx.IsDBNull(0) ? "" : rIdx.GetString(0);
- string th = rIdx.IsDBNull(1) ? "" : rIdx.GetString(1);
- string xh = rIdx.IsDBNull(2) ? "" : rIdx.GetString(2);
- if (!string.IsNullOrWhiteSpace(realTbl))
- allYjTables.Add(realTbl + "|" + th + "|" + xh);
- }
- }
- Log("[DeleteRowsByFrameHandle] 元件表数量: " + allYjTables.Count + " 查找Handle=" + frameHandle);
- foreach (string info in allYjTables)
- {
- string[] parts = info.Split('|');
- string realTbl = parts[0];
- string th = parts.Length > 1 ? parts[1] : "";
- string xh = parts.Length > 2 ? parts[2] : "";
- // ★ 先列出该表所有的框Handle,排查是否真的写进去了
- using (var selAll = new System.Data.SQLite.SQLiteCommand(
- "SELECT 序号, 框Handle FROM \"" + realTbl + "\";", conn))
- using (var rAll = selAll.ExecuteReader())
- {
- while (rAll.Read())
- {
- string s = rAll.IsDBNull(0) ? "" : rAll.GetString(0);
- string h = rAll.IsDBNull(1) ? "" : rAll.GetString(1);
- Log(" [元件表 " + realTbl + "] 序号=" + s + " 框Handle=[" + h + "]");
- }
- }
- using (var sel = new System.Data.SQLite.SQLiteCommand(
- "SELECT COUNT(*) FROM \"" + realTbl + "\" WHERE 框Handle=@fh;", conn))
- {
- sel.Parameters.AddWithValue("@fh", frameHandle);
- object cnt = sel.ExecuteScalar();
- int matchCount = (cnt != null && cnt != DBNull.Value) ? Convert.ToInt32(cnt) : 0;
- if (matchCount > 0)
- {
- deletedTuhao = th;
- deletedXianghao = xh;
- Log("[DeleteRowsByFrameHandle] 命中元件表: 图号=" + th + " 箱号=" + xh + " 匹配行数=" + matchCount);
-
- // ★ 直接用框Handle 删除所有匹配行(解决重复行问题)
- using (var delCmd = new System.Data.SQLite.SQLiteCommand(
- "DELETE FROM \"" + realTbl + "\" WHERE 框Handle=@fh;", conn))
- {
- delCmd.Parameters.AddWithValue("@fh", frameHandle);
- int affected = delCmd.ExecuteNonQuery();
- Log("[DeleteRowsByFrameHandle] DELETE 完成,影响行数=" + affected);
- }
- deleted = true;
- break;
- }
- }
- }
- }
- }
-
- if (deleted)
- {
- Log("[DeleteRowsByFrameHandle] 删除成功: Handle=" + frameHandle + " cascadeFrames=" + cascadeFrames.Count);
-
- _xianghaoCache.Clear();
- _yuanjianCache.Clear();
-
- // 重新编号(直接操作数据库)
- if (!string.IsNullOrWhiteSpace(deletedTuhao) && !string.IsNullOrWhiteSpace(deletedXianghao))
- {
- string yjTbl = GetYuanjianTableByIndex(_currentProjectId, deletedTuhao, deletedXianghao);
- if (!string.IsNullOrEmpty(yjTbl))
- RenumberTable(_currentProjectId, "\"" + yjTbl + "\"");
- string xhTbl = GetXianghaoTableByIndex(_currentProjectId, deletedTuhao);
- if (!string.IsNullOrEmpty(xhTbl))
- RenumberTable(_currentProjectId, "\"" + xhTbl + "\"");
- }
- else if (!string.IsNullOrWhiteSpace(deletedTuhao))
- {
- string xhTbl = GetXianghaoTableByIndex(_currentProjectId, deletedTuhao);
- if (!string.IsNullOrEmpty(xhTbl))
- RenumberTable(_currentProjectId, "\"" + xhTbl + "\"");
- }
-
- // ★ 直接在数据库层面重算(不经过内存表,不触发回写)
- try { RecalcAllFromDatabase(_currentProjectId); } catch { }
-
- // ★ 从数据库重新加载到 UI(覆盖内存表,确保 UI 与数据库一致)
- if (!string.IsNullOrWhiteSpace(deletedTuhao) && !string.IsNullOrWhiteSpace(deletedXianghao))
- {
- if (_currentTuhao == deletedTuhao)
- {
- ReloadXianghaoByTuhao(_currentProjectId, deletedTuhao);
- if (_currentXianghao == deletedXianghao)
- ReloadYuanjianByXianghao(_currentProjectId, deletedTuhao, deletedXianghao);
- }
- }
- else if (!string.IsNullOrWhiteSpace(deletedTuhao))
- {
- ReloadTuhaoByProject(_currentProjectId);
- if (_currentTuhao == deletedTuhao)
- ReloadXianghaoByTuhao(_currentProjectId, deletedTuhao);
- }
-
- // ★ 删除级联的框实体(图号删除时,其下箱号和元件的蒙版也要删除)
- Log("[DeleteRowsByFrameHandle] cascadeFrames 数量: " + cascadeFrames.Count + " 当前Handle=" + frameHandle);
- if (cascadeFrames.Count > 0)
- {
- // ★ 收集后一次性批量删除(排除当前正在删除的 frameHandle,已由 CAD 端删除)
- var toDel = new List();
- foreach (string h in cascadeFrames)
- {
- if (h != frameHandle) toDel.Add(h);
- }
- if (toDel.Count > 0)
- {
- Log("[DeleteRowsByFrameHandle] 级联删除框Handle数: " + toDel.Count);
- DeleteFramesByHandles(toDel);
- }
- SaveCurrentDwg();
- Log("[DeleteRowsByFrameHandle] 级联删除完成");
- }
- }
- }
- finally
- {
- _isReloading = false;
- }
- }
-
- /// 重写 OnLoad:在所有 Load 事件订阅者之前确保项目库文件存在。
- protected override void OnLoad(EventArgs e)
- {
- try { EnsureProjectDbExists(GetDbFullPath(ProjectsDbPath)); }
- catch { }
- base.OnLoad(e);
- }
-
- // ============================================================
- // 通用辅助方法
- // ============================================================
-
- private void Log(string msg)
- {
- try
- {
- string logPath = Path.Combine(_baseDir, "diag.log");
- File.AppendAllText(logPath,
- DateTime.Now.ToString("HH:mm:ss.fff") + " " + msg + "\r\n");
- }
- catch { }
- }
-
- private string GetDbFullPath(string relativePath)
- {
- return Path.Combine(_baseDir, relativePath);
- }
-
- private string GetConnString(string dbPath)
- {
- // ★ busy_timeout=3000:数据库被 CAD 或其他进程短暂占用时等待重试而非卡死;
- // Pooling 关闭,避免连接池长期持有文件句柄
- return "Data Source=" + dbPath + ";Version=3;busy_timeout=3000;";
- }
-
- private string GetQuoteDbPath(string projectId)
- {
- string safeName = projectId;
- char[] invalidChars = Path.GetInvalidFileNameChars();
- foreach (char c in invalidChars) safeName = safeName.Replace(c, '_');
- return GetDbFullPath(QuoteDbDir + @"\项目" + safeName + ".db");
- }
-
- private static decimal ParseDecimal(object v)
- {
- if (v == null || v == DBNull.Value) return 0m;
- decimal d;
- if (decimal.TryParse(v.ToString().Trim(), out d)) return d;
- return 0m;
- }
-
- private static DataGridViewColumn FindColumn(DataGridView dgv, string name)
- {
- if (dgv == null || dgv.Columns == null) return null;
- foreach (DataGridViewColumn c in dgv.Columns)
- {
- if (c == null) continue;
- if (c.DataPropertyName == name || c.HeaderText == name || c.Name == name) return c;
- }
- return null;
- }
-
- private static string GetCellString(DataGridViewRow row, string name)
- {
- if (row == null || row.DataGridView == null) return "";
- DataGridViewColumn col = FindColumn(row.DataGridView, name);
- if (col == null) return "";
- object v = row.Cells[col.Index].Value;
- return v == null ? "" : v.ToString().Trim();
- }
-
- private static decimal GetCellDecimal(DataGridViewRow row, string name)
- {
- return ParseDecimal(GetCellString(row, name));
- }
-
- private static string GetCellValueAsString(DataGridViewRow row, string colName)
- {
- if (row == null || row.Cells == null || string.IsNullOrEmpty(colName)) return "";
- DataGridView grid = row.DataGridView;
- if (grid != null)
- {
- foreach (DataGridViewColumn col in grid.Columns)
- {
- if (col == null) continue;
- string key = !string.IsNullOrEmpty(col.DataPropertyName)
- ? col.DataPropertyName
- : (!string.IsNullOrEmpty(col.HeaderText) ? col.HeaderText : col.Name);
- if (key == colName)
- {
- object v = row.Cells[col.Index].Value;
- return v == null ? "" : v.ToString().Trim();
- }
- }
- }
- return "";
- }
-
- private static void SetCell(DataGridViewRow row, string colName, decimal value)
- {
- if (row == null || row.DataGridView == null) return;
- DataGridViewColumn col = FindColumn(row.DataGridView, colName);
- if (col == null) return;
- row.Cells[col.Index].Value = value == 0m ? 0d : (double)value;
- }
-
- private static DataGridViewRow GetFirstSelectedRow(DataGridView dgv)
- {
- if (dgv == null || dgv.Rows == null || dgv.Rows.Count == 0) return null;
- foreach (DataGridViewRow r in dgv.SelectedRows)
- {
- if (r == null || r.IsNewRow) continue;
- return r;
- }
- if (dgv.CurrentRow != null && !dgv.CurrentRow.IsNewRow) return dgv.CurrentRow;
- return null;
- }
-
- private static List GetAllSelectedRows(DataGridView dgv)
- {
- var result = new List();
- if (dgv == null || dgv.Rows == null || dgv.Rows.Count == 0) return result;
- var seenRows = new HashSet();
- if (dgv.SelectedRows != null)
- {
- foreach (DataGridViewRow r in dgv.SelectedRows)
- {
- if (r == null || r.IsNewRow) continue;
- if (seenRows.Add(r.Index)) result.Add(r);
- }
- }
- // ★ 总是通过 SelectedCells 补充收集(不再限制 result.Count == 0)
- // ADGV 多选时 SelectedRows 可能不完整,SelectedCells 能覆盖所有选中行
- if (dgv.SelectedCells != null)
- {
- foreach (DataGridViewCell c in dgv.SelectedCells)
- {
- if (c == null || c.RowIndex < 0) continue;
- DataGridViewRow r = dgv.Rows[c.RowIndex];
- if (r == null || r.IsNewRow) continue;
- if (seenRows.Add(r.Index)) result.Add(r);
- }
- }
- // 兜底:如果以上都没收集到,取当前行
- if (result.Count == 0 && dgv.CurrentRow != null && !dgv.CurrentRow.IsNewRow)
- {
- result.Add(dgv.CurrentRow);
- }
- return result;
- }
-
- private DataGridViewRow GetFirstSelectedProjectRow()
- {
- DataGridView dgv = this.advancedDataGridView6;
- if (dgv == null || dgv.Rows == null || dgv.Rows.Count == 0) return null;
- foreach (DataGridViewRow r in dgv.SelectedRows)
- {
- if (r == null || r.IsNewRow) continue;
- return r;
- }
- if (dgv.CurrentRow != null && !dgv.CurrentRow.IsNewRow) return dgv.CurrentRow;
- return null;
- }
-
- private DataGridViewRow FindProjectRowById(string projectId)
- {
- if (string.IsNullOrWhiteSpace(projectId)) return null;
- DataGridView dgv = this.advancedDataGridView6;
- if (dgv == null || dgv.Rows == null) return null;
- foreach (DataGridViewRow r in dgv.Rows)
- {
- if (r == null || r.IsNewRow) continue;
- if (GetCellValueAsString(r, "项目编号") == projectId) return r;
- }
- return null;
- }
-
- private static void SetCurrentCell(DataGridView dgv, int rowIndex, int colIndex = 0)
- {
- if (dgv == null || dgv.Rows == null || rowIndex < 0 || rowIndex >= dgv.Rows.Count) return;
- try
- {
- if (dgv.Rows[rowIndex].IsNewRow) return;
- if (colIndex < 0 || colIndex >= dgv.Columns.Count) colIndex = 0;
- dgv.ClearSelection();
- dgv.Rows[rowIndex].Selected = true;
- dgv.CurrentCell = dgv.Rows[rowIndex].Cells[colIndex];
- }
- catch { }
- }
-
- private void SelectRowByValue(DataGridView dgv, string colName, string value)
- {
- if (dgv == null || dgv.Rows == null || string.IsNullOrEmpty(value)) return;
- try
- {
- _isReloading = true;
- foreach (DataGridViewRow r in dgv.Rows)
- {
- if (r == null || r.IsNewRow) continue;
- if (GetCellValueAsString(r, colName) == value)
- {
- dgv.ClearSelection();
- r.Selected = true;
- dgv.CurrentCell = r.Cells[0];
- return;
- }
- }
- }
- catch { }
- finally { _isReloading = false; }
- }
-
- private static int GetSelectedRowIndex(DataGridView dgv)
- {
- if (dgv == null) return -1;
- if (dgv.CurrentRow == null || dgv.CurrentRow.IsNewRow) return -1;
- return dgv.CurrentRow.Index;
- }
-
- private static string MakeSafeFileName(string s)
- {
- if (string.IsNullOrEmpty(s)) return "未命名";
- string r = s;
- char[] invalid = Path.GetInvalidFileNameChars();
- foreach (char c in invalid) r = r.Replace(c, '_');
- return r;
- }
-
- private static string EscapeJsonString(string s)
- {
- if (s == null) return "";
- return s.Replace("\\", "\\\\").Replace("\"", "\\\"")
- .Replace("\r", "\\r").Replace("\n", "\\n").Replace("\t", "\\t");
- }
-
- private string ShowInputDialog(string title, string prompt, string defaultValue)
- {
- using (var dlg = new Form())
- {
- dlg.Text = title;
- dlg.StartPosition = FormStartPosition.CenterParent;
- dlg.FormBorderStyle = FormBorderStyle.FixedDialog;
- dlg.MinimizeBox = false;
- dlg.MaximizeBox = false;
- dlg.Width = 340;
- dlg.Height = 170;
-
- var lbl = new Label();
- lbl.Text = prompt;
- lbl.Left = 12; lbl.Top = 15;
- lbl.Width = 300; lbl.Height = 30;
- dlg.Controls.Add(lbl);
-
- var txt = new TextBox();
- txt.Text = defaultValue;
- txt.Left = 12; txt.Top = 55;
- txt.Width = 300;
- dlg.Controls.Add(txt);
-
- var btnOk = new Button();
- btnOk.Text = "确定";
- btnOk.Left = 210; btnOk.Top = 92;
- btnOk.Width = 90;
- btnOk.DialogResult = DialogResult.OK;
- dlg.Controls.Add(btnOk);
-
- var btnCancel = new Button();
- btnCancel.Text = "取消";
- btnCancel.Left = 108; btnCancel.Top = 92;
- btnCancel.Width = 90;
- btnCancel.DialogResult = DialogResult.Cancel;
- dlg.Controls.Add(btnCancel);
-
- dlg.AcceptButton = btnOk;
- dlg.CancelButton = btnCancel;
-
- if (dlg.ShowDialog(this) == DialogResult.OK) return txt.Text;
- return "";
- }
- }
-
- /// 开启 DataGridView 的双缓冲(消除闪烁)。
- private static void EnableDoubleBuffered(DataGridView dgv)
- {
- if (dgv == null) return;
- try
- {
- typeof(DataGridView).InvokeMember("DoubleBuffered",
- System.Reflection.BindingFlags.SetProperty |
- System.Reflection.BindingFlags.Instance |
- System.Reflection.BindingFlags.NonPublic,
- null, dgv, new object[] { true });
- }
- catch { }
- }
-
- /// 按列名设置只读(运行时按 DataPropertyName/HeaderText 查找)。
- private static void ApplyReadOnlyColumns(DataGridView dgv, string[] colNames)
- {
- if (dgv == null || colNames == null) return;
- foreach (string name in colNames)
- {
- DataGridViewColumn col = FindColumn(dgv, name);
- if (col != null) col.ReadOnly = true;
- }
- }
-
- // ============================================================
- // 价格显示格式化
- // ============================================================
-
- /// 把"保留2位小数"/"保留整数"等转成 .NET 格式字符串(F0/F2)。
- private static string ToFormatString(string 小数位文本)
- {
- int n = 解析小数位(小数位文本);
- if (n < 0) n = 2;
- return "F" + n.ToString();
- }
-
- private static int 解析小数位(string text)
- {
- if (string.IsNullOrWhiteSpace(text)) return 2;
- string t = text.Trim();
- if (t.Contains("整数")) return 0;
- if (t.Contains("1位")) return 1;
- if (t.Contains("2位")) return 2;
- if (t.Contains("3位")) return 3;
- if (t.Contains("4位")) return 4;
- return 2;
- }
-
- private void ApplyPriceFormat(DataGridView dgv, string 小数位文本)
- {
- if (dgv == null || dgv.Columns == null) return;
- string fmt = ToFormatString(小数位文本);
- foreach (DataGridViewColumn col in dgv.Columns)
- {
- if (col == null) continue;
- string name = !string.IsNullOrEmpty(col.DataPropertyName)
- ? col.DataPropertyName : col.HeaderText;
- if (string.IsNullOrEmpty(name)) continue;
- if (s_公式列集合.Contains(name))
- {
- col.DefaultCellStyle.Format = fmt;
- }
- }
- }
-
- /// 老库兼容:把 DataTable 中公式列的类型从 string 转为 double。
- private static DataTable ConvertFormulaColumnsToDouble(DataTable table)
- {
- if (table == null || table.Columns.Count == 0) return table;
- bool needsConvert = false;
- foreach (DataColumn dc in table.Columns)
- {
- if (s_公式列集合.Contains(dc.ColumnName) && dc.DataType == typeof(string))
- {
- needsConvert = true;
- break;
- }
- }
- if (!needsConvert) return table;
-
- var newTable = new DataTable();
- foreach (DataColumn dc in table.Columns)
- {
- Type t = s_公式列集合.Contains(dc.ColumnName) ? typeof(double) : dc.DataType;
- newTable.Columns.Add(dc.ColumnName, t);
- }
- foreach (DataRow row in table.Rows)
- {
- var newRow = newTable.NewRow();
- foreach (DataColumn dc in table.Columns)
- {
- if (s_公式列集合.Contains(dc.ColumnName))
- {
- object v = row[dc];
- if (v == null || v == DBNull.Value) newRow[dc.ColumnName] = 0d;
- else if (v is double) newRow[dc.ColumnName] = v;
- else
- {
- double d;
- newRow[dc.ColumnName] = double.TryParse(v.ToString().Trim(), out d) ? d : 0d;
- }
- }
- else newRow[dc.ColumnName] = row[dc];
- }
- newTable.Rows.Add(newRow);
- }
- newTable.TableName = table.TableName;
- return newTable;
- }
-
- // ============================================================
- // 数据库结构维护
- // ============================================================
-
- private void EnsureProjectDbExists(string dbPath)
- {
- string dir = Path.GetDirectoryName(dbPath);
- if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- string sql =
- "CREATE TABLE IF NOT EXISTS " + ProjectsTableName + " (" +
- " 项目编号 TEXT, 项目名称 TEXT, 客户名称 TEXT, 客户地址 TEXT," +
- " 联系人 TEXT, 联系电话 TEXT, 项目日期 TEXT, 箱柜台数 REAL," +
- " 成本总价 REAL, 报出总价 REAL, 利润 REAL, 利润率 REAL, 备注 TEXT" +
- ");";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn)) cmd.ExecuteNonQuery();
- EnsureColumns(conn, ProjectsTableName, new[] {
- "成套厂名称", "成套厂地址", "成套厂联系人", "成套厂联系电话"
- });
- }
- }
-
- private static void EnsureColumns(System.Data.SQLite.SQLiteConnection conn, string tableName, string[] columns)
- {
- if (columns == null || columns.Length == 0) return;
- var existing = new HashSet(StringComparer.OrdinalIgnoreCase);
- using (var infoCmd = new System.Data.SQLite.SQLiteCommand("PRAGMA table_info(" + tableName + ");", conn))
- using (var reader = infoCmd.ExecuteReader())
- {
- while (reader.Read())
- {
- object nameObj = reader["name"];
- if (nameObj != null && nameObj != DBNull.Value) existing.Add(nameObj.ToString());
- }
- }
- foreach (string col in columns)
- {
- if (!existing.Contains(col))
- {
- string sql = "ALTER TABLE " + tableName + " ADD COLUMN " + col + " TEXT;";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn)) cmd.ExecuteNonQuery();
- }
- }
- }
-
- private static List GetProjectTableColumns(System.Data.SQLite.SQLiteConnection conn)
- {
- var cols = new List();
- try
- {
- using (var infoCmd = new System.Data.SQLite.SQLiteCommand("PRAGMA table_info(" + ProjectsTableName + ");", conn))
- using (var reader = infoCmd.ExecuteReader())
- {
- while (reader.Read())
- {
- object nameObj = reader["name"];
- if (nameObj != null && nameObj != DBNull.Value) cols.Add(nameObj.ToString());
- }
- }
- }
- catch { }
- return cols;
- }
-
- private void EnsureQuoteDbExists(string projectId)
- {
- if (string.IsNullOrWhiteSpace(projectId)) return;
- string dbPath = GetQuoteDbPath(projectId);
- string dir = Path.GetDirectoryName(dbPath);
- if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
-
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- string sqlTuhao =
- "CREATE TABLE IF NOT EXISTS " + TuhaoTableName + " (" +
- " 序号 TEXT, 图号 TEXT, 图名 TEXT, 台数 TEXT, 箱柜数量 REAL," +
- " 单价 REAL, 总价 REAL, 成本总价 REAL, 毛利 REAL, 毛利率 REAL," +
- " 框Handle TEXT, 文本Handle TEXT" +
- ");";
- string sqlIndex =
- "CREATE TABLE IF NOT EXISTS 表索引 (" +
- " 类型 TEXT, 图号 TEXT, 箱号 TEXT, 实际表名 TEXT" +
- ");";
- string sqlProjectInfo =
- "CREATE TABLE IF NOT EXISTS " + ProjectInfoTableName + " (" +
- " 项目编号 TEXT, 项目名称 TEXT, 客户名称 TEXT, 客户地址 TEXT," +
- " 联系人 TEXT, 联系电话 TEXT, 项目日期 TEXT, 备注 TEXT," +
- " 成套厂名称 TEXT, 成套厂地址 TEXT, 成套厂联系人 TEXT, 成套厂联系电话 TEXT," +
- " 单台小数位 TEXT, 单台取整方式 TEXT, 项目小数位 TEXT, 项目取整方式 TEXT" +
- ");";
- foreach (string sql in new[] { sqlTuhao, sqlIndex, sqlProjectInfo })
- {
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn)) cmd.ExecuteNonQuery();
- }
- EnsureColumns(conn, ProjectInfoTableName, new[] {
- "成套厂名称", "成套厂地址", "成套厂联系人", "成套厂联系电话",
- "单台小数位", "单台取整方式", "项目小数位", "项目取整方式"
- });
- // ★ 确保旧库的图号表也有"框Handle"/"文本Handle"列
- EnsureColumns(conn, TuhaoTableName, new[] { "框Handle", "文本Handle" });
- }
- }
-
- // ---------- 箱号表(每个图号一张独立表,表名=图号原名,双引号括起)----------
-
- private static string GetXianghaoTableName(string tuhao)
- {
- if (string.IsNullOrWhiteSpace(tuhao)) return "\"图号箱号表\"";
- return "\"" + tuhao.Replace("\"", "\"\"") + "\"";
- }
-
- private void EnsureXianghaoTableExists(string projectId, string tuhao)
- {
- if (string.IsNullOrWhiteSpace(projectId) || string.IsNullOrWhiteSpace(tuhao)) return;
- // 先查表索引,已有则跳过
- string existing = GetXianghaoTableByIndex(projectId, tuhao);
- if (!string.IsNullOrEmpty(existing)) return;
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return;
- // 用唯一ID做表名,避免图号名含特殊字符
- string realTbl = GetNextTableId(projectId, "箱号");
- try
- {
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- string sql =
- "CREATE TABLE \"" + realTbl + "\" (" +
- " 序号 TEXT, 箱号 TEXT, 型号 TEXT, 规格 TEXT, 单位 TEXT, 数量 TEXT," +
- " 单台成本 REAL, 成本价 REAL, 单台报出 REAL, 报出价 REAL," +
- " 利润 REAL, 利润率 REAL, 毛利率 REAL, 箱柜类型 TEXT, 备注 TEXT, 图纸 TEXT," +
- " 框Handle TEXT, 文本Handle TEXT" +
- ");";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn)) cmd.ExecuteNonQuery();
- }
- // ★ 注册到表索引,后续 GetXianghaoTableByIndex 才能查到
- AddTableIndex(projectId, "箱号", tuhao, "", realTbl);
- }
- catch { }
- }
-
- private string GetXianghaoCount(string projectId, string tuhao)
- {
- if (string.IsNullOrWhiteSpace(projectId) || string.IsNullOrWhiteSpace(tuhao)) return "1";
- string realTbl = GetXianghaoTableByIndex(projectId, tuhao);
- if (string.IsNullOrEmpty(realTbl)) return "1";
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return "1";
- try
- {
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- string sql = "SELECT COUNT(*) FROM \"" + realTbl + "\";";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- int n = 0;
- object o = cmd.ExecuteScalar();
- if (o != null && o != DBNull.Value) n = Convert.ToInt32(o);
- return (n + 1).ToString();
- }
- }
- }
- catch { return "1"; }
- }
-
- // ---------- 元件计数(用于新建元件命名"新元件N")----------
-
- private string GetYuanjianCount(string projectId, string tuhao, string xianghao)
- {
- if (string.IsNullOrWhiteSpace(projectId) ||
- string.IsNullOrWhiteSpace(xianghao)) return "1";
- // 查索引表拿该箱号元件表的真实表名
- string realTbl = GetYuanjianTableByIndex(projectId, tuhao, xianghao);
- if (string.IsNullOrEmpty(realTbl)) return "1";
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return "1";
- try
- {
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- string sql = "SELECT COUNT(*) FROM \"" + realTbl + "\";";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- int n = 0;
- object o = cmd.ExecuteScalar();
- if (o != null && o != DBNull.Value) n = Convert.ToInt32(o);
- return (n + 1).ToString();
- }
- }
- }
- catch { return "1"; }
- }
-
- // ---------- 元件表(每个箱号一张独立表)----------
-
- private static string GetYuanjianTableName(string xianghao)
- {
- if (string.IsNullOrWhiteSpace(xianghao)) return "\"元件表\"";
- return "\"" + xianghao.Replace("\"", "\"\"") + "\"";
- }
-
- private void EnsureYuanjianTableExists(string projectId, string tuhao, string xianghao)
- {
- if (string.IsNullOrWhiteSpace(projectId) || string.IsNullOrWhiteSpace(tuhao) || string.IsNullOrWhiteSpace(xianghao)) return;
- // 先查表索引,已有则跳过
- string existing = GetYuanjianTableByIndex(projectId, tuhao, xianghao);
- if (!string.IsNullOrEmpty(existing)) return;
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return;
- // 用唯一ID做表名
- string realTbl = GetNextTableId(projectId, "元件");
- try
- {
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- string sql =
- "CREATE TABLE \"" + realTbl + "\" (" +
- " 序号 TEXT, 元件名称 TEXT, 规格 TEXT, 单位 TEXT, 数量 TEXT," +
- " 表价 REAL, 采购单价 REAL, 采购系数 TEXT, 采购价 REAL," +
- " 报出单价 REAL, 报出系数 TEXT, 报出价 REAL," +
- " 图纸规格 TEXT, 品牌 TEXT, 系列 TEXT, 类型 TEXT, 备注 TEXT," +
- " 框Handle TEXT, 文本Handle TEXT" +
- ");";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn)) cmd.ExecuteNonQuery();
- }
- // ★ 注册到表索引(类型=元件,图号,箱号) — 后续 GetYuanjianTableByIndex 才能查到
- AddTableIndex(projectId, "元件", tuhao, xianghao, realTbl);
- }
- catch { }
- }
-
- // ---------- 表索引(用唯一ID做表名,索引表记录 图号/箱号 → 真实表名)----------
-
- private string GetNextTableId(string projectId, string prefix)
- {
- if (string.IsNullOrWhiteSpace(projectId)) return prefix + "_1";
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return prefix + "_1";
- try
- {
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- string sql = "SELECT 实际表名 FROM 表索引 WHERE 实际表名 LIKE @p;";
- int maxN = 0;
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- cmd.Parameters.AddWithValue("@p", prefix + "_%");
- using (var reader = cmd.ExecuteReader())
- {
- while (reader.Read())
- {
- string t = reader.IsDBNull(0) ? "" : reader.GetString(0);
- string numPart = t.StartsWith(prefix + "_") ? t.Substring(prefix.Length + 1) : "";
- int n;
- if (int.TryParse(numPart, out n) && n > maxN) maxN = n;
- }
- }
- }
- return prefix + "_" + (maxN + 1).ToString();
- }
- }
- catch { return prefix + "_1"; }
- }
-
- private void AddTableIndex(string projectId, string type, string tuhao, string xianghao, string realTableName)
- {
- if (string.IsNullOrWhiteSpace(projectId) || string.IsNullOrWhiteSpace(realTableName)) return;
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return;
- try
- {
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- string sql = "INSERT INTO 表索引 (类型, 图号, 箱号, 实际表名) VALUES (@t, @th, @xh, @real);";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- cmd.Parameters.AddWithValue("@t", type);
- cmd.Parameters.AddWithValue("@th", tuhao ?? "");
- cmd.Parameters.AddWithValue("@xh", xianghao ?? "");
- cmd.Parameters.AddWithValue("@real", realTableName);
- cmd.ExecuteNonQuery();
- }
- }
- }
- catch { }
- }
-
- private void RemoveTableIndex(string projectId, string type, string tuhao, string xianghao)
- {
- if (string.IsNullOrWhiteSpace(projectId)) return;
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return;
- try
- {
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- string sql = "DELETE FROM 表索引 WHERE 类型=@t AND 图号=@th AND 箱号=@xh;";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- cmd.Parameters.AddWithValue("@t", type);
- cmd.Parameters.AddWithValue("@th", tuhao ?? "");
- cmd.Parameters.AddWithValue("@xh", xianghao ?? "");
- cmd.ExecuteNonQuery();
- }
- }
- }
- catch { }
- }
-
- private string GetXianghaoTableByIndex(string projectId, string tuhao)
- {
- return LookupTableByIndex(projectId, "箱号", tuhao, "");
- }
-
- private string GetYuanjianTableByIndex(string projectId, string tuhao, string xianghao)
- {
- return LookupTableByIndex(projectId, "元件", tuhao, xianghao);
- }
-
- private string LookupTableByIndex(string projectId, string type, string tuhao, string xianghao)
- {
- if (string.IsNullOrWhiteSpace(projectId) || string.IsNullOrWhiteSpace(tuhao)) return "";
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return "";
- try
- {
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- return LookupTableByIndex(type, tuhao, xianghao, conn);
- }
- }
- catch { return ""; }
- }
-
- private string LookupTableByIndex(string type, string tuhao, string xianghao, System.Data.SQLite.SQLiteConnection conn)
- {
- if (conn == null || string.IsNullOrWhiteSpace(tuhao)) return "";
- try
- {
- string sql = "SELECT 实际表名 FROM 表索引 WHERE 类型=@t AND 图号=@th AND 箱号=@xh LIMIT 1;";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- cmd.Parameters.AddWithValue("@t", type);
- cmd.Parameters.AddWithValue("@th", tuhao);
- cmd.Parameters.AddWithValue("@xh", xianghao ?? "");
- object o = cmd.ExecuteScalar();
- return (o == null || o == DBNull.Value) ? "" : o.ToString();
- }
- }
- catch { return ""; }
- }
-
- private string GetXianghaoTableByIndex(string tuhao, System.Data.SQLite.SQLiteConnection conn)
- {
- return LookupTableByIndex("箱号", tuhao, "", conn);
- }
-
- private string GetYuanjianTableByIndex(string tuhao, string xianghao, System.Data.SQLite.SQLiteConnection conn)
- {
- return LookupTableByIndex("元件", tuhao, xianghao, conn);
- }
-
- private void CreateXianghaoTable(string projectId, string realTableName)
- {
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return;
- try
- {
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- string sql =
- "CREATE TABLE \"" + realTableName + "\" (" +
- " 序号 TEXT, 箱号 TEXT, 箱名 TEXT, 型号 TEXT, 规格 TEXT, 单位 TEXT, 数量 TEXT," +
- " 单台成本 REAL, 成本价 REAL, 单台报出 REAL, 报出价 REAL," +
- " 利润 REAL, 利润率 REAL, 毛利率 REAL, 箱柜类型 TEXT, 备注 TEXT, 图纸 TEXT" +
- ");";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn)) cmd.ExecuteNonQuery();
- }
- }
- catch { }
- }
-
- private void RenumberTable(string projectId, string quotedTableName)
- {
- if (string.IsNullOrWhiteSpace(projectId) || string.IsNullOrWhiteSpace(quotedTableName)) return;
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return;
- try
- {
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- string selSql = "SELECT rowid FROM " + quotedTableName + " ORDER BY rowid;";
- var rowids = new List();
- using (var sel = new System.Data.SQLite.SQLiteCommand(selSql, conn))
- using (var reader = sel.ExecuteReader())
- {
- while (reader.Read()) rowids.Add(reader.GetInt64(0));
- }
- int newSeq = 1;
- foreach (long rowid in rowids)
- {
- string updSql = "UPDATE " + quotedTableName + " SET 序号 = @seq WHERE rowid = @rid;";
- using (var upd = new System.Data.SQLite.SQLiteCommand(updSql, conn))
- {
- upd.Parameters.AddWithValue("@seq", newSeq.ToString());
- upd.Parameters.AddWithValue("@rid", rowid);
- upd.ExecuteNonQuery();
- }
- newSeq++;
- }
- }
- }
- catch { }
- }
-
- // ============================================================
- // 报价库「项目信息」表读写
- // ============================================================
-
- private void InsertProjectInfoToQuoteDb(string projectId, Dictionary values)
- {
- if (string.IsNullOrWhiteSpace(projectId) || values == null) return;
- EnsureQuoteDbExists(projectId);
- string dbPath = GetQuoteDbPath(projectId);
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- string delSql = "DELETE FROM " + ProjectInfoTableName + " WHERE 项目编号 = @id;";
- using (var del = new System.Data.SQLite.SQLiteCommand(delSql, conn))
- {
- del.Parameters.AddWithValue("@id", projectId);
- del.ExecuteNonQuery();
- }
- var cols = new List();
- var paras = new List();
- foreach (string c in ProjectInfoColumns)
- {
- if (values.ContainsKey(c)) { cols.Add(c); paras.Add("@" + c); }
- }
- if (cols.Count == 0) return;
- string sql = "INSERT INTO " + ProjectInfoTableName + " (" +
- string.Join(", ", cols.ToArray()) + ") VALUES (" +
- string.Join(", ", paras.ToArray()) + ");";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- foreach (string c in cols) cmd.Parameters.AddWithValue("@" + c, values[c] ?? "");
- cmd.ExecuteNonQuery();
- }
- }
- }
-
- private Dictionary GetProjectInfoFromQuoteDb(string projectId)
- {
- var info = new Dictionary();
- if (string.IsNullOrWhiteSpace(projectId)) return info;
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return info;
- try
- {
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- string chkSql = "SELECT name FROM sqlite_master WHERE type='table' AND name=@n;";
- using (var chk = new System.Data.SQLite.SQLiteCommand(chkSql, conn))
- {
- chk.Parameters.AddWithValue("@n", ProjectInfoTableName);
- if (chk.ExecuteScalar() == null) return info;
- }
- string sql = "SELECT * FROM " + ProjectInfoTableName + " WHERE 项目编号 = @id LIMIT 1;";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- cmd.Parameters.AddWithValue("@id", projectId);
- using (var reader = cmd.ExecuteReader())
- {
- if (reader.Read())
- {
- var existCols = new HashSet(StringComparer.OrdinalIgnoreCase);
- for (int i = 0; i < reader.FieldCount; i++) existCols.Add(reader.GetName(i));
- foreach (string c in ProjectInfoColumns)
- {
- if (!existCols.Contains(c)) continue;
- object v = reader[c];
- info[c] = (v == null || v == DBNull.Value) ? "" : v.ToString();
- }
- }
- }
- }
- }
- }
- catch { }
- return info;
- }
-
- private void LoadPriceFormatConfig(string projectId)
- {
- _单台小数位文本 = "保留2位小数";
- _单台取整方式 = "不取整";
- _项目小数位文本 = "保留2位小数";
- _项目取整方式 = "不取整";
- try
- {
- var info = GetProjectInfoFromQuoteDb(projectId);
- if (info == null || info.Count == 0) return;
- string v;
- if (info.TryGetValue("单台小数位", out v) && !string.IsNullOrWhiteSpace(v)) _单台小数位文本 = v;
- if (info.TryGetValue("单台取整方式", out v) && !string.IsNullOrWhiteSpace(v)) _单台取整方式 = v;
- if (info.TryGetValue("项目小数位", out v) && !string.IsNullOrWhiteSpace(v)) _项目小数位文本 = v;
- if (info.TryGetValue("项目取整方式", out v) && !string.IsNullOrWhiteSpace(v)) _项目取整方式 = v;
- }
- catch { }
- }
-
- // ============================================================
- // 项目库 CRUD
- // ============================================================
-
- private int InsertProjectToDatabase(Dictionary values)
- {
- if (values == null || values.Count == 0) return 0;
- string dbPath = GetDbFullPath(ProjectsDbPath);
- if (!File.Exists(dbPath))
- {
- EnsureProjectDbExists(dbPath);
- if (!File.Exists(dbPath))
- throw new FileNotFoundException("无法创建项目数据库文件: " + dbPath, dbPath);
- }
- int affected;
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- var allowed = new HashSet(GetProjectTableColumns(conn), StringComparer.OrdinalIgnoreCase);
- var colNames = new List();
- var paramNames = new List();
- foreach (string col in values.Keys)
- {
- if (allowed.Contains(col)) { colNames.Add(col); paramNames.Add("@" + col); }
- }
- if (colNames.Count == 0) { affected = 0; }
- else
- {
- string sql = "INSERT INTO " + ProjectsTableName + " (" +
- string.Join(", ", colNames.ToArray()) + ") VALUES (" +
- string.Join(", ", paramNames.ToArray()) + ");";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- foreach (string col in colNames) cmd.Parameters.AddWithValue("@" + col, values[col]);
- affected = cmd.ExecuteNonQuery();
- }
- }
- }
- string projectId;
- values.TryGetValue("项目编号", out projectId);
- if (!string.IsNullOrWhiteSpace(projectId)) InsertProjectInfoToQuoteDb(projectId, values);
- return affected;
- }
-
- private int DeleteProjectFromDatabase(string projectId)
- {
- if (string.IsNullOrWhiteSpace(projectId)) return 0;
- string dbPath = GetDbFullPath(ProjectsDbPath);
- if (!File.Exists(dbPath)) throw new FileNotFoundException("找不到项目数据库文件: " + dbPath, dbPath);
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- string sql = "DELETE FROM " + ProjectsTableName + " WHERE 项目编号 = @id;";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- cmd.Parameters.AddWithValue("@id", projectId);
- return cmd.ExecuteNonQuery();
- }
- }
- }
-
- private void CascadeDeleteByProject(string projectId)
- {
- if (string.IsNullOrWhiteSpace(projectId)) return;
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return;
- try { File.Delete(dbPath); }
- catch { }
- }
-
- private List> ReadAllProjectsFromDatabase()
- {
- var list = new List>();
- try
- {
- string dbPath = GetDbFullPath(ProjectsDbPath);
- if (!File.Exists(dbPath)) return list;
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- using (var cmd = new System.Data.SQLite.SQLiteCommand(
- "SELECT * FROM " + ProjectsTableName + " ORDER BY rowid;", conn))
- using (var rd = cmd.ExecuteReader())
- {
- while (rd.Read())
- {
- var dict = new Dictionary(StringComparer.Ordinal);
- for (int i = 0; i < rd.FieldCount; i++)
- {
- object v = rd.GetValue(i);
- if (v == null || v == DBNull.Value) v = "";
- dict[rd.GetName(i)] = v;
- }
- list.Add(dict);
- }
- }
- }
- }
- catch { }
- return list;
- }
-
- private Dictionary ReadProjectMetaData(string pid)
- {
- var dict = new Dictionary(StringComparer.Ordinal);
- try
- {
- string dbPath = GetDbFullPath(ProjectsDbPath);
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- using (var cmd = new System.Data.SQLite.SQLiteCommand(
- "SELECT * FROM " + ProjectsTableName + " WHERE 项目编号 = @p LIMIT 1;", conn))
- {
- cmd.Parameters.AddWithValue("@p", pid);
- using (var rd = cmd.ExecuteReader())
- {
- if (!rd.Read()) return null;
- for (int i = 0; i < rd.FieldCount; i++)
- {
- object v = rd.GetValue(i);
- if (v == null || v == DBNull.Value) v = "";
- dict[rd.GetName(i)] = v;
- }
- }
- }
- }
- }
- catch { return null; }
- return dict;
- }
-
- // ============================================================
- // 图号/箱号/元件 CRUD
- // ============================================================
-
- private string GetNextSeqNumber(string tableName, string nameCol, string projectId, string tuhao = null)
- {
- if (string.IsNullOrWhiteSpace(projectId)) return "1";
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return "1";
- try
- {
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- string sql;
- if (tuhao == null)
- {
- sql = "SELECT COUNT(*) FROM " + tableName + ";";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- int n = 0;
- object o = cmd.ExecuteScalar();
- if (o != null && o != DBNull.Value) n = Convert.ToInt32(o);
- return (n + 1).ToString();
- }
- }
- else
- {
- sql = "SELECT COUNT(*) FROM " + tableName + " WHERE 图号 = @th;";
- using (var cmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- cmd.Parameters.AddWithValue("@th", tuhao);
- int n = 0;
- object o = cmd.ExecuteScalar();
- if (o != null && o != DBNull.Value) n = Convert.ToInt32(o);
- return (n + 1).ToString();
- }
- }
- }
- }
- catch { return "1"; }
- }
-
- // ============================================================
- // 扒图号/扒箱号/扒元件:CAD 文本选择交互
- // ============================================================
-
- ///
- /// 向 CAD 发送扒数据命令,触发框选交互。
- /// ★ 关键:先发 ESC 取消当前可能正在进行的扒图循环,再发新命令
- /// 这样用户从"扒图号"循环里点"扒箱号"也能立即切换
- ///
- private void SendCadPaCommand(string cmd)
- {
- try
- {
- if (!pdfbt.PdfBridge.IsViewerReady)
- {
- MessageBox.Show(this, "尚未打开 PDF 图纸,请先在文档区打开 PDF 文件。",
- "扒数据", MessageBoxButtons.OK, MessageBoxIcon.Warning);
- return;
- }
- // 转发到 PDF 查看器(patu/paxh/payj/pacl 模式)
- pdfbt.PdfBridge.SendPaCommand(cmd);
- }
- catch (Exception ex)
- {
- MessageBox.Show(this, "发送扒图命令失败:\n" + ex.Message,
- "扒数据", MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- }
-
- ///
- /// CAD 选中文本后的回调:把选中的文本批量插入到对应表格。
- /// 由 CadPlugin.ExecutePaCommand 在 UI 线程调用。
- ///
- public void OnPaTextsPicked(PaMode mode, List results)
- {
- if (results == null || results.Count == 0) return;
- if (string.IsNullOrWhiteSpace(_currentProjectId))
- {
- MessageBox.Show(this, "请先在项目表中双击选择一个项目,再扒数据。",
- "扒数据", MessageBoxButtons.OK, MessageBoxIcon.Information);
- return;
- }
-
- switch (mode)
- {
- case PaMode.Tuhao:
- PaTuhaoInsert(results);
- break;
- case PaMode.Xianghao:
- PaXianghaoInsert(results);
- break;
- case PaMode.Yuanjian:
- PaYuanjianInsert(results);
- break;
- }
- }
-
- /// 扒图号:把选中文本作为图号批量插入到当前项目,同时保存框Handle。
- /// ★ 重复扒图:如果图号已存在,删除旧框和数据库行(不新增)。
- private void PaTuhaoInsert(List results)
- {
- string lastInsertedTuhao = null; // ★ 记录最后插入的图号,用于自动选中联动
- try
- {
- _isReloading = true;
- // 先 AcceptChanges,避免 SaveAllQuoteTablesIfDirty 把旧内存表回写
- if (_tuhaoTable != null) _tuhaoTable.AcceptChanges();
- if (_xianghaoTable != null) _xianghaoTable.AcceptChanges();
- if (_yuanjianTable != null) _yuanjianTable.AcceptChanges();
-
- // ★ 新增框架Handle列表: PaTextSelector刚画的框,如果是重复,需要删除这些新框
- var newFramesToErase = new List();
- int deletedCount = 0;
- int inserted = 0;
-
- foreach (var r in results)
- {
- if (string.IsNullOrWhiteSpace(r.Text)) continue;
- string clean = r.Text.Trim();
- // ★ 按"同一个文本实体"判断重复:查该文本实体Handle是否已入库。
- // 不同位置的相同内容文本 Handle 不同 → 不算重复,正常插入。
- string oldFrame = GetTuhaoFrameHandleByTextHandle(_currentProjectId, clean, r.TextHandle);
- if (!string.IsNullOrEmpty(oldFrame))
- {
- // ★ 重复(同一个文本再次选中):删除旧框+数据库行+新框
- DeleteTuhao(_currentProjectId, clean);
- DeleteFrameByHandle(oldFrame);
- if (!string.IsNullOrWhiteSpace(r.FrameHandle)) newFramesToErase.Add(r.FrameHandle);
- deletedCount++;
- }
- else
- {
- InsertTuhao(_currentProjectId, clean, r.FrameHandle, r.TextHandle);
- lastInsertedTuhao = clean; // ★ 记录最后插入的图号
- inserted++;
- }
- }
-
- // ★ 删除重复图号对应的新框(PaTextSelector已经画出来了,但不需要保留)——批量一次删
- DeleteFramesByHandles(newFramesToErase);
-
- _xianghaoCache.Clear();
- _yuanjianCache.Clear();
-
- // 直接在数据库层面重算(不经过内存回写)
- try { RecalcAllFromDatabase(_currentProjectId); } catch { }
- ReloadTuhaoByProject(_currentProjectId);
-
- // 保存
- try
- {
- if (this.advancedDataGridView9 != null) this.advancedDataGridView9.EndEdit();
- if (_tuhaoTable != null)
- {
- SaveTableToDatabase(_tuhaoTable, _currentProjectId, TuhaoTableName, null, null, true);
- _tuhaoTable.AcceptChanges();
- }
- }
- catch { }
- SaveCurrentDwg();
-
- if (deletedCount > 0 && inserted == 0)
- {
- Log("[PaTuhaoInsert] 删除了 " + deletedCount + " 条重复图号");
- }
- }
- catch (Exception ex)
- {
- MessageBox.Show(this, "扒图号失败:\n" + ex.Message,
- "扒图号", MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- finally
- {
- _isReloading = false;
- // ★ 扒完图号后自动选中刚插入的图号行,联动刷新箱号表
- if (!string.IsNullOrWhiteSpace(lastInsertedTuhao))
- {
- _currentTuhao = lastInsertedTuhao;
- SelectRowByValue(this.advancedDataGridView9, "图号", lastInsertedTuhao);
- // 手动联动刷新箱号表(SelectRowByValue 在 _isReloading 下不触发 SelectionChanged)
- ReloadXianghaoByTuhao(_currentProjectId, lastInsertedTuhao);
- }
- }
- }
-
- /// 扒箱号:把选中文本作为箱号批量插入到当前图号,同时保存框Handle。
- /// ★ 重复扒图:如果箱号已存在,删除旧框和数据库行(不新增)。
- private void PaXianghaoInsert(List results)
- {
- string lastInsertedXianghao = null; // ★ 记录最后插入的箱号,用于自动选中联动
- if (string.IsNullOrWhiteSpace(_currentTuhao))
- {
- MessageBox.Show(this, "请先在图号表中选择一个图号,再扒箱号。",
- "扒箱号", MessageBoxButtons.OK, MessageBoxIcon.Information);
- return;
- }
- try
- {
- _isReloading = true;
- // 先 AcceptChanges,避免 SaveAllQuoteTablesIfDirty 把旧内存表回写
- if (_tuhaoTable != null) _tuhaoTable.AcceptChanges();
- if (_xianghaoTable != null) _xianghaoTable.AcceptChanges();
- if (_yuanjianTable != null) _yuanjianTable.AcceptChanges();
-
- var newFramesToErase = new List();
- int deletedCount = 0;
- int inserted = 0;
-
- foreach (var r in results)
- {
- if (string.IsNullOrWhiteSpace(r.Text)) continue;
- string clean = r.Text.Trim();
- // ★ 按"同一个文本实体"判断重复(不同位置的相同内容文本不算重复)
- string oldFrame = GetXianghaoFrameHandleByTextHandle(_currentProjectId, _currentTuhao, clean, r.TextHandle);
- if (!string.IsNullOrEmpty(oldFrame))
- {
- // ★ 重复(同一个文本再次选中):删除旧框+数据库行+新框
- DeleteXianghao(_currentProjectId, _currentTuhao, clean);
- DeleteFrameByHandle(oldFrame);
- if (!string.IsNullOrWhiteSpace(r.FrameHandle)) newFramesToErase.Add(r.FrameHandle);
- deletedCount++;
- }
- else
- {
- InsertXianghao(_currentProjectId, _currentTuhao, clean, r.FrameHandle, r.TextHandle);
- lastInsertedXianghao = clean; // ★ 记录最后插入的箱号
- inserted++;
- }
- }
-
- DeleteFramesByHandles(newFramesToErase);
-
- _xianghaoCache.Clear();
- _yuanjianCache.Clear();
-
- try { RecalcAllFromDatabase(_currentProjectId); } catch { }
- ReloadXianghaoByTuhao(_currentProjectId, _currentTuhao);
-
- try
- {
- if (this.advancedDataGridView4 != null) this.advancedDataGridView4.EndEdit();
- if (_xianghaoTable != null && !string.IsNullOrWhiteSpace(_xianghaoTable.TableName))
- {
- SaveTableToDatabase(_xianghaoTable, _currentProjectId,
- "\"" + _xianghaoTable.TableName + "\"", null, null, true);
- _xianghaoTable.AcceptChanges();
- }
- }
- catch { }
- SaveCurrentDwg();
-
- if (deletedCount > 0 && inserted == 0)
- {
- Log("[PaXianghaoInsert] 删除了 " + deletedCount + " 条重复箱号");
- }
- }
- catch (Exception ex)
- {
- MessageBox.Show(this, "扒箱号失败:\n" + ex.Message,
- "扒箱号", MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- finally
- {
- _isReloading = false;
- // ★ 扒完箱号后自动选中刚插入的箱号行,联动刷新元件表
- if (!string.IsNullOrWhiteSpace(lastInsertedXianghao))
- {
- _currentXianghao = lastInsertedXianghao;
- SelectRowByValue(this.advancedDataGridView4, "箱号", lastInsertedXianghao);
- // 手动联动刷新元件表(SelectRowByValue 在 _isReloading 下不触发 SelectionChanged)
- ReloadYuanjianByXianghao(_currentProjectId, _currentTuhao, lastInsertedXianghao);
- }
- }
- }
-
- /// 扒元件:把选中文本作为【规格】批量插入到当前箱号(写到规格列),同时保存框Handle。
- /// ★ 关键:在单个事务里按 results 顺序依次插入,保证序号连续。
- /// ★ 重复扒图:如果规格已存在,删除旧框+数据库行(不新增)。
- private void PaYuanjianInsert(List results)
- {
- if (string.IsNullOrWhiteSpace(_currentXianghao))
- {
- MessageBox.Show(this, "请先在箱号表中选择一个箱号,再扒元件。",
- "扒元件", MessageBoxButtons.OK, MessageBoxIcon.Information);
- return;
- }
- try
- {
- _isReloading = true;
- // ★ 关键:先 AcceptChanges 清掉内存表的改动标记,避免 SaveAllQuoteTablesIfDirty
- // 用旧的内存数据覆盖数据库
- if (_yuanjianTable != null) _yuanjianTable.AcceptChanges();
- if (_xianghaoTable != null) _xianghaoTable.AcceptChanges();
- if (_tuhaoTable != null) _tuhaoTable.AcceptChanges();
- EnsureQuoteDbExists(_currentProjectId);
- string dbPath = GetQuoteDbPath(_currentProjectId);
- EnsureYuanjianTableExists(_currentProjectId, _currentTuhao, _currentXianghao);
- string tblName = GetYuanjianTableByIndex(_currentProjectId, _currentTuhao, _currentXianghao);
- if (string.IsNullOrEmpty(tblName))
- {
- MessageBox.Show("元件表创建失败(表索引未注册),图号=" + _currentTuhao + " 箱号=" + _currentXianghao);
- return;
- }
-
- // ★ 确保旧元件表也有"框Handle"/"文本Handle"列
- using (var connEns = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- connEns.Open();
- EnsureColumns(connEns, "\"" + tblName + "\"", new[] { "框Handle", "文本Handle" });
- }
-
- // 过滤掉空文本,保留原始顺序(同时保留框Handle+文本Handle)
- var cleanResults = new List();
- foreach (var r in results)
- {
- if (!string.IsNullOrWhiteSpace(r.Text))
- {
- cleanResults.Add(new PaTextResult
- {
- Text = r.Text.Trim(),
- FrameHandle = r.FrameHandle ?? "",
- TextHandle = r.TextHandle ?? ""
- });
- }
- }
- if (cleanResults.Count == 0) return;
-
- // ★ 判断是否是逆向合并模式(所有result共用同一个框Handle且数量>1)
- bool isMergeMode = cleanResults.Count > 1;
- string mergeHandle = cleanResults[0].FrameHandle;
- if (isMergeMode)
- {
- foreach (var r in cleanResults)
- {
- if (r.FrameHandle != mergeHandle) { isMergeMode = false; break; }
- }
- }
-
- // ★ 新增:重复检测辅助集合
- // newFramesToErase: PaTextSelector刚画的框,如果是重复项,这些框要删除
- var newFramesToErase = new List();
- // oldFrameHandlesToDelete: 数据库里匹配到的旧框,要删除
- var oldFrameHandlesToDelete = new List();
- // toInsert: 不重复、需要插入的项
- var toInsert = new List();
- // ★ 本地匹配失败的规格(收集后交给 DeepSeek AI 兜底识别)
- var aiFailedSpecs = new List();
- int deletedCount = 0;
-
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
-
- if (isMergeMode)
- {
- // ★ 合并模式:所有文本按图纸阅读顺序拼成一个规格
- // (PaTextSelector 已按列分组、列内从上到下排好序,保持此顺序
- // 与库中自然书写顺序一致,如 HD13BX-1500/31 + 1500A)
- // 文本Handle串与文本一一对应拼接(同一批文本Handle集合相同即重复)。
- var orderedTexts = new List();
- var orderedHandles = new List();
- foreach (var r in cleanResults)
- {
- orderedTexts.Add(r.Text);
- orderedHandles.Add(r.TextHandle ?? "");
- }
- string mergedSpec = string.Join("", orderedTexts.ToArray());
- // ★ Handle串排序后拼接(Handle集合相同即同一批文本,与顺序无关)
- var sortedHandles = new List(orderedHandles);
- sortedHandles.Sort(StringComparer.Ordinal);
- string mergedTextHandle = string.Join("|", sortedHandles.ToArray());
-
- // ★ 1. 查"同一批文本实体"的合并规格是否已存在
- // (文本Handle拼接串相同 = 同一批文本再次被选中,才是真重复)
- var matchFrames = new List();
- using (var selCmd = new System.Data.SQLite.SQLiteCommand(
- "SELECT 框Handle FROM \"" + tblName + "\" WHERE 规格=@spec AND 文本Handle=@th;", conn))
- {
- selCmd.Parameters.AddWithValue("@spec", mergedSpec);
- selCmd.Parameters.AddWithValue("@th", mergedTextHandle);
- using (var reader = selCmd.ExecuteReader())
- {
- while (reader.Read())
- {
- object v = reader["框Handle"];
- if (v != null && v != DBNull.Value)
- {
- string s = v.ToString();
- if (!string.IsNullOrWhiteSpace(s) && !matchFrames.Contains(s))
- matchFrames.Add(s);
- }
- }
- }
- }
-
- // ★ 2. 再查:本批每个文本实体是否已作为"独立元件"入库(按文本Handle精确匹配)
- var perTextFrames = new List();
- var perTextSpecs = new List();
- foreach (var r in cleanResults)
- {
- List fhs = GetYuanjianFrameHandlesByTextHandle(
- _currentProjectId, _currentTuhao, _currentXianghao, r.Text, r.TextHandle);
- foreach (string fh in fhs)
- {
- if (!perTextFrames.Contains(fh)) perTextFrames.Add(fh);
- }
- if (fhs.Count > 0 && !perTextSpecs.Contains(r.Text)) perTextSpecs.Add(r.Text);
- }
-
- // ★ 只要匹配到(1.同一批文本的合并规格 或 2.同一文本实体的独立元件) → 执行删除
- bool hitMergeMatch = matchFrames.Count > 0;
- bool hitPerTextMatch = perTextSpecs.Count > 0;
-
- if (hitMergeMatch || hitPerTextMatch)
- {
- // ★ 删除:同一批文本的合并规格匹配的行(文本Handle+规格双条件)
- if (hitMergeMatch)
- {
- using (var delCmd = new System.Data.SQLite.SQLiteCommand(
- "DELETE FROM \"" + tblName + "\" WHERE 规格=@spec AND 文本Handle=@th;", conn))
- {
- delCmd.Parameters.AddWithValue("@spec", mergedSpec);
- delCmd.Parameters.AddWithValue("@th", mergedTextHandle);
- int aff = delCmd.ExecuteNonQuery();
- deletedCount += aff;
- }
- foreach (string fh in matchFrames)
- if (!oldFrameHandlesToDelete.Contains(fh)) oldFrameHandlesToDelete.Add(fh);
- }
- // ★ 删除:同一文本实体的独立元件行(按文本Handle删除)
- if (hitPerTextMatch)
- {
- foreach (var r in cleanResults)
- {
- if (string.IsNullOrWhiteSpace(r.TextHandle)) continue;
- using (var selCmd2 = new System.Data.SQLite.SQLiteCommand(
- "SELECT COUNT(*) FROM \"" + tblName + "\" WHERE 文本Handle=@th;", conn))
- {
- selCmd2.Parameters.AddWithValue("@th", r.TextHandle);
- object cnt = selCmd2.ExecuteScalar();
- int n = (cnt != null && cnt != DBNull.Value) ? Convert.ToInt32(cnt) : 0;
- if (n > 0)
- {
- using (var delCmd = new System.Data.SQLite.SQLiteCommand(
- "DELETE FROM \"" + tblName + "\" WHERE 文本Handle=@th;", conn))
- {
- delCmd.Parameters.AddWithValue("@th", r.TextHandle);
- int aff = delCmd.ExecuteNonQuery();
- deletedCount += aff;
- }
- }
- }
- }
- foreach (string fh in perTextFrames)
- if (!oldFrameHandlesToDelete.Contains(fh)) oldFrameHandlesToDelete.Add(fh);
- }
- // ★ 删除 PaTextSelector 刚画的新合并框
- if (!string.IsNullOrWhiteSpace(mergeHandle))
- if (!newFramesToErase.Contains(mergeHandle))
- newFramesToErase.Add(mergeHandle);
- Log("[PaYuanjianInsert] 合并模式:删除重复项 mergedMatch=" + hitMergeMatch
- + " perTextMatch=" + hitPerTextMatch + ", 删除行数=" + deletedCount
- + ", 删除旧框数=" + oldFrameHandlesToDelete.Count);
- }
- else
- {
- // ★ 没有匹配:新增一行(合并规格)
- toInsert.Add(new PaTextResult
- {
- Text = mergedSpec,
- FrameHandle = mergeHandle,
- TextHandle = mergedTextHandle
- });
- }
- }
- else
- {
- // ★ 正向模式:每个文本一条记录,按"同一个文本实体"判断是否重复
- foreach (var r in cleanResults)
- {
- // ★ 按文本Handle精确匹配:同一文本实体才删除,
- // 不同位置的相同内容文本(Handle不同)正常插入
- List matchFrames = GetYuanjianFrameHandlesByTextHandle(
- _currentProjectId, _currentTuhao, _currentXianghao, r.Text, r.TextHandle);
- if (matchFrames.Count > 0)
- {
- // 重复:按文本Handle删除数据库行 + 旧框 + 新画的框
- using (var delCmd = new System.Data.SQLite.SQLiteCommand(
- "DELETE FROM \"" + tblName + "\" WHERE 文本Handle=@th;", conn))
- {
- delCmd.Parameters.AddWithValue("@th", r.TextHandle);
- int aff = delCmd.ExecuteNonQuery();
- deletedCount += aff;
- }
- foreach (string fh in matchFrames) oldFrameHandlesToDelete.Add(fh);
- if (!string.IsNullOrWhiteSpace(r.FrameHandle)) newFramesToErase.Add(r.FrameHandle);
- }
- else
- {
- toInsert.Add(r);
- }
- }
- }
-
- // ★ 写入需要新增的项
- if (toInsert.Count > 0)
- {
- // 先取当前最大序号(用MAX函数)
- int startSeq = 0;
- using (var cntCmd = new System.Data.SQLite.SQLiteCommand(
- "SELECT COALESCE(MAX(CAST(序号 AS INTEGER)), 0) FROM \"" + tblName + "\";", conn))
- {
- object o = cntCmd.ExecuteScalar();
- if (o != null && o != DBNull.Value) startSeq = Convert.ToInt32(o);
- }
- string sql = "INSERT INTO \"" + tblName + "\"" +
- " (序号, 元件名称, 规格, 单位, 数量, 采购系数, 报出系数," +
- " 表价, 采购单价, 采购价, 报出单价, 报出价, 类型, 框Handle, 文本Handle) " +
- "VALUES (@seq, @name, @spec, @unit, @shuliang, @caigou, @baochu, 0, 0, 0, 0, 0, '元件', @fh, @th);";
- for (int i = 0; i < toInsert.Count; i++)
- {
- // ★ 自动匹配元件名称(用户库CSV模糊匹配,匹配不上为空)
- string matchedName = MatchSpecName(toInsert[i].Text) ?? "";
- if (matchedName.Length == 0) aiFailedSpecs.Add(toInsert[i].Text);
- using (var insCmd = new System.Data.SQLite.SQLiteCommand(sql, conn))
- {
- insCmd.Parameters.AddWithValue("@seq", (startSeq + i + 1).ToString());
- insCmd.Parameters.AddWithValue("@name", matchedName);
- insCmd.Parameters.AddWithValue("@spec", toInsert[i].Text);
- insCmd.Parameters.AddWithValue("@unit", "只");
- insCmd.Parameters.AddWithValue("@shuliang", "1");
- insCmd.Parameters.AddWithValue("@caigou", "1");
- insCmd.Parameters.AddWithValue("@baochu", "1");
- insCmd.Parameters.AddWithValue("@fh", toInsert[i].FrameHandle ?? "");
- insCmd.Parameters.AddWithValue("@th", toInsert[i].TextHandle ?? "");
- insCmd.ExecuteNonQuery();
- }
- }
- }
- }
-
- // ★ 删除旧框和重复新框——合并成一次批量删除(单事务+单次刷新)
- var framesToErase = new List(oldFrameHandlesToDelete);
- framesToErase.AddRange(newFramesToErase);
- DeleteFramesByHandles(framesToErase);
-
- // ★ 重新编号(删除后序号可能不连续)
- RenumberTable(_currentProjectId, "\"" + tblName + "\"");
-
- _yuanjianCache.Clear();
- _xianghaoCache.Clear();
-
- // 直接在数据库层面重算(不经过内存回写)
- try { RecalcAllFromDatabase(_currentProjectId); } catch { }
- ReloadYuanjianByXianghao(_currentProjectId, _currentTuhao, _currentXianghao);
-
- // ★ 收集新插入元件的框Handle(finally 里再统一选中,
- // 避免被后续 SaveTable/AcceptChanges/表格刷新清掉选中)
- foreach (var r in toInsert)
- if (!string.IsNullOrWhiteSpace(r.FrameHandle))
- _pendingSelectYuanjianHandles.Add(r.FrameHandle);
-
- // 保存
- try
- {
- if (this.advancedDataGridView5 != null) this.advancedDataGridView5.EndEdit();
- if (_yuanjianTable != null)
- {
- SaveTableToDatabase(_yuanjianTable, _currentProjectId,
- "\"" + _yuanjianTable.TableName + "\"", null, null, true);
- _yuanjianTable.AcceptChanges();
- }
- }
- catch { }
- SaveCurrentDwg();
-
- if (deletedCount > 0)
- {
- Log("[PaYuanjianInsert] 删除了 " + deletedCount + " 条重复元件(匹配框:" + oldFrameHandlesToDelete.Count + ")");
- }
-
- // ★ DeepSeek AI 兜底:本地未匹配到名称的规格,异步提交 AI 识别并回填
- if (aiFailedSpecs.Count > 0)
- {
- Log("[PaYuanjianInsert] " + aiFailedSpecs.Count + " 条本地未匹配,提交AI识别");
- AiFillMissingNames(aiFailedSpecs, tblName);
- }
- }
- catch (Exception ex)
- {
- MessageBox.Show(this, "扒元件失败:\n" + ex.Message,
- "扒元件", MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- finally
- {
- _isReloading = false;
- // ★ 扒到的元件行保持选中(供 F1 合并):延迟两拍执行,
- // 等保存/刷新/绑定事件链全部走完,否则选中会被冲掉
- if (_pendingSelectYuanjianHandles.Count > 0)
- {
- var snapshot = new List(_pendingSelectYuanjianHandles);
- _pendingSelectYuanjianHandles.Clear();
- BeginInvoke((Action)(() =>
- {
- BeginInvoke((Action)(() =>
- {
- SelectYuanjianRowsByFrameHandles(snapshot);
- Log("[PaYuanjianInsert] 已选中 " + snapshot.Count + " 条新元件行(供F1合并)");
- }));
- }));
- }
- }
- }
-
- /// 查询图号是否已存在(避免重复插入)。
- private bool TuhaoExists(string projectId, string tuhao)
- {
- return !string.IsNullOrEmpty(GetTuhaoFrameHandle(projectId, tuhao));
- }
-
- ///
- /// ★ 按"同一个文本实体"判断重复:查该文本实体Handle是否已入库。
- /// 命中返回旧框Handle(真重复);未命中返回 null(不同位置的相同内容文本,正常插入)。
- ///
- private string GetTuhaoFrameHandleByTextHandle(string projectId, string tuhao, string textHandle)
- {
- // 旧数据没有文本Handle → 按旧逻辑(文本内容)判断,保持旧行为
- if (string.IsNullOrWhiteSpace(textHandle)) return GetTuhaoFrameHandle(projectId, tuhao);
- try
- {
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return null;
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- // ★ 先确保旧图号表有"文本Handle"列,避免查询报错
- EnsureColumns(conn, TuhaoTableName, new[] { "文本Handle" });
- // ★ 双条件:同一文本实体(Handle精确匹配) 或 旧数据行(无文本Handle,按内容兜底)
- using (var cmd = new System.Data.SQLite.SQLiteCommand(
- "SELECT 框Handle FROM " + TuhaoTableName +
- " WHERE 文本Handle=@th OR (图号=@t AND (文本Handle IS NULL OR 文本Handle='')) LIMIT 1;", conn))
- {
- cmd.Parameters.AddWithValue("@th", textHandle);
- cmd.Parameters.AddWithValue("@t", tuhao);
- using (var rdr = cmd.ExecuteReader())
- {
- if (rdr.Read())
- {
- object v = rdr["框Handle"];
- if (v != null && v != DBNull.Value)
- {
- string s = v.ToString();
- if (!string.IsNullOrWhiteSpace(s)) return s;
- }
- }
- }
- }
- }
- }
- catch { }
- return null;
- }
-
- /// 查询指定图号的框Handle(不存在返回null)。
- private string GetTuhaoFrameHandle(string projectId, string tuhao)
- {
- try
- {
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return null;
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- using (var cmd = new System.Data.SQLite.SQLiteCommand(
- "SELECT 框Handle FROM " + TuhaoTableName + " WHERE 图号=@t LIMIT 1;", conn))
- {
- cmd.Parameters.AddWithValue("@t", tuhao);
- using (var rdr = cmd.ExecuteReader())
- {
- if (rdr.Read())
- {
- object v = rdr["框Handle"];
- if (v != null && v != DBNull.Value)
- {
- string s = v.ToString();
- if (!string.IsNullOrWhiteSpace(s)) return s;
- }
- }
- }
- }
- }
- }
- catch { }
- return null;
- }
-
- /// 查询箱号是否已存在(避免重复插入)。
- private bool XianghaoExists(string projectId, string tuhao, string xianghao)
- {
- return !string.IsNullOrEmpty(GetXianghaoFrameHandle(projectId, tuhao, xianghao));
- }
-
- ///
- /// ★ 按"同一个文本实体"判断重复:查该文本实体Handle是否已入库。
- /// 命中返回旧框Handle(真重复);未命中返回 null(不同位置的相同内容文本,正常插入)。
- ///
- private string GetXianghaoFrameHandleByTextHandle(string projectId, string tuhao, string xianghao, string textHandle)
- {
- // 旧数据没有文本Handle → 按旧逻辑(文本内容)判断,保持旧行为
- if (string.IsNullOrWhiteSpace(textHandle)) return GetXianghaoFrameHandle(projectId, tuhao, xianghao);
- try
- {
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return null;
- string tableName = GetQuoteTableName(projectId, tuhao);
- if (string.IsNullOrEmpty(tableName)) return null;
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- // ★ 先确保旧箱号表有"文本Handle"列,避免查询报错
- EnsureColumns(conn, "\"" + tableName + "\"", new[] { "文本Handle" });
- // ★ 双条件:同一文本实体(Handle精确匹配) 或 旧数据行(无文本Handle,按内容兜底)
- using (var cmd = new System.Data.SQLite.SQLiteCommand(
- "SELECT 框Handle FROM \"" + tableName + "\"" +
- " WHERE 文本Handle=@th OR (箱号=@x AND (文本Handle IS NULL OR 文本Handle='')) LIMIT 1;", conn))
- {
- cmd.Parameters.AddWithValue("@th", textHandle);
- cmd.Parameters.AddWithValue("@x", xianghao);
- using (var rdr = cmd.ExecuteReader())
- {
- if (rdr.Read())
- {
- object v = rdr["框Handle"];
- if (v != null && v != DBNull.Value)
- {
- string s = v.ToString();
- if (!string.IsNullOrWhiteSpace(s)) return s;
- }
- }
- }
- }
- }
- }
- catch { }
- return null;
- }
-
- /// 查询指定箱号的框Handle(不存在返回null)。
- private string GetXianghaoFrameHandle(string projectId, string tuhao, string xianghao)
- {
- try
- {
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return null;
- string tableName = GetQuoteTableName(projectId, tuhao);
- if (string.IsNullOrEmpty(tableName)) return null;
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- using (var cmd = new System.Data.SQLite.SQLiteCommand(
- "SELECT 框Handle FROM \"" + tableName + "\" WHERE 箱号=@x LIMIT 1;", conn))
- {
- cmd.Parameters.AddWithValue("@x", xianghao);
- using (var rdr = cmd.ExecuteReader())
- {
- if (rdr.Read())
- {
- object v = rdr["框Handle"];
- if (v != null && v != DBNull.Value)
- {
- string s = v.ToString();
- if (!string.IsNullOrWhiteSpace(s)) return s;
- }
- }
- }
- }
- }
- }
- catch { }
- return null;
- }
-
- /// 查询指定元件规格的所有框Handle(可能有多个重复行,返回List)。
- private List GetYuanjianFrameHandles(string projectId, string tuhao, string xianghao, string spec)
- {
- var list = new List();
- try
- {
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return list;
- string tableName = GetYuanjianTableByIndex(projectId, tuhao, xianghao);
- if (string.IsNullOrEmpty(tableName)) return list;
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- using (var cmd = new System.Data.SQLite.SQLiteCommand(
- "SELECT 框Handle FROM \"" + tableName + "\" WHERE 规格=@s;", conn))
- {
- cmd.Parameters.AddWithValue("@s", spec);
- using (var rdr = cmd.ExecuteReader())
- {
- while (rdr.Read())
- {
- object v = rdr["框Handle"];
- if (v != null && v != DBNull.Value)
- {
- string s = v.ToString();
- if (!string.IsNullOrWhiteSpace(s)) list.Add(s);
- }
- }
- }
- }
- }
- }
- catch { }
- return list;
- }
-
- ///
- /// ★ 按"同一个文本实体"判断重复:查该文本实体Handle在元件表中是否已入库。
- /// 命中返回旧框Handle列表(真重复);未命中返回空列表(不同位置的相同内容文本,正常插入)。
- ///
- private List GetYuanjianFrameHandlesByTextHandle(string projectId, string tuhao, string xianghao, string spec, string textHandle)
- {
- var list = new List();
- // 旧数据没有文本Handle → 按旧逻辑(文本内容)判断,保持旧行为
- if (string.IsNullOrWhiteSpace(textHandle)) return GetYuanjianFrameHandles(projectId, tuhao, xianghao, spec);
- try
- {
- string dbPath = GetQuoteDbPath(projectId);
- if (!File.Exists(dbPath)) return list;
- string tableName = GetYuanjianTableByIndex(projectId, tuhao, xianghao);
- if (string.IsNullOrEmpty(tableName)) return list;
- using (var conn = new System.Data.SQLite.SQLiteConnection(GetConnString(dbPath)))
- {
- conn.Open();
- // ★ 先确保旧元件表有"文本Handle"列,避免查询报错
- EnsureColumns(conn, "\"" + tableName + "\"", new[] { "文本Handle" });
- // ★ 双条件:同一文本实体(Handle精确匹配) 或 旧数据行(无文本Handle,按规格兜底)
- using (var cmd = new System.Data.SQLite.SQLiteCommand(
- "SELECT 框Handle FROM \"" + tableName + "\"" +
- " WHERE 文本Handle=@th OR (规格=@s AND (文本Handle IS NULL OR 文本Handle=''));", conn))
- {
- cmd.Parameters.AddWithValue("@th", textHandle);
- cmd.Parameters.AddWithValue("@s", spec);
- using (var rdr = cmd.ExecuteReader())
- {
- while (rdr.Read())
- {
- object v = rdr["框Handle"];
- if (v != null && v != DBNull.Value)
- {
- string s = v.ToString();
- if (!string.IsNullOrWhiteSpace(s)) list.Add(s);
- }
- }
- }
- }
- }
- }
- catch { }
- return list;
- }
-
- // ============================================================
- // 扒元件自动匹配元件名称(用户库CSV模糊匹配)
- // · 扫描插件上级目录/自身目录下最新的 用户库_*.csv(GBK编码)
- // · 匹配策略:L1归一化相等 → L2包含(60%长度) → L3编辑距离≥0.70
- // · 硬保护:模糊匹配时数字序列必须完全一致(63A 不会配到 100A)
- // ============================================================
-
- /// 用户库条目:规格 → 元件名称
- private class SpecNameEntry
- {
- public string Name;
- public string NormSpec; // 归一化后的规格
- public string[] Numbers; // 规格中的数字序列(模糊匹配保护用)
- public string Skeleton; // 字母骨架(去数字/分隔符/尾部单位,如 DZ47-4P/C80A → DZPC)
- }
-
- private static List _specNameLib = null;
- private static string _specLibCsvPath = null;
- private static DateTime _specLibCsvTime = DateTime.MinValue;
-
- ///
- /// 确保用户库CSV已加载(取最新修改时间的 用户库_*.csv,
- /// 文件时间戳变化时自动重新加载;文件被 Excel 占用时用共享读)。
- ///
- private static void EnsureUserLibCsvLoaded()
- {
- try
- {
- // 候选目录:上级目录(成套报价软件根目录) + 插件目录自身
- var dirs = new List();
- try
- {
- var parent = Path.GetDirectoryName(_baseDir);
- if (!string.IsNullOrEmpty(parent) && Directory.Exists(parent)) dirs.Add(parent);
- }
- catch { }
- dirs.Add(_baseDir);
-
- string best = null;
- DateTime bestTime = DateTime.MinValue;
- foreach (string d in dirs)
- {
- try
- {
- string[] files = Directory.GetFiles(d, "用户库*.csv");
- foreach (string f in files)
- {
- DateTime t = File.GetLastWriteTime(f);
- if (best == null || t > bestTime) { best = f; bestTime = t; }
- }
- }
- catch { }
- }
- if (best == null) return; // 没找到CSV,保持空库
-
- // 时间戳没变且已加载 → 不重复加载
- if (_specNameLib != null &&
- string.Equals(best, _specLibCsvPath, StringComparison.OrdinalIgnoreCase) &&
- bestTime == _specLibCsvTime) return;
-
- var lib = new List();
- var prefixRules = new List();
- // ★ 共享读:文件被 Excel 打开也能读
- using (var fs = new FileStream(best, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
- using (var sr = new StreamReader(fs, DetectCsvEncoding(fs)))
- {
- string line;
- bool first = true;
- while ((line = sr.ReadLine()) != null)
- {
- if (string.IsNullOrWhiteSpace(line)) continue;
- string[] cols = SplitCsvLine(line);
- if (cols.Length < 2) continue;
- string name = cols[0].Trim();
- string spec = cols[1].Trim();
- if (first)
- {
- first = false;
- // 跳过表头
- if (name == "元件名称") continue;
- }
- if (name.Length == 0 || spec.Length == 0) continue;
-
- // ★ "元件类型"列 = "前缀" 的行是型号前缀规则(不是库条目)
- string elemType = cols.Length >= 10 ? cols[9].Trim() : "";
- if (elemType == "前缀")
- {
- string pfx = spec.ToUpperInvariant();
- if (pfx.Length >= 2) prefixRules.Add(new[] { pfx, name });
- continue;
- }
-
- string normSpec = NormalizeSpec(spec);
- lib.Add(new SpecNameEntry
- {
- Name = name,
- NormSpec = normSpec,
- // ★ 必须用原始 spec 提取数字(保留空格/符号作数字边界);
- // 用 normSpec 会导致 3300 800 粘连成 3300800,数字序列错位
- Numbers = ExtractNumbers(spec),
- Skeleton = ExtractSkeleton(spec)
- });
- }
- }
- _specNameLib = lib;
- _prefixRules = prefixRules;
- _specLibCsvPath = best;
- _specLibCsvTime = bestTime;
- WriteDebugLog("[用户库匹配] 加载CSV: " + best + " 条数=" + lib.Count +
- " 前缀规则=" + prefixRules.Count);
- }
- catch (Exception ex) { WriteDebugLog("[用户库匹配] 加载CSV异常: " + ex.Message); }
- }
-
- /// 检测CSV编码:有UTF-8 BOM用UTF8,否则按GBK(主程序导出编码)。
- private static System.Text.Encoding DetectCsvEncoding(FileStream fs)
- {
- try
- {
- long pos = fs.Position;
- int b1 = fs.ReadByte();
- int b2 = fs.ReadByte();
- int b3 = fs.ReadByte();
- fs.Position = pos;
- if (b1 == 0xEF && b2 == 0xBB && b3 == 0xBF) return System.Text.Encoding.UTF8;
- }
- catch { }
- return System.Text.Encoding.GetEncoding("GBK");
- }
-
- /// 按CSV规则拆分一行(支持双引号包裹和转义"")。
- private static string[] SplitCsvLine(string line)
- {
- var parts = new List();
- var sb = new System.Text.StringBuilder();
- bool inQuotes = false;
- for (int i = 0; i < line.Length; i++)
- {
- char c = line[i];
- if (c == '"')
- {
- if (inQuotes && i + 1 < line.Length && line[i + 1] == '"') { sb.Append('"'); i++; }
- else inQuotes = !inQuotes;
- }
- else if (c == ',' && !inQuotes)
- {
- parts.Add(sb.ToString());
- sb.Length = 0;
- }
- else sb.Append(c);
- }
- parts.Add(sb.ToString());
- return parts.ToArray();
- }
-
- /// 规格归一化:全角→半角、统一大写、去空白和分隔符号(保留字母/数字/中文)。
- private static string NormalizeSpec(string s)
- {
- if (string.IsNullOrEmpty(s)) return "";
- var sb = new System.Text.StringBuilder(s.Length);
- foreach (char c0 in s)
- {
- char c = c0;
- // 全角→半角
- if (c >= 0xFF01 && c <= 0xFF5E) c = (char)(c - 0xFEE0);
- else if (c == 0x3000) c = ' ';
- if (c == ' ' || c == '\t') continue;
- if (IsSpecSeparator(c)) continue;
- sb.Append(char.ToUpperInvariant(c));
- }
- return sb.ToString();
- }
-
- /// 规格中的分隔符号(归一化时删除;数字提取时作为数字段边界)。
- private static bool IsSpecSeparator(char c)
- {
- return c == '-' || c == '/' || c == '*' || c == '×' || c == '·' || c == '.' ||
- c == '、' || c == ',' || c == ',' || c == '(' || c == ')' || c == '(' ||
- c == ')' || c == '#' || c == '+' || c == '_' || c == ':' || c == ':' ||
- c == '~' || c == '~';
- }
-
- ///
- /// 轻量归一化(保留分隔符和空格):全角→半角、统一大写。
- /// ★ 用于数字序列提取:分隔符和空格是数字段的天然边界,
- /// 先删分隔符会导致 HYM1-63/3300 的 63 和 3300 粘连成 633300;
- /// 删空格会导致 3300 800 粘连成 3300800(与 3300,800 数字序列不一致)。
- ///
- private static string NormalizeKeepSeparators(string s)
- {
- if (string.IsNullOrEmpty(s)) return "";
- var sb = new System.Text.StringBuilder(s.Length);
- foreach (char c0 in s)
- {
- char c = c0;
- if (c >= 0xFF01 && c <= 0xFF5E) c = (char)(c - 0xFEE0);
- else if (c == 0x3000) c = ' ';
- if (c == '\t') c = ' '; // 制表符当空格
- sb.Append(char.ToUpperInvariant(c));
- }
- return sb.ToString();
- }
-
- ///
- /// 提取规格中的所有数字序列(在保留分隔符的版本上提取,
- /// 如 HYM1-63/3300 63A → ["1","63","3300","63"])。
- ///
- private static string[] ExtractNumbers(string spec)
- {
- var list = new List();
- if (string.IsNullOrEmpty(spec)) return list.ToArray();
- string light = NormalizeKeepSeparators(spec);
- var sb = new System.Text.StringBuilder();
- foreach (char c in light)
- {
- if (c >= '0' && c <= '9') sb.Append(c);
- else if (sb.Length > 0) { list.Add(sb.ToString()); sb.Length = 0; }
- }
- if (sb.Length > 0) list.Add(sb.ToString());
- return list.ToArray();
- }
-
- /// 两个数字序列是否完全一致。
- private static bool NumbersEqual(string[] a, string[] b)
- {
- if (a == null || b == null) return false;
- if (a.Length != b.Length) return false;
- for (int i = 0; i < a.Length; i++)
- if (a[i] != b[i]) return false;
- return true;
- }
-
- ///
- /// 数字序列兼容(子序列检查):短方的数字按顺序都能在长方中找到即通过。
- /// ★ 用于 L2 包含关系:一方文本是另一方的一部分,数字自然也可能少
- /// (如图纸只写 HD13BX-1500/31,库里是 HD13BX-1500/31 1500A)。
- /// ★ 依然防误配:63A vs 100A 时 63 不在对方序列对应位置,拒绝。
- ///
- private static bool NumbersCompatible(string[] a, string[] b)
- {
- if (a == null || b == null) return false;
- string[] shorter = a.Length <= b.Length ? a : b;
- string[] longer = a.Length <= b.Length ? b : a;
- if (longer.Length == 0) return shorter.Length == 0;
- int i = 0;
- foreach (string n in longer)
- {
- if (i < shorter.Length && n == shorter[i]) i++;
- }
- return i == shorter.Length;
- }
-
- ///
- /// 数字序列严格相等 + 两种容错(L3 模糊匹配用):
- /// 1.粘连拆分:图纸连写导致数字粘连(如 0.66+1500 提取出 661500),拆成两段后对上即通过;
- /// 2.壳架容错:图纸把额定电流写进型号段(如 HYW1-2500/3P 2500A,2500出现两次),
- /// 库里型号段是壳架等级(HYW1-3200),删掉图纸型号段那个数字后能对上即通过。
- /// ★ 仅当该数字在图纸中出现≥2次才允许删,220V/380V 这类无重复差异依然拒绝。
- ///
- private static bool NumbersEqualEx(string[] a, string[] b)
- {
- if (a == null || b == null) return false;
- if (NumbersEqual(a, b)) return true;
- // 容错1:粘连拆分
- if (TrySplitAndCompatible(a, b)) return true;
- if (TrySplitAndCompatible(b, a)) return true;
- // 容错2:壳架(删图纸中重复出现的电流数字之一)
- if (TryDropFrameCurrent(a, b)) return true;
- if (TryDropFrameCurrent(b, a)) return true;
- return false;
- }
-
- ///
- /// 壳架容错:seq 中存在出现≥2次的数字 X,删掉其中一次后作为子序列能对上 other。
- /// 典型:图纸 HYW1-2500/3P 2500A(2500×2) vs 库 HYW1-3200/3P 2500A(3200×1,2500×1)。
- ///
- private static bool TryDropFrameCurrent(string[] seq, string[] other)
- {
- for (int i = 0; i < seq.Length; i++)
- {
- string s = seq[i];
- if (s == null || s.Length < 2) continue;
- // 该数字必须在 seq 中出现≥2次(型号段+电流段重复)
- int cnt = 0;
- foreach (string n in seq) if (n == s) cnt++;
- if (cnt < 2) continue;
- // 删掉第 i 个,其余保持顺序
- var list = new List(seq.Length - 1);
- for (int k = 0; k < seq.Length; k++)
- if (k != i) list.Add(seq[k]);
- if (NumbersCompatible(list.ToArray(), other)) return true;
- }
- return false;
- }
-
- /// 把 seq 中某个数字串拆成两段,拆分后作为子序列能对上 other 即返回 true。
- private static bool TrySplitAndCompatible(string[] seq, string[] other)
- {
- for (int i = 0; i < seq.Length; i++)
- {
- string s = seq[i];
- if (s == null || s.Length < 2) continue;
- for (int cut = 1; cut < s.Length; cut++)
- {
- var list = new List(seq.Length + 1);
- for (int k = 0; k < seq.Length; k++)
- {
- if (k == i)
- {
- list.Add(s.Substring(0, cut));
- list.Add(s.Substring(cut));
- }
- else list.Add(seq[k]);
- }
- if (NumbersCompatible(list.ToArray(), other)) return true;
- }
- }
- return false;
- }
-
- ///
- /// 提取字母骨架:去数字、去分隔符、去尾部单位词(A/V/kA 等)。
- /// ★ 用于图纸省略壳架等级的场景:DZ47-4P/C80A 与 DZ47-100 4P C80
- /// 骨架同为 DZPC,配合数字子序列保护可安全匹配。
- ///
- private static string ExtractSkeleton(string spec)
- {
- if (string.IsNullOrEmpty(spec)) return "";
- string light = NormalizeKeepSeparators(spec);
- var sb = new System.Text.StringBuilder();
- for (int i = 0; i < light.Length; i++)
- {
- char c = light[i];
- if (c >= 'A' && c <= 'Z')
- {
- // 单位词必须紧跟在数字后面才有效(如 80A、450V);
- // 6L2-V 的 V 前面是分隔符,属于型号的一部分,不能截断
- bool prevIsDigit = i > 0 && light[i - 1] >= '0' && light[i - 1] <= '9';
- if (prevIsDigit && IsTailUnit(light.Substring(i))) break;
- sb.Append(c);
- }
- // 数字、分隔符、中文等其他字符全部跳过
- }
- return sb.ToString();
- }
-
- /// 判断剩余部分是否为纯尾部单位词(如 "A"、"80A" 里的 A、"0~450V" 里的 V)。
- private static bool IsTailUnit(string rest)
- {
- if (string.IsNullOrEmpty(rest)) return false;
- string r = rest.Trim();
- if (r.Length > 2) return false; // 单位最多2字符(HZ/KA/KW/VA)
- return r == "A" || r == "V" || r == "W" || r == "VA" || r == "HZ" || r == "KA" || r == "KW";
- }
-
- /// Levenshtein 编辑距离(滚动数组实现)。
- private static int LevenshteinDistance(string a, string b)
- {
- if (string.IsNullOrEmpty(a)) return string.IsNullOrEmpty(b) ? 0 : b.Length;
- if (string.IsNullOrEmpty(b)) return a.Length;
- int n = a.Length, m = b.Length;
- int[] prev = new int[m + 1];
- int[] cur = new int[m + 1];
- for (int j = 0; j <= m; j++) prev[j] = j;
- for (int i = 1; i <= n; i++)
- {
- cur[0] = i;
- for (int j = 1; j <= m; j++)
- {
- int cost = (a[i - 1] == b[j - 1]) ? 0 : 1;
- int v1 = prev[j] + 1;
- int v2 = cur[j - 1] + 1;
- int v3 = prev[j - 1] + cost;
- cur[j] = Math.Min(v1, Math.Min(v2, v3));
- }
- int[] tmp = prev; prev = cur; cur = tmp;
- }
- return prev[m];
- }
-
- ///
- /// 规格匹配元件名称(模糊):
- /// L1 归一化后完全相等 → 直接命中;
- /// L2 包含关系(短方长度≥长方60%,数字序列一致);
- /// L3 编辑距离相似度≥0.70(数字序列必须完全一致,唯一最高分才命中)。
- /// 都不中返回 null(不硬猜)。
- ///
- ///
- /// 粘连清洗:扒图可能把相邻文本粘连(如 "0mAVigiC65N-...")。
- /// 若文本开头是"数字+单位(mA/A/V/W)"且后面紧跟大写字母开头的型号,
- /// 从型号处截取;否则原样返回。
- ///
- private static string CleanLeadingNoise(string spec)
- {
- if (string.IsNullOrEmpty(spec)) return spec;
- string s = spec.Trim();
-
- // ★ 先剥"数量×"前缀:如 "3xLMZ1-0.5" → "LMZ1-0.5"、"2×AD16" → "AD16"
- // (图纸常在型号前写元件数量,3x=3只)
- if (s.Length > 2)
- {
- char c0 = s[0];
- if (c0 >= '0' && c0 <= '9')
- {
- int i = 0;
- while (i < s.Length && s[i] >= '0' && s[i] <= '9') i++;
- if (i < s.Length && (s[i] == 'x' || s[i] == 'X' || s[i] == '×' || s[i] == '*'))
- {
- int after = i + 1;
- if (after < s.Length && s[after] >= 'A' && s[after] <= 'Z')
- return s.Substring(after);
- }
- }
- }
-
- // 找开头最长的"数字(可含小数点)+单位"模式
- int j = 0;
- while (j < s.Length && ((s[j] >= '0' && s[j] <= '9') || s[j] == '.')) j++;
- if (j == 0 || j >= s.Length) return spec; // 开头不是数字
- // 单位段(1~3个字母)
- int u = j;
- while (u < s.Length && u - j <= 3 && s[u] >= 'A' && s[u] <= 'z') u++;
- if (u == j || u >= s.Length) return spec; // 没有单位或后面没内容
- string unit = s.Substring(j, u - j).ToUpperInvariant();
- if (unit != "MA" && unit != "A" && unit != "V" && unit != "W" && unit != "KW" && unit != "HZ") return spec;
- // 单位后必须紧跟大写字母(型号开头)
- char next = s[u];
- if (next < 'A' || next > 'Z') return spec;
- return s.Substring(u); // 从型号处截取
- }
-
- // ★ 匹配结果缓存:同一规格文本(一批框选里重复文本很常见)只完整跑一次 L0-L5。
- // L3 会按库逐条算编辑距离(库大时是 CPU 热点),缓存能直接砍掉重复计算。
- private static readonly System.Collections.Generic.Dictionary _specMatchCache =
- new System.Collections.Generic.Dictionary(System.StringComparer.Ordinal);
- private static readonly object _specMatchCacheLock = new object();
-
- /// 规格匹配元件名称(带结果缓存):相同规格文本第二次起直接返回缓存结果。
- private static string MatchSpecName(string spec)
- {
- if (string.IsNullOrWhiteSpace(spec)) return null;
- string cached;
- lock (_specMatchCacheLock)
- {
- if (_specMatchCache.TryGetValue(spec, out cached)) return cached;
- }
- string result = MatchSpecNameCore(spec);
- lock (_specMatchCacheLock)
- {
- // 上限保护:超过2万条清空重来(规格文本总量有限,防内存无限增长)
- if (_specMatchCache.Count > 20000) _specMatchCache.Clear();
- _specMatchCache[spec] = result;
- }
- return result;
- }
-
- private static string MatchSpecNameCore(string spec)
- {
- if (string.IsNullOrWhiteSpace(spec)) return null;
-
- // ★ 粘连清洗:扒图可能把相邻文本粘连(如 "0mAVigiC65N-...")。
- // 若文本前部含"数字+单位(mA/A/V)"后跟已知型号,从型号处截取
- spec = CleanLeadingNoise(spec);
-
- EnsureUserLibCsvLoaded();
- if (_specNameLib == null || _specNameLib.Count == 0) return null;
-
- string norm = NormalizeSpec(spec);
- if (norm.Length == 0) return null;
- string[] nums = ExtractNumbers(spec);
-
- string result = null;
- string via = "none";
-
- // L0: 型号前缀规则(本地权威,最优先,覆盖国标型号命名体系)
- string ruleName = MatchByPrefixRule(spec);
- if (ruleName != null)
- {
- WriteDebugLog("[用户库匹配] 「" + spec + "」 → " + ruleName + " via L0规则");
- return ruleName;
- }
-
- // L0.5: JB/T 2930 国标类组代号(官方定义:前2位字母=品类代号)
- string gbName = MatchByGbCode(spec);
- if (gbName != null)
- {
- WriteDebugLog("[用户库匹配] 「" + spec + "」 → " + gbName + " via L0.5国标");
- return gbName;
- }
-
- // L1: 归一化后完全相等
- foreach (var e in _specNameLib)
- {
- if (e.NormSpec == norm) { result = e.Name; via = "L1相等"; break; }
- }
-
- // L2: 包含关系(如图纸只写型号主体,库里有完整版)
- if (result == null)
- {
- foreach (var e in _specNameLib)
- {
- if (e.NormSpec.Length == 0) continue;
- bool contains = e.NormSpec.Contains(norm) || norm.Contains(e.NormSpec);
- if (!contains) continue;
- int shortLen = Math.Min(e.NormSpec.Length, norm.Length);
- int longLen = Math.Max(e.NormSpec.Length, norm.Length);
- if (longLen == 0 || (double)shortLen / longLen < 0.6) continue;
- if (!NumbersCompatible(nums, e.Numbers)) continue; // ★ 数字子序列兼容(允许少,不允许错)
- result = e.Name; via = "L2包含"; break;
- }
- }
-
- // L3: 编辑距离模糊匹配(字母/符号容错,数字绝对不放过)
- if (result == null)
- {
- string bestName = null;
- double bestScore = 0.0;
- int bestCount = 0;
- foreach (var e in _specNameLib)
- {
- if (e.NormSpec.Length == 0) continue;
- if (!NumbersEqualEx(nums, e.Numbers)) continue; // ★ 数字一致(含粘连拆分容错)
- // ★ 长度差剪枝:编辑距离 ≥ 长度差,长度差已超过 0.30×maxLen 时
- // score 必然 < 0.70,直接跳过(编辑距离是 O(m×n),库里条目多时全算是卡顿热点)
- int maxLen = Math.Max(norm.Length, e.NormSpec.Length);
- if (Math.Abs(norm.Length - e.NormSpec.Length) * 10 > maxLen * 3) continue;
- int dist = LevenshteinDistance(norm, e.NormSpec);
- double score = 1.0 - (double)dist / maxLen;
- if (score >= 0.70)
- {
- if (score > bestScore + 0.0001) { bestScore = score; bestName = e.Name; bestCount = 1; }
- else if (Math.Abs(score - bestScore) <= 0.0001 && bestName != e.Name) bestCount++;
- }
- }
- if (bestCount == 1 && bestName != null) { result = bestName; via = "L3模糊"; }
- }
-
- // L4: 字母骨架匹配(图纸省略壳架等级的场景)
- // DZ47-4P/C80A 与 DZ47-100 4P C80:骨架同为 DZPC,
- // 且图纸数字 [47,4,80] 是库数字 [47,100,4,80] 的子序列 → 命中
- if (result == null)
- {
- string skel = ExtractSkeleton(spec);
- if (skel.Length >= 3)
- {
- string bestName = null;
- int bestLen = int.MaxValue;
- foreach (var e in _specNameLib)
- {
- if (e.Skeleton == null || e.Skeleton.Length < 3) continue;
- if (e.Skeleton != skel) continue;
- if (!NumbersCompatible(nums, e.Numbers)) continue; // ★ 数字子序列保护
- // 多条同骨架时取数字数量最接近的
- int diff = Math.Abs(nums.Length - e.Numbers.Length);
- if (diff < bestLen) { bestLen = diff; bestName = e.Name; }
- }
- if (bestName != null) { result = bestName; via = "L4骨架"; }
- }
- }
-
- // L5: 大电流启发式(最后兜底)
- // 框架级特征:数字≥1600 + 3P/4P + 型号含W(万能式标记) → 万能式/智能断路器
- if (result == null)
- {
- string sUp = spec.Trim().ToUpperInvariant();
- bool hasBig = false;
- foreach (string n in nums)
- {
- long v;
- if (long.TryParse(n, out v) && v >= 1600 && v <= 6300) { hasBig = true; break; }
- }
- bool hasPole = sUp.Contains("/3P") || sUp.Contains("/4P") || sUp.Contains(" 3P") || sUp.Contains(" 4P") ||
- sUp.EndsWith("3P") || sUp.EndsWith("4P");
- bool hasW = sUp.IndexOf('W') >= 0;
- if (hasBig && hasPole && hasW)
- {
- // 含 I/E(智能型标记,如 HUWI/CW1I) → 智能断路器
- bool hasSmart = sUp.IndexOf('I') >= 0 || sUp.IndexOf('E') >= 0;
- result = hasSmart ? "智能断路器" : "万能式断路器";
- via = "L5大电流启发";
- }
- }
-
- // ★ 匹配日志:输入/归一化/数字序列/结果,失败可从日志直接定位原因
- WriteDebugLog("[用户库匹配] 「" + spec + "」 norm=" + norm +
- " nums=[" + string.Join(",", nums) + "] → " +
- (result == null ? "(未匹配)" : result + " via " + via));
- return result;
- }
-
- // ============================================================
- // DeepSeek AI 智能匹配(本地匹配失败后的兜底)
- // · 设置窗口填 API Key,存插件目录 deepseek.json
- // · 扒元件后本地未命中的规格批量提交 AI 识别元器件名称
- // · 结果缓存到 deepseek_cache.json(同规格只问一次)
- // · AI 结果回填元件表"元件名称"列
- // ============================================================
-
- private string DeepSeekConfigPath { get { return GetDbFullPath("deepseek.json"); } }
- private string DeepSeekCachePath { get { return GetDbFullPath("deepseek_cache.json"); } }
-
- /// DeepSeek 设置(加载/保存 JSON)
- private class DeepSeekConfig
- {
- public string ApiKey = "";
- public string BaseUrl = "https://api.deepseek.com";
- public string Model = "deepseek-v4-flash"; // ★ 支持联网搜索的模型
- public bool Enabled = false;
- public bool WebSearch = true; // ★ 联网搜索(罕见型号也能查)
- }
-
- private DeepSeekConfig _dsConfig;
- private System.Collections.Hashtable _dsCache;
-
- private DeepSeekConfig LoadDsConfig()
- {
- if (_dsConfig != null) return _dsConfig;
- var cfg = new DeepSeekConfig();
- try
- {
- if (File.Exists(DeepSeekConfigPath))
- {
- string json = File.ReadAllText(DeepSeekConfigPath, System.Text.Encoding.UTF8);
- var map = SimpleJsonParse(json);
- if (map.ContainsKey("ApiKey")) cfg.ApiKey = (string)map["ApiKey"] ?? "";
- if (map.ContainsKey("BaseUrl")) cfg.BaseUrl = (string)map["BaseUrl"] ?? "https://api.deepseek.com";
- if (map.ContainsKey("Model")) cfg.Model = (string)map["Model"] ?? "deepseek-v4-flash";
- // ★ 布尔值无引号,解析出的 val 可能带换行/空格前缀,比较前必须 Trim
- if (map.ContainsKey("Enabled")) cfg.Enabled = ((string)map["Enabled"] ?? "").Trim() == "true";
- if (map.ContainsKey("WebSearch")) cfg.WebSearch = ((string)map["WebSearch"] ?? "").Trim() != "false";
- // ★ 旧模型(deepseek-chat 不支持联网)自动迁移到 v4
- if (cfg.Model == "deepseek-chat" || cfg.Model == "deepseek-reasoner") cfg.Model = "deepseek-v4-flash";
- }
- }
- catch { }
- _dsConfig = cfg;
- return cfg;
- }
-
- private void SaveDsConfig(DeepSeekConfig cfg)
- {
- try
- {
- string json = "{\n" +
- " \"ApiKey\": \"" + (cfg.ApiKey ?? "").Replace("\"", "\\\"") + "\",\n" +
- " \"BaseUrl\": \"" + (cfg.BaseUrl ?? "").Replace("\"", "\\\"") + "\",\n" +
- " \"Model\": \"" + (cfg.Model ?? "").Replace("\"", "\\\"") + "\",\n" +
- " \"Enabled\": " + (cfg.Enabled ? "true" : "false") + ",\n" +
- " \"WebSearch\": " + (cfg.WebSearch ? "true" : "false") + "\n" +
- "}";
- File.WriteAllText(DeepSeekConfigPath, json, System.Text.Encoding.UTF8);
- _dsConfig = cfg;
- }
- catch (Exception ex) { Log("[DeepSeek配置] 保存失败: " + ex.Message); }
- }
-
- /// AI 匹配缓存:规格 → 元件名称(未命中/失败也缓存,避免反复请求)
- private System.Collections.Hashtable LoadDsCache()
- {
- if (_dsCache != null) return _dsCache;
- var ht = new System.Collections.Hashtable();
- try
- {
- if (File.Exists(DeepSeekCachePath))
- {
- string json = File.ReadAllText(DeepSeekCachePath, System.Text.Encoding.UTF8);
- var map = SimpleJsonParse(json);
- foreach (System.Collections.DictionaryEntry kv in map)
- ht[kv.Key.ToString()] = (kv.Value ?? "").ToString();
- }
- }
- catch { }
- _dsCache = ht;
- return ht;
- }
-
- private void SaveDsCache()
- {
- if (_dsCache == null) return;
- try
- {
- var sb = new System.Text.StringBuilder("{\n");
- bool first = true;
- foreach (System.Collections.DictionaryEntry kv in _dsCache)
- {
- if (!first) sb.Append(",\n");
- sb.Append(" \"" + kv.Key.ToString().Replace("\"", "\\\"") + "\": \"" +
- kv.Value.ToString().Replace("\"", "\\\"") + "\"");
- first = false;
- }
- sb.Append("\n}");
- File.WriteAllText(DeepSeekCachePath, sb.ToString(), System.Text.Encoding.UTF8);
- }
- catch (Exception ex) { Log("[DeepSeek缓存] 保存失败: " + ex.Message); }
- }
-
- /// 极简 JSON 解析(扁平 key:value 结构,支持字符串/数字/布尔值)
- private static System.Collections.Hashtable SimpleJsonParse(string json)
- {
- var ht = new System.Collections.Hashtable();
- if (string.IsNullOrEmpty(json)) return ht;
- int depth = 0; bool inStr = false;
- var key = new System.Text.StringBuilder();
- var val = new System.Text.StringBuilder();
- bool inKey = true;
- for (int i = 0; i < json.Length; i++)
- {
- char c = json[i];
- if (inStr)
- {
- if (c == '\\' && i + 1 < json.Length) { val.Append(json[i + 1]); i++; continue; }
- if (c == '"') { inStr = false; continue; }
- (inKey ? key : val).Append(c);
- continue;
- }
- if (c == '"') { inStr = true; continue; }
- if (c == '{' || c == '[') { depth++; continue; }
- if (c == '}' || c == ']')
- {
- // ★ 闭合括号收掉最后一个键值对(布尔值结尾无逗号)
- if (depth == 1 && key.Length > 0)
- {
- ht[key.ToString()] = val.ToString().Trim();
- key.Length = 0; val.Length = 0; inKey = true;
- }
- depth--; continue;
- }
- if (c == ':' && depth == 1) { inKey = false; val.Length = 0; continue; }
- if (c == ',' && depth == 1)
- {
- if (key.Length > 0) ht[key.ToString()] = val.ToString().Trim();
- key.Length = 0; val.Length = 0; inKey = true;
- continue;
- }
- // ★ 无引号值(true/false/数字)必须累积,否则解析成空
- if (!inKey && !char.IsWhiteSpace(c)) val.Append(c);
- }
- if (key.Length > 0) ht[key.ToString()] = val.ToString().Trim();
- return ht;
- }
-
- // ============================================================
- // 电器型号前缀规则(与用户库共用同一个 CSV 数据文件)
- // ★ 用户库 CSV 中"元件类型"列 = "前缀" 的行即为前缀规则:
- // 隔离开关,HGL,只,1,0,1,1,规则,0,前缀
- // (元件名称列=名称,规格列=型号前缀)
- // ★ Excel 里直接编辑用户库即可增删规则,随库自动重载
- // ★ 规则结果与 AI 冲突时,以规则为准(根治 AI 误判)
- // ============================================================
-
- private static List _prefixRules = new List();
-
- /// 内置最小规则集(仅当用户库无任何前缀行时兜底)。
- private static readonly string[,] s_BuiltinPrefixRules =
- {
- { "HGL", "隔离开关" }, { "DZ47", "小型断路器" }, { "NM1", "塑壳断路器" },
- { "CJX2", "交流接触器" }, { "RT16", "熔断器" }, { "LMZ", "电流互感器" },
- };
-
- // ============================================================
- // ★ JB/T 2930 国标类组代号表(低压电器型号编制方法的官方定义)
- // 国标型号前2位字母=品类代号:第1位类别+第2位组别。
- // 在前缀规则(L0)之后、CSV 库(L1)之前执行,覆盖所有国标型号。
- // ============================================================
- private static readonly System.Collections.Hashtable s_GbClassCodes = new System.Collections.Hashtable(StringComparer.OrdinalIgnoreCase)
- {
- // H 刀开关/隔离开关族
- { "HD", "隔离开关" }, // 单投刀开关
- { "HS", "隔离开关" }, // 双投刀开关(转换)
- { "HR", "隔离开关" }, // 熔断器式刀开关
- { "HH", "隔离开关" }, // 封闭式负荷开关
- { "HK", "隔离开关" }, // 开启式负荷开关(胶盖闸)
- { "HZ", "转换开关" }, // 组合开关
- { "HG", "隔离开关" }, // 熔断器式隔离器(另:HG1/HG13)
- // R 熔断器族
- { "RC", "熔断器" }, // 插入式
- { "RL", "熔断器" }, // 螺旋式(RL6/RL8)
- { "RM", "熔断器" }, // 密封管式
- { "RS", "快速熔断器" }, // 快速(RS0/RS3)
- { "RT", "熔断器" }, // 有填料管式(RT0/RT16/RT18)
- { "RX", "熔断器" }, // 限流
- { "RTO", "熔断器" },
- // D 断路器族
- { "DW", "万能式断路器" }, // 框架式(DW15/DW45)
- { "DZ", "塑壳断路器" }, // 装置式/塑料外壳(DZ15/DZ20)
- { "DX", "小型断路器" },
- { "DM", "塑壳断路器" },
- { "DC", "断路器" },
- // C 接触器族
- { "CJ", "交流接触器" }, // 交流(CJ20/CJX)
- { "CZ", "直流接触器" }, // 直流
- { "CG", "接触器" }, // 高压
- { "CP", "接触器" }, // 中频
- { "CS", "接触器" }, // 时间
- // Q 起动器族
- { "QC", "电磁起动器" }, { "QS", "手动起动器" }, { "QX", "星三角起动器" },
- { "QJ", "自耦减压起动器" }, { "QT", "起动器" }, { "QU", "起动器" },
- // J 控制继电器族
- { "JL", "电流继电器" }, { "JR", "热过载继电器" }, { "JS", "时间继电器" },
- { "JT", "通用继电器" }, { "JW", "温度继电器" }, { "JZ", "中间继电器" },
- { "JX", "继电器" },
- // L 主令电器族
- { "LA", "按钮" }, // 按钮(LA38/LA39)
- { "LK", "主令控制器" }, { "LT", "主令开关" }, { "LW", "转换开关" },
- { "LX", "行程开关" }, { "LU", "足踏开关" }, { "LS", "主令开关" },
- // Z 电阻/终端族
- { "ZB", "电阻器" }, { "ZG", "电阻器" }, { "ZC", "电阻器" },
- // B 变阻器族
- { "BL", "励磁变阻器" }, { "BP", "频敏变阻器" }, { "BQ", "起动变阻器" },
- { "BT", "变阻器" }, { "BC", "旋臂变阻器" },
- // M 电磁铁族
- { "MQ", "牵引电磁铁" }, { "MZ", "制动电磁铁" }, { "MW", "起重电磁铁" },
- // A 其他族
- { "AD", "指示灯" }, // 信号灯(AD11/AD16 习惯用)
- { "AN", "按钮" },
- // P 仪用互感器(行业习惯,P 不在 JB/T2930 主表,单列)
- { "LQG", "电流互感器" },
- // 变压器(控制变压器 BK 不在 JB/T2930,行业通用)
- { "BK", "控制变压器" },
- };
-
- ///
- /// ★ 国标类组代号解析:按 JB/T 2930 定义,取型号前2位字母查类组表。
- /// 仅当:①前缀规则未命中 ②开头≥2位字母 ③类组表命中 时返回名称。
- /// 数字开头/单字母/进口品牌型号不适用(返回 null 交给后续层)。
- ///
- private static string MatchByGbCode(string spec)
- {
- if (string.IsNullOrWhiteSpace(spec)) return null;
- string s = spec.Trim();
- // 前2位必须是字母(国标类组代号为2位拼音)
- if (s.Length < 3) return null;
- if (!((s[0] >= 'A' && s[0] <= 'Z') || (s[0] >= 'a' && s[0] <= 'z'))) return null;
- if (!((s[1] >= 'A' && s[1] <= 'Z') || (s[1] >= 'a' && s[1] <= 'z'))) return null;
- // 第3位应是数字或分隔符(确认是类组代号+设计序号结构,排除品牌词)
- if (s.Length > 2)
- {
- char c2 = s[2];
- bool ok = (c2 >= '0' && c2 <= '9') || c2 == '-' || c2 == ' ' || c2 == '/';
- if (!ok) return null;
- }
- string code = s.Substring(0, 2).ToUpperInvariant();
- object v = s_GbClassCodes[code];
- return v as string;
- }
-
- ///
- /// 按型号前缀规则查元器件名称。
- /// ★ 规则来自用户库 CSV"元件类型=前缀"的行(EnsureUserLibCsvLoaded 时提取),
- /// 规则前缀直接与规格开头比对(支持字母+数字混合前缀,如 DZ47/CDM3/CJX2),
- /// 最长前缀优先(7→2字符)。
- /// 返回 null 表示无规则。
- ///
- private static string MatchByPrefixRule(string spec)
- {
- if (string.IsNullOrWhiteSpace(spec)) return null;
- string s = spec.Trim().ToUpperInvariant();
- if (s.Length < 2) return null;
-
- var rules = _prefixRules;
- if (rules.Count == 0)
- {
- // 用户库无前缀行 → 内置兜底
- for (int i = 0; i < s_BuiltinPrefixRules.GetLength(0); i++)
- rules.Add(new[] { s_BuiltinPrefixRules[i, 0], s_BuiltinPrefixRules[i, 1] });
- _prefixRules = rules;
- }
-
- for (int plen = 7; plen >= 2; plen--)
- {
- if (s.Length < plen) continue;
- string head = s.Substring(0, plen);
- foreach (var rule in rules)
- {
- if (rule[0].Length != plen || rule[0] != head) continue;
- return rule[1];
- }
- }
- return null;
- }
-
- /// 打开 DeepSeek 设置窗口(运行时创建,不改 ui.cs)
- private void ShowDeepSeekSettings()
- {
- var cfg = LoadDsConfig();
- var form = new System.Windows.Forms.Form();
- form.Text = "DeepSeek AI 匹配设置";
- form.Size = new System.Drawing.Size(420, 260);
- form.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
- form.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
- form.MaximizeBox = false; form.MinimizeBox = false;
-
- var lblKey = new System.Windows.Forms.Label { Text = "API Key:", Location = new System.Drawing.Point(15, 18), AutoSize = true };
- var txtKey = new System.Windows.Forms.TextBox
- {
- Location = new System.Drawing.Point(80, 15), Size = new System.Drawing.Size(310, 23),
- Text = cfg.ApiKey, UseSystemPasswordChar = true
- };
- var chkShow = new System.Windows.Forms.CheckBox
- {
- Text = "显示密钥", Location = new System.Drawing.Point(80, 44), AutoSize = true
- };
- chkShow.CheckedChanged += (s2, e2) => txtKey.UseSystemPasswordChar = !chkShow.Checked;
-
- var lblModel = new System.Windows.Forms.Label { Text = "模型:", Location = new System.Drawing.Point(15, 78), AutoSize = true };
- var cboModel = new System.Windows.Forms.ComboBox
- {
- Location = new System.Drawing.Point(80, 74), Size = new System.Drawing.Size(180, 23),
- DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
- };
- cboModel.Items.Add("deepseek-v4-flash");
- cboModel.Items.Add("deepseek-v4-pro");
- cboModel.Items.Add("deepseek-chat");
- cboModel.SelectedItem = string.IsNullOrEmpty(cfg.Model) ? "deepseek-v4-flash" : cfg.Model;
-
- var chkEnable = new System.Windows.Forms.CheckBox
- {
- Text = "启用 AI 匹配(本地匹配失败后自动提交 DeepSeek 识别)",
- Location = new System.Drawing.Point(15, 108), AutoSize = true, Checked = cfg.Enabled
- };
-
- var lblTip = new System.Windows.Forms.Label
- {
- Text = "提示:AI 结果会缓存到本地,相同规格只请求一次。\nAPI Key 从 platform.deepseek.com 获取。",
- Location = new System.Drawing.Point(15, 138), AutoSize = true, ForeColor = System.Drawing.Color.Gray
- };
-
- var btnClear = new System.Windows.Forms.Button { Text = "清空AI缓存", Location = new System.Drawing.Point(80, 178), Size = new System.Drawing.Size(100, 28) };
- btnClear.Click += (s2, e2) =>
- {
- try { if (File.Exists(DeepSeekCachePath)) File.Delete(DeepSeekCachePath); _dsCache = null; }
- catch { }
- MessageBox.Show(form, "AI 缓存已清空。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
- };
-
- var btnOk = new System.Windows.Forms.Button { Text = "保存", Location = new System.Drawing.Point(240, 178), Size = new System.Drawing.Size(75, 28) };
- var btnCancel = new System.Windows.Forms.Button { Text = "取消", Location = new System.Drawing.Point(325, 178), Size = new System.Drawing.Size(75, 28) };
-
- btnOk.Click += (s2, e2) =>
- {
- cfg.ApiKey = txtKey.Text.Trim();
- cfg.Model = cboModel.SelectedItem == null ? "deepseek-v4-flash" : cboModel.SelectedItem.ToString();
- cfg.Enabled = chkEnable.Checked && cfg.ApiKey.Length > 0;
- SaveDsConfig(cfg);
- form.Close();
- };
- btnCancel.Click += (s2, e2) => form.Close();
-
- form.Controls.AddRange(new System.Windows.Forms.Control[] { lblKey, txtKey, chkShow, lblModel, cboModel, chkEnable, lblTip, btnClear, btnOk, btnCancel });
- form.ShowDialog(this);
- }
-
- ///
- /// 调 DeepSeek API 批量识别规格对应的元器件名称。
- /// 返回 规格→名称 的哈希表(失败的规格不在结果里)。
- ///
- private System.Collections.Hashtable CallDeepSeekMatch(List specs)
- {
- var result = new System.Collections.Hashtable();
- var cfg = LoadDsConfig();
- if (!cfg.Enabled || string.IsNullOrWhiteSpace(cfg.ApiKey)) return result;
-
- // 构造提问:证据链推理法(查厂商→确认型号→按厂商定义归类)
- var sb = new System.Text.StringBuilder();
- sb.Append("你是低压电器型号识别专家,精通 JB/T 2930《低压电器产品型号编制方法》。为每个规格型号返回【元器件名称】(中文标准品类词)。\n\n");
- sb.Append("【推理方法】(对每个型号按证据链三步走,不要直接猜):\n");
- sb.Append("第1步·识别厂商:从型号前缀判断是哪家厂(如 HUWI→沪工/环宇系、NM→正泰、CDM→德力西、CM→常熟、CW→常熟框架、SZRM→上海人民、XBK→湘湖/新宝凯、QAM→七仪);\n");
- sb.Append("第2步·确认系列:该厂商的此系列号是否存在、属于什么产品线(用你的产品知识回忆厂商型录:如 HUWI=沪工智能型万能式、YLEM=某厂智能框架、BM3=塑壳);\n");
- sb.Append("第3步·按厂商定义归类:厂商型录里该系列挂哪个品类就答什么,不要凭字母表面猜。\n\n");
- sb.Append("【辅助规律】(第2步无记忆时用):\n");
- sb.Append("· 国标类组:前2位字母=品类(DW万能断路器/DZ塑壳/CJ交流接触器/JR热继/LA按钮/HD-HS-HR隔离开关/RT熔断器);\n");
- sb.Append("· 结构特征:电流≥1600A+3P/4P+含W → 框架级(万能式/智能断路器);壳架≤630A+3P → 塑壳;63A以下+1P/2P → 微型;\n");
- sb.Append("· 派生代号:L/E=漏电或电子式,I=智能型,Z=直流/智能,N=可逆;\n");
- sb.Append("· 进口系列:施耐德(NSX/iC65/Vigi/LC1/LR)、ABB(S/SH)、西门子(3RT/5SL)、伊顿(IS)。\n\n");
- sb.Append("【输出格式】(严格遵守):\n");
- sb.Append("只返回纯 JSON 对象 {\"规格原文\":\"元器件名称\",...},不要任何解释、思考过程或其他文字;\n");
- sb.Append("每个规格都必须给出判断:按证据链推理,无法确认厂商和系列时按结构特征推断,实在无据可依才给空字符串;\n");
- sb.Append("名称用标准品类词:万能式断路器/智能断路器/塑壳断路器/小型断路器/漏电断路器/交流接触器/直流接触器/热过载继电器/时间继电器/中间继电器/电流互感器/电压互感器/熔断器/快速熔断器/隔离开关/负荷开关/转换开关/按钮/指示灯/行程开关/双电源/电磁起动器/自耦减压起动器/控制变压器/干式变压器/电涌保护器/电容器/电能表/软启动器/变频器等。\n");
- sb.Append("规格列表:\n");
- for (int i = 0; i < specs.Count; i++)
- sb.Append((i + 1) + ". " + specs[i] + "\n");
-
- try
- {
- // ★ 纯AI知识模式:chat/completions(不走联网搜索,快且稳)
- // deepseek-v4 系列是思考模型:正式回答在 content,思考过程在 reasoning_content;
- // 有时 content 空、答案藏在 reasoning_content 末尾 → 两处都提取
- string body = "{" +
- "\"model\":\"" + cfg.Model + "\"," +
- "\"messages\":[" +
- "{\"role\":\"user\",\"content\":\"" + JsonEscape(sb.ToString()) + "\"}" +
- "]," +
- "\"temperature\":0.1," +
- "\"max_tokens\":3000" +
- "}";
-
- string url = (cfg.BaseUrl ?? "https://api.deepseek.com").TrimEnd('/') + "/chat/completions";
- var req = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url);
- req.Method = "POST";
- req.ContentType = "application/json";
- req.Headers.Add("Authorization", "Bearer " + cfg.ApiKey);
- req.Timeout = 60000; // 60秒
- req.ReadWriteTimeout = 60000;
- req.Proxy = null; // ★ 不走系统代理(防代理环境卡死)
- byte[] data = System.Text.Encoding.UTF8.GetBytes(body);
- req.ContentLength = data.Length;
- Log("[DeepSeek] 发起请求: " + specs.Count + " 条规格(AI知识模式), url=" + url);
- using (var rs = req.GetRequestStream()) rs.Write(data, 0, data.Length);
-
- string respText;
- using (var resp = (System.Net.HttpWebResponse)req.GetResponse())
- using (var sr = new StreamReader(resp.GetResponseStream(), System.Text.Encoding.UTF8))
- respText = sr.ReadToEnd();
- Log("[DeepSeek] 响应长度: " + respText.Length + " 字符");
-
- // 从响应提取 content(手工解析,取 choices[0].message.content)
- string content = ExtractJsonContent(respText);
- if (string.IsNullOrEmpty(content))
- {
- Log("[DeepSeek] 响应解析失败: " + (respText.Length > 400 ? respText.Substring(0, 400) : respText));
- return result;
- }
- // ★ 诊断:AI原始输出(排查"返回0条"问题,只打前400字符)
- Log("[DeepSeek] AI输出内容: " + (content.Length > 400 ? content.Substring(0, 400) + "..." : content));
- // content 里是 {"规格":"名称",...}
- // ★ 思考模型(deepseek-v4)的 content 可能为空,答案在 reasoning_content 末尾:
- // 思维链最后一般会写出最终 JSON,从 reasoning_content 里找 {...} 提取
- var map = SimpleJsonParse(content);
- if (map.Count == 0)
- {
- // 从 reasoning_content 提取最后一个完整 JSON 对象
- int rIdx = respText.IndexOf("\"reasoning_content\":\"", System.StringComparison.Ordinal);
- if (rIdx >= 0)
- {
- string reasoning = ExtractEscapedString(respText, rIdx + 21);
- int braceStart = reasoning.LastIndexOf('{');
- if (braceStart >= 0)
- {
- // 从最后一个 { 找到配对的 }
- int depth2 = 0; int end = -1;
- for (int k = braceStart; k < reasoning.Length; k++)
- {
- if (reasoning[k] == '{') depth2++;
- else if (reasoning[k] == '}')
- {
- depth2--;
- if (depth2 == 0) { end = k; break; }
- }
- }
- if (end > braceStart)
- {
- string jsonPart = reasoning.Substring(braceStart, end - braceStart + 1);
- map = SimpleJsonParse(jsonPart);
- Log("[DeepSeek] 从思维链提取到 " + map.Count + " 条结果");
- }
- }
- }
- }
- foreach (System.Collections.DictionaryEntry kv in map)
- {
- string key = kv.Key.ToString();
- string name = (kv.Value ?? "").ToString().Trim();
- if (name.Length == 0) continue;
-
- // ★ 防线:AI 结果先过本地前缀规则校验,冲突时以规则为准
- // (根治 AI 偶发误判,如把 HGL 隔离开关答成熔断器)
- string rule = MatchByPrefixRule(key);
- if (rule != null && rule != name)
- {
- Log("[DeepSeek校验] 「" + key + "」 AI答[" + name + "] 与规则冲突,已改用[" + rule + "]");
- name = rule;
- }
- result[key] = name;
- }
- Log("[DeepSeek] 识别 " + specs.Count + " 条,返回 " + result.Count + " 条结果");
- }
- catch (Exception ex)
- {
- Log("[DeepSeek] 请求失败: " + ex.Message);
- }
- return result;
- }
-
- ///
- /// 从 API 响应中提取模型输出文本。
- /// 兼容两种格式:
- /// · chat/completions: choices[0].message.content("content":"...")
- /// · responses API: output[].content[].text("text":"...")或顶层"output_text"
- ///
- private static string ExtractJsonContent(string respText)
- {
- try
- {
- // 方式1:responses API 的 "output_text":"..."
- int idx = respText.IndexOf("\"output_text\":\"", System.StringComparison.Ordinal);
- if (idx >= 0)
- {
- string s = ExtractEscapedString(respText, idx + 15);
- if (!string.IsNullOrEmpty(s)) return s;
- }
- // 方式2:responses API 的输出项文本 "text":"..."(跳过 summary/reasoning,
- // 直接找最后一个大 text——输出 message 的正文通常最大)
- int best = -1, bestLen = 0;
- int pos = 0;
- while (true)
- {
- int t = respText.IndexOf("\"text\":\"", pos, System.StringComparison.Ordinal);
- if (t < 0) break;
- // 取这个字符串的长度估算
- int len = EstimateEscapedLen(respText, t + 8);
- if (len > bestLen) { bestLen = len; best = t; }
- pos = t + 8;
- }
- if (best >= 0)
- {
- string s = ExtractEscapedString(respText, best + 8);
- if (!string.IsNullOrEmpty(s)) return s;
- }
- // 方式3:chat 的 "content":"..."
- idx = respText.IndexOf("\"content\":\"", System.StringComparison.Ordinal);
- if (idx >= 0)
- {
- return ExtractEscapedString(respText, idx + 11);
- }
- return null;
- }
- catch { return null; }
- }
-
- /// 从 start 位置读取一个 JSON 转义字符串(处理 \n \" \\ \uXXXX)。
- private static string ExtractEscapedString(string text, int start)
- {
- var sb = new System.Text.StringBuilder();
- int i = start;
- while (i < text.Length)
- {
- char c = text[i];
- if (c == '\\' && i + 1 < text.Length)
- {
- char n = text[i + 1];
- if (n == 'n') sb.Append('\n');
- else if (n == 't') sb.Append('\t');
- else if (n == 'r') sb.Append('\r');
- else if (n == '"') sb.Append('"');
- else if (n == '\\') sb.Append('\\');
- else if (n == '/' ) sb.Append('/');
- else if (n == 'u' && i + 5 < text.Length)
- {
- int code = Convert.ToInt32(text.Substring(i + 2, 4), 16);
- sb.Append((char)code);
- i += 4;
- }
- else sb.Append(n);
- i += 2;
- continue;
- }
- if (c == '"') break;
- sb.Append(c);
- i++;
- }
- return sb.ToString();
- }
-
- /// 估算 start 位置转义字符串的长度(到未转义引号为止)。
- private static int EstimateEscapedLen(string text, int start)
- {
- int i = start, len = 0;
- while (i < text.Length)
- {
- char c = text[i];
- if (c == '\\' && i + 1 < text.Length) { i += 2; len += 2; continue; }
- if (c == '"') break;
- i++; len++;
- }
- return len;
- }
-
- private static string JsonEscape(string s)
- {
- if (string.IsNullOrEmpty(s)) return "";
- var sb = new System.Text.StringBuilder();
- foreach (char c in s)
- {
- if (c == '"') sb.Append("\\\"");
- else if (c == '\\') sb.Append("\\\\");
- else if (c == '\n') sb.Append("\\n");
- else if (c == '\t') sb.Append("\\t");
- else if (c == '\r') sb.Append("");
- else sb.Append(c);
- }
- return sb.ToString();
- }
-
- ///
- /// 扒元件插入后:对本地匹配失败的规格异步调用 DeepSeek 补名称,
- /// 完成后回填数据库 + 刷新表格(UI 线程)。
- /// ★ 单飞+排队:上一个 AI 批次未完成时,后续规格累积到待办队列,
- /// 完成后一并提交(防并发互踩/请求堆积)。
- ///
- private static readonly object _aiLock = new object();
- private static bool _aiRunning = false;
- private static List _aiPendingSpecs = new List();
- private static string _aiPendingTbl = null;
-
- private void AiFillMissingNames(List failedSpecs, string tblName)
- {
- if (failedSpecs == null || failedSpecs.Count == 0) return;
- var cfg = LoadDsConfig();
- if (!cfg.Enabled || string.IsNullOrWhiteSpace(cfg.ApiKey)) return;
-
- lock (_aiLock)
- {
- // 并发防抖:AI 批次进行中 → 累积到待办,由运行中的批次完成后接力
- if (_aiRunning)
- {
- foreach (string sp in failedSpecs)
- if (!_aiPendingSpecs.Contains(sp)) _aiPendingSpecs.Add(sp);
- if (_aiPendingTbl == null) _aiPendingTbl = tblName;
- Log("[AI队列] 批次进行中," + failedSpecs.Count + " 条已加入待办(累计 " + _aiPendingSpecs.Count + ")");
- return;
- }
- _aiRunning = true;
- _aiPendingTbl = tblName;
- }
-
- RunAiBatch(failedSpecs, tblName);
- }
-
- /// 执行一个 AI 批次(完成后处理待办队列)。
- private void RunAiBatch(List specs, string tblName)
- {
- var bgw = new System.ComponentModel.BackgroundWorker();
- bgw.DoWork += (s, e) =>
- {
- try
- {
- // 先查缓存,未缓存的才提交 AI
- var cache = LoadDsCache();
- var toAsk = new List();
- var localHits = new System.Collections.Hashtable();
- lock (_aiLock)
- {
- foreach (string sp in specs)
- {
- if (cache.ContainsKey(sp))
- {
- string cached = (cache[sp] ?? "").ToString();
- // ★ 规则有结果但缓存为空(AI曾未识别) → 用规则(补漏)
- string rule = MatchByPrefixRule(sp);
- if (rule != null && rule.Length > 0 && rule != cached)
- {
- Log("[缓存校验] 「" + sp + "」 缓存[" + cached + "]与规则冲突,已纠正为[" + rule + "]");
- cached = rule;
- cache[sp] = rule;
- }
- if (cached.Length > 0) localHits[sp] = cached;
- }
- else if (!toAsk.Contains(sp)) toAsk.Add(sp);
- }
- }
-
- var ai = new System.Collections.Hashtable();
- if (toAsk.Count > 0)
- {
- ai = CallDeepSeekMatch(toAsk);
- // 写缓存(包括未命中的,避免反复问)
- lock (_aiLock)
- {
- foreach (string sp in toAsk)
- cache[sp] = ai.Contains(sp) ? ai[sp].ToString() : "";
- SaveDsCache();
- }
- }
-
- // 合并结果
- var final = new System.Collections.Hashtable();
- foreach (System.Collections.DictionaryEntry kv in localHits) final[kv.Key] = kv.Value;
- foreach (System.Collections.DictionaryEntry kv in ai) final[kv.Key] = kv.Value;
- e.Result = final;
- }
- catch (Exception ex)
- {
- Log("[AI回填] 后台异常: " + ex);
- e.Result = new System.Collections.Hashtable();
- }
- };
- bgw.RunWorkerCompleted += (s, e) =>
- {
- // ★ 无论成败都处理:先取走待办队列并释放单飞标记
- List