退役独立扒图程序与试验工具,消除重复源码:删 pdfbt 项目/cadbt C#部分(保留 node+CAD-Viewer 网页引擎,主程序扒图依赖)/ghj/yjktool;打包链同步(make_package 去独立exe/setup.iss 删pdfbt/更新包不再带pdfbt.exe);护栏扩到全部4对双胞胎文件;README 结构更新;编译+组装验证通过
This commit is contained in:
@@ -30,16 +30,16 @@
|
|||||||
|
|
||||||
```
|
```
|
||||||
成套报价软件\ 主程序源码(MainForm 拆 14 个 partial;xiangmu/shezhi/ku 子模块窗体)
|
成套报价软件\ 主程序源码(MainForm 拆 14 个 partial;xiangmu/shezhi/ku 子模块窗体)
|
||||||
└ 扒图\ CAD/PDF 扒图窗口 + OCR/PDF 基础设施(唯一权威源,pdfbt 链接共享)
|
└ 扒图\ CAD/PDF 扒图窗口 + OCR/PDF 基础设施(唯一权威源)
|
||||||
cadbt\ CAD 扒图独立程序(含 CAD-Viewer 网页引擎)
|
cadbt\ CAD 网页引擎运行时(node.exe + CAD-Viewer;2026-10-01 独立 cadbt.exe 退役)
|
||||||
pdfbt\ PDF 扒图独立程序(OCR 等基础设施链接主项目扒图\ 源码)
|
|
||||||
ai助手\ ZCode 引擎发行包 + 启停脚本(发行包不进 git)
|
ai助手\ ZCode 引擎发行包 + 启停脚本(发行包不进 git)
|
||||||
会员服务器\ 肥牛 fnnas 会员服务端 v1.5.1(fpk 工程)
|
会员服务器\ 肥牛 fnnas 会员服务端 v1.5.1(fpk 工程)
|
||||||
tools\ 构建/打包/维护脚本(见下表)
|
tools\ 构建/打包/维护脚本(见下表)
|
||||||
release\ 组装产物(仅 setup.iss 进 git)
|
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\` 报表模板。
|
**数据目录**(运行时,均不进 git):`sjk\bjb\项目<编号>.db` 每项目一库;`sjk\fak.db` 公式库;`sjk\方案库\*.db` 一方案一库;`shezhi\` 用户配置;`xiangmu\` 报表模板。
|
||||||
|
|
||||||
## 构建与验证
|
## 构建与验证
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -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();
|
|
||||||
|
|
||||||
/// <summary>网页 CAD 是否已挂载(WebView2 已附加)。</summary>
|
|
||||||
public static bool IsViewerReady
|
|
||||||
{
|
|
||||||
get { return _wv != null && _wv.CoreWebView2 != null; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>网页 CAD 中实体被删除(句柄十六进制字符串)。</summary>
|
|
||||||
public static event Action<string> EntityErased;
|
|
||||||
|
|
||||||
/// <summary>网页 CAD 扒图完成一批(图号/箱号/元件)。</summary>
|
|
||||||
public static event Action<MyApp.PaMode, List<MyApp.PaTextResult>> PaPicked;
|
|
||||||
|
|
||||||
/// <summary>用户按 ESC 退出网页扒图连续模式。</summary>
|
|
||||||
public static event Action PaExited;
|
|
||||||
|
|
||||||
/// <summary>用户按 F1(焦点在网页或宿主时都触发)——元件两两合并。</summary>
|
|
||||||
public static event Action F1Requested;
|
|
||||||
|
|
||||||
/// <summary>用户按 F2——元件三个一组合并。</summary>
|
|
||||||
public static event Action F2Requested;
|
|
||||||
|
|
||||||
/// <summary>用户按 F3——元件四个一组合并。</summary>
|
|
||||||
public static event Action F3Requested;
|
|
||||||
|
|
||||||
/// <summary>触发 F1 请求(消息过滤器等宿主侧来源调用)。</summary>
|
|
||||||
public static void RaiseF1()
|
|
||||||
{
|
|
||||||
if (F1Requested != null) F1Requested();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>触发 F2 请求(消息过滤器等宿主侧来源调用)。</summary>
|
|
||||||
public static void RaiseF2()
|
|
||||||
{
|
|
||||||
if (F2Requested != null) F2Requested();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>触发 F3 请求(消息过滤器等宿主侧来源调用)。</summary>
|
|
||||||
public static void RaiseF3()
|
|
||||||
{
|
|
||||||
if (F3Requested != null) F3Requested();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>把 WebView2 挂到桥上(在控件初始化完成后调用一次)。</summary>
|
|
||||||
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<Dictionary<string, object>>(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<MyApp.PaTextResult>();
|
|
||||||
var arr = msg["results"] as System.Collections.ArrayList;
|
|
||||||
if (arr != null)
|
|
||||||
{
|
|
||||||
foreach (Dictionary<string, object> 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 { }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 发送扒图命令。接受原 CAD 命令名(CADPATU/CADPAXH/CADPAYJ/CADPACL)
|
|
||||||
/// 或网页命令名(patu/paxh/payj)。
|
|
||||||
/// </summary>
|
|
||||||
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 });
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>缩放居中到指定 Handle 的实体并高亮(点击表格行定位框)。</summary>
|
|
||||||
public static void ZoomToFrameHandle(string handle)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(handle)) return;
|
|
||||||
Post(new { type = "zoomToHandle", handle = handle });
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>批量删除指定 Handle 的实体(删表格行联动删框)。</summary>
|
|
||||||
public static void DeleteFramesByHandles(IEnumerable<string> handles)
|
|
||||||
{
|
|
||||||
if (handles == null) return;
|
|
||||||
var list = new List<string>();
|
|
||||||
foreach (string h in handles)
|
|
||||||
if (!string.IsNullOrWhiteSpace(h)) list.Add(h);
|
|
||||||
if (list.Count == 0) return;
|
|
||||||
Post(new { type = "deleteHandles", handles = list });
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 合并蒙版:保留 keep 句柄的蒙版并扩大到所有 removes 蒙版的并集,
|
|
||||||
/// 被合并行的蒙版从网页 CAD 移除(元件合并时蒙版同步合并)。
|
|
||||||
/// </summary>
|
|
||||||
public static void MergeMasks(string keep, System.Collections.Generic.IEnumerable<string> removes)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(keep)) return;
|
|
||||||
var list = new List<string>();
|
|
||||||
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 });
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>清除网页 CAD 中的所有高亮。</summary>
|
|
||||||
public static void ClearHighlight()
|
|
||||||
{
|
|
||||||
Post(new { type = "clearHighlight" });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-27
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
{
|
|
||||||
/// <summary>停靠窗口:网页 CAD 查看器(DockState.Document)。</summary>
|
|
||||||
public partial class CadViewerWindow : WeifenLuo.WinFormsUI.Docking.DockContent
|
|
||||||
{
|
|
||||||
private WebView2 _webView;
|
|
||||||
private Label _hint;
|
|
||||||
|
|
||||||
/// <summary>静态服务进程句柄(退出时杀进程树)。</summary>
|
|
||||||
private static Process _serverProcess;
|
|
||||||
|
|
||||||
public CadViewerWindow()
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
Text = "CAD 查看器";
|
|
||||||
TabText = "CAD 查看器";
|
|
||||||
FormClosed += (s, e) => 停止网页服务();
|
|
||||||
LoadViewer();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>CAD 网页服务端口(与 server.cjs 一致)。</summary>
|
|
||||||
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 运行时。");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>启动 CAD 网页静态服务(端口已通=复用;不通=node server.cjs 后台拉起)。</summary>
|
|
||||||
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); }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>快速探测本机端口。</summary>
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>退出清理:杀 node 静态服务进程树(taskkill /T 覆盖可能的子进程)。</summary>
|
|
||||||
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); }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>简单诊断日志(logs\cad服务.log)。</summary>
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-27
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
// ============================================================
|
|
||||||
// 停靠窗口:报价插件工具栏(左侧)
|
|
||||||
// 把 cadcj 的 Form3 报价界面作为子控件嵌入(TopLevel=false)。
|
|
||||||
// ============================================================
|
|
||||||
using System.Windows.Forms;
|
|
||||||
|
|
||||||
namespace cadbt.DockWindows
|
|
||||||
{
|
|
||||||
/// <summary>停靠窗口:报价插件工具栏(DockState.DockLeft)。</summary>
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Generated
-69
@@ -1,69 +0,0 @@
|
|||||||
namespace cadbt
|
|
||||||
{
|
|
||||||
partial class MainForm
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Designer variable used to keep track of non-visual components.
|
|
||||||
/// </summary>
|
|
||||||
private System.ComponentModel.IContainer components = null;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Disposes resources used by the form.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
|
||||||
protected override void Dispose(bool disposing)
|
|
||||||
{
|
|
||||||
if (disposing) {
|
|
||||||
if (components != null) {
|
|
||||||
components.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
base.Dispose(disposing);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 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.
|
|
||||||
/// </summary>
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Description of MainForm.
|
|
||||||
/// </summary>
|
|
||||||
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();
|
|
||||||
|
|
||||||
/// <summary>把 F1 按键(0x70)转成 CadBridge.F1Requested,不拦截按键本身。</summary>
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,29 +0,0 @@
|
|||||||
// ============================================================
|
|
||||||
// 扒图数据类型(与原 cadcj 插件 / 网页端 cadbridge.ts 保持一致)
|
|
||||||
// ============================================================
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace MyApp
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 扒数据模式:图号/箱号/元件
|
|
||||||
/// </summary>
|
|
||||||
public enum PaMode
|
|
||||||
{
|
|
||||||
Tuhao, // 扒图号
|
|
||||||
Xianghao, // 扒箱号
|
|
||||||
Yuanjian // 扒元件
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 扒图结果:一条文本 + 它对应的彩色框的 Handle(句柄字符串)
|
|
||||||
/// 用于关联表格数据行与网页 CAD 框实体,实现点击行定位、删除行删框。
|
|
||||||
/// ★ TextHandle:源文本实体自身的 Handle,用于判断"是否同一个文本"。
|
|
||||||
/// </summary>
|
|
||||||
public class PaTextResult
|
|
||||||
{
|
|
||||||
public string Text;
|
|
||||||
public string FrameHandle;
|
|
||||||
public string TextHandle = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,132 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
|
|
||||||
namespace MyApp
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 新建项目 窗口(简化版,不依赖企业信息)。
|
|
||||||
/// UI 布局见 新建项目.ui.cs,本文件只含交互逻辑。
|
|
||||||
/// </summary>
|
|
||||||
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) { }
|
|
||||||
|
|
||||||
/// <summary>带数据库路径的构造函数(用于自动生成项目编号)。</summary>
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>自动填充项目日期(当天)和项目编号(yyyyMMdd+3位序号)。</summary>
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>查数据库当天最大序号+1,失败返回1。</summary>
|
|
||||||
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; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>收集对话框字段,以列名为键返回(供 Form3 写入数据库)。</summary>
|
|
||||||
public Dictionary<string, string> GetInputValues()
|
|
||||||
{
|
|
||||||
var values = new Dictionary<string, string>();
|
|
||||||
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<string, string> dict, string key, string value)
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrWhiteSpace(value)) dict[key] = value.Trim();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* 由SharpDevelop创建。
|
|
||||||
* 用户: 099978
|
|
||||||
* 日期: 2026-09-04
|
|
||||||
* 时间: 12:24
|
|
||||||
*
|
|
||||||
* 要改变这种模板请点击 工具|选项|代码编写|编辑标准头文件
|
|
||||||
*/
|
|
||||||
using System;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
|
|
||||||
namespace cadbt
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Class with program entry point.
|
|
||||||
/// </summary>
|
|
||||||
internal sealed class Program
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Program entry point.
|
|
||||||
/// </summary>
|
|
||||||
[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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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.*")]
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<configuration>
|
|
||||||
<startup>
|
|
||||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
|
|
||||||
</startup>
|
|
||||||
</configuration>
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
|
||||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
|
||||||
<windowsSettings>
|
|
||||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
|
|
||||||
</windowsSettings>
|
|
||||||
</application>
|
|
||||||
</assembly>
|
|
||||||
@@ -1,147 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
|
|
||||||
<PropertyGroup>
|
|
||||||
<ProjectGuid>{0A91D57B-B279-4672-9440-78088D022EB1}</ProjectGuid>
|
|
||||||
<ProjectTypeGuids>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
|
||||||
<OutputType>WinExe</OutputType>
|
|
||||||
<RootNamespace>cadbt</RootNamespace>
|
|
||||||
<AssemblyName>cadbt</AssemblyName>
|
|
||||||
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
|
||||||
<PlatformTarget>x86</PlatformTarget>
|
|
||||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
|
||||||
<OutputPath>bin\Debug\</OutputPath>
|
|
||||||
<DebugSymbols>True</DebugSymbols>
|
|
||||||
<DebugType>Full</DebugType>
|
|
||||||
<Optimize>False</Optimize>
|
|
||||||
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
|
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
|
||||||
<OutputPath>bin\Release\</OutputPath>
|
|
||||||
<DebugSymbols>False</DebugSymbols>
|
|
||||||
<DebugType>None</DebugType>
|
|
||||||
<Optimize>True</Optimize>
|
|
||||||
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
|
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' ">
|
|
||||||
<Prefer32Bit>True</Prefer32Bit>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Reference Include="Microsoft.CSharp">
|
|
||||||
<RequiredTargetFramework>4.0</RequiredTargetFramework>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System" />
|
|
||||||
<Reference Include="System.Core">
|
|
||||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System.Data" />
|
|
||||||
<Reference Include="System.Data.DataSetExtensions">
|
|
||||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System.Drawing" />
|
|
||||||
<Reference Include="System.Windows.Forms" />
|
|
||||||
<Reference Include="System.Xml" />
|
|
||||||
<Reference Include="System.Xml.Linq">
|
|
||||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System.Web.Extensions">
|
|
||||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System.IO.Compression" />
|
|
||||||
<Reference Include="System.IO.Compression.FileSystem" />
|
|
||||||
<Reference Include="Smart.CustomComponents, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ba044a4aa43e0dc4">
|
|
||||||
<HintPath>C:\Program Files (x86)\SharpDevelop\5.2\bin\Smart.CustomComponents.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="WeifenLuo.WinFormsUI.Docking">
|
|
||||||
<HintPath>C:\Program Files (x86)\SharpDevelop\5.2\bin\WeifenLuo.WinFormsUI.Docking.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="WeifenLuo.WinFormsUI.Docking.ThemeVS2015">
|
|
||||||
<HintPath>C:\Program Files (x86)\SharpDevelop\5.2\bin\WeifenLuo.WinFormsUI.Docking.ThemeVS2015.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System.Data.SQLite">
|
|
||||||
<HintPath>C:\Program Files (x86)\SharpDevelop\5.2\bin\System.Data.SQLite.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="log4net">
|
|
||||||
<HintPath>C:\Program Files (x86)\SharpDevelop\5.2\bin\log4net.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System.Resources.Extensions">
|
|
||||||
<HintPath>C:\Program Files (x86)\SharpDevelop\5.2\bin\System.Resources.Extensions.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System.Memory">
|
|
||||||
<HintPath>C:\Program Files (x86)\SharpDevelop\5.2\bin\System.Memory.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System.Runtime.CompilerServices.Unsafe">
|
|
||||||
<HintPath>C:\Program Files (x86)\SharpDevelop\5.2\bin\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System.Numerics.Vectors">
|
|
||||||
<HintPath>C:\Program Files (x86)\SharpDevelop\5.2\bin\System.Numerics.Vectors.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="AdvancedDataGridView">
|
|
||||||
<HintPath>libs\AdvancedDataGridView.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Microsoft.Web.WebView2.Core">
|
|
||||||
<HintPath>libs\webview2\Microsoft.Web.WebView2.Core.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Microsoft.Web.WebView2.WinForms">
|
|
||||||
<HintPath>libs\webview2\Microsoft.Web.WebView2.WinForms.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Compile Include="MainForm.cs" />
|
|
||||||
<Compile Include="MainForm.Designer.cs">
|
|
||||||
<DependentUpon>MainForm.cs</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="MainForm.DockWindows.cs">
|
|
||||||
<DependentUpon>MainForm.cs</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="Program.cs" />
|
|
||||||
<Compile Include="CadBridge.cs" />
|
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
|
||||||
<Compile Include="Plugin\Form3.cs" />
|
|
||||||
<Compile Include="Plugin\Form3.ui.cs">
|
|
||||||
<DependentUpon>Form3.cs</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="Plugin\PaTypes.cs" />
|
|
||||||
<Compile Include="Plugin\新建项目.cs" />
|
|
||||||
<Compile Include="Plugin\新建项目.ui.cs">
|
|
||||||
<DependentUpon>新建项目.cs</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="DockWindows\CadViewerWindow.cs" />
|
|
||||||
<Compile Include="DockWindows\CadViewerWindow.Designer.cs">
|
|
||||||
<DependentUpon>CadViewerWindow.cs</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="DockWindows\QuoteWindow.cs" />
|
|
||||||
<Compile Include="DockWindows\QuoteWindow.Designer.cs">
|
|
||||||
<DependentUpon>QuoteWindow.cs</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="app.config" />
|
|
||||||
<None Include="app.manifest" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Content Include="libs\webview2\WebView2Loader.dll">
|
|
||||||
<Link>WebView2Loader.dll</Link>
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
|
||||||
</Project>
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Generated
-47
@@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
* 由SharpDevelop创建。
|
|
||||||
* 用户: 099978
|
|
||||||
* 日期: 2026-09-28
|
|
||||||
* 时间: 13:00
|
|
||||||
*
|
|
||||||
* 要改变这种模板请点击 工具|选项|代码编写|编辑标准头文件
|
|
||||||
*/
|
|
||||||
namespace ghj
|
|
||||||
{
|
|
||||||
partial class MainForm
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Designer variable used to keep track of non-visual components.
|
|
||||||
/// </summary>
|
|
||||||
private System.ComponentModel.IContainer components = null;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Disposes resources used by the form.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
|
||||||
protected override void Dispose(bool disposing)
|
|
||||||
{
|
|
||||||
if (disposing) {
|
|
||||||
if (components != null) {
|
|
||||||
components.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
base.Dispose(disposing);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 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.
|
|
||||||
/// </summary>
|
|
||||||
private void InitializeComponent()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// MainForm
|
|
||||||
//
|
|
||||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
|
||||||
this.Text = "ghj";
|
|
||||||
this.Name = "MainForm";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Description of MainForm.
|
|
||||||
/// </summary>
|
|
||||||
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.
|
|
||||||
//
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* 由SharpDevelop创建。
|
|
||||||
* 用户: 099978
|
|
||||||
* 日期: 2026-09-28
|
|
||||||
* 时间: 13:00
|
|
||||||
*
|
|
||||||
* 要改变这种模板请点击 工具|选项|代码编写|编辑标准头文件
|
|
||||||
*/
|
|
||||||
using System;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
|
|
||||||
namespace ghj
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Class with program entry point.
|
|
||||||
/// </summary>
|
|
||||||
internal sealed class Program
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Program entry point.
|
|
||||||
/// </summary>
|
|
||||||
[STAThread]
|
|
||||||
private static void Main(string[] args)
|
|
||||||
{
|
|
||||||
Application.EnableVisualStyles();
|
|
||||||
Application.SetCompatibleTextRenderingDefault(false);
|
|
||||||
Application.Run(new MainForm());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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.*")]
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<configuration>
|
|
||||||
<startup>
|
|
||||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
|
|
||||||
</startup>
|
|
||||||
</configuration>
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
|
||||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
|
||||||
<windowsSettings>
|
|
||||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
|
|
||||||
</windowsSettings>
|
|
||||||
</application>
|
|
||||||
</assembly>
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
|
|
||||||
<PropertyGroup>
|
|
||||||
<ProjectGuid>{C9E28D5E-B911-4F7C-9C9D-75EBD3250694}</ProjectGuid>
|
|
||||||
<ProjectTypeGuids>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
|
||||||
<OutputType>WinExe</OutputType>
|
|
||||||
<RootNamespace>ghj</RootNamespace>
|
|
||||||
<AssemblyName>ghj</AssemblyName>
|
|
||||||
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
|
||||||
<PlatformTarget>x86</PlatformTarget>
|
|
||||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
|
||||||
<OutputPath>bin\Debug\</OutputPath>
|
|
||||||
<DebugSymbols>True</DebugSymbols>
|
|
||||||
<DebugType>Full</DebugType>
|
|
||||||
<Optimize>False</Optimize>
|
|
||||||
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
|
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
|
||||||
<OutputPath>bin\Release\</OutputPath>
|
|
||||||
<DebugSymbols>False</DebugSymbols>
|
|
||||||
<DebugType>None</DebugType>
|
|
||||||
<Optimize>True</Optimize>
|
|
||||||
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
|
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' ">
|
|
||||||
<Prefer32Bit>True</Prefer32Bit>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Reference Include="Microsoft.CSharp">
|
|
||||||
<RequiredTargetFramework>4.0</RequiredTargetFramework>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System" />
|
|
||||||
<Reference Include="System.Core">
|
|
||||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System.Data" />
|
|
||||||
<Reference Include="System.Data.DataSetExtensions">
|
|
||||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System.Drawing" />
|
|
||||||
<Reference Include="System.Windows.Forms" />
|
|
||||||
<Reference Include="System.Xml" />
|
|
||||||
<Reference Include="System.Xml.Linq">
|
|
||||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
|
||||||
</Reference>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Compile Include="MainForm.cs" />
|
|
||||||
<Compile Include="MainForm.Designer.cs">
|
|
||||||
<DependentUpon>MainForm.cs</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="Program.cs" />
|
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="app.config" />
|
|
||||||
<None Include="app.manifest" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
|
||||||
</Project>
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
# 新增 UApiPro(uapis.cn) 通用文字识别引擎(第五个 OCR 引擎)
|
|
||||||
|
|
||||||
## 已确认的接口细节(官方文档 + 官网已核实)
|
|
||||||
- 端点:`POST https://uapis.cn/api/v1/image/ocr`,multipart/form-data
|
|
||||||
- 鉴权:`X-API-Key: <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 已退役
|
|
||||||
-27
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
// ============================================================
|
|
||||||
// 停靠窗口:报价插件工具栏(左侧)
|
|
||||||
// 把 cadcj 的 Form3 报价界面作为子控件嵌入(TopLevel=false)。
|
|
||||||
// ============================================================
|
|
||||||
using System.Windows.Forms;
|
|
||||||
|
|
||||||
namespace pdfbt.DockWindows
|
|
||||||
{
|
|
||||||
/// <summary>停靠窗口:报价插件工具栏(DockState.DockLeft)。</summary>
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Generated
-71
@@ -1,71 +0,0 @@
|
|||||||
namespace pdfbt
|
|
||||||
{
|
|
||||||
partial class MainForm
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Designer variable used to keep track of non-visual components.
|
|
||||||
/// </summary>
|
|
||||||
private System.ComponentModel.IContainer components = null;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Disposes resources used by the form.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
|
||||||
protected override void Dispose(bool disposing)
|
|
||||||
{
|
|
||||||
if (disposing) {
|
|
||||||
if (components != null) {
|
|
||||||
components.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
base.Dispose(disposing);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This method is required for Windows Forms designer support.
|
|
||||||
/// Do not change the method contents inside the source code editor.
|
|
||||||
/// </summary>
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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<System.Collections.Generic.Dictionary<string, string>>(
|
|
||||||
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();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 把 F1/F2/F3 按键(0x70/0x71/0x72)转成 PdfBridge 事件。
|
|
||||||
/// ★ 焦点在报价插件(Form3)树内时不触发——那条路径由 Form3.ProcessCmdKey
|
|
||||||
/// 处理,此处再触发会双跑一次(F1 合并两遍:第一遍成功、第二遍弹
|
|
||||||
/// "请先选中至少2行"的误提示)。
|
|
||||||
/// </summary>
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,120 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<root>
|
|
||||||
<!--
|
|
||||||
Microsoft ResX Schema
|
|
||||||
|
|
||||||
Version 2.0
|
|
||||||
|
|
||||||
The primary goals of this format is to allow a simple XML format
|
|
||||||
that is mostly human readable. The generation and parsing of the
|
|
||||||
various data types are done through the TypeConverter classes
|
|
||||||
associated with the data types.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
... ado.net/XML headers & schema ...
|
|
||||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
|
||||||
<resheader name="version">2.0</resheader>
|
|
||||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
|
||||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
|
||||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
|
||||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
|
||||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
|
||||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
|
||||||
</data>
|
|
||||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
|
||||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
|
||||||
<comment>This is a comment</comment>
|
|
||||||
</data>
|
|
||||||
|
|
||||||
There are any number of "resheader" rows that contain simple
|
|
||||||
name/value pairs.
|
|
||||||
|
|
||||||
Each data row contains a name, and value. The row also contains a
|
|
||||||
type or mimetype. Type corresponds to a .NET class that support
|
|
||||||
text/value conversion through the TypeConverter architecture.
|
|
||||||
Classes that don't support this are serialized and stored with the
|
|
||||||
mimetype set.
|
|
||||||
|
|
||||||
The mimetype is used for serialized objects, and tells the
|
|
||||||
ResXResourceReader how to depersist the object. This is currently not
|
|
||||||
extensible. For a given mimetype the value must be set accordingly:
|
|
||||||
|
|
||||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
|
||||||
that the ResXResourceWriter will generate, however the reader can
|
|
||||||
read any of the formats listed below.
|
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.binary.base64
|
|
||||||
value : The object must be serialized with
|
|
||||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
|
||||||
: and then encoded with base64 encoding.
|
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.soap.base64
|
|
||||||
value : The object must be serialized with
|
|
||||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
|
||||||
: and then encoded with base64 encoding.
|
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
|
||||||
value : The object must be serialized into a byte array
|
|
||||||
: using a System.ComponentModel.TypeConverter
|
|
||||||
: and then encoded with base64 encoding.
|
|
||||||
-->
|
|
||||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
|
||||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
|
||||||
<xsd:element name="root" msdata:IsDataSet="true">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:choice maxOccurs="unbounded">
|
|
||||||
<xsd:element name="metadata">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
|
||||||
<xsd:attribute name="type" type="xsd:string" />
|
|
||||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
|
||||||
<xsd:attribute ref="xml:space" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="assembly">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:attribute name="alias" type="xsd:string" />
|
|
||||||
<xsd:attribute name="name" type="xsd:string" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="data">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
|
||||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
|
||||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
|
||||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
|
||||||
<xsd:attribute ref="xml:space" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="resheader">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
</xsd:choice>
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
</xsd:schema>
|
|
||||||
<resheader name="resmimetype">
|
|
||||||
<value>text/microsoft-resx</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="version">
|
|
||||||
<value>2.0</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="reader">
|
|
||||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="writer">
|
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
|
||||||
</resheader>
|
|
||||||
</root>
|
|
||||||
@@ -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;
|
|
||||||
|
|
||||||
/// <summary>PDF 查看器是否已挂载且打开了文档。</summary>
|
|
||||||
public static bool IsViewerReady
|
|
||||||
{
|
|
||||||
get { return _viewer != null && _viewer.IsDocumentOpen; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>扒图连续模式当前是否激活(供 ESC 全局过滤判断)。</summary>
|
|
||||||
public static bool PickModeActive
|
|
||||||
{
|
|
||||||
get { return _viewer != null && _viewer.PickModeActive; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>兼容 CadBridge:查看器中蒙版被外部删除(当前无触发源,保留事件形状)。</summary>
|
|
||||||
public static event Action<string> EntityErased;
|
|
||||||
|
|
||||||
/// <summary>框选识别完成一批(图号/箱号/元件)。</summary>
|
|
||||||
public static event Action<MyApp.PaMode, List<MyApp.PaTextResult>> PaPicked;
|
|
||||||
|
|
||||||
/// <summary>用户按 ESC 退出连续扒图模式。</summary>
|
|
||||||
public static event Action PaExited;
|
|
||||||
|
|
||||||
/// <summary>用户按 F1 —— 元件两两合并。</summary>
|
|
||||||
public static event Action F1Requested;
|
|
||||||
|
|
||||||
/// <summary>用户按 F2 —— 元件三个一组合并。</summary>
|
|
||||||
public static event Action F2Requested;
|
|
||||||
|
|
||||||
/// <summary>用户按 F3 —— 元件四个一组合并。</summary>
|
|
||||||
public static event Action F3Requested;
|
|
||||||
|
|
||||||
/// <summary>把 PDF 查看器挂到桥上(查看器构造时调用一次)。</summary>
|
|
||||||
public static void Attach(PdfViewerWindow viewer)
|
|
||||||
{
|
|
||||||
_viewer = viewer;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------
|
|
||||||
// 查看器 → Form3 的上行事件触发(仅查看器调用)
|
|
||||||
// ------------------------------------------------------------
|
|
||||||
|
|
||||||
public static void RaisePaPicked(MyApp.PaMode mode, List<MyApp.PaTextResult> 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 → 查看器的下行命令
|
|
||||||
// ------------------------------------------------------------
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 发送扒图命令。接受原 CAD 命令名(CADPATU/CADPAXH/CADPAYJ/CADPACL)
|
|
||||||
/// 或网页命令名(patu/paxh/payj/pacl)。
|
|
||||||
/// </summary>
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>定位到指定 Handle 的蒙版框(点击表格行定位)。</summary>
|
|
||||||
public static void ZoomToFrameHandle(string handle)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(handle) || _viewer == null) return;
|
|
||||||
_viewer.ZoomToFrame(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>批量删除指定 Handle 的蒙版(删表格行联动删框)。</summary>
|
|
||||||
public static void DeleteFramesByHandles(IEnumerable<string> handles)
|
|
||||||
{
|
|
||||||
if (handles == null || _viewer == null) return;
|
|
||||||
var list = new List<string>();
|
|
||||||
foreach (string h in handles)
|
|
||||||
if (!string.IsNullOrWhiteSpace(h)) list.Add(h);
|
|
||||||
if (list.Count == 0) return;
|
|
||||||
_viewer.DeleteFrames(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 合并蒙版:保留 keep 的蒙版并扩大到所有 removes 蒙版的并集,
|
|
||||||
/// 被合并行的蒙版移除(元件合并时蒙版同步合并)。
|
|
||||||
/// </summary>
|
|
||||||
public static void MergeMasks(string keep, IEnumerable<string> removes)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(keep) || _viewer == null) return;
|
|
||||||
var list = new List<string>();
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>清除所有高亮。</summary>
|
|
||||||
public static void ClearHighlight()
|
|
||||||
{
|
|
||||||
if (_viewer == null) return;
|
|
||||||
_viewer.ClearHighlight();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
Generated
-1321
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,120 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<root>
|
|
||||||
<!--
|
|
||||||
Microsoft ResX Schema
|
|
||||||
|
|
||||||
Version 2.0
|
|
||||||
|
|
||||||
The primary goals of this format is to allow a simple XML format
|
|
||||||
that is mostly human readable. The generation and parsing of the
|
|
||||||
various data types are done through the TypeConverter classes
|
|
||||||
associated with the data types.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
... ado.net/XML headers & schema ...
|
|
||||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
|
||||||
<resheader name="version">2.0</resheader>
|
|
||||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
|
||||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
|
||||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
|
||||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
|
||||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
|
||||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
|
||||||
</data>
|
|
||||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
|
||||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
|
||||||
<comment>This is a comment</comment>
|
|
||||||
</data>
|
|
||||||
|
|
||||||
There are any number of "resheader" rows that contain simple
|
|
||||||
name/value pairs.
|
|
||||||
|
|
||||||
Each data row contains a name, and value. The row also contains a
|
|
||||||
type or mimetype. Type corresponds to a .NET class that support
|
|
||||||
text/value conversion through the TypeConverter architecture.
|
|
||||||
Classes that don't support this are serialized and stored with the
|
|
||||||
mimetype set.
|
|
||||||
|
|
||||||
The mimetype is used for serialized objects, and tells the
|
|
||||||
ResXResourceReader how to depersist the object. This is currently not
|
|
||||||
extensible. For a given mimetype the value must be set accordingly:
|
|
||||||
|
|
||||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
|
||||||
that the ResXResourceWriter will generate, however the reader can
|
|
||||||
read any of the formats listed below.
|
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.binary.base64
|
|
||||||
value : The object must be serialized with
|
|
||||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
|
||||||
: and then encoded with base64 encoding.
|
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.soap.base64
|
|
||||||
value : The object must be serialized with
|
|
||||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
|
||||||
: and then encoded with base64 encoding.
|
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
|
||||||
value : The object must be serialized into a byte array
|
|
||||||
: using a System.ComponentModel.TypeConverter
|
|
||||||
: and then encoded with base64 encoding.
|
|
||||||
-->
|
|
||||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
|
||||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
|
||||||
<xsd:element name="root" msdata:IsDataSet="true">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:choice maxOccurs="unbounded">
|
|
||||||
<xsd:element name="metadata">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
|
||||||
<xsd:attribute name="type" type="xsd:string" />
|
|
||||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
|
||||||
<xsd:attribute ref="xml:space" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="assembly">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:attribute name="alias" type="xsd:string" />
|
|
||||||
<xsd:attribute name="name" type="xsd:string" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="data">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
|
||||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
|
||||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
|
||||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
|
||||||
<xsd:attribute ref="xml:space" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="resheader">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
</xsd:choice>
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
</xsd:schema>
|
|
||||||
<resheader name="resmimetype">
|
|
||||||
<value>text/microsoft-resx</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="version">
|
|
||||||
<value>2.0</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="reader">
|
|
||||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="writer">
|
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
|
||||||
</resheader>
|
|
||||||
</root>
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
// ============================================================
|
|
||||||
// 扒图数据类型(与原 cadcj 插件 / 网页端 cadbridge.ts 保持一致)
|
|
||||||
// ============================================================
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace MyApp
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 扒数据模式:图号/箱号/元件
|
|
||||||
/// </summary>
|
|
||||||
public enum PaMode
|
|
||||||
{
|
|
||||||
Tuhao, // 扒图号
|
|
||||||
Xianghao, // 扒箱号
|
|
||||||
Yuanjian // 扒元件
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 扒图结果:一条文本 + 它对应的彩色框的 Handle(句柄字符串)
|
|
||||||
/// 用于关联表格数据行与网页 CAD 框实体,实现点击行定位、删除行删框。
|
|
||||||
/// ★ TextHandle:源文本实体自身的 Handle,用于判断"是否同一个文本"。
|
|
||||||
/// </summary>
|
|
||||||
public class PaTextResult
|
|
||||||
{
|
|
||||||
public string Text;
|
|
||||||
public string FrameHandle;
|
|
||||||
public string TextHandle = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Generated
-609
@@ -1,609 +0,0 @@
|
|||||||
namespace MyApp
|
|
||||||
{
|
|
||||||
public partial class 新建项目 : System.Windows.Forms.Form
|
|
||||||
{
|
|
||||||
/// <summary>必需的设计器变量。</summary>
|
|
||||||
private System.ComponentModel.IContainer components = null;
|
|
||||||
|
|
||||||
/// <summary>清理正在使用的资源。</summary>
|
|
||||||
protected override void Dispose(bool disposing)
|
|
||||||
{
|
|
||||||
if (disposing && (components != null))
|
|
||||||
{
|
|
||||||
components.Dispose();
|
|
||||||
}
|
|
||||||
base.Dispose(disposing);
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Windows 窗体设计器生成的代码
|
|
||||||
|
|
||||||
private void InitializeComponent()
|
|
||||||
{
|
|
||||||
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项目编号.BackColor = System.Drawing.SystemColors.Control;
|
|
||||||
this.lbl项目编号.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.lbl项目编号.ForeColor = System.Drawing.SystemColors.ControlText;
|
|
||||||
this.lbl项目编号.Location = new System.Drawing.Point(20, 25);
|
|
||||||
this.lbl项目编号.Name = "lbl项目编号";
|
|
||||||
this.lbl项目编号.Size = new System.Drawing.Size(70, 23);
|
|
||||||
this.lbl项目编号.TabIndex = 0;
|
|
||||||
this.lbl项目编号.Text = "项目编号:";
|
|
||||||
this.lbl项目编号.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
|
||||||
//
|
|
||||||
// txt项目编号
|
|
||||||
//
|
|
||||||
this.txt项目编号.BackColor = System.Drawing.SystemColors.Window;
|
|
||||||
this.txt项目编号.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.txt项目编号.ForeColor = System.Drawing.SystemColors.WindowText;
|
|
||||||
this.txt项目编号.Location = new System.Drawing.Point(95, 25);
|
|
||||||
this.txt项目编号.Name = "txt项目编号";
|
|
||||||
this.txt项目编号.Size = new System.Drawing.Size(220, 28);
|
|
||||||
this.txt项目编号.TabIndex = 0;
|
|
||||||
//
|
|
||||||
// lbl项目日期
|
|
||||||
//
|
|
||||||
this.lbl项目日期.BackColor = System.Drawing.SystemColors.Control;
|
|
||||||
this.lbl项目日期.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.lbl项目日期.ForeColor = System.Drawing.SystemColors.ControlText;
|
|
||||||
this.lbl项目日期.Location = new System.Drawing.Point(380, 28);
|
|
||||||
this.lbl项目日期.Name = "lbl项目日期";
|
|
||||||
this.lbl项目日期.Size = new System.Drawing.Size(70, 18);
|
|
||||||
this.lbl项目日期.TabIndex = 1;
|
|
||||||
this.lbl项目日期.Text = "项目日期:";
|
|
||||||
//
|
|
||||||
// txt项目日期
|
|
||||||
//
|
|
||||||
this.txt项目日期.BackColor = System.Drawing.SystemColors.Window;
|
|
||||||
this.txt项目日期.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.txt项目日期.ForeColor = System.Drawing.SystemColors.WindowText;
|
|
||||||
this.txt项目日期.Location = new System.Drawing.Point(455, 25);
|
|
||||||
this.txt项目日期.Name = "txt项目日期";
|
|
||||||
this.txt项目日期.Size = new System.Drawing.Size(210, 28);
|
|
||||||
this.txt项目日期.TabIndex = 1;
|
|
||||||
//
|
|
||||||
// lbl项目名称
|
|
||||||
//
|
|
||||||
this.lbl项目名称.BackColor = System.Drawing.SystemColors.Control;
|
|
||||||
this.lbl项目名称.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.lbl项目名称.ForeColor = System.Drawing.SystemColors.ControlText;
|
|
||||||
this.lbl项目名称.Location = new System.Drawing.Point(20, 55);
|
|
||||||
this.lbl项目名称.Name = "lbl项目名称";
|
|
||||||
this.lbl项目名称.Size = new System.Drawing.Size(70, 23);
|
|
||||||
this.lbl项目名称.TabIndex = 2;
|
|
||||||
this.lbl项目名称.Text = "项目名称:";
|
|
||||||
this.lbl项目名称.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
|
||||||
//
|
|
||||||
// txt项目名称
|
|
||||||
//
|
|
||||||
this.txt项目名称.BackColor = System.Drawing.SystemColors.Window;
|
|
||||||
this.txt项目名称.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.txt项目名称.ForeColor = System.Drawing.SystemColors.WindowText;
|
|
||||||
this.txt项目名称.Location = new System.Drawing.Point(95, 55);
|
|
||||||
this.txt项目名称.Name = "txt项目名称";
|
|
||||||
this.txt项目名称.Size = new System.Drawing.Size(570, 28);
|
|
||||||
this.txt项目名称.TabIndex = 2;
|
|
||||||
//
|
|
||||||
// lbl客户名称
|
|
||||||
//
|
|
||||||
this.lbl客户名称.BackColor = System.Drawing.SystemColors.Control;
|
|
||||||
this.lbl客户名称.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.lbl客户名称.ForeColor = System.Drawing.SystemColors.ControlText;
|
|
||||||
this.lbl客户名称.Location = new System.Drawing.Point(20, 85);
|
|
||||||
this.lbl客户名称.Name = "lbl客户名称";
|
|
||||||
this.lbl客户名称.Size = new System.Drawing.Size(70, 23);
|
|
||||||
this.lbl客户名称.TabIndex = 3;
|
|
||||||
this.lbl客户名称.Text = "客户名称:";
|
|
||||||
this.lbl客户名称.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
|
||||||
//
|
|
||||||
// txt客户名称
|
|
||||||
//
|
|
||||||
this.txt客户名称.BackColor = System.Drawing.SystemColors.Window;
|
|
||||||
this.txt客户名称.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.txt客户名称.ForeColor = System.Drawing.SystemColors.WindowText;
|
|
||||||
this.txt客户名称.Location = new System.Drawing.Point(95, 85);
|
|
||||||
this.txt客户名称.Name = "txt客户名称";
|
|
||||||
this.txt客户名称.Size = new System.Drawing.Size(479, 28);
|
|
||||||
this.txt客户名称.TabIndex = 3;
|
|
||||||
//
|
|
||||||
// btn选择客户
|
|
||||||
//
|
|
||||||
this.btn选择客户.BackColor = System.Drawing.SystemColors.Control;
|
|
||||||
this.btn选择客户.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.btn选择客户.ForeColor = System.Drawing.SystemColors.ControlText;
|
|
||||||
this.btn选择客户.Location = new System.Drawing.Point(580, 85);
|
|
||||||
this.btn选择客户.Name = "btn选择客户";
|
|
||||||
this.btn选择客户.Size = new System.Drawing.Size(85, 28);
|
|
||||||
this.btn选择客户.TabIndex = 4;
|
|
||||||
this.btn选择客户.Text = "选择客户";
|
|
||||||
this.btn选择客户.UseVisualStyleBackColor = true;
|
|
||||||
//
|
|
||||||
// lbl客户地址
|
|
||||||
//
|
|
||||||
this.lbl客户地址.BackColor = System.Drawing.SystemColors.Control;
|
|
||||||
this.lbl客户地址.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.lbl客户地址.ForeColor = System.Drawing.SystemColors.ControlText;
|
|
||||||
this.lbl客户地址.Location = new System.Drawing.Point(20, 115);
|
|
||||||
this.lbl客户地址.Name = "lbl客户地址";
|
|
||||||
this.lbl客户地址.Size = new System.Drawing.Size(70, 23);
|
|
||||||
this.lbl客户地址.TabIndex = 5;
|
|
||||||
this.lbl客户地址.Text = "客户地址:";
|
|
||||||
this.lbl客户地址.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
|
||||||
//
|
|
||||||
// txt客户地址
|
|
||||||
//
|
|
||||||
this.txt客户地址.BackColor = System.Drawing.SystemColors.Window;
|
|
||||||
this.txt客户地址.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.txt客户地址.ForeColor = System.Drawing.SystemColors.WindowText;
|
|
||||||
this.txt客户地址.Location = new System.Drawing.Point(95, 115);
|
|
||||||
this.txt客户地址.Name = "txt客户地址";
|
|
||||||
this.txt客户地址.Size = new System.Drawing.Size(570, 28);
|
|
||||||
this.txt客户地址.TabIndex = 5;
|
|
||||||
//
|
|
||||||
// lbl联系人
|
|
||||||
//
|
|
||||||
this.lbl联系人.BackColor = System.Drawing.SystemColors.Control;
|
|
||||||
this.lbl联系人.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.lbl联系人.ForeColor = System.Drawing.SystemColors.ControlText;
|
|
||||||
this.lbl联系人.Location = new System.Drawing.Point(30, 145);
|
|
||||||
this.lbl联系人.Name = "lbl联系人";
|
|
||||||
this.lbl联系人.Size = new System.Drawing.Size(60, 23);
|
|
||||||
this.lbl联系人.TabIndex = 6;
|
|
||||||
this.lbl联系人.Text = "联系人:";
|
|
||||||
this.lbl联系人.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
|
||||||
//
|
|
||||||
// txt联系人
|
|
||||||
//
|
|
||||||
this.txt联系人.BackColor = System.Drawing.SystemColors.Window;
|
|
||||||
this.txt联系人.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.txt联系人.ForeColor = System.Drawing.SystemColors.WindowText;
|
|
||||||
this.txt联系人.Location = new System.Drawing.Point(95, 145);
|
|
||||||
this.txt联系人.Name = "txt联系人";
|
|
||||||
this.txt联系人.Size = new System.Drawing.Size(220, 28);
|
|
||||||
this.txt联系人.TabIndex = 6;
|
|
||||||
//
|
|
||||||
// lbl联系电话
|
|
||||||
//
|
|
||||||
this.lbl联系电话.BackColor = System.Drawing.SystemColors.Control;
|
|
||||||
this.lbl联系电话.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.lbl联系电话.ForeColor = System.Drawing.SystemColors.ControlText;
|
|
||||||
this.lbl联系电话.Location = new System.Drawing.Point(380, 145);
|
|
||||||
this.lbl联系电话.Name = "lbl联系电话";
|
|
||||||
this.lbl联系电话.Size = new System.Drawing.Size(70, 21);
|
|
||||||
this.lbl联系电话.TabIndex = 7;
|
|
||||||
this.lbl联系电话.Text = "联系电话:";
|
|
||||||
//
|
|
||||||
// txt联系电话
|
|
||||||
//
|
|
||||||
this.txt联系电话.BackColor = System.Drawing.SystemColors.Window;
|
|
||||||
this.txt联系电话.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.txt联系电话.ForeColor = System.Drawing.SystemColors.WindowText;
|
|
||||||
this.txt联系电话.Location = new System.Drawing.Point(455, 145);
|
|
||||||
this.txt联系电话.Name = "txt联系电话";
|
|
||||||
this.txt联系电话.Size = new System.Drawing.Size(210, 28);
|
|
||||||
this.txt联系电话.TabIndex = 7;
|
|
||||||
//
|
|
||||||
// lbl成套厂名称
|
|
||||||
//
|
|
||||||
this.lbl成套厂名称.BackColor = System.Drawing.SystemColors.Control;
|
|
||||||
this.lbl成套厂名称.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.lbl成套厂名称.ForeColor = System.Drawing.SystemColors.ControlText;
|
|
||||||
this.lbl成套厂名称.Location = new System.Drawing.Point(10, 175);
|
|
||||||
this.lbl成套厂名称.Name = "lbl成套厂名称";
|
|
||||||
this.lbl成套厂名称.Size = new System.Drawing.Size(80, 23);
|
|
||||||
this.lbl成套厂名称.TabIndex = 8;
|
|
||||||
this.lbl成套厂名称.Text = "成套厂名称:";
|
|
||||||
this.lbl成套厂名称.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
|
||||||
//
|
|
||||||
// txt成套厂名称
|
|
||||||
//
|
|
||||||
this.txt成套厂名称.BackColor = System.Drawing.SystemColors.Window;
|
|
||||||
this.txt成套厂名称.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.txt成套厂名称.ForeColor = System.Drawing.SystemColors.WindowText;
|
|
||||||
this.txt成套厂名称.Location = new System.Drawing.Point(95, 175);
|
|
||||||
this.txt成套厂名称.Name = "txt成套厂名称";
|
|
||||||
this.txt成套厂名称.Size = new System.Drawing.Size(570, 28);
|
|
||||||
this.txt成套厂名称.TabIndex = 8;
|
|
||||||
//
|
|
||||||
// lbl成套厂地址
|
|
||||||
//
|
|
||||||
this.lbl成套厂地址.BackColor = System.Drawing.SystemColors.Control;
|
|
||||||
this.lbl成套厂地址.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.lbl成套厂地址.ForeColor = System.Drawing.SystemColors.ControlText;
|
|
||||||
this.lbl成套厂地址.Location = new System.Drawing.Point(10, 205);
|
|
||||||
this.lbl成套厂地址.Name = "lbl成套厂地址";
|
|
||||||
this.lbl成套厂地址.Size = new System.Drawing.Size(80, 23);
|
|
||||||
this.lbl成套厂地址.TabIndex = 9;
|
|
||||||
this.lbl成套厂地址.Text = "成套厂地址:";
|
|
||||||
this.lbl成套厂地址.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
|
||||||
//
|
|
||||||
// txt成套厂地址
|
|
||||||
//
|
|
||||||
this.txt成套厂地址.BackColor = System.Drawing.SystemColors.Window;
|
|
||||||
this.txt成套厂地址.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.txt成套厂地址.ForeColor = System.Drawing.SystemColors.WindowText;
|
|
||||||
this.txt成套厂地址.Location = new System.Drawing.Point(95, 205);
|
|
||||||
this.txt成套厂地址.Name = "txt成套厂地址";
|
|
||||||
this.txt成套厂地址.Size = new System.Drawing.Size(570, 28);
|
|
||||||
this.txt成套厂地址.TabIndex = 9;
|
|
||||||
//
|
|
||||||
// lbl成套厂联系人
|
|
||||||
//
|
|
||||||
this.lbl成套厂联系人.BackColor = System.Drawing.SystemColors.Control;
|
|
||||||
this.lbl成套厂联系人.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.lbl成套厂联系人.ForeColor = System.Drawing.SystemColors.ControlText;
|
|
||||||
this.lbl成套厂联系人.Location = new System.Drawing.Point(30, 235);
|
|
||||||
this.lbl成套厂联系人.Name = "lbl成套厂联系人";
|
|
||||||
this.lbl成套厂联系人.Size = new System.Drawing.Size(60, 23);
|
|
||||||
this.lbl成套厂联系人.TabIndex = 10;
|
|
||||||
this.lbl成套厂联系人.Text = "联系人:";
|
|
||||||
this.lbl成套厂联系人.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
|
||||||
//
|
|
||||||
// txt成套厂联系人
|
|
||||||
//
|
|
||||||
this.txt成套厂联系人.BackColor = System.Drawing.SystemColors.Window;
|
|
||||||
this.txt成套厂联系人.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.txt成套厂联系人.ForeColor = System.Drawing.SystemColors.WindowText;
|
|
||||||
this.txt成套厂联系人.Location = new System.Drawing.Point(95, 235);
|
|
||||||
this.txt成套厂联系人.Name = "txt成套厂联系人";
|
|
||||||
this.txt成套厂联系人.Size = new System.Drawing.Size(220, 28);
|
|
||||||
this.txt成套厂联系人.TabIndex = 10;
|
|
||||||
//
|
|
||||||
// lbl成套厂联系电话
|
|
||||||
//
|
|
||||||
this.lbl成套厂联系电话.BackColor = System.Drawing.SystemColors.Control;
|
|
||||||
this.lbl成套厂联系电话.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.lbl成套厂联系电话.ForeColor = System.Drawing.SystemColors.ControlText;
|
|
||||||
this.lbl成套厂联系电话.Location = new System.Drawing.Point(380, 235);
|
|
||||||
this.lbl成套厂联系电话.Name = "lbl成套厂联系电话";
|
|
||||||
this.lbl成套厂联系电话.Size = new System.Drawing.Size(70, 21);
|
|
||||||
this.lbl成套厂联系电话.TabIndex = 11;
|
|
||||||
this.lbl成套厂联系电话.Text = "联系电话:";
|
|
||||||
//
|
|
||||||
// txt成套厂联系电话
|
|
||||||
//
|
|
||||||
this.txt成套厂联系电话.BackColor = System.Drawing.SystemColors.Window;
|
|
||||||
this.txt成套厂联系电话.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.txt成套厂联系电话.ForeColor = System.Drawing.SystemColors.WindowText;
|
|
||||||
this.txt成套厂联系电话.Location = new System.Drawing.Point(455, 232);
|
|
||||||
this.txt成套厂联系电话.Name = "txt成套厂联系电话";
|
|
||||||
this.txt成套厂联系电话.Size = new System.Drawing.Size(210, 28);
|
|
||||||
this.txt成套厂联系电话.TabIndex = 11;
|
|
||||||
//
|
|
||||||
// lbl报出方式
|
|
||||||
//
|
|
||||||
this.lbl报出方式.BackColor = System.Drawing.SystemColors.Control;
|
|
||||||
this.lbl报出方式.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.lbl报出方式.ForeColor = System.Drawing.SystemColors.ControlText;
|
|
||||||
this.lbl报出方式.Location = new System.Drawing.Point(20, 265);
|
|
||||||
this.lbl报出方式.Name = "lbl报出方式";
|
|
||||||
this.lbl报出方式.Size = new System.Drawing.Size(70, 23);
|
|
||||||
this.lbl报出方式.TabIndex = 12;
|
|
||||||
this.lbl报出方式.Text = "报出方式:";
|
|
||||||
this.lbl报出方式.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
|
||||||
//
|
|
||||||
// cmb报出方式
|
|
||||||
//
|
|
||||||
this.cmb报出方式.BackColor = System.Drawing.SystemColors.Window;
|
|
||||||
this.cmb报出方式.DropDownWidth = 200;
|
|
||||||
this.cmb报出方式.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.cmb报出方式.ForeColor = System.Drawing.SystemColors.WindowText;
|
|
||||||
this.cmb报出方式.ItemHeight = 18;
|
|
||||||
this.cmb报出方式.Location = new System.Drawing.Point(95, 265);
|
|
||||||
this.cmb报出方式.Name = "cmb报出方式";
|
|
||||||
this.cmb报出方式.Size = new System.Drawing.Size(220, 26);
|
|
||||||
this.cmb报出方式.TabIndex = 12;
|
|
||||||
this.cmb报出方式.Text = "报出价=表价*采购系数*报出系数";
|
|
||||||
//
|
|
||||||
// lbl箱柜模板
|
|
||||||
//
|
|
||||||
this.lbl箱柜模板.BackColor = System.Drawing.SystemColors.Control;
|
|
||||||
this.lbl箱柜模板.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.lbl箱柜模板.ForeColor = System.Drawing.SystemColors.ControlText;
|
|
||||||
this.lbl箱柜模板.Location = new System.Drawing.Point(380, 265);
|
|
||||||
this.lbl箱柜模板.Name = "lbl箱柜模板";
|
|
||||||
this.lbl箱柜模板.Size = new System.Drawing.Size(70, 20);
|
|
||||||
this.lbl箱柜模板.TabIndex = 13;
|
|
||||||
this.lbl箱柜模板.Text = "箱柜模板:";
|
|
||||||
//
|
|
||||||
// cmb箱柜模板
|
|
||||||
//
|
|
||||||
this.cmb箱柜模板.BackColor = System.Drawing.SystemColors.Window;
|
|
||||||
this.cmb箱柜模板.DropDownWidth = 200;
|
|
||||||
this.cmb箱柜模板.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.cmb箱柜模板.ForeColor = System.Drawing.SystemColors.WindowText;
|
|
||||||
this.cmb箱柜模板.ItemHeight = 18;
|
|
||||||
this.cmb箱柜模板.Location = new System.Drawing.Point(455, 262);
|
|
||||||
this.cmb箱柜模板.Name = "cmb箱柜模板";
|
|
||||||
this.cmb箱柜模板.Size = new System.Drawing.Size(210, 26);
|
|
||||||
this.cmb箱柜模板.TabIndex = 13;
|
|
||||||
//
|
|
||||||
// lbl单台价格
|
|
||||||
//
|
|
||||||
this.lbl单台价格.BackColor = System.Drawing.SystemColors.Control;
|
|
||||||
this.lbl单台价格.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.lbl单台价格.ForeColor = System.Drawing.SystemColors.ControlText;
|
|
||||||
this.lbl单台价格.Location = new System.Drawing.Point(20, 293);
|
|
||||||
this.lbl单台价格.Name = "lbl单台价格";
|
|
||||||
this.lbl单台价格.Size = new System.Drawing.Size(70, 23);
|
|
||||||
this.lbl单台价格.TabIndex = 14;
|
|
||||||
this.lbl单台价格.Text = "单台价格:";
|
|
||||||
this.lbl单台价格.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
|
||||||
//
|
|
||||||
// cmb单台价格
|
|
||||||
//
|
|
||||||
this.cmb单台价格.BackColor = System.Drawing.SystemColors.Window;
|
|
||||||
this.cmb单台价格.DropDownWidth = 200;
|
|
||||||
this.cmb单台价格.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.cmb单台价格.ForeColor = System.Drawing.SystemColors.WindowText;
|
|
||||||
this.cmb单台价格.ItemHeight = 18;
|
|
||||||
this.cmb单台价格.Location = new System.Drawing.Point(95, 293);
|
|
||||||
this.cmb单台价格.Name = "cmb单台价格";
|
|
||||||
this.cmb单台价格.Size = new System.Drawing.Size(220, 26);
|
|
||||||
this.cmb单台价格.TabIndex = 14;
|
|
||||||
this.cmb单台价格.Text = "保留整数";
|
|
||||||
//
|
|
||||||
// lbl项目总价
|
|
||||||
//
|
|
||||||
this.lbl项目总价.BackColor = System.Drawing.SystemColors.Control;
|
|
||||||
this.lbl项目总价.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.lbl项目总价.ForeColor = System.Drawing.SystemColors.ControlText;
|
|
||||||
this.lbl项目总价.Location = new System.Drawing.Point(379, 293);
|
|
||||||
this.lbl项目总价.Name = "lbl项目总价";
|
|
||||||
this.lbl项目总价.Size = new System.Drawing.Size(70, 20);
|
|
||||||
this.lbl项目总价.TabIndex = 15;
|
|
||||||
this.lbl项目总价.Text = "项目总价:";
|
|
||||||
//
|
|
||||||
// lbl备注
|
|
||||||
//
|
|
||||||
this.lbl备注.BackColor = System.Drawing.SystemColors.Control;
|
|
||||||
this.lbl备注.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.lbl备注.ForeColor = System.Drawing.SystemColors.ControlText;
|
|
||||||
this.lbl备注.Location = new System.Drawing.Point(44, 352);
|
|
||||||
this.lbl备注.Name = "lbl备注";
|
|
||||||
this.lbl备注.Size = new System.Drawing.Size(46, 23);
|
|
||||||
this.lbl备注.TabIndex = 16;
|
|
||||||
this.lbl备注.Text = "备注:";
|
|
||||||
this.lbl备注.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
|
||||||
//
|
|
||||||
// txt备注
|
|
||||||
//
|
|
||||||
this.txt备注.BackColor = System.Drawing.SystemColors.Window;
|
|
||||||
this.txt备注.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.txt备注.ForeColor = System.Drawing.SystemColors.WindowText;
|
|
||||||
this.txt备注.Location = new System.Drawing.Point(95, 352);
|
|
||||||
this.txt备注.Multiline = true;
|
|
||||||
this.txt备注.Name = "txt备注";
|
|
||||||
this.txt备注.Size = new System.Drawing.Size(570, 80);
|
|
||||||
this.txt备注.TabIndex = 16;
|
|
||||||
//
|
|
||||||
// btn确定
|
|
||||||
//
|
|
||||||
this.btn确定.BackColor = System.Drawing.SystemColors.Control;
|
|
||||||
this.btn确定.DialogResult = System.Windows.Forms.DialogResult.OK;
|
|
||||||
this.btn确定.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.btn确定.ForeColor = System.Drawing.SystemColors.ControlText;
|
|
||||||
this.btn确定.Location = new System.Drawing.Point(455, 449);
|
|
||||||
this.btn确定.Name = "btn确定";
|
|
||||||
this.btn确定.Size = new System.Drawing.Size(100, 28);
|
|
||||||
this.btn确定.TabIndex = 17;
|
|
||||||
this.btn确定.Text = "确定";
|
|
||||||
this.btn确定.UseVisualStyleBackColor = true;
|
|
||||||
//
|
|
||||||
// btn取消
|
|
||||||
//
|
|
||||||
this.btn取消.BackColor = System.Drawing.SystemColors.Control;
|
|
||||||
this.btn取消.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
|
||||||
this.btn取消.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.btn取消.ForeColor = System.Drawing.SystemColors.ControlText;
|
|
||||||
this.btn取消.Location = new System.Drawing.Point(565, 449);
|
|
||||||
this.btn取消.Name = "btn取消";
|
|
||||||
this.btn取消.Size = new System.Drawing.Size(100, 28);
|
|
||||||
this.btn取消.TabIndex = 18;
|
|
||||||
this.btn取消.Text = "取消";
|
|
||||||
this.btn取消.UseVisualStyleBackColor = true;
|
|
||||||
//
|
|
||||||
// comboBox1
|
|
||||||
//
|
|
||||||
this.comboBox1.BackColor = System.Drawing.SystemColors.Window;
|
|
||||||
this.comboBox1.DropDownWidth = 210;
|
|
||||||
this.comboBox1.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.comboBox1.ForeColor = System.Drawing.SystemColors.WindowText;
|
|
||||||
this.comboBox1.ItemHeight = 18;
|
|
||||||
this.comboBox1.Location = new System.Drawing.Point(455, 322);
|
|
||||||
this.comboBox1.Name = "comboBox1";
|
|
||||||
this.comboBox1.Size = new System.Drawing.Size(210, 26);
|
|
||||||
this.comboBox1.TabIndex = 14;
|
|
||||||
this.comboBox1.Text = "四舍五入";
|
|
||||||
//
|
|
||||||
// label1
|
|
||||||
//
|
|
||||||
this.label1.BackColor = System.Drawing.SystemColors.Control;
|
|
||||||
this.label1.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.label1.ForeColor = System.Drawing.SystemColors.ControlText;
|
|
||||||
this.label1.Location = new System.Drawing.Point(19, 320);
|
|
||||||
this.label1.Name = "label1";
|
|
||||||
this.label1.Size = new System.Drawing.Size(70, 23);
|
|
||||||
this.label1.TabIndex = 14;
|
|
||||||
this.label1.Text = "单台取整:";
|
|
||||||
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
|
||||||
//
|
|
||||||
// label2
|
|
||||||
//
|
|
||||||
this.label2.BackColor = System.Drawing.SystemColors.Control;
|
|
||||||
this.label2.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.label2.ForeColor = System.Drawing.SystemColors.ControlText;
|
|
||||||
this.label2.Location = new System.Drawing.Point(379, 324);
|
|
||||||
this.label2.Name = "label2";
|
|
||||||
this.label2.Size = new System.Drawing.Size(70, 20);
|
|
||||||
this.label2.TabIndex = 15;
|
|
||||||
this.label2.Text = "项目取整:";
|
|
||||||
//
|
|
||||||
// comboBox2
|
|
||||||
//
|
|
||||||
this.comboBox2.BackColor = System.Drawing.SystemColors.Window;
|
|
||||||
this.comboBox2.DropDownWidth = 220;
|
|
||||||
this.comboBox2.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.comboBox2.ForeColor = System.Drawing.SystemColors.WindowText;
|
|
||||||
this.comboBox2.ItemHeight = 18;
|
|
||||||
this.comboBox2.Location = new System.Drawing.Point(95, 324);
|
|
||||||
this.comboBox2.Name = "comboBox2";
|
|
||||||
this.comboBox2.Size = new System.Drawing.Size(220, 26);
|
|
||||||
this.comboBox2.TabIndex = 14;
|
|
||||||
this.comboBox2.Text = "四舍五入";
|
|
||||||
//
|
|
||||||
// cmb项目总价
|
|
||||||
//
|
|
||||||
this.cmb项目总价.BackColor = System.Drawing.SystemColors.Window;
|
|
||||||
this.cmb项目总价.DropDownWidth = 200;
|
|
||||||
this.cmb项目总价.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.cmb项目总价.ForeColor = System.Drawing.SystemColors.WindowText;
|
|
||||||
this.cmb项目总价.ItemHeight = 18;
|
|
||||||
this.cmb项目总价.Location = new System.Drawing.Point(455, 290);
|
|
||||||
this.cmb项目总价.Name = "cmb项目总价";
|
|
||||||
this.cmb项目总价.Size = new System.Drawing.Size(210, 26);
|
|
||||||
this.cmb项目总价.TabIndex = 14;
|
|
||||||
this.cmb项目总价.Text = "保留整数";
|
|
||||||
//
|
|
||||||
// 新建项目
|
|
||||||
//
|
|
||||||
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(678, 482);
|
|
||||||
this.Controls.Add(this.lbl项目编号);
|
|
||||||
this.Controls.Add(this.txt项目编号);
|
|
||||||
this.Controls.Add(this.lbl项目日期);
|
|
||||||
this.Controls.Add(this.txt项目日期);
|
|
||||||
this.Controls.Add(this.lbl项目名称);
|
|
||||||
this.Controls.Add(this.txt项目名称);
|
|
||||||
this.Controls.Add(this.lbl客户名称);
|
|
||||||
this.Controls.Add(this.txt客户名称);
|
|
||||||
this.Controls.Add(this.btn选择客户);
|
|
||||||
this.Controls.Add(this.lbl客户地址);
|
|
||||||
this.Controls.Add(this.txt客户地址);
|
|
||||||
this.Controls.Add(this.lbl联系人);
|
|
||||||
this.Controls.Add(this.txt联系人);
|
|
||||||
this.Controls.Add(this.lbl联系电话);
|
|
||||||
this.Controls.Add(this.txt联系电话);
|
|
||||||
this.Controls.Add(this.lbl成套厂名称);
|
|
||||||
this.Controls.Add(this.txt成套厂名称);
|
|
||||||
this.Controls.Add(this.lbl成套厂地址);
|
|
||||||
this.Controls.Add(this.txt成套厂地址);
|
|
||||||
this.Controls.Add(this.lbl成套厂联系人);
|
|
||||||
this.Controls.Add(this.txt成套厂联系人);
|
|
||||||
this.Controls.Add(this.lbl成套厂联系电话);
|
|
||||||
this.Controls.Add(this.txt成套厂联系电话);
|
|
||||||
this.Controls.Add(this.lbl报出方式);
|
|
||||||
this.Controls.Add(this.cmb报出方式);
|
|
||||||
this.Controls.Add(this.lbl箱柜模板);
|
|
||||||
this.Controls.Add(this.cmb箱柜模板);
|
|
||||||
this.Controls.Add(this.lbl单台价格);
|
|
||||||
this.Controls.Add(this.cmb单台价格);
|
|
||||||
this.Controls.Add(this.lbl项目总价);
|
|
||||||
this.Controls.Add(this.lbl备注);
|
|
||||||
this.Controls.Add(this.txt备注);
|
|
||||||
this.Controls.Add(this.btn确定);
|
|
||||||
this.Controls.Add(this.btn取消);
|
|
||||||
this.Controls.Add(this.comboBox1);
|
|
||||||
this.Controls.Add(this.label1);
|
|
||||||
this.Controls.Add(this.label2);
|
|
||||||
this.Controls.Add(this.comboBox2);
|
|
||||||
this.Controls.Add(this.cmb项目总价);
|
|
||||||
this.Font = new System.Drawing.Font("宋体", 9F);
|
|
||||||
this.ForeColor = System.Drawing.SystemColors.ControlText;
|
|
||||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
|
|
||||||
this.MaximizeBox = false;
|
|
||||||
this.MinimizeBox = false;
|
|
||||||
this.Name = "新建项目";
|
|
||||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
|
||||||
this.Text = "新建项目";
|
|
||||||
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项目总价;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,132 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
|
|
||||||
namespace MyApp
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 新建项目 窗口(简化版,不依赖企业信息)。
|
|
||||||
/// UI 布局见 新建项目.ui.cs,本文件只含交互逻辑。
|
|
||||||
/// </summary>
|
|
||||||
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) { }
|
|
||||||
|
|
||||||
/// <summary>带数据库路径的构造函数(用于自动生成项目编号)。</summary>
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>自动填充项目日期(当天)和项目编号(yyyyMMdd+3位序号)。</summary>
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>查数据库当天最大序号+1,失败返回1。</summary>
|
|
||||||
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; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>收集对话框字段,以列名为键返回(供 Form3 写入数据库)。</summary>
|
|
||||||
public Dictionary<string, string> GetInputValues()
|
|
||||||
{
|
|
||||||
var values = new Dictionary<string, string>();
|
|
||||||
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<string, string> dict, string key, string value)
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrWhiteSpace(value)) dict[key] = value.Trim();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,120 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<root>
|
|
||||||
<!--
|
|
||||||
Microsoft ResX Schema
|
|
||||||
|
|
||||||
Version 2.0
|
|
||||||
|
|
||||||
The primary goals of this format is to allow a simple XML format
|
|
||||||
that is mostly human readable. The generation and parsing of the
|
|
||||||
various data types are done through the TypeConverter classes
|
|
||||||
associated with the data types.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
... ado.net/XML headers & schema ...
|
|
||||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
|
||||||
<resheader name="version">2.0</resheader>
|
|
||||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
|
||||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
|
||||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
|
||||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
|
||||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
|
||||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
|
||||||
</data>
|
|
||||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
|
||||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
|
||||||
<comment>This is a comment</comment>
|
|
||||||
</data>
|
|
||||||
|
|
||||||
There are any number of "resheader" rows that contain simple
|
|
||||||
name/value pairs.
|
|
||||||
|
|
||||||
Each data row contains a name, and value. The row also contains a
|
|
||||||
type or mimetype. Type corresponds to a .NET class that support
|
|
||||||
text/value conversion through the TypeConverter architecture.
|
|
||||||
Classes that don't support this are serialized and stored with the
|
|
||||||
mimetype set.
|
|
||||||
|
|
||||||
The mimetype is used for serialized objects, and tells the
|
|
||||||
ResXResourceReader how to depersist the object. This is currently not
|
|
||||||
extensible. For a given mimetype the value must be set accordingly:
|
|
||||||
|
|
||||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
|
||||||
that the ResXResourceWriter will generate, however the reader can
|
|
||||||
read any of the formats listed below.
|
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.binary.base64
|
|
||||||
value : The object must be serialized with
|
|
||||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
|
||||||
: and then encoded with base64 encoding.
|
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.soap.base64
|
|
||||||
value : The object must be serialized with
|
|
||||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
|
||||||
: and then encoded with base64 encoding.
|
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
|
||||||
value : The object must be serialized into a byte array
|
|
||||||
: using a System.ComponentModel.TypeConverter
|
|
||||||
: and then encoded with base64 encoding.
|
|
||||||
-->
|
|
||||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
|
||||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
|
||||||
<xsd:element name="root" msdata:IsDataSet="true">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:choice maxOccurs="unbounded">
|
|
||||||
<xsd:element name="metadata">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
|
||||||
<xsd:attribute name="type" type="xsd:string" />
|
|
||||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
|
||||||
<xsd:attribute ref="xml:space" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="assembly">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:attribute name="alias" type="xsd:string" />
|
|
||||||
<xsd:attribute name="name" type="xsd:string" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="data">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
|
||||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
|
||||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
|
||||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
|
||||||
<xsd:attribute ref="xml:space" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="resheader">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
</xsd:choice>
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
</xsd:schema>
|
|
||||||
<resheader name="resmimetype">
|
|
||||||
<value>text/microsoft-resx</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="version">
|
|
||||||
<value>2.0</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="reader">
|
|
||||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="writer">
|
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
|
||||||
</resheader>
|
|
||||||
</root>
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
/*
|
|
||||||
* pdfbt:PDF 扒图报价工具(由 cadbt 改造,CAD 查看器 → PDF 查看 + 框选 OCR)
|
|
||||||
*/
|
|
||||||
using System;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
|
|
||||||
namespace pdfbt
|
|
||||||
{
|
|
||||||
internal sealed class Program
|
|
||||||
{
|
|
||||||
[STAThread]
|
|
||||||
private static int Main(string[] args)
|
|
||||||
{
|
|
||||||
// 自检模式:pdfbt.exe --selftest <pdf路径> [输出目录]
|
|
||||||
if (args != null && args.Length >= 2 && args[0] == "--selftest")
|
|
||||||
{
|
|
||||||
return SelfTest.Run(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 单实例保护:重复启动时激活已有实例并退出
|
|
||||||
bool createdNew;
|
|
||||||
using (var mutex = new System.Threading.Mutex(true, "pdfbt_SingleInstance", out createdNew))
|
|
||||||
{
|
|
||||||
if (!createdNew)
|
|
||||||
{
|
|
||||||
MessageBox.Show("pdfbt 已在运行中。", "pdfbt",
|
|
||||||
MessageBoxButtons.OK, MessageBoxIcon.Information);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
Application.EnableVisualStyles();
|
|
||||||
Application.SetCompatibleTextRenderingDefault(false);
|
|
||||||
Application.Run(new MainForm());
|
|
||||||
GC.KeepAlive(mutex);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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("pdfbt")]
|
|
||||||
[assembly: AssemblyDescription("")]
|
|
||||||
[assembly: AssemblyConfiguration("")]
|
|
||||||
[assembly: AssemblyCompany("")]
|
|
||||||
[assembly: AssemblyProduct("pdfbt")]
|
|
||||||
[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.*")]
|
|
||||||
@@ -1,99 +0,0 @@
|
|||||||
// ============================================================
|
|
||||||
// SelfTest:命令行自检(--selftest <pdf> [outdir])
|
|
||||||
// 无 UI 验证:pdfium 渲染 → PNG 落盘;OCR 工作进程识别 → JSON 落盘
|
|
||||||
// 用法:pdfbt.exe --selftest test.pdf .
|
|
||||||
// 返回码:0 成功;1 失败
|
|
||||||
// ============================================================
|
|
||||||
using System;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.Drawing.Imaging;
|
|
||||||
using System.IO;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using 成套报价软件; // ★ A1:OCR/PDF 基础设施已链接共享主项目源码(类型在 成套报价软件 命名空间)
|
|
||||||
namespace pdfbt
|
|
||||||
{
|
|
||||||
internal static class SelfTest
|
|
||||||
{
|
|
||||||
public static int Run(string[] args)
|
|
||||||
{
|
|
||||||
string pdf = args[1];
|
|
||||||
string outDir = args.Length >= 3 ? args[2] : ".";
|
|
||||||
var log = new StringBuilder();
|
|
||||||
int exit = 0;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// 1) pdfium 渲染
|
|
||||||
string renderPath = Path.Combine(outDir, "selftest_render.png");
|
|
||||||
Bitmap page;
|
|
||||||
using (var doc = new PdfDocument())
|
|
||||||
{
|
|
||||||
doc.Open(pdf, null);
|
|
||||||
log.AppendLine("[render] 打开成功: " + pdf + " 页数=" + doc.PageCount);
|
|
||||||
page = doc.RenderPage(0, 1.5f);
|
|
||||||
if (page == null) throw new Exception("渲染返回 null");
|
|
||||||
}
|
|
||||||
using (page)
|
|
||||||
{
|
|
||||||
page.Save(renderPath, ImageFormat.Png);
|
|
||||||
log.AppendLine("[render] 已保存: " + renderPath +
|
|
||||||
" (" + page.Width + "x" + page.Height + ")");
|
|
||||||
|
|
||||||
// 2) OCR(渲染图上半区)
|
|
||||||
var crop = new Bitmap(page.Width, page.Height / 2,
|
|
||||||
System.Drawing.Imaging.PixelFormat.Format24bppRgb);
|
|
||||||
using (var g = Graphics.FromImage(crop))
|
|
||||||
{
|
|
||||||
g.DrawImage(page, new Rectangle(0, 0, crop.Width, crop.Height),
|
|
||||||
new Rectangle(0, 0, page.Width, page.Height / 2), GraphicsUnit.Pixel);
|
|
||||||
}
|
|
||||||
|
|
||||||
using (var ocr = new OcrClient())
|
|
||||||
{
|
|
||||||
var items = ocr.RecognizeAsync(crop, 180000).Result;
|
|
||||||
var json = new StringBuilder();
|
|
||||||
json.AppendLine("{");
|
|
||||||
json.AppendLine(" \"count\": " + (items == null ? 0 : items.Count) + ",");
|
|
||||||
json.AppendLine(" \"items\": [");
|
|
||||||
if (items != null)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < items.Count; i++)
|
|
||||||
{
|
|
||||||
var it = items[i];
|
|
||||||
var b = it.Bounds;
|
|
||||||
json.AppendLine(" {\"text\": \"" +
|
|
||||||
(it.Text ?? "").Replace("\\", "\\\\").Replace("\"", "\\\"") +
|
|
||||||
"\", \"score\": " + it.Score.ToString("0.000") +
|
|
||||||
", \"bounds\": [" + b.X.ToString("0") + "," + b.Y.ToString("0") +
|
|
||||||
"," + b.Width.ToString("0") + "," + b.Height.ToString("0") + "]}" +
|
|
||||||
(i < items.Count - 1 ? "," : ""));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
json.AppendLine(" ]");
|
|
||||||
json.AppendLine("}");
|
|
||||||
string ocrPath = Path.Combine(outDir, "selftest_ocr.json");
|
|
||||||
File.WriteAllText(ocrPath, json.ToString(), new UTF8Encoding(false));
|
|
||||||
log.AppendLine("[ocr] 识别 " + (items == null ? 0 : items.Count) +
|
|
||||||
" 条,已保存: " + ocrPath);
|
|
||||||
if (items != null)
|
|
||||||
{
|
|
||||||
foreach (var it in items)
|
|
||||||
log.AppendLine(" - " + it.Text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
log.AppendLine("[FAIL] " + ex);
|
|
||||||
exit = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
string resultPath = Path.Combine(outDir, "selftest_result.txt");
|
|
||||||
File.WriteAllText(resultPath, log.ToString(), new UTF8Encoding(false));
|
|
||||||
Console.Out.WriteLine(log.ToString());
|
|
||||||
return exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<configuration>
|
|
||||||
<startup>
|
|
||||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
|
|
||||||
</startup>
|
|
||||||
<appSettings>
|
|
||||||
<!-- Python 解释器(已装 rapidocr + onnxruntime-directml) -->
|
|
||||||
<add key="PythonExe" value="F:\PythonDev\python\python\python.exe" />
|
|
||||||
<!-- OCR 工作进程脚本(相对 exe 目录) -->
|
|
||||||
<add key="OcrWorkerScript" value="ocr_worker.py" />
|
|
||||||
</appSettings>
|
|
||||||
</configuration>
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
|
||||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
|
||||||
<windowsSettings>
|
|
||||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
|
|
||||||
</windowsSettings>
|
|
||||||
</application>
|
|
||||||
</assembly>
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
-nologo
|
|
||||||
-target:winexe
|
|
||||||
-platform:x86
|
|
||||||
-utf8output
|
|
||||||
-optimize+
|
|
||||||
-out:bin\Debug\pdfbt_new.exe
|
|
||||||
-win32manifest:app.manifest
|
|
||||||
-resource:MainForm.resx,pdfbt.MainForm.resources
|
|
||||||
-resource:OcrSettingsForm.resx,pdfbt.OcrSettingsForm.resources
|
|
||||||
-resource:Plugin\Form3.resx,pdfbt.Plugin.Form3.resources
|
|
||||||
-resource:Plugin\新建项目.resx,pdfbt.Plugin.新建项目.resources
|
|
||||||
-r:bin\Debug\Smart.CustomComponents.dll
|
|
||||||
-r:bin\Debug\AdvancedDataGridView.dll
|
|
||||||
-r:bin\Debug\WeifenLuo.WinFormsUI.Docking.dll
|
|
||||||
-r:bin\Debug\WeifenLuo.WinFormsUI.Docking.ThemeVS2015.dll
|
|
||||||
-r:bin\Debug\System.Data.SQLite.dll
|
|
||||||
-r:bin\Debug\System.Memory.dll
|
|
||||||
-r:bin\Debug\System.Numerics.Vectors.dll
|
|
||||||
-r:bin\Debug\System.Resources.Extensions.dll
|
|
||||||
-r:bin\Debug\System.Runtime.CompilerServices.Unsafe.dll
|
|
||||||
-r:System.dll
|
|
||||||
-r:System.Configuration.dll
|
|
||||||
-r:System.Data.dll
|
|
||||||
-r:System.Data.DataSetExtensions.dll
|
|
||||||
-r:System.Xml.Linq.dll
|
|
||||||
-r:System.IO.Compression.dll
|
|
||||||
-r:System.IO.Compression.FileSystem.dll
|
|
||||||
-r:bin\Debug\log4net.dll
|
|
||||||
-r:netstandard.dll
|
|
||||||
-r:System.Core.dll
|
|
||||||
-r:System.Drawing.dll
|
|
||||||
-r:System.Windows.Forms.dll
|
|
||||||
-r:System.Xml.dll
|
|
||||||
-r:System.Web.Extensions.dll
|
|
||||||
-r:Microsoft.CSharp.dll
|
|
||||||
MainForm.cs
|
|
||||||
MainForm.Designer.cs
|
|
||||||
MainForm.DockWindows.cs
|
|
||||||
Program.cs
|
|
||||||
SelfTest.cs
|
|
||||||
PdfBridge.cs
|
|
||||||
PdfiumNative.cs
|
|
||||||
PdfDocument.cs
|
|
||||||
OcrClient.cs
|
|
||||||
GlmOcrClient.cs
|
|
||||||
QianfanOcrClient.cs
|
|
||||||
UapisOcrClient.cs
|
|
||||||
UmiOcrClient.cs
|
|
||||||
UmiOcrHost.cs
|
|
||||||
OcrSettingsForm.cs
|
|
||||||
OcrSettingsForm.Designer.cs
|
|
||||||
PdfViewerWindow.cs
|
|
||||||
Properties\AssemblyInfo.cs
|
|
||||||
Plugin\Form3.cs
|
|
||||||
Plugin\Form3.Designer.cs
|
|
||||||
Plugin\PaTypes.cs
|
|
||||||
Plugin\新建项目.cs
|
|
||||||
Plugin\新建项目.Designer.cs
|
|
||||||
DockWindows\QuoteWindow.cs
|
|
||||||
DockWindows\QuoteWindow.Designer.cs
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,194 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
|
|
||||||
<PropertyGroup>
|
|
||||||
<ProjectGuid>{7C2A9D4E-1F58-4B6A-9E77-3A5B10D9C8F1}</ProjectGuid>
|
|
||||||
<ProjectTypeGuids>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
|
||||||
<OutputType>WinExe</OutputType>
|
|
||||||
<RootNamespace>pdfbt</RootNamespace>
|
|
||||||
<AssemblyName>pdfbt</AssemblyName>
|
|
||||||
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
|
||||||
<PlatformTarget>x86</PlatformTarget>
|
|
||||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
|
||||||
<OutputPath>bin\Debug\</OutputPath>
|
|
||||||
<DebugSymbols>True</DebugSymbols>
|
|
||||||
<DebugType>Full</DebugType>
|
|
||||||
<Optimize>False</Optimize>
|
|
||||||
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
|
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
|
||||||
<OutputPath>bin\Release\</OutputPath>
|
|
||||||
<DebugSymbols>False</DebugSymbols>
|
|
||||||
<DebugType>None</DebugType>
|
|
||||||
<Optimize>True</Optimize>
|
|
||||||
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
|
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' ">
|
|
||||||
<Prefer32Bit>True</Prefer32Bit>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Reference Include="Microsoft.CSharp">
|
|
||||||
<RequiredTargetFramework>4.0</RequiredTargetFramework>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System" />
|
|
||||||
<Reference Include="System.Configuration" />
|
|
||||||
<Reference Include="System.Core">
|
|
||||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System.Data" />
|
|
||||||
<Reference Include="System.Data.DataSetExtensions">
|
|
||||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System.Drawing" />
|
|
||||||
<Reference Include="System.Windows.Forms" />
|
|
||||||
<Reference Include="System.Xml" />
|
|
||||||
<Reference Include="System.Xml.Linq">
|
|
||||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System.Web.Extensions">
|
|
||||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System.IO.Compression" />
|
|
||||||
<Reference Include="System.IO.Compression.FileSystem" />
|
|
||||||
<Reference Include="Smart.CustomComponents, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ba044a4aa43e0dc4">
|
|
||||||
<HintPath>C:\Program Files (x86)\SharpDevelop\5.2\bin\Smart.CustomComponents.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="WeifenLuo.WinFormsUI.Docking">
|
|
||||||
<HintPath>C:\Program Files (x86)\SharpDevelop\5.2\bin\WeifenLuo.WinFormsUI.Docking.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="WeifenLuo.WinFormsUI.Docking.ThemeVS2015">
|
|
||||||
<HintPath>C:\Program Files (x86)\SharpDevelop\5.2\bin\WeifenLuo.WinFormsUI.Docking.ThemeVS2015.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System.Data.SQLite">
|
|
||||||
<HintPath>C:\Program Files (x86)\SharpDevelop\5.2\bin\System.Data.SQLite.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="log4net">
|
|
||||||
<HintPath>C:\Program Files (x86)\SharpDevelop\5.2\bin\log4net.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System.Resources.Extensions">
|
|
||||||
<HintPath>C:\Program Files (x86)\SharpDevelop\5.2\bin\System.Resources.Extensions.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System.Memory">
|
|
||||||
<HintPath>C:\Program Files (x86)\SharpDevelop\5.2\bin\System.Memory.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System.Runtime.CompilerServices.Unsafe">
|
|
||||||
<HintPath>C:\Program Files (x86)\SharpDevelop\5.2\bin\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System.Numerics.Vectors">
|
|
||||||
<HintPath>C:\Program Files (x86)\SharpDevelop\5.2\bin\System.Numerics.Vectors.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="AdvancedDataGridView">
|
|
||||||
<HintPath>libs\AdvancedDataGridView.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<!-- System.Memory 等 facade 库触发 CS0012,需 netstandard 契约 -->
|
|
||||||
<Reference Include="netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51">
|
|
||||||
<HintPath>C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\Facades\netstandard.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Compile Include="MainForm.cs" />
|
|
||||||
<Compile Include="MainForm.Designer.cs">
|
|
||||||
<DependentUpon>MainForm.cs</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="MainForm.DockWindows.cs">
|
|
||||||
<DependentUpon>MainForm.cs</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="Program.cs" />
|
|
||||||
<Compile Include="SelfTest.cs" />
|
|
||||||
<Compile Include="PdfBridge.cs" />
|
|
||||||
<!-- ★ A1(2026-10-01):OCR/PDF 基础设施与主项目共享同一份源码(链接编译,不再各留副本)——
|
|
||||||
权威源 成套报价软件\扒图\(主项目版为演进版,含 OcrPaths 旧布局回退/ocr.cls 方向纠正/
|
|
||||||
UmiOcr 启停拆分等修复);此前 pdfbt 侧 10 个本地副本是旧快照,已删除(git 基线可找回) -->
|
|
||||||
<Compile Include="..\成套报价软件\扒图\PdfiumNative.cs">
|
|
||||||
<Link>共享扒图\PdfiumNative.cs</Link>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="..\成套报价软件\扒图\PdfDocument.cs">
|
|
||||||
<Link>共享扒图\PdfDocument.cs</Link>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="..\成套报价软件\扒图\OcrClient.cs">
|
|
||||||
<Link>共享扒图\OcrClient.cs</Link>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="..\成套报价软件\扒图\GlmOcrClient.cs">
|
|
||||||
<Link>共享扒图\GlmOcrClient.cs</Link>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="..\成套报价软件\扒图\QianfanOcrClient.cs">
|
|
||||||
<Link>共享扒图\QianfanOcrClient.cs</Link>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="..\成套报价软件\扒图\UapisOcrClient.cs">
|
|
||||||
<Link>共享扒图\UapisOcrClient.cs</Link>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="..\成套报价软件\扒图\UmiOcrClient.cs">
|
|
||||||
<Link>共享扒图\UmiOcrClient.cs</Link>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="..\成套报价软件\扒图\UmiOcrHost.cs">
|
|
||||||
<Link>共享扒图\UmiOcrHost.cs</Link>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="..\成套报价软件\扒图\UmiOcrLauncher.cs">
|
|
||||||
<Link>共享扒图\UmiOcrLauncher.cs</Link>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="..\成套报价软件\扒图\OcrSettingsForm.cs">
|
|
||||||
<Link>共享扒图\OcrSettingsForm.cs</Link>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="..\成套报价软件\扒图\OcrSettingsForm.Designer.cs">
|
|
||||||
<Link>共享扒图\OcrSettingsForm.Designer.cs</Link>
|
|
||||||
<DependentUpon>OcrSettingsForm.cs</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="PdfViewerWindow.cs" />
|
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
|
||||||
<Compile Include="Plugin\Form3.cs" />
|
|
||||||
<Compile Include="Plugin\Form3.Designer.cs">
|
|
||||||
<DependentUpon>Form3.cs</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="Plugin\PaTypes.cs" />
|
|
||||||
<Compile Include="Plugin\新建项目.cs" />
|
|
||||||
<Compile Include="Plugin\新建项目.Designer.cs">
|
|
||||||
<DependentUpon>新建项目.cs</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="DockWindows\QuoteWindow.cs" />
|
|
||||||
<Compile Include="DockWindows\QuoteWindow.Designer.cs">
|
|
||||||
<DependentUpon>QuoteWindow.cs</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="app.config" />
|
|
||||||
<None Include="app.manifest" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<!-- x86 pdfium(pypdfium2 win32 wheel 提取,与 SQLite x86 一致) -->
|
|
||||||
<Content Include="libs\pdfium\pdfium.dll">
|
|
||||||
<Link>pdfium.dll</Link>
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<!-- Python OCR 工作进程脚本(rapidocr + DirectML GPU 加速) -->
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<EmbeddedResource Include="MainForm.resx">
|
|
||||||
<DependentUpon>MainForm.cs</DependentUpon>
|
|
||||||
</EmbeddedResource>
|
|
||||||
<!-- OcrSettingsForm.resx 删除:表单已链接共享主项目源码(A1),本地空壳 resx 与链接 Designer 不再匹配 -->
|
|
||||||
<EmbeddedResource Include="Plugin\Form3.resx">
|
|
||||||
<DependentUpon>Form3.cs</DependentUpon>
|
|
||||||
</EmbeddedResource>
|
|
||||||
<EmbeddedResource Include="Plugin\新建项目.resx">
|
|
||||||
<DependentUpon>新建项目.cs</DependentUpon>
|
|
||||||
</EmbeddedResource>
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
|
||||||
</Project>
|
|
||||||
@@ -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}") = "pdfbt", "pdfbt.csproj", "{7C2A9D4E-1F58-4B6A-9E77-3A5B10D9C8F1}"
|
|
||||||
EndProject
|
|
||||||
Global
|
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
||||||
Debug|Any CPU = Debug|Any CPU
|
|
||||||
Release|Any CPU = Release|Any CPU
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
||||||
{7C2A9D4E-1F58-4B6A-9E77-3A5B10D9C8F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{7C2A9D4E-1F58-4B6A-9E77-3A5B10D9C8F1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{7C2A9D4E-1F58-4B6A-9E77-3A5B10D9C8F1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{7C2A9D4E-1F58-4B6A-9E77-3A5B10D9C8F1}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
// 复现 OCR 设置窗报错,把完整异常写到文件
|
|
||||||
using System;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
|
|
||||||
namespace pdfbt
|
|
||||||
{
|
|
||||||
static class ShowErr
|
|
||||||
{
|
|
||||||
[STAThread]
|
|
||||||
static void Main()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var f = new OcrSettingsForm(null);
|
|
||||||
f.Show();
|
|
||||||
Application.DoEvents();
|
|
||||||
FileLog("窗口创建成功,无异常");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
FileLog("EX: " + ex);
|
|
||||||
var inner = ex.InnerException;
|
|
||||||
while (inner != null) { FileLog("INNER: " + inner); inner = inner.InnerException; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static void FileLog(string s)
|
|
||||||
{
|
|
||||||
System.IO.File.AppendAllText(@"C:\Users\099978\Documents\SharpDevelop Projects\pdfbt\showerr.log", s + "\r\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -118,10 +118,8 @@ Source: "sjk\*"; DestDir: "{app}\sjk"; Flags: ignoreversion recursesubdirs creat
|
|||||||
Source: "shezhi\*"; DestDir: "{app}\shezhi"; Flags: ignoreversion recursesubdirs createallsubdirs
|
Source: "shezhi\*"; DestDir: "{app}\shezhi"; Flags: ignoreversion recursesubdirs createallsubdirs
|
||||||
; 甲方报表 Excel 模板(按图号/按箱号/按箱号+箱体面积/按箱类型)
|
; 甲方报表 Excel 模板(按图号/按箱号/按箱号+箱体面积/按箱类型)
|
||||||
Source: "xiangmu\*"; DestDir: "{app}\xiangmu"; Flags: ignoreversion recursesubdirs createallsubdirs
|
Source: "xiangmu\*"; DestDir: "{app}\xiangmu"; Flags: ignoreversion recursesubdirs createallsubdirs
|
||||||
; CAD 扒图(独立程序,默认安装)
|
; CAD 网页引擎运行时(node+CAD-Viewer;2026-10-01 独立 cadbt.exe 退役,主程序内嵌扒图窗口用)
|
||||||
Source: "cadbt\*"; DestDir: "{app}\cadbt"; Flags: ignoreversion recursesubdirs createallsubdirs
|
Source: "cadbt\*"; DestDir: "{app}\cadbt"; Flags: ignoreversion recursesubdirs createallsubdirs
|
||||||
; PDF 扒图(独立程序+OCR 环境,默认安装)
|
|
||||||
Source: "pdfbt\*"; DestDir: "{app}\pdfbt"; Flags: ignoreversion recursesubdirs createallsubdirs
|
|
||||||
; AI 助手引擎(ZCode 开源版 zai-org/ZCode,Apache-2.0:zcode 发行包+捆绑 node+预置+启停 cmd;zcode数据 运行时自建不进包)
|
; AI 助手引擎(ZCode 开源版 zai-org/ZCode,Apache-2.0:zcode 发行包+捆绑 node+预置+启停 cmd;zcode数据 运行时自建不进包)
|
||||||
Source: "ai助手\*"; DestDir: "{app}\ai助手"; Flags: ignoreversion recursesubdirs createallsubdirs
|
Source: "ai助手\*"; DestDir: "{app}\ai助手"; Flags: ignoreversion recursesubdirs createallsubdirs
|
||||||
; 会员服务器不进包(2026-09-22 用户长期规则:客户端默认连云端 https://ss61.odn.cc,部署套件单独交付)
|
; 会员服务器不进包(2026-09-22 用户长期规则:客户端默认连云端 https://ss61.odn.cc,部署套件单独交付)
|
||||||
|
|||||||
+2
-17
@@ -119,13 +119,9 @@ def main():
|
|||||||
ignore=shutil.ignore_patterns("__pycache__", "*.pyc"))
|
ignore=shutil.ignore_patterns("__pycache__", "*.pyc"))
|
||||||
print("复制目录", d)
|
print("复制目录", d)
|
||||||
|
|
||||||
# ===== cadbt(CAD扒图独立程序,默认安装) =====
|
# ===== cadbt(CAD 网页引擎运行时;2026-10-01 独立 cadbt.exe 退役,只装 node+CAD-Viewer) =====
|
||||||
cadbt_src = os.path.join(ROOT, "cadbt", "cadbt", "bin", "Debug")
|
cadbt_src = os.path.join(ROOT, "cadbt", "cadbt", "bin", "Debug")
|
||||||
cadbt_dst = os.path.join(REL, "cadbt")
|
cadbt_dst = os.path.join(REL, "cadbt")
|
||||||
os.makedirs(cadbt_dst, exist_ok=True)
|
|
||||||
for f in os.listdir(cadbt_src):
|
|
||||||
if f.endswith((".exe", ".dll", ".config")):
|
|
||||||
shutil.copy2(os.path.join(cadbt_src, f), os.path.join(cadbt_dst, f))
|
|
||||||
os.makedirs(os.path.join(cadbt_dst, "node"), exist_ok=True)
|
os.makedirs(os.path.join(cadbt_dst, "node"), exist_ok=True)
|
||||||
shutil.copy2(os.path.join(cadbt_src, "node", "node.exe"), os.path.join(cadbt_dst, "node", "node.exe"))
|
shutil.copy2(os.path.join(cadbt_src, "node", "node.exe"), os.path.join(cadbt_dst, "node", "node.exe"))
|
||||||
dist_src = os.path.join(ROOT, "cadbt", "cadbt", "CAD-Viewer", "packages", "cad-viewer-example", "dist")
|
dist_src = os.path.join(ROOT, "cadbt", "cadbt", "CAD-Viewer", "packages", "cad-viewer-example", "dist")
|
||||||
@@ -148,18 +144,7 @@ def main():
|
|||||||
print("补齐 dist/server.cjs")
|
print("补齐 dist/server.cjs")
|
||||||
else:
|
else:
|
||||||
print("!! 运行目录缺少 server.cjs(CAD 网页服务起不来!)")
|
print("!! 运行目录缺少 server.cjs(CAD 网页服务起不来!)")
|
||||||
os.makedirs(os.path.join(cadbt_dst, "sjk", "bjb"), exist_ok=True)
|
print("复制目录 cadbt(node+CAD-Viewer 网页引擎+fonts/templates/server.cjs;独立 exe 已退役)")
|
||||||
print("复制目录 cadbt(exe+DLL+node+dist 网页+fonts/templates/server.cjs)")
|
|
||||||
|
|
||||||
# ===== pdfbt(PDF扒图独立程序+OCR Python 环境,默认安装) =====
|
|
||||||
pdfbt_src = os.path.join(ROOT, "pdfbt", "bin", "Debug")
|
|
||||||
pdfbt_dst = os.path.join(REL, "pdfbt")
|
|
||||||
os.makedirs(pdfbt_dst, exist_ok=True)
|
|
||||||
for f in os.listdir(pdfbt_src):
|
|
||||||
if f.endswith((".exe", ".dll", ".config")):
|
|
||||||
shutil.copy2(os.path.join(pdfbt_src, f), os.path.join(pdfbt_dst, f))
|
|
||||||
os.makedirs(os.path.join(pdfbt_dst, "sjk", "bjb"), exist_ok=True)
|
|
||||||
print("复制目录 pdfbt(exe+pdfium,OCR=百度API无需本地环境)")
|
|
||||||
|
|
||||||
# ===== AI 助手引擎目录(2026-09-26 OpenClaw→ZCode 开源版 zai-org/ZCode) =====
|
# ===== AI 助手引擎目录(2026-09-26 OpenClaw→ZCode 开源版 zai-org/ZCode) =====
|
||||||
# ai助手\ = zcode\(官方 build:zcode 发行包:bin/web/server/agent/node_modules + 捆绑 node)
|
# ai助手\ = zcode\(官方 build:zcode 发行包:bin/web/server/agent/node_modules + 捆绑 node)
|
||||||
|
|||||||
@@ -48,9 +48,7 @@ def main():
|
|||||||
|
|
||||||
# 主程序
|
# 主程序
|
||||||
shutil.copy2(os.path.join(REL, "成套报价软件.exe"), PKG)
|
shutil.copy2(os.path.join(REL, "成套报价软件.exe"), PKG)
|
||||||
|
# (2026-10-01 独立 pdfbt.exe 退役后不再随更新包分发)
|
||||||
# PDF 扒图独立程序(2026-10-01 第2期:缩放卡顿同步修复)
|
|
||||||
shutil.copy2(os.path.join(REL, "pdfbt", "pdfbt.exe"), PKG)
|
|
||||||
|
|
||||||
# 使用说明(GBK,记事本直接打开不乱码)
|
# 使用说明(GBK,记事本直接打开不乱码)
|
||||||
with open(os.path.join(PKG, "使用说明.txt"), "w", encoding="gbk", newline="\r\n") as f:
|
with open(os.path.join(PKG, "使用说明.txt"), "w", encoding="gbk", newline="\r\n") as f:
|
||||||
|
|||||||
+24
-10
@@ -1,4 +1,4 @@
|
|||||||
# ============================================================
|
# ============================================================
|
||||||
# 扒图同步检查.ps1 —— Cad/Pdf 扒图窗口 Form3.cs 漂移护栏
|
# 扒图同步检查.ps1 —— Cad/Pdf 扒图窗口 Form3.cs 漂移护栏
|
||||||
# ============================================================
|
# ============================================================
|
||||||
# 背景: 扒图\Cad\Form3.cs 与 扒图\Pdf\Form3.cs 是约 98% 重复的双胞胎文件
|
# 背景: 扒图\Cad\Form3.cs 与 扒图\Pdf\Form3.cs 是约 98% 重复的双胞胎文件
|
||||||
@@ -18,8 +18,19 @@ $cadPath = Join-Path $root '成套报价软件\扒图\Cad\Form3.cs'
|
|||||||
$pdfPath = Join-Path $root '成套报价软件\扒图\Pdf\Form3.cs'
|
$pdfPath = Join-Path $root '成套报价软件\扒图\Pdf\Form3.cs'
|
||||||
$baseline = Join-Path $PSScriptRoot '扒图同步基线.txt'
|
$baseline = Join-Path $PSScriptRoot '扒图同步基线.txt'
|
||||||
|
|
||||||
foreach ($f in @($cadPath, $pdfPath)) {
|
# ★ 2026-10-01 扩充:从只查 Form3.cs 扩展到全部 Cad/Pdf 双胞胎文件对
|
||||||
|
# (新建项目.cs 与两对 Designer/ui.cs 此前是漂移盲区)
|
||||||
|
$pairs = @(
|
||||||
|
@('成套报价软件\扒图\Cad\Form3.cs', '成套报价软件\扒图\Pdf\Form3.cs'),
|
||||||
|
@('成套报价软件\扒图\Cad\新建项目.cs', '成套报价软件\扒图\Pdf\新建项目.cs'),
|
||||||
|
@('成套报价软件\扒图\Cad\Form3.ui.cs', '成套报价软件\扒图\Pdf\Form3.Designer.cs'),
|
||||||
|
@('成套报价软件\扒图\Cad\新建项目.ui.cs', '成套报价软件\扒图\Pdf\新建项目.Designer.cs')
|
||||||
|
)
|
||||||
|
|
||||||
|
foreach ($p in $pairs) {
|
||||||
|
foreach ($f in @((Join-Path $root $p[0]), (Join-Path $root $p[1]))) {
|
||||||
if (-not (Test-Path $f)) { Write-Host "[FAIL] 缺少文件: $f" -ForegroundColor Red; exit 2 }
|
if (-not (Test-Path $f)) { Write-Host "[FAIL] 缺少文件: $f" -ForegroundColor Red; exit 2 }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Normalize([string]$path) {
|
function Normalize([string]$path) {
|
||||||
@@ -34,17 +45,20 @@ function Normalize([string]$path) {
|
|||||||
|
|
||||||
$tmpCad = Join-Path $env:TEMP 'baotu_cad_norm.cs'
|
$tmpCad = Join-Path $env:TEMP 'baotu_cad_norm.cs'
|
||||||
$tmpPdf = Join-Path $env:TEMP 'baotu_pdf_norm.cs'
|
$tmpPdf = Join-Path $env:TEMP 'baotu_pdf_norm.cs'
|
||||||
Normalize $cadPath | Set-Content $tmpCad -Encoding UTF8
|
|
||||||
Normalize $pdfPath | Set-Content $tmpPdf -Encoding UTF8
|
|
||||||
|
|
||||||
$diffFile = Join-Path $env:TEMP 'baotu_drift.diff'
|
$diffFile = Join-Path $env:TEMP 'baotu_drift.diff'
|
||||||
$null = git diff --no-index --unified=1 $tmpCad $tmpPdf 2>$null | Out-File $diffFile -Encoding UTF8
|
|
||||||
|
|
||||||
$numstat = git diff --no-index --numstat $tmpCad $tmpPdf 2>$null
|
|
||||||
$added = 0; $deleted = 0
|
$added = 0; $deleted = 0
|
||||||
if ($numstat) {
|
"" | Out-File $diffFile -Encoding UTF8
|
||||||
|
|
||||||
|
foreach ($p in $pairs) {
|
||||||
|
$cadF = Join-Path $root $p[0]; $pdfF = Join-Path $root $p[1]
|
||||||
|
Normalize $cadF | Set-Content $tmpCad -Encoding UTF8
|
||||||
|
Normalize $pdfF | Set-Content $tmpPdf -Encoding UTF8
|
||||||
|
$null = git diff --no-index --unified=1 $tmpCad $tmpPdf 2>$null | Out-File $diffFile -Append -Encoding UTF8
|
||||||
|
$numstat = git diff --no-index --numstat $tmpCad $tmpPdf 2>$null
|
||||||
|
if ($numstat) {
|
||||||
$parts = (@($numstat)[0]) -split "`t"
|
$parts = (@($numstat)[0]) -split "`t"
|
||||||
if ($parts.Count -ge 2) { $added = [int]$parts[0]; $deleted = [int]$parts[1] }
|
if ($parts.Count -ge 2) { $added += [int]$parts[0]; $deleted += [int]$parts[1] }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$drift = $added + $deleted
|
$drift = $added + $deleted
|
||||||
|
|
||||||
|
|||||||
Generated
-269
@@ -1,269 +0,0 @@
|
|||||||
namespace yjktool
|
|
||||||
{
|
|
||||||
partial class MainForm
|
|
||||||
{
|
|
||||||
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.lbl搜索 = new System.Windows.Forms.Label();
|
|
||||||
this.txt搜索 = new System.Windows.Forms.TextBox();
|
|
||||||
this.lst厂家 = new System.Windows.Forms.ListView();
|
|
||||||
this.btn全选 = new System.Windows.Forms.Button();
|
|
||||||
this.btn反选 = new System.Windows.Forms.Button();
|
|
||||||
this.lbl线程 = new System.Windows.Forms.Label();
|
|
||||||
this.num线程 = new System.Windows.Forms.NumericUpDown();
|
|
||||||
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.chk代理 = new System.Windows.Forms.CheckBox();
|
|
||||||
this.lbl代理 = new System.Windows.Forms.Label();
|
|
||||||
this.chk清理 = new System.Windows.Forms.CheckBox();
|
|
||||||
this.progress = new System.Windows.Forms.ProgressBar();
|
|
||||||
this.lbl进度 = new System.Windows.Forms.Label();
|
|
||||||
this.rtb日志 = new System.Windows.Forms.RichTextBox();
|
|
||||||
this.lbl统计 = new System.Windows.Forms.Label();
|
|
||||||
((System.ComponentModel.ISupportInitialize)(this.num线程)).BeginInit();
|
|
||||||
this.SuspendLayout();
|
|
||||||
//
|
|
||||||
// lbl搜索
|
|
||||||
//
|
|
||||||
this.lbl搜索.AutoSize = true;
|
|
||||||
this.lbl搜索.Location = new System.Drawing.Point(12, 15);
|
|
||||||
this.lbl搜索.Name = "lbl搜索";
|
|
||||||
this.lbl搜索.Size = new System.Drawing.Size(37, 17);
|
|
||||||
this.lbl搜索.TabIndex = 0;
|
|
||||||
this.lbl搜索.Text = "搜索:";
|
|
||||||
//
|
|
||||||
// txt搜索
|
|
||||||
//
|
|
||||||
this.txt搜索.Location = new System.Drawing.Point(55, 12);
|
|
||||||
this.txt搜索.Name = "txt搜索";
|
|
||||||
this.txt搜索.Size = new System.Drawing.Size(200, 25);
|
|
||||||
this.txt搜索.TabIndex = 1;
|
|
||||||
this.txt搜索.TextChanged += new System.EventHandler(this.txt搜索_TextChanged);
|
|
||||||
//
|
|
||||||
// lst厂家
|
|
||||||
//
|
|
||||||
this.lst厂家.CheckBoxes = true;
|
|
||||||
this.lst厂家.Columns.Add("厂家");
|
|
||||||
this.lst厂家.Columns[0].Width = 240;
|
|
||||||
this.lst厂家.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
|
|
||||||
this.lst厂家.HideSelection = true;
|
|
||||||
this.lst厂家.Location = new System.Drawing.Point(12, 44);
|
|
||||||
this.lst厂家.MultiSelect = false;
|
|
||||||
this.lst厂家.Name = "lst厂家";
|
|
||||||
this.lst厂家.ShowGroups = false;
|
|
||||||
this.lst厂家.Size = new System.Drawing.Size(262, 470);
|
|
||||||
this.lst厂家.TabIndex = 2;
|
|
||||||
this.lst厂家.View = System.Windows.Forms.View.Details;
|
|
||||||
//
|
|
||||||
// btn全选
|
|
||||||
//
|
|
||||||
this.btn全选.Location = new System.Drawing.Point(12, 520);
|
|
||||||
this.btn全选.Name = "btn全选";
|
|
||||||
this.btn全选.Size = new System.Drawing.Size(75, 28);
|
|
||||||
this.btn全选.TabIndex = 3;
|
|
||||||
this.btn全选.Text = "全选";
|
|
||||||
this.btn全选.UseVisualStyleBackColor = true;
|
|
||||||
this.btn全选.Click += new System.EventHandler(this.btn全选_Click);
|
|
||||||
//
|
|
||||||
// btn反选
|
|
||||||
//
|
|
||||||
this.btn反选.Location = new System.Drawing.Point(96, 520);
|
|
||||||
this.btn反选.Name = "btn反选";
|
|
||||||
this.btn反选.Size = new System.Drawing.Size(75, 28);
|
|
||||||
this.btn反选.TabIndex = 4;
|
|
||||||
this.btn反选.Text = "反选";
|
|
||||||
this.btn反选.UseVisualStyleBackColor = true;
|
|
||||||
this.btn反选.Click += new System.EventHandler(this.btn反选_Click);
|
|
||||||
//
|
|
||||||
// lbl统计
|
|
||||||
//
|
|
||||||
this.lbl统计.AutoSize = true;
|
|
||||||
this.lbl统计.ForeColor = System.Drawing.Color.DimGray;
|
|
||||||
this.lbl统计.Location = new System.Drawing.Point(180, 525);
|
|
||||||
this.lbl统计.Name = "lbl统计";
|
|
||||||
this.lbl统计.Size = new System.Drawing.Size(0, 17);
|
|
||||||
this.lbl统计.TabIndex = 5;
|
|
||||||
//
|
|
||||||
// lbl线程
|
|
||||||
//
|
|
||||||
this.lbl线程.AutoSize = true;
|
|
||||||
this.lbl线程.Location = new System.Drawing.Point(290, 15);
|
|
||||||
this.lbl线程.Name = "lbl线程";
|
|
||||||
this.lbl线程.Size = new System.Drawing.Size(52, 17);
|
|
||||||
this.lbl线程.TabIndex = 6;
|
|
||||||
this.lbl线程.Text = "线程数:";
|
|
||||||
//
|
|
||||||
// num线程
|
|
||||||
//
|
|
||||||
this.num线程.Location = new System.Drawing.Point(348, 12);
|
|
||||||
this.num线程.Maximum = new decimal(new int[] { 16, 0, 0, 0 });
|
|
||||||
this.num线程.Minimum = new decimal(new int[] { 1, 0, 0, 0 });
|
|
||||||
this.num线程.Name = "num线程";
|
|
||||||
this.num线程.Size = new System.Drawing.Size(52, 25);
|
|
||||||
this.num线程.TabIndex = 7;
|
|
||||||
this.num线程.Value = new decimal(new int[] { 4, 0, 0, 0 });
|
|
||||||
//
|
|
||||||
// lbl输出
|
|
||||||
//
|
|
||||||
this.lbl输出.AutoSize = true;
|
|
||||||
this.lbl输出.Location = new System.Drawing.Point(418, 15);
|
|
||||||
this.lbl输出.Name = "lbl输出";
|
|
||||||
this.lbl输出.Size = new System.Drawing.Size(67, 17);
|
|
||||||
this.lbl输出.TabIndex = 8;
|
|
||||||
this.lbl输出.Text = "输出目录:";
|
|
||||||
//
|
|
||||||
// txt输出
|
|
||||||
//
|
|
||||||
this.txt输出.Location = new System.Drawing.Point(487, 12);
|
|
||||||
this.txt输出.Name = "txt输出";
|
|
||||||
this.txt输出.Size = new System.Drawing.Size(340, 25);
|
|
||||||
this.txt输出.TabIndex = 9;
|
|
||||||
//
|
|
||||||
// btn开始
|
|
||||||
//
|
|
||||||
this.btn开始.Location = new System.Drawing.Point(290, 44);
|
|
||||||
this.btn开始.Name = "btn开始";
|
|
||||||
this.btn开始.Size = new System.Drawing.Size(120, 32);
|
|
||||||
this.btn开始.TabIndex = 10;
|
|
||||||
this.btn开始.Text = "开始抓取";
|
|
||||||
this.btn开始.UseVisualStyleBackColor = true;
|
|
||||||
this.btn开始.Click += new System.EventHandler(this.btn开始_Click);
|
|
||||||
//
|
|
||||||
// btn打包
|
|
||||||
//
|
|
||||||
this.btn打包.Location = new System.Drawing.Point(420, 44);
|
|
||||||
this.btn打包.Name = "btn打包";
|
|
||||||
this.btn打包.Size = new System.Drawing.Size(120, 32);
|
|
||||||
this.btn打包.TabIndex = 11;
|
|
||||||
this.btn打包.Text = "打包数据包";
|
|
||||||
this.btn打包.UseVisualStyleBackColor = true;
|
|
||||||
this.btn打包.Click += new System.EventHandler(this.btn打包_Click);
|
|
||||||
//
|
|
||||||
// progress
|
|
||||||
//
|
|
||||||
this.progress.Location = new System.Drawing.Point(560, 50);
|
|
||||||
this.progress.Name = "progress";
|
|
||||||
this.progress.Size = new System.Drawing.Size(180, 20);
|
|
||||||
this.progress.TabIndex = 12;
|
|
||||||
//
|
|
||||||
// lbl进度
|
|
||||||
//
|
|
||||||
this.lbl进度.AutoSize = true;
|
|
||||||
this.lbl进度.Location = new System.Drawing.Point(750, 54);
|
|
||||||
this.lbl进度.Name = "lbl进度";
|
|
||||||
this.lbl进度.Size = new System.Drawing.Size(0, 17);
|
|
||||||
this.lbl进度.TabIndex = 13;
|
|
||||||
//
|
|
||||||
// chk代理
|
|
||||||
//
|
|
||||||
this.chk代理.AutoSize = true;
|
|
||||||
this.chk代理.Location = new System.Drawing.Point(290, 82);
|
|
||||||
this.chk代理.Name = "chk代理";
|
|
||||||
this.chk代理.Size = new System.Drawing.Size(204, 21);
|
|
||||||
this.chk代理.TabIndex = 15;
|
|
||||||
this.chk代理.Text = "价格走旧代理(8081,自动启动)";
|
|
||||||
this.chk代理.UseVisualStyleBackColor = true;
|
|
||||||
this.chk代理.CheckedChanged += new System.EventHandler(this.chk代理_CheckedChanged);
|
|
||||||
//
|
|
||||||
// lbl代理
|
|
||||||
//
|
|
||||||
this.lbl代理.AutoSize = true;
|
|
||||||
this.lbl代理.ForeColor = System.Drawing.Color.Firebrick;
|
|
||||||
this.lbl代理.Location = new System.Drawing.Point(500, 85);
|
|
||||||
this.lbl代理.Name = "lbl代理";
|
|
||||||
this.lbl代理.Size = new System.Drawing.Size(103, 17);
|
|
||||||
this.lbl代理.TabIndex = 16;
|
|
||||||
this.lbl代理.Text = "旧代理:未检测";
|
|
||||||
//
|
|
||||||
// chk清理
|
|
||||||
//
|
|
||||||
this.chk清理.AutoSize = true;
|
|
||||||
this.chk清理.Checked = true;
|
|
||||||
this.chk清理.CheckState = System.Windows.Forms.CheckState.Checked;
|
|
||||||
this.chk清理.Location = new System.Drawing.Point(620, 82);
|
|
||||||
this.chk清理.Name = "chk清理";
|
|
||||||
this.chk清理.Size = new System.Drawing.Size(163, 21);
|
|
||||||
this.chk清理.TabIndex = 17;
|
|
||||||
this.chk清理.Text = "抓取前清空旧数据(缓存+输出)";
|
|
||||||
this.chk清理.UseVisualStyleBackColor = true;
|
|
||||||
//
|
|
||||||
// rtb日志
|
|
||||||
//
|
|
||||||
this.rtb日志.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(30)))), ((int)(((byte)(30)))), ((int)(((byte)(30)))));
|
|
||||||
this.rtb日志.BorderStyle = System.Windows.Forms.BorderStyle.None;
|
|
||||||
this.rtb日志.ForeColor = System.Drawing.Color.Gainsboro;
|
|
||||||
this.rtb日志.Font = new System.Drawing.Font("Consolas", 9F);
|
|
||||||
this.rtb日志.Location = new System.Drawing.Point(290, 110);
|
|
||||||
this.rtb日志.Name = "rtb日志";
|
|
||||||
this.rtb日志.ReadOnly = true;
|
|
||||||
this.rtb日志.Size = new System.Drawing.Size(537, 404);
|
|
||||||
this.rtb日志.TabIndex = 14;
|
|
||||||
this.rtb日志.Text = "";
|
|
||||||
//
|
|
||||||
// MainForm
|
|
||||||
//
|
|
||||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F);
|
|
||||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
|
||||||
this.ClientSize = new System.Drawing.Size(842, 561);
|
|
||||||
this.Controls.Add(this.lbl代理);
|
|
||||||
this.Controls.Add(this.chk代理);
|
|
||||||
this.Controls.Add(this.chk清理);
|
|
||||||
this.Controls.Add(this.rtb日志);
|
|
||||||
this.Controls.Add(this.lbl进度);
|
|
||||||
this.Controls.Add(this.progress);
|
|
||||||
this.Controls.Add(this.btn打包);
|
|
||||||
this.Controls.Add(this.btn开始);
|
|
||||||
this.Controls.Add(this.txt输出);
|
|
||||||
this.Controls.Add(this.lbl输出);
|
|
||||||
this.Controls.Add(this.num线程);
|
|
||||||
this.Controls.Add(this.lbl线程);
|
|
||||||
this.Controls.Add(this.lbl统计);
|
|
||||||
this.Controls.Add(this.btn反选);
|
|
||||||
this.Controls.Add(this.btn全选);
|
|
||||||
this.Controls.Add(this.lst厂家);
|
|
||||||
this.Controls.Add(this.txt搜索);
|
|
||||||
this.Controls.Add(this.lbl搜索);
|
|
||||||
this.MaximizeBox = false;
|
|
||||||
this.Name = "MainForm";
|
|
||||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
|
||||||
this.Text = "元件库厂家数据工具";
|
|
||||||
((System.ComponentModel.ISupportInitialize)(this.num线程)).EndInit();
|
|
||||||
this.ResumeLayout(false);
|
|
||||||
this.PerformLayout();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
private System.Windows.Forms.Label lbl搜索;
|
|
||||||
private System.Windows.Forms.TextBox txt搜索;
|
|
||||||
private System.Windows.Forms.ListView lst厂家;
|
|
||||||
private System.Windows.Forms.Button btn全选;
|
|
||||||
private System.Windows.Forms.Button btn反选;
|
|
||||||
private System.Windows.Forms.Label lbl统计;
|
|
||||||
private System.Windows.Forms.Label lbl线程;
|
|
||||||
private System.Windows.Forms.NumericUpDown num线程;
|
|
||||||
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.ProgressBar progress;
|
|
||||||
private System.Windows.Forms.Label lbl进度;
|
|
||||||
private System.Windows.Forms.RichTextBox rtb日志;
|
|
||||||
private System.Windows.Forms.CheckBox chk代理;
|
|
||||||
private System.Windows.Forms.Label lbl代理;
|
|
||||||
private System.Windows.Forms.CheckBox chk清理;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,352 +0,0 @@
|
|||||||
// 元件库数据工具:按厂家勾选抓取数据(树/系列/价格),打包成数据包 zip 供新服务读取
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.IO;
|
|
||||||
using System.IO.Compression;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
|
|
||||||
namespace yjktool
|
|
||||||
{
|
|
||||||
public partial class MainForm : Form
|
|
||||||
{
|
|
||||||
private List<厂家项> 全部厂家 = new List<厂家项>();
|
|
||||||
private string 工作根; // 抓取落盘根(data 布局)
|
|
||||||
private 抓取器 抓;
|
|
||||||
private volatile bool 运行中;
|
|
||||||
|
|
||||||
private class 厂家项
|
|
||||||
{
|
|
||||||
public string 树id;
|
|
||||||
public string 名称;
|
|
||||||
public override string ToString() { return 名称; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public MainForm()
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
工作根 = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "抓取输出");
|
|
||||||
txt输出.Text = 工作根;
|
|
||||||
加载厂家清单();
|
|
||||||
chk代理.Checked = true; // 默认走旧代理(抓取时会自动启动工具内置的旧代理)
|
|
||||||
检测旧代理(); // 启动时显示旧代理在线状态
|
|
||||||
FormClosing += (s, e) => 关闭内置旧代理();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- 旧代理(工具内置副本,8081;node 新服务占 8080 不能同端口) ----------
|
|
||||||
private const int 代理端口 = 8081;
|
|
||||||
private System.Diagnostics.Process _代理进程; // 本工具拉起的内置旧代理(退出时收尾)
|
|
||||||
|
|
||||||
private static bool 端口通(int 端口)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using (var c = new System.Net.Sockets.TcpClient())
|
|
||||||
{
|
|
||||||
var ar = c.BeginConnect("127.0.0.1", 端口, null, null);
|
|
||||||
return ar.AsyncWaitHandle.WaitOne(600) && c.Connected;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch { return false; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>8081 不通时自动启动工具旁的内置旧代理(旧代理\python\python.exe -u proxy_server.py --port 8081)。
|
|
||||||
/// 阻塞最多约 15 秒等端口就绪,应在后台线程调用。</summary>
|
|
||||||
private bool 确保旧代理运行()
|
|
||||||
{
|
|
||||||
if (端口通(代理端口)) return true;
|
|
||||||
string dir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "旧代理");
|
|
||||||
string py = Path.Combine(dir, "python", "python.exe");
|
|
||||||
if (!File.Exists(py) || !File.Exists(Path.Combine(dir, "proxy_server.py")))
|
|
||||||
{
|
|
||||||
UI日志("! 工具旁没有内置旧代理目录(旧代理\\python\\python.exe),价格将全部落空");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
UI日志("正在启动内置旧代理(端口 " + 代理端口 + ")…");
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_代理进程 = System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
|
|
||||||
{
|
|
||||||
FileName = py,
|
|
||||||
Arguments = "-u proxy_server.py --port " + 代理端口,
|
|
||||||
WorkingDirectory = dir,
|
|
||||||
UseShellExecute = false,
|
|
||||||
CreateNoWindow = true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
catch (Exception ex) { UI日志("! 启动旧代理失败: " + ex.Message); return false; }
|
|
||||||
for (int i = 0; i < 30 && !端口通(代理端口); i++) Thread.Sleep(500);
|
|
||||||
bool ok = 端口通(代理端口);
|
|
||||||
UI日志(ok ? "✅ 内置旧代理已启动(端口 " + 代理端口 + ")" : "! 内置旧代理 15 秒内未就绪(可能启动报错)");
|
|
||||||
检测旧代理();
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>工具退出时结束自己拉起的内置旧代理,避免留孤儿进程</summary>
|
|
||||||
private void 关闭内置旧代理()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (_代理进程 != null && !_代理进程.HasExited) _代理进程.Kill();
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>所有可用的种子目录:工具内置副本+根目录原件(预热缓存)+元件库网页 data(现成真价,含原始 t)。</summary>
|
|
||||||
private static string[] 旧代理缓存目录们()
|
|
||||||
{
|
|
||||||
string baseDir = AppDomain.CurrentDomain.BaseDirectory;
|
|
||||||
string[] 候选 = {
|
|
||||||
Path.Combine(baseDir, @"旧代理\proxy_cache"), // 工具内置副本
|
|
||||||
Path.Combine(baseDir, @"..\..\..\旧服务-python代理\src\proxy_cache"), // 根目录原件(预热流程)
|
|
||||||
Path.Combine(baseDir, @"..\..\..\成套报价软件\bin\Debug\元件库网页\data\dx2_webGetPrice"), // 新服务现成真价(开发机)
|
|
||||||
Path.Combine(baseDir, @"元件库网页\data\dx2_webGetPrice"), // 安装布局
|
|
||||||
};
|
|
||||||
return Array.FindAll(候选, p => Directory.Exists(p));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>清空旧数据:抓取输出两目录(树/系列包+价格)+两处旧代理缓存(proxy_cache)。
|
|
||||||
/// 旧代理缓存会被直接回放成旧响应(等于抓到的还是旧价),要拿全新数据就得先清。在启动代理前执行。</summary>
|
|
||||||
private int 清空旧数据()
|
|
||||||
{
|
|
||||||
int n = 0;
|
|
||||||
string baseDir = AppDomain.CurrentDomain.BaseDirectory;
|
|
||||||
string[] 目录们 = {
|
|
||||||
Path.Combine(工作根, @"dian\electricData_zips"),
|
|
||||||
Path.Combine(工作根, @"dx2_webGetPrice"),
|
|
||||||
Path.Combine(baseDir, @"旧代理\proxy_cache"), // 工具内置副本
|
|
||||||
Path.Combine(baseDir, @"..\..\..\旧服务-python代理\src\proxy_cache"), // 根目录原件
|
|
||||||
};
|
|
||||||
foreach (string d in 目录们)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (!Directory.Exists(d)) continue;
|
|
||||||
int 个数 = Directory.GetFiles(d, "*", SearchOption.AllDirectories).Length;
|
|
||||||
Directory.Delete(d, true);
|
|
||||||
Directory.CreateDirectory(d);
|
|
||||||
n++;
|
|
||||||
UI日志(" 已清空 " + 个数 + " 个文件: " + d);
|
|
||||||
}
|
|
||||||
catch (Exception ex) { UI日志(" ! 清空失败 " + d + ": " + ex.Message); }
|
|
||||||
}
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void 检测旧代理()
|
|
||||||
{
|
|
||||||
if (InvokeRequired) { BeginInvoke((Action)(检测旧代理)); return; }
|
|
||||||
bool 在线 = 端口通(代理端口);
|
|
||||||
lbl代理.Text = 在线 ? "旧代理:在线 ✓" : "旧代理:离线";
|
|
||||||
lbl代理.ForeColor = 在线 ? System.Drawing.Color.Green : System.Drawing.Color.Firebrick;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void chk代理_CheckedChanged(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
if (chk代理.Checked) 检测旧代理();
|
|
||||||
else lbl代理.Text = "旧代理:未使用";
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- 厂家清单:元件库网页\data(开发/安装布局)→exe旁→内置 f.zip 都无则提示 ----------
|
|
||||||
private void 加载厂家清单()
|
|
||||||
{
|
|
||||||
string fzip = null;
|
|
||||||
string baseDir = AppDomain.CurrentDomain.BaseDirectory;
|
|
||||||
string[] 候选 = {
|
|
||||||
Path.Combine(baseDir, @"..\..\..\成套报价软件\bin\Debug\元件库网页\data\dian\electricData_zips\f.zip"),
|
|
||||||
Path.Combine(baseDir, @"..\..\..\..\..\..\成套报价软件\bin\Debug\元件库网页\data\dian\electricData_zips\f.zip"),
|
|
||||||
Path.Combine(baseDir, @"元件库网页\data\dian\electricData_zips\f.zip"),
|
|
||||||
Path.Combine(baseDir, "f.zip"),
|
|
||||||
};
|
|
||||||
foreach (string p in 候选)
|
|
||||||
if (File.Exists(p)) { fzip = p; break; }
|
|
||||||
if (fzip == null)
|
|
||||||
{
|
|
||||||
MessageBox.Show(this, "找不到厂家清单 f.zip。\r\n请把工具放在 元件库网页\\ 目录旁,或把 f.zip 拷到工具旁。",
|
|
||||||
"元件库数据工具", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
string 文;
|
|
||||||
using (var z = ZipFile.OpenRead(fzip))
|
|
||||||
using (var r = new StreamReader(z.Entries[0].Open(), System.Text.Encoding.UTF8))
|
|
||||||
文 = r.ReadToEnd();
|
|
||||||
var 见过 = new HashSet<string>();
|
|
||||||
foreach (Match m in Regex.Matches(文, @"\{[^{}]*?""f""\s*:\s*(\d+)[^{}]*?""name""\s*:\s*""([^""]+)""[^{}]*?\}"))
|
|
||||||
{
|
|
||||||
string id = m.Groups[1].Value;
|
|
||||||
if (id == "0" || 见过.Contains(id)) continue;
|
|
||||||
见过.Add(id);
|
|
||||||
全部厂家.Add(new 厂家项 { 树id = id, 名称 = m.Groups[2].Value });
|
|
||||||
}
|
|
||||||
// f 在 name 前的变体
|
|
||||||
if (全部厂家.Count == 0)
|
|
||||||
{
|
|
||||||
foreach (Match m in Regex.Matches(文, @"\{[^{}]*?""name""\s*:\s*""([^""]+)""[^{}]*?""f""\s*:\s*(\d+)[^{}]*?\}"))
|
|
||||||
{
|
|
||||||
string id = m.Groups[2].Value;
|
|
||||||
if (id == "0" || 见过.Contains(id)) continue;
|
|
||||||
见过.Add(id);
|
|
||||||
全部厂家.Add(new 厂家项 { 树id = id, 名称 = m.Groups[1].Value });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
填列表("");
|
|
||||||
lbl统计.Text = "厂家 " + 全部厂家.Count + " 家";
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
MessageBox.Show(this, "读取 f.zip 失败: " + ex.Message, "元件库数据工具");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void 填列表(string 过滤)
|
|
||||||
{
|
|
||||||
lst厂家.BeginUpdate();
|
|
||||||
lst厂家.Items.Clear();
|
|
||||||
foreach (var f in 全部厂家)
|
|
||||||
{
|
|
||||||
if (过滤 != "" && f.名称.IndexOf(过滤, StringComparison.OrdinalIgnoreCase) < 0) continue;
|
|
||||||
var it = lst厂家.Items.Add(f.名称);
|
|
||||||
it.Checked = false;
|
|
||||||
it.Tag = f;
|
|
||||||
}
|
|
||||||
lst厂家.EndUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void txt搜索_TextChanged(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
填列表(txt搜索.Text.Trim());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void btn全选_Click(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
foreach (ListViewItem it in lst厂家.Items) it.Checked = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void btn反选_Click(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
foreach (ListViewItem it in lst厂家.Items) it.Checked = !it.Checked;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- UI 线程调度 ----------
|
|
||||||
private void UI日志(string s)
|
|
||||||
{
|
|
||||||
if (InvokeRequired) { BeginInvoke((Action)(() => UI日志(s))); return; }
|
|
||||||
rtb日志.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "] " + s + "\r\n");
|
|
||||||
}
|
|
||||||
private void UI进度(int 厂完成, int 厂总数)
|
|
||||||
{
|
|
||||||
if (InvokeRequired) { BeginInvoke((Action)(() => UI进度(厂完成, 厂总数))); return; }
|
|
||||||
if (厂总数 > 0) progress.Value = Math.Min(progress.Maximum, 厂完成 * 100 / 厂总数);
|
|
||||||
lbl进度.Text = 厂完成 + " / " + 厂总数;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void btn开始_Click(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
if (运行中) { 抓.停止 = true; btn开始.Text = "正在停止…"; return; }
|
|
||||||
var 选中 = lst厂家.Items.Cast<ListViewItem>().Where(i => i.Checked).Select(i => (厂家项)i.Tag).ToList();
|
|
||||||
if (选中.Count == 0)
|
|
||||||
{
|
|
||||||
MessageBox.Show(this, "请先勾选要抓取的厂家。", "元件库数据工具");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
工作根 = txt输出.Text.Trim();
|
|
||||||
Directory.CreateDirectory(Path.Combine(工作根, "dian", "electricData_zips"));
|
|
||||||
Directory.CreateDirectory(Path.Combine(工作根, "dx2_webGetPrice"));
|
|
||||||
抓 = new 抓取器(工作根) { 日志 = UI日志 };
|
|
||||||
抓.经旧代理 = chk代理.Checked;
|
|
||||||
运行中 = true;
|
|
||||||
btn开始.Text = "停止";
|
|
||||||
progress.Maximum = 100; progress.Value = 0;
|
|
||||||
int 线程 = (int)num线程.Value;
|
|
||||||
UI日志("开始抓取 " + 选中.Count + " 家,线程 " + 线程 + ",输出 " + 工作根 + (抓.经旧代理 ? ",价格走旧代理" : ",价格直连"));
|
|
||||||
int 总系 = 0, 总价 = 0;
|
|
||||||
ThreadPool.QueueUserWorkItem(_ =>
|
|
||||||
{
|
|
||||||
// 先清旧数据(用户要求:旧代理缓存会回放旧响应、抓取输出留旧文件,要全新数据先清干净)
|
|
||||||
if (chk清理.Checked)
|
|
||||||
{
|
|
||||||
UI日志("清空旧数据…");
|
|
||||||
清空旧数据();
|
|
||||||
}
|
|
||||||
// 代理仅在勾选时启动(终版机制直连+种子 t 即可命中,不依赖代理)
|
|
||||||
if (抓.经旧代理) 确保旧代理运行();
|
|
||||||
// ★ 种子加载与代理无关,必须无条件执行:种子(系列有效时刻 t)决定价格能不能查,
|
|
||||||
// 不加载种子则所有系列按"无 t"跳过查价 → 0 价格
|
|
||||||
string[] 缓存们 = 旧代理缓存目录们();
|
|
||||||
if (缓存们.Length > 0)
|
|
||||||
{
|
|
||||||
int n种 = 0;
|
|
||||||
foreach (string 缓存 in 缓存们) n种 = 抓.加载种子(缓存); // 多处种子合并
|
|
||||||
UI日志("已加载种子: " + n种 + " 个系列的有效时刻(来自 " + 缓存们.Length + " 处目录)");
|
|
||||||
if (n种 == 0)
|
|
||||||
UI日志("! 种子为 0:价格将全部跳过。先在预热页面浏览目标厂家系列,或确认元件库网页 data 目录存在");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
UI日志("! 未找到种子目录(价格将全部跳过)");
|
|
||||||
var sw = Stopwatch.StartNew();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 选中.Count && !抓.停止; i++)
|
|
||||||
{
|
|
||||||
var kv = 抓.抓厂家(选中[i].树id, 选中[i].名称, 线程);
|
|
||||||
总系 += kv.Key; 总价 += kv.Value;
|
|
||||||
UI进度(i + 1, 选中.Count);
|
|
||||||
}
|
|
||||||
UI日志((抓.停止 ? "已停止: " : "抓取完成: ") + "系列 " + 总系 + ", 价格组合 " + 总价 +
|
|
||||||
", 用时 " + (int)sw.Elapsed.TotalMinutes + " 分钟。可点【打包数据包】。");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
UI日志("! 抓取中断: " + ex);
|
|
||||||
}
|
|
||||||
BeginInvoke((Action)(() => { 运行中 = false; btn开始.Text = "开始抓取"; }));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- 打包 ----------
|
|
||||||
private void btn打包_Click(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
if (运行中) { MessageBox.Show(this, "抓取进行中,请先停止。"); return; }
|
|
||||||
if (!Directory.Exists(工作根))
|
|
||||||
{
|
|
||||||
MessageBox.Show(this, "输出目录不存在,先抓取。"); return;
|
|
||||||
}
|
|
||||||
using (var dlg = new SaveFileDialog
|
|
||||||
{
|
|
||||||
Title = "打包数据包",
|
|
||||||
Filter = "元件库数据包 (*.zip)|*.zip",
|
|
||||||
FileName = "厂家数据包_" + DateTime.Now.ToString("yyyyMMdd_HHmm") + ".zip",
|
|
||||||
InitialDirectory = AppDomain.CurrentDomain.BaseDirectory,
|
|
||||||
})
|
|
||||||
{
|
|
||||||
if (dlg.ShowDialog(this) != DialogResult.OK) return;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
int n = 0;
|
|
||||||
using (var zip = ZipFile.Open(dlg.FileName, ZipArchiveMode.Create))
|
|
||||||
{
|
|
||||||
foreach (string f in Directory.GetFiles(工作根, "*", SearchOption.AllDirectories))
|
|
||||||
{
|
|
||||||
if (f.EndsWith(".json")) continue; // 树缓存伴随文件不入包
|
|
||||||
string rel = f.Substring(工作根.Length + 1).Replace('\\', '/');
|
|
||||||
zip.CreateEntryFromFile(f, rel, CompressionLevel.Optimal);
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MessageBox.Show(this, "打包完成: " + n + " 个文件\r\n" + dlg.FileName +
|
|
||||||
"\r\n\r\n把 zip 放进主程序 元件库网页\\ 目录,重启程序即自动导入。", "元件库数据工具");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
MessageBox.Show(this, "打包失败: " + ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
|
|
||||||
namespace yjktool
|
|
||||||
{
|
|
||||||
static class Program
|
|
||||||
{
|
|
||||||
[STAThread]
|
|
||||||
static void Main()
|
|
||||||
{
|
|
||||||
// 全局异常兜底:任何未捕获异常弹窗而不是闪退
|
|
||||||
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
|
|
||||||
Application.ThreadException += (s, e) => 弹(e.Exception);
|
|
||||||
AppDomain.CurrentDomain.UnhandledException += (s, e) => 弹(e.ExceptionObject as Exception);
|
|
||||||
Application.EnableVisualStyles();
|
|
||||||
Application.SetCompatibleTextRenderingDefault(false);
|
|
||||||
Application.Run(new MainForm());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void 弹(Exception ex)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
MessageBox.Show("程序异常(可继续):\n\n" + (ex == null ? "?" : ex.ToString()),
|
|
||||||
"元件库数据工具", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
|
|
||||||
<PropertyGroup>
|
|
||||||
<ProjectGuid>{8A1E5C72-9D3B-4E7A-A0C1-5F6E7D8B9E01}</ProjectGuid>
|
|
||||||
<ProjectTypeGuids>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
|
||||||
<OutputType>WinExe</OutputType>
|
|
||||||
<RootNamespace>yjktool</RootNamespace>
|
|
||||||
<AssemblyName>元件库数据工具</AssemblyName>
|
|
||||||
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
|
||||||
<PlatformTarget>x86</PlatformTarget>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
|
||||||
<OutputPath>bin\Debug\</OutputPath>
|
|
||||||
<DebugSymbols>True</DebugSymbols>
|
|
||||||
<DebugType>Full</DebugType>
|
|
||||||
<Optimize>False</Optimize>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
|
||||||
<OutputPath>bin\Release\</OutputPath>
|
|
||||||
<DebugSymbols>False</DebugSymbols>
|
|
||||||
<DebugType>None</DebugType>
|
|
||||||
<Optimize>True</Optimize>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Reference Include="System" />
|
|
||||||
<Reference Include="System.Core">
|
|
||||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System.Web.Extensions" />
|
|
||||||
<Reference Include="System.Data" />
|
|
||||||
<Reference Include="System.Drawing" />
|
|
||||||
<Reference Include="System.IO.Compression" />
|
|
||||||
<Reference Include="System.IO.Compression.FileSystem" />
|
|
||||||
<Reference Include="System.Windows.Forms" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Compile Include="Program.cs" />
|
|
||||||
<Compile Include="MainForm.cs" />
|
|
||||||
<Compile Include="MainForm.Designer.cs">
|
|
||||||
<DependentUpon>MainForm.cs</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="抓取器.cs" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
|
||||||
</Project>
|
|
||||||
-422
@@ -1,422 +0,0 @@
|
|||||||
// 抓取器:抓厂家树/系列规格/价格,按新服务布局落盘(断点续抓,多线程安全)
|
|
||||||
// 两种价格通道:直连 dq123(默认) / 经内置旧代理 localhost:8081(带会话伪装,命中率高——工具自动启动它)
|
|
||||||
// 8081 是工具专用端口:node 新服务(元件库网页)占了 8080,两者须能同时跑
|
|
||||||
// 种子模式:从旧代理 proxy_cache 提取真实查询过的组合(sid→bg 列表),优先按种子形状抓价(重放+单变化)
|
|
||||||
using System;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.IO.Compression;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net;
|
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
namespace yjktool
|
|
||||||
{
|
|
||||||
internal class 抓取器
|
|
||||||
{
|
|
||||||
// 域名映射照旧 python 代理
|
|
||||||
private const string 电数据 = "https://dian.dq123.com/electricData?v=";
|
|
||||||
private const string 价格口 = "https://dx2.dhub.com.cn/pcprice/default/dx2/interface/webGetPrice?infoJson=";
|
|
||||||
// 经旧代理(路径同源,代理按前缀转发到真实域名并注入会话头)
|
|
||||||
private const string 代电数据 = "http://127.0.0.1:8081/electricData?v=";
|
|
||||||
private const string 代价格口 = "http://127.0.0.1:8081/dx2/pcprice/default/dx2/interface/webGetPrice?infoJson=";
|
|
||||||
|
|
||||||
public string 输出根 { get; private set; }
|
|
||||||
private string ZipDir { get { return Path.Combine(输出根, "dian", "electricData_zips"); } }
|
|
||||||
private string 价Dir { get { return Path.Combine(输出根, "dx2_webGetPrice"); } }
|
|
||||||
|
|
||||||
/// <summary>价格请求是否经旧代理(8081)。树/系列包恒直连(静态资源无会话要求)。</summary>
|
|
||||||
public bool 经旧代理;
|
|
||||||
|
|
||||||
/// <summary>种子组合:旧代理缓存里真实查询过的 (系列→组合串列表),价格抓取优先按种子形状。</summary>
|
|
||||||
/// <summary>种子表:sid → [bg组合串, t历史时间戳] 列表。
|
|
||||||
/// 终版机制(实测):命中 = 系列在有效时刻 t 查过(服务器按 sid+t 记录) AND 组合是真实型号——
|
|
||||||
/// 系列只要有一个种子的 t,即可解锁它全部规格组组合的价格查询;t 用当前时间必返空。</summary>
|
|
||||||
private Dictionary<string, List<string[]>> 种子 = new Dictionary<string, List<string[]>>();
|
|
||||||
private int 无t系列数;
|
|
||||||
private int 无t提示过;
|
|
||||||
|
|
||||||
// 进度/日志回调(UI 线程调度由调用方处理)
|
|
||||||
public Action<string> 日志 { get; set; }
|
|
||||||
public Action<int, int> 进度 { get; set; } // (当前,总数)
|
|
||||||
public volatile bool 停止;
|
|
||||||
|
|
||||||
public 抓取器(string 输出目录)
|
|
||||||
{
|
|
||||||
输出根 = 输出目录;
|
|
||||||
Directory.CreateDirectory(ZipDir);
|
|
||||||
Directory.CreateDirectory(价Dir);
|
|
||||||
// net48 下显式启用 TLS1.2(dq123 全站 https,不设会握手失败)
|
|
||||||
try { ServicePointManager.SecurityProtocol = ServicePointManager.SecurityProtocol | SecurityProtocolType.Tls12; }
|
|
||||||
catch { }
|
|
||||||
ServicePointManager.DefaultConnectionLimit = 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>从缓存/数据目录加载种子(webGetPrice 响应里的 bg 组合串+原始 t 时间戳)。
|
|
||||||
/// 可多处调用合并(旧代理缓存+元件库网页 data 的现成真价都吃)。返回种子系列数。</summary>
|
|
||||||
public int 加载种子(string 目录)
|
|
||||||
{
|
|
||||||
if (种子 == null) 种子 = new Dictionary<string, List<string[]>>();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
foreach (string f in Directory.GetFiles(目录, "*webGetPrice*.data"))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
string body = File.ReadAllText(f);
|
|
||||||
foreach (System.Text.RegularExpressions.Match m in
|
|
||||||
System.Text.RegularExpressions.Regex.Matches(body, "\"content\"\\s*:\\s*\"([A-Za-z0-9+/=]+)\""))
|
|
||||||
{
|
|
||||||
string decoded;
|
|
||||||
try { decoded = Encoding.UTF8.GetString(Convert.FromBase64String(m.Groups[1].Value)); }
|
|
||||||
catch { continue; }
|
|
||||||
if (string.IsNullOrEmpty(decoded) || decoded.Trim() == "[]") continue;
|
|
||||||
// ★ JavaScriptSerializer.Deserialize<object> 对顶层数组返回 Object[](不是 ArrayList),
|
|
||||||
// 按 IEnumerable 遍历两者通吃——之前 as ArrayList 恒 null,种子从来没加载成功过
|
|
||||||
System.Collections.IEnumerable 条集 = 解析器.Deserialize<object>(decoded) as System.Collections.IEnumerable;
|
|
||||||
if (条集 == null) continue;
|
|
||||||
foreach (object o in 条集)
|
|
||||||
{
|
|
||||||
var it = o as Dictionary<string, object>;
|
|
||||||
if (it == null || !it.ContainsKey("sid")) continue;
|
|
||||||
string sid = Convert.ToString(it["sid"]);
|
|
||||||
string bg = it.ContainsKey("bg") ? Convert.ToString(it["bg"]) : "";
|
|
||||||
// ★ t 是 13 位毫秒时间戳:JavaScriptSerializer 把 JSON 整数解析成 double,
|
|
||||||
// Convert.ToString(double) 会变成科学计数法(1.785401168E+12)拼进 time 服务器不认——
|
|
||||||
// 必须经 ToDouble→ToInt64 还原成纯数字串
|
|
||||||
string t = "";
|
|
||||||
object tv;
|
|
||||||
if (it.TryGetValue("t", out tv) && tv != null)
|
|
||||||
{
|
|
||||||
try { t = Convert.ToInt64(Convert.ToDouble(tv)).ToString(); }
|
|
||||||
catch { }
|
|
||||||
}
|
|
||||||
if (string.IsNullOrEmpty(sid) || string.IsNullOrEmpty(bg) || bg.IndexOf('-') < 0) continue;
|
|
||||||
if (string.IsNullOrEmpty(t)) continue; // 没 t 的种子重放不了(当前时间必空),跳过
|
|
||||||
List<string[]> l;
|
|
||||||
if (!种子.TryGetValue(sid, out l)) { l = new List<string[]>(); 种子[sid] = l; }
|
|
||||||
if (!l.Any(e => e[0] == bg)) l.Add(new[] { bg, t });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
return 种子.Count;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void L(string s) { if (日志 != null) 日志(s); }
|
|
||||||
|
|
||||||
// ---------- HTTP(简单重试) ----------
|
|
||||||
private byte[] Get(string url, int timeoutMs)
|
|
||||||
{
|
|
||||||
for (int 试 = 0; 试 < 3 && !停止; 试++)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var req = (HttpWebRequest)WebRequest.Create(url);
|
|
||||||
req.Method = "GET";
|
|
||||||
req.Timeout = timeoutMs;
|
|
||||||
req.ReadWriteTimeout = timeoutMs;
|
|
||||||
req.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Edg/137.0.0.0";
|
|
||||||
req.Referer = "https://www.dq123.com/";
|
|
||||||
req.Proxy = null;
|
|
||||||
using (var r = (HttpWebResponse)req.GetResponse())
|
|
||||||
using (var ms = new MemoryStream())
|
|
||||||
{
|
|
||||||
r.GetResponseStream().CopyTo(ms);
|
|
||||||
return ms.ToArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (WebException we)
|
|
||||||
{
|
|
||||||
var hr = we.Response as HttpWebResponse;
|
|
||||||
if (hr != null && (int)hr.StatusCode >= 400 && (int)hr.StatusCode < 500)
|
|
||||||
return null; // 4xx(404 无此包)不重试,快速跳过
|
|
||||||
Thread.Sleep(600);
|
|
||||||
}
|
|
||||||
catch (Exception) { return null; }
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- v 参数(base64 逻辑名去 padding) ----------
|
|
||||||
private static string V参数(string 逻辑名)
|
|
||||||
{
|
|
||||||
string b = Convert.ToBase64String(Encoding.UTF8.GetBytes(逻辑名));
|
|
||||||
return b.TrimEnd('=');
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>读 ZIP 字节数组里的首个文件文本(JSON)。失败返回 null。</summary>
|
|
||||||
private static string 读Zip内文(byte[] zip)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using (var ms = new MemoryStream(zip))
|
|
||||||
using (var z = new ZipArchive(ms))
|
|
||||||
{
|
|
||||||
var e = z.Entries[0];
|
|
||||||
using (var r = new StreamReader(e.Open(), Encoding.UTF8))
|
|
||||||
return r.ReadToEnd();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch { return null; }
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- JSON 反序列化(JavaScriptSerializer) ----------
|
|
||||||
private static readonly System.Web.Script.Serialization.JavaScriptSerializer 解析器 =
|
|
||||||
new System.Web.Script.Serialization.JavaScriptSerializer { MaxJsonLength = 64 * 1024 * 1024 };
|
|
||||||
|
|
||||||
/// <summary>系列包 → 主规格组有序表(aq顺序号→as选项列表)。
|
|
||||||
/// ★ 实测规则(1122 对照页面真实组合 337-350-15-9-29-30-37 破解):
|
|
||||||
/// 参与组合的组 = 顶层 c 键里 bc==0 且 p==2 的项;段顺序 = aq 字段升序;
|
|
||||||
/// bc!=0 / p!=2 的组(附件名称、延时类型等)不参与组合。
|
|
||||||
/// 系列包名 = 4/z_p/{系列id}.jss(不是 z_seri)。</summary>
|
|
||||||
private static SortedDictionary<int, List<int>> 规格组(string 系文)
|
|
||||||
{
|
|
||||||
var g = new SortedDictionary<int, List<int>>();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var root = 解析器.Deserialize<Dictionary<string, object>>(系文);
|
|
||||||
object co;
|
|
||||||
if (root == null || !root.TryGetValue("c", out co)) return g;
|
|
||||||
var cArr = co as System.Collections.ArrayList;
|
|
||||||
if (cArr == null) return g;
|
|
||||||
foreach (object o in cArr)
|
|
||||||
{
|
|
||||||
var 组 = o as Dictionary<string, object>;
|
|
||||||
if (组 == null) continue;
|
|
||||||
// ★ 终版规则(SDK Ke 过滤器:z 数组=an==1;两厂实测 725/1122 真实组合段 100% 命中):
|
|
||||||
// p 各家不同(正泰=1 德力西=2),不能加 p 条件
|
|
||||||
if (Convert.ToInt32(组.ContainsKey("an") ? 组["an"] : 0) != 1) continue;
|
|
||||||
int aq = Convert.ToInt32(组.ContainsKey("aq") ? 组["aq"] : 0);
|
|
||||||
var ar = 组.ContainsKey("ar") ? 组["ar"] as System.Collections.ArrayList : null;
|
|
||||||
if (ar == null || ar.Count == 0) continue;
|
|
||||||
var l = new List<int>();
|
|
||||||
foreach (object oo in ar)
|
|
||||||
{
|
|
||||||
var 选项 = oo as Dictionary<string, object>;
|
|
||||||
if (选项 == null || !选项.ContainsKey("as")) continue;
|
|
||||||
l.Add(Convert.ToInt32(选项["as"]));
|
|
||||||
}
|
|
||||||
if (l.Count > 0 && !g.ContainsKey(aq)) g[aq] = l;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
return g;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- 最小 JSON 取值(避免引第三方库;仅取固定结构字段) ----------
|
|
||||||
private static System.Text.RegularExpressions.MatchCollection 正则匹配(string json, string pattern)
|
|
||||||
{
|
|
||||||
return System.Text.RegularExpressions.Regex.Matches(json, pattern);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>解析厂家树 ZIP 文本 → 叶子系列号(s 字段非 0)列表。</summary>
|
|
||||||
public static List<string> 树系列(string 树文)
|
|
||||||
{
|
|
||||||
var r = new List<string>();
|
|
||||||
foreach (System.Text.RegularExpressions.Match m in 正则匹配(树文, "\"s\"\\s*:\\s*(\\d+)"))
|
|
||||||
{
|
|
||||||
string v = m.Groups[1].Value;
|
|
||||||
if (v != "0" && !r.Contains(v)) r.Add(v);
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>组合策略(照 preheat 脚本):默认组合 + 每组每选项单独变化。</summary>
|
|
||||||
private static List<string> 组合(SortedDictionary<int, List<int>> g)
|
|
||||||
{
|
|
||||||
if (g.Count == 0) return new List<string>();
|
|
||||||
var 默认 = g.Values.Select(l => l[0].ToString()).ToList();
|
|
||||||
var r = new List<string> { string.Join("-", 默认) };
|
|
||||||
for (int i = 0; i < g.Count; i++)
|
|
||||||
{
|
|
||||||
foreach (int ab in g.Values.ElementAt(i).Skip(1))
|
|
||||||
{
|
|
||||||
var c = new List<string>(默认) { };
|
|
||||||
c[i] = ab.ToString();
|
|
||||||
r.Add(string.Join("-", c));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- webGetPrice 哈希(复刻 python json.dumps 分隔符) ----------
|
|
||||||
private static string PyDumps(string json)
|
|
||||||
{
|
|
||||||
// 本场景 JSON 只含 ASCII 字符串/数字/数组/对象,手工重排分隔符即可:
|
|
||||||
// 把 "," 与 ":" 后补空格(仅结构符,字符串内部不会出现裸的这些符号——base64 内容安全)
|
|
||||||
var sb = new StringBuilder(json.Length * 2);
|
|
||||||
bool 引号内 = false;
|
|
||||||
for (int i = 0; i < json.Length; i++)
|
|
||||||
{
|
|
||||||
char c = json[i];
|
|
||||||
sb.Append(c);
|
|
||||||
if (c == '"') 引号内 = !引号内;
|
|
||||||
else if (!引号内 && (c == ',' || c == ':'))
|
|
||||||
{
|
|
||||||
char 后 = i + 1 < json.Length ? json[i + 1] : ' ';
|
|
||||||
if (后 != ' ') sb.Append(' ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string 价格哈希(string infoJsonB64)
|
|
||||||
{
|
|
||||||
string json = Encoding.UTF8.GetString(Convert.FromBase64String(infoJsonB64));
|
|
||||||
// 剥 time 字段("time":123,) —— 手工正则
|
|
||||||
json = System.Text.RegularExpressions.Regex.Replace(json, "\"time\"\\s*:\\s*\\d+\\s*,?\\s*", "");
|
|
||||||
json = json.Replace(",}", "}").Replace(",]", "]");
|
|
||||||
string 稳定 = "infoJson=" + Convert.ToBase64String(Encoding.UTF8.GetBytes(PyDumps(json)));
|
|
||||||
using (var md5 = MD5.Create())
|
|
||||||
return BitConverter.ToString(md5.ComputeHash(Encoding.UTF8.GetBytes(稳定))).Replace("-", "").ToLower().Substring(0, 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------- 抓取主流程 ----------
|
|
||||||
/// <summary>抓一个厂家:树+全部系列+全部组合价格。返回 (系列数, 价格数)。任何异常不外抛(记日志返回 0)。</summary>
|
|
||||||
public KeyValuePair<int, int> 抓厂家(string 树id, string 厂名, int 线程数)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return 抓厂家内部(树id, 厂名, 线程数);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
L("! 厂家 " + 厂名 + " 抓取异常: " + ex.Message);
|
|
||||||
return new KeyValuePair<int, int>(0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private KeyValuePair<int, int> 抓厂家内部(string 树id, string 厂名, int 线程数)
|
|
||||||
{
|
|
||||||
// 1) 厂家树(断点:已存在直接读)
|
|
||||||
string 树zip路径 = Path.Combine(ZipDir, 树id + ".zip");
|
|
||||||
string 树文 = null;
|
|
||||||
if (File.Exists(树zip路径))
|
|
||||||
{
|
|
||||||
树文 = 读Zip内文(File.ReadAllBytes(树zip路径));
|
|
||||||
}
|
|
||||||
if (树文 == null)
|
|
||||||
{
|
|
||||||
byte[] z = Get(电数据 + V参数("z_seri/" + 树id + ".jss") + "&t=" + 时间戳(), 20000);
|
|
||||||
if (z == null || z.Length < 100) { L("× 厂家 " + 厂名 + " 树拉取失败"); return new KeyValuePair<int, int>(0, 0); }
|
|
||||||
File.WriteAllBytes(树zip路径, z);
|
|
||||||
树文 = 读Zip内文(z);
|
|
||||||
Thread.Sleep(50);
|
|
||||||
}
|
|
||||||
if (树文 == null) { L("× 厂家 " + 厂名 + " 树解析失败"); return new KeyValuePair<int, int>(0, 0); }
|
|
||||||
var 系列 = 树系列(树文);
|
|
||||||
L("▶ " + 厂名 + ": " + 系列.Count + " 个系列");
|
|
||||||
无t系列数 = 0; 无t提示过 = 0;
|
|
||||||
|
|
||||||
// 2) 并发抓系列
|
|
||||||
var 队列 = new ConcurrentQueue<string>(系列);
|
|
||||||
var 计数 = new int[2];
|
|
||||||
var 线程 = new List<Thread>();
|
|
||||||
for (int i = 0; i < Math.Max(1, 线程数); i++)
|
|
||||||
{
|
|
||||||
var t = new Thread(delegate()
|
|
||||||
{
|
|
||||||
string sid;
|
|
||||||
while (!停止 && 队列.TryDequeue(out sid))
|
|
||||||
{
|
|
||||||
int 局系 = 0, 局价 = 0;
|
|
||||||
string szPath = Path.Combine(ZipDir, sid + ".zip");
|
|
||||||
string 系文 = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
系文 = File.Exists(szPath) ? 读Zip内文(File.ReadAllBytes(szPath)) : null;
|
|
||||||
if (系文 == null)
|
|
||||||
{
|
|
||||||
byte[] z = Get(电数据 + V参数("4/z_p/" + sid + ".jss") + "&t=" + 时间戳(), 20000);
|
|
||||||
if (z != null && z.Length > 100) { File.WriteAllBytes(szPath, z); 系文 = 读Zip内文(z); Thread.Sleep(20); }
|
|
||||||
}
|
|
||||||
if (系文 != null && 系文.IndexOf("\"c\"") >= 0)
|
|
||||||
{
|
|
||||||
局系 = 1;
|
|
||||||
// ★ 终版机制(实测):命中 = 系列在有效时刻 t 查过 AND 组合是真实型号。
|
|
||||||
// 每个系列只要有一个种子的 t,就能解锁它全部规格组组合;无 t 的系列必空,跳过查价。
|
|
||||||
List<string[]> sd;
|
|
||||||
bool 有种子 = 种子.TryGetValue(sid, out sd) && sd.Count > 0;
|
|
||||||
if (!有种子)
|
|
||||||
{
|
|
||||||
Interlocked.Increment(ref 无t系列数);
|
|
||||||
if (无t提示过 == 0)
|
|
||||||
{
|
|
||||||
int n = Interlocked.Increment(ref 无t提示过);
|
|
||||||
if (n == 1)
|
|
||||||
L("· 提示: 无有效时刻(t)的系列跳过价格查询(服务器对没查过的系列+当前时间必返空)——已跳过 " + sid + " 等");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string t种 = sd[0][1]; // 系列任一种子的 t(系列级会话标识,只配自己系列)
|
|
||||||
// ★ 组合恒用当前系列包规格组生成(默认+单变化):编号与页面渲染同源,查到的价页面必能命中。
|
|
||||||
// 种子 bg(旧版本编号)不再作基底——跨版本编号混合的组合页面永远点不出来(725 教训:75条仅1条可用)。
|
|
||||||
var cs = 组合(规格组(系文));
|
|
||||||
foreach (string c in cs)
|
|
||||||
{
|
|
||||||
string info = 构造infoJson(sid, c, t种);
|
|
||||||
string h = 价格哈希(info);
|
|
||||||
string 价path = Path.Combine(价Dir, "dx2_pcprice_default_dx2_interface_webGetPrice_" + h + ".data");
|
|
||||||
if (!File.Exists(价path))
|
|
||||||
{
|
|
||||||
string 口 = 经旧代理 ? 代价格口 : 价格口;
|
|
||||||
byte[] body = Get(口 + info, 20000);
|
|
||||||
// ★ 空结果不落盘:content="W10="(base64("[]"))或 content="" 都表示该组合厂家无报价,
|
|
||||||
// 存了也是废数据(旧代理靠运行时合成兜底,新服务只需要真价格)
|
|
||||||
string 文 = body == null ? null : Encoding.UTF8.GetString(body);
|
|
||||||
bool 有价 = 文 != null && 文.Length > 30 && 文.Length < 300000
|
|
||||||
&& 文.IndexOf("\"content\":\"W10=\"") < 0
|
|
||||||
&& 文.IndexOf("\"content\": \"W10=\"") < 0
|
|
||||||
&& 文.IndexOf("\"content\":\"\"") < 0
|
|
||||||
&& 文.IndexOf("\"content\": \"\"") < 0;
|
|
||||||
if (有价)
|
|
||||||
{
|
|
||||||
File.WriteAllBytes(价path, body);
|
|
||||||
var mb = System.Text.RegularExpressions.Regex.Match(文, "\"bh\"\\s*:\\s*\"?([0-9.]+)");
|
|
||||||
L(" ¥ 系列" + sid + " 命中真价" + (mb.Success ? " " + mb.Groups[1].Value + " 元" : "") + ": " + c);
|
|
||||||
}
|
|
||||||
Thread.Sleep(20);
|
|
||||||
}
|
|
||||||
局价++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex_series)
|
|
||||||
{
|
|
||||||
L("· 系列 " + sid + " 异常: " + ex_series.Message);
|
|
||||||
}
|
|
||||||
Interlocked.Add(ref 计数[0], 局系);
|
|
||||||
Interlocked.Add(ref 计数[1], 局价);
|
|
||||||
if (进度 != null) 进度(0, 0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
t.IsBackground = true;
|
|
||||||
线程.Add(t); t.Start();
|
|
||||||
}
|
|
||||||
foreach (var t in 线程) t.Join();
|
|
||||||
if (无t系列数 > 0)
|
|
||||||
L("· " + 厂名 + ": " + 无t系列数 + " 个系列无有效时刻(t),已跳过价格查询(可先在预热页面浏览这些系列再抓)");
|
|
||||||
return new KeyValuePair<int, int>(计数[0], 计数[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static long 时间戳() { return (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds; }
|
|
||||||
|
|
||||||
/// <summary>构造 infoJson 的 base64。t 必须传历史时间戳(种子的原始 t 或兜底 t):
|
|
||||||
/// 实测服务器只对「真实查过的组合+历史时间戳」返回真价,当前时间必空。</summary>
|
|
||||||
private static string 构造infoJson(string 系列, string 组合串, string t)
|
|
||||||
{
|
|
||||||
// {"s": "1122", "options": ["337-350"], "time": 123, "from": "dx2jsapi"} —— 键序照 SDK
|
|
||||||
string json = "{\"s\": \"" + 系列 + "\", \"options\": [\"" + 组合串 + "\"], \"time\": " + t + ", \"from\": \"dx2jsapi\"}";
|
|
||||||
return Convert.ToBase64String(Encoding.UTF8.GetBytes(json));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace yjktool
|
|
||||||
{
|
|
||||||
static class 测试入口
|
|
||||||
{
|
|
||||||
[STAThread]
|
|
||||||
static int Main(string[] args)
|
|
||||||
{
|
|
||||||
string 树id = args.Length > 0 ? args[0] : "10";
|
|
||||||
Console.OutputEncoding = System.Text.Encoding.UTF8;
|
|
||||||
var g = new 抓取器(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "抓取输出"))
|
|
||||||
{ 日志 = s => Console.WriteLine(s) };
|
|
||||||
var kv = g.抓厂家(树id, "(测试厂" + 树id + ")", 4);
|
|
||||||
Console.WriteLine("== 结果: 系列 {0}, 价格 {1}", kv.Key, kv.Value);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,135 +0,0 @@
|
|||||||
{
|
|
||||||
"37141": [
|
|
||||||
"5-10-14-15-19-21-23"
|
|
||||||
],
|
|
||||||
"1506": [
|
|
||||||
"10-15-19-21-460-26-44",
|
|
||||||
"8-15-19-21-460-26-44",
|
|
||||||
"230-15-19-21-460-26-39",
|
|
||||||
"230-331-19-21-460-446-39",
|
|
||||||
"11-15-19-21-460-26-48",
|
|
||||||
"182-313",
|
|
||||||
"11-17-19-21-460-27-50",
|
|
||||||
"11-17-19-21-460-27-48",
|
|
||||||
"9-12-19-21-460-26-28",
|
|
||||||
"7-15-19-21-460-26-39",
|
|
||||||
"10-15-19-21-460-26-48",
|
|
||||||
"11-17-19-21-460-26-48",
|
|
||||||
"11-329-19-21-460-26-48",
|
|
||||||
"159-285",
|
|
||||||
"230-14-19-21-460-26-39",
|
|
||||||
"119-279",
|
|
||||||
"7-331-19-21-460-446-28",
|
|
||||||
"114-115-267",
|
|
||||||
"11-330-19-21-460-26-48",
|
|
||||||
"8-15-19-21-460-26-39",
|
|
||||||
"382-384"
|
|
||||||
],
|
|
||||||
"46805": [
|
|
||||||
"5-7-14"
|
|
||||||
],
|
|
||||||
"725": [
|
|
||||||
"7-13-22-15-17-18-19-25-74-20-46-27-82-83-96-84-353",
|
|
||||||
"8-13-22-15-17-18-19-25-74-20-46-27-82-83-96-84-353",
|
|
||||||
"56-24-22-15-17-18-19-25-74-20-33-27-82-83-96-84-353",
|
|
||||||
"23-24-22-15-17-18-19-25-74-20-85-27-82-83-96-84-353",
|
|
||||||
"7-13-22-15-17-18-19-25-74-20-41-27-82-83-96-84-353",
|
|
||||||
"6-12-22-15-17-18-19-25-74-20-39-27-82-83-96-84-353",
|
|
||||||
"341-13-22-15-17-18-19-25-74-20-48-27-82-83-96-84-352",
|
|
||||||
"56-24-22-28-17-18-19-25-74-20-85-27-82-83-96-84-353",
|
|
||||||
"23-24-22-15-17-18-19-25-74-20-35-27-82-83-96-84-353",
|
|
||||||
"56-24-22-15-17-18-59-25-75-20-29-27-82-83-96-84-353",
|
|
||||||
"319-12-22-28-17-18-19-25-74-20-29-27-82-83-96-84-352",
|
|
||||||
"5-12-22-28-17-18-19-25-74-20-29-27-82-83-96-84-353",
|
|
||||||
"56-24-22-15-17-18-59-25-74-20-29-27-82-83-96-84-353",
|
|
||||||
"6-12-22-15-17-18-19-25-74-20-37-27-82-83-96-84-353",
|
|
||||||
"56-24-22-15-17-18-19-25-74-20-85-27-82-83-96-84-353",
|
|
||||||
"23-24-22-28-17-18-19-25-74-20-85-27-82-83-96-84-353",
|
|
||||||
"56-24-22-28-17-18-19-25-74-20-85-27-82-83-96-84-350",
|
|
||||||
"330-13-22-15-17-18-19-25-74-20-46-27-82-83-96-84-352",
|
|
||||||
"6-12-22-15-17-18-19-25-74-20-36-27-82-83-96-84-353"
|
|
||||||
],
|
|
||||||
"47762": [
|
|
||||||
"5-6-8-9-10"
|
|
||||||
],
|
|
||||||
"42825": [
|
|
||||||
"5-11-14",
|
|
||||||
"5-6-13",
|
|
||||||
"5-10-14",
|
|
||||||
"5-12-15"
|
|
||||||
],
|
|
||||||
"3205": [
|
|
||||||
"5-11-15-27",
|
|
||||||
"10-13-15-27"
|
|
||||||
],
|
|
||||||
"56242": [
|
|
||||||
"5-10-14-19-20-22-29-31-32"
|
|
||||||
],
|
|
||||||
"1401": [
|
|
||||||
"5-6-8-12-16"
|
|
||||||
],
|
|
||||||
"2486": [
|
|
||||||
"5-8-6-936-14-46-35-33"
|
|
||||||
],
|
|
||||||
"1245": [
|
|
||||||
"5-7-16-17"
|
|
||||||
],
|
|
||||||
"10586": [
|
|
||||||
"6-12"
|
|
||||||
],
|
|
||||||
"48269": [
|
|
||||||
"5-807-22-37-58-60-17-67-810"
|
|
||||||
],
|
|
||||||
"47084": [
|
|
||||||
"5-6-12-16-20"
|
|
||||||
],
|
|
||||||
"1122": [
|
|
||||||
"337-350-15-9-29-30-37",
|
|
||||||
"6-13-18-10-28-30-37"
|
|
||||||
],
|
|
||||||
"40": [
|
|
||||||
"5-8"
|
|
||||||
],
|
|
||||||
"23641": [
|
|
||||||
"7-163-10-12-14-164-19-21"
|
|
||||||
],
|
|
||||||
"757": [
|
|
||||||
"5-11-66-17-20-21-22-23-25-27-68-67-91-90-96-92-134"
|
|
||||||
],
|
|
||||||
"1825": [
|
|
||||||
"5-18-26-9-15-8"
|
|
||||||
],
|
|
||||||
"733": [
|
|
||||||
"18-37-32-39"
|
|
||||||
],
|
|
||||||
"59163": [
|
|
||||||
"5-11-13-16-19-21",
|
|
||||||
"5-11-15-17-20-27"
|
|
||||||
],
|
|
||||||
"32339": [
|
|
||||||
"7-124-8-34"
|
|
||||||
],
|
|
||||||
"1427": [
|
|
||||||
"5-7-24-17"
|
|
||||||
],
|
|
||||||
"604": [
|
|
||||||
"16-5-12-15",
|
|
||||||
"16-5-12-14"
|
|
||||||
],
|
|
||||||
"71": [
|
|
||||||
"5-15-50-154"
|
|
||||||
],
|
|
||||||
"47960": [
|
|
||||||
"5-12-10-20-23-26-37-63"
|
|
||||||
],
|
|
||||||
"791": [
|
|
||||||
"5-7-11-13"
|
|
||||||
],
|
|
||||||
"1086": [
|
|
||||||
"10-6-30",
|
|
||||||
"12-6-30"
|
|
||||||
],
|
|
||||||
"735": [
|
|
||||||
"5-7-17-12-13-15-16-119"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
-1524
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user