diff --git a/dist.7z b/dist.7z index 39667915..9e47e824 100644 Binary files a/dist.7z and b/dist.7z differ diff --git a/dist.zip b/dist.zip index 370984ef..93f78883 100644 Binary files a/dist.zip and b/dist.zip differ diff --git a/docs/生产计划组件补充需求方案.docx b/docs/生产计划组件补充需求方案.docx new file mode 100644 index 00000000..0dbf3584 Binary files /dev/null and b/docs/生产计划组件补充需求方案.docx differ diff --git a/docs/生产计划组件补充需求方案.md b/docs/生产计划组件补充需求方案.md new file mode 100644 index 00000000..e35abfbb --- /dev/null +++ b/docs/生产计划组件补充需求方案.md @@ -0,0 +1,324 @@ +# 生产计划组件补充需求方案 + +## 一、需求范围 + +本次先做方案,不修改业务页面和数据库过程。围绕生产计划组件的四项补充需求,建议拆成三个前端能力和一组后端数据源: + +1. 生产计划支持“周计划”显示。 +2. 点击设备查看后续工作时,模块时间显示到“小时/分钟”。 +3. 在生产任务计划之外,增加“销售合同计划”视角。 +4. 增加类似医院诊室门口屏幕的“设备当前生产/下一项生产”直观展示。 + +## 二、总体设计 + +建议新增一个“计划看板”入口,保留现有 `生产计划` 表格页作为明细查询和导出页面,在其上扩展三种视图: + +| 视图 | 主要用途 | 展示粒度 | 用户动作 | +| --- | --- | --- | --- | +| 月计划 | 复用现有生产计划表格 | 月 | 查询、导出、打开可视化 | +| 周计划 | 查看本周投产、派工、交付压力 | 周、天 | 周次切换、按天筛选、查看明细 | +| 设备门牌看板 | 现场快速查看每台设备当前和下一项 | 设备、当前任务、下一任务 | 自动刷新、点击设备查看后续队列 | +| 销售合同计划 | 从合同交付节点倒推生产风险 | 合同、订单、产品、计划节点 | 查看合同进度、跳转生产计划/订单进度 | + +## 三、功能方案 + +### 3.1 周计划显示 + +现有生产计划页面已经按月份查询,建议周计划不新增单独页面,先在当前生产计划页面增加“视图模式”: + +- `月计划`:保持现有表格。 +- `周计划`:按选中月份自动生成第 1 周到第 5/6 周。 +- 周计划筛选规则:按 `投产时间` 或 `精工期限` 两种口径切换,默认按 `投产时间`。 +- 周计划展示建议: + - 顶部显示本周计划数、生产中、已完成、逾期风险、完成率。 + - 中部按周一到周日分列,每列列出订单/零件卡片。 + - 底部保留明细表格,便于导出。 + +周计划最小改造方案:继续调用现有 `车间生产管理_生产计划_查询数据`,前端按日期过滤并分组。 +周计划推荐方案:后端过程增加 `开始时间`、`结束时间` 参数,由 SQL Server 过滤,减少月份数据量过大时的前端压力。 + +### 3.2 设备后续工作时间显示到小时 + +现有生产计划页面点击设备后,会打开设备后续已派工任务弹窗,样式接近 APS 时间轴。建议增强: + +- 显示字段从日期改为 `yyyy-MM-dd HH:mm`。 +- 时间轴横向粒度由“天”增强为“天 + 小时刻度”。 +- 任务卡片显示: + - 订单号/合同号 + - 零件名称、图号 + - 工序顺序、工序名称 + - 操作者 + - 设备 + - 分配时间、预计完成时间、开始加工时间、完成时间 +- 如果没有预计完成时间,则按 `分配时间 + 计划工时/设备能力` 计算临时结束时间,并标记为“估算”。 + +前端格式统一建议: + +```text +2026-08-12 14:30 +``` + +### 3.3 销售合同计划 + +销售合同计划不建议等同于生产任务计划。它应从“合同交付承诺”看“生产是否支撑交付”,核心不是设备排产,而是合同节点和生产状态对齐。 + +建议新增 `销售合同计划` 视角,展示以下层级: + +```text +销售合同 + -> 订单 + -> 产品/部件 + -> 生产计划 + -> 工艺/派工/完工 +``` + +销售合同计划关键字段: + +| 字段 | 来源 | 用途 | +| --- | --- | --- | +| 合同编号 | `PDM_项目名称` 或合同信息相关视图 | 合同主键展示 | +| 客户/收货人 | 客户关系或订单关联客户 | 识别交付对象 | +| 合同签订日期 | 合同信息 | 计划起点 | +| 交货日期/精工期限 | 订单或生产计划 | 风险判断 | +| 订单编号 | `PDM_订单信息_视图`、`合同管理_订单信息_基础表` | 关联生产 | +| 产品名称 | PDM 产品/组件视图 | 合同产品范围 | +| 计划数量 | 生产计划视图 | 生产负荷 | +| 完成率 | 生产计划或工艺完工统计 | 进度展示 | +| 当前工序/设备 | 工艺计划、派工数据 | 当前进展 | +| 风险状态 | 计算字段 | 正常、临期、逾期、无生产计划 | + +建议状态规则: + +| 状态 | 判断 | +| --- | --- | +| 正常 | 精工期限未到,生产进度匹配 | +| 临期 | 距交付日期小于等于 7 天且未完成 | +| 逾期 | 当前日期超过交付日期且未完成 | +| 无计划 | 合同/订单已存在但没有生产计划 | +| 已完成 | 生产计划全部完成 | + +### 3.4 设备门牌看板 + +“医院诊室门口样式”建议做成现场大屏/看板页面,不放在复杂表格里。页面以设备为单位,每台设备一张门牌卡,重点展示“正在生产什么、下一项生产什么”。 + +每张设备卡片建议结构: + +```text +设备名称 / 工位号 状态灯 +正在生产: + 订单号 零件名称 图号 + 工序 操作者 已用时/计划工时 + +下一项: + 订单号 零件名称 图号 + 工序 计划开始时间 + +后续队列:3 项 +更新时间:2026-08-12 14:24 +``` + +看板规则: + +- 设备状态颜色复用现有设备监控状态:运行、等待、关机、报警、断网。 +- 当前任务优先取 MES 实时加工/工位零件接口。 +- 下一项任务取该设备未完成、未开始或已派工未加工的最早任务。 +- 看板自动刷新,建议 30 秒一次。 +- 支持按工位、设备类型、是否只看异常筛选。 +- 点击卡片进入设备后续工作 APS 弹窗。 + +## 四、流程图 + +### 4.1 周计划查询流程 + +```mermaid +flowchart TD + A["用户进入生产计划"] --> B["选择月份"] + B --> C["系统生成周次列表"] + C --> D["选择周次和统计口径"] + D --> E["查询生产计划数据"] + E --> F["按周起止日期过滤"] + F --> G["按周一到周日分组"] + G --> H["显示周计划卡片和明细表格"] + H --> I["导出周计划"] +``` + +### 4.2 设备后续工作流程 + +```mermaid +flowchart TD + A["生产计划列表点击设备"] --> B["传入设备名称或工位号"] + B --> C["查询设备后续派工任务"] + C --> D["补齐分配时间、开始时间、完成时间、预计完成时间"] + D --> E["统一格式化到 yyyy-MM-dd HH:mm"] + E --> F["按操作者或设备分组"] + F --> G["渲染小时级 APS 时间轴"] +``` + +### 4.3 销售合同计划流程 + +```mermaid +flowchart TD + A["销售合同"] --> B["关联订单"] + B --> C["关联产品/部件"] + C --> D["关联生产计划"] + D --> E["关联工艺和派工"] + E --> F["计算完成率和风险状态"] + F --> G["销售合同计划看板"] + G --> H["跳转订单进度或生产计划明细"] +``` + +### 4.4 设备门牌看板流程 + +```mermaid +flowchart TD + A["设备清单"] --> B["查询实时设备状态"] + B --> C["查询当前加工零件"] + C --> D["查询后续待加工任务"] + D --> E["合并为设备门牌数据"] + E --> F["显示当前任务"] + E --> G["显示下一项任务"] + F --> H["30秒自动刷新"] + G --> H +``` + +## 五、数据源设计 + +### 5.1 已有前端页面和接口 + +| 功能 | 文件/接口 | 说明 | +| --- | --- | --- | +| 生产计划 | `src/views/SeikoWorkshop/ProductionPlan/index.vue` | 当前生产计划主页面 | +| 生产任务查询 | `src/views/SeikoWorkshop/ProductionTaskQuery/index.vue` | 生产任务、工艺、派工入口 | +| 设备监控 | `src/views/SeikoWorkshop/EquipmentMonitoringNew/index.vue`、`src/views/DeviceManagement/EquipmentStatusMonitoring/index.vue` | 设备实时状态和设备跳转 | +| 合同查询 | `src/views/SalesManagement/ContractSearch/index.vue`、`src/views/SalesManagement/ContractSearchNew/index.vue` | 销售合同信息 | +| 订单进度 | `src/views/SalesManagement/OrderProgress/index.vue` | 销售订单进度展示 | + +### 5.2 已有后端过程/视图 + +| 数据用途 | 已识别数据源 | +| --- | --- | +| 生产计划主数据 | `车间生产管理_生产计划_查询数据` | +| 生产计划视图 | `车间生产管理_生产计划_视图_新` | +| 生产任务查询 | `精工车间_生成任务_查询数据` | +| 订单下拉 | `生产任务查询_订单信息_列表_查询数据` | +| 订单产品 | `订单信息_产品信息_查询数据` | +| 零件追溯工序 | `车间生产管理工艺_追溯加工_查询工序` | +| 设备当前零件 | `MES_机加工MES_工位零件图号查询_设备监控` | +| 设备待加工队列 | `MES_机加工MES_待加工零件_查询_设备监控` | +| 设备状态 | `MES_机加工MES_设备数据采集_工位状态_查询_新`、`MES_机加工MES_设备状态查询_初始化` | +| 合同/项目 | `PDM_项目名称_全部_查询数据`、`合同信息管理_合同信息_查询_分页` | +| 订单基础关联 | `合同管理_订单信息_基础表`、`PDM_订单信息_视图` | + +### 5.3 建议新增后端接口 + +#### 5.3.1 周计划查询 + +```text +name: 车间生产管理_生产计划_周计划_查询数据 +type: 1 +param: + 开始时间 + 结束时间 + 日期口径:投产时间/精工期限 + 合同编号_check + 合同编号 + 零件名称_check + 零件名称 + 产品名称_check + 产品名称 + 状态_check + 状态 +``` + +返回字段建议: + +```text +周次、日期、状态、合同编号、订单号、收货人、投产时间、精工期限、计划数、产品名称、零件名称、零件图号、材料、完成率、当前设备、当前工序、OP010~OP110 +``` + +#### 5.3.2 设备后续小时级任务 + +```text +name: 车间生产管理_设备后续任务_小时计划_查询数据 +type: 1 +param: + 设备名称 + 工位号 + 开始时间 + 结束时间 + 是否只看未完成 +``` + +返回字段建议: + +```text +设备名称、工位号、订单号、合同编号、产品名称、零件名称、零件图号、工序顺序、工序、操作者、数量、完成数、分配时间、开始加工、预计完成时间、完成时间、计划工时M、任务状态 +``` + +#### 5.3.3 销售合同计划 + +```text +name: 销售管理_销售合同计划_查询数据 +type: 1 +param: + 合同编号_check + 合同编号 + 客户_check + 客户 + 开始时间 + 结束时间 + 风险状态_check + 风险状态 +``` + +返回字段建议: + +```text +合同编号、项目流水号、客户名称、收货人、合同签订日期、交付日期、订单号、产品名称、计划数量、生产计划数、完成数量、完成率、当前工序、当前设备、最晚精工期限、风险状态 +``` + +#### 5.3.4 设备门牌看板 + +```text +name: 车间生产管理_设备门牌看板_查询数据 +type: 1 +param: + 工位号_check + 工位号 + 设备状态_check + 设备状态 + 只看异常 +``` + +返回字段建议: + +```text +设备名称、工位号、设备状态、状态颜色、当前订单号、当前合同编号、当前零件名称、当前零件图号、当前工序、当前操作者、开始加工时间、已用时M、计划工时M、下一订单号、下一合同编号、下一零件名称、下一零件图号、下一工序、下一计划开始时间、后续队列数、更新时间 +``` + +## 六、实施顺序 + +建议按风险从低到高实施: + +1. 先做设备后续任务时间显示到小时,只改显示和查询字段,风险最低。 +2. 做周计划前端视图,先复用月计划数据过滤,确认业务口径。 +3. 做设备门牌看板,先复用设备监控和待加工队列接口,后续再合并成单接口。 +4. 做销售合同计划,需要合同、订单、生产计划多源联查,建议最后做。 + +## 七、验收口径 + +| 需求 | 验收方式 | +| --- | --- | +| 周计划 | 选择月份和周次后,只显示该周对应计划;周一到周日分组正确 | +| 设备后续小时 | 点击设备后,分配时间、开始加工、预计完成、完成时间显示到小时分钟 | +| 销售合同计划 | 能按合同看到关联订单、生产完成率、风险状态,并能跳转明细 | +| 设备门牌看板 | 每台设备清楚显示当前任务、下一项任务、状态颜色和更新时间 | + +## 八、注意事项 + +- 周计划必须确认日期口径:按投产时间、精工期限,还是两者都支持。 +- 销售合同计划需要统一合同编号来源,优先使用已补充的 `关联合同编号`,其次再使用订单备注/MK 关联逻辑。 +- 设备门牌看板若用于现场大屏,建议单独配置自动刷新间隔,避免频繁查询影响 MES 采集接口。 +- 所有新增接口仍按项目规范 POST 到 `MESCommonBase.ashx`,携带 `UserID` 和 `ModularID`。 + +修改人:Ld 修改时间:2026-08-12 14:24:23; diff --git a/scripts/build_production_plan_requirement_docx.py b/scripts/build_production_plan_requirement_docx.py new file mode 100644 index 00000000..91ddaaa2 --- /dev/null +++ b/scripts/build_production_plan_requirement_docx.py @@ -0,0 +1,347 @@ +# 修改人:Ld 修改时间:2026-08-12 14:53:07; 生成生产计划组件补充需求方案 Word 文档。 +from docx import Document +from docx.enum.section import WD_SECTION +from docx.enum.table import WD_CELL_VERTICAL_ALIGNMENT, WD_TABLE_ALIGNMENT +from docx.enum.text import WD_ALIGN_PARAGRAPH +from docx.oxml import OxmlElement +from docx.oxml.ns import qn +from docx.shared import Cm, Inches, Pt, RGBColor + + +OUT = r"D:\景耀\JY1.0\docs\生产计划组件补充需求方案.docx" + + +def set_cell_shading(cell, fill): + tc_pr = cell._tc.get_or_add_tcPr() + shd = tc_pr.find(qn("w:shd")) + if shd is None: + shd = OxmlElement("w:shd") + tc_pr.append(shd) + shd.set(qn("w:fill"), fill) + + +def set_cell_text(cell, text, bold=False, color=None): + cell.text = "" + p = cell.paragraphs[0] + p.paragraph_format.space_after = Pt(0) + run = p.add_run(text) + run.bold = bold + run.font.name = "Microsoft YaHei" + run._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei") + run.font.size = Pt(9.5) + if color: + run.font.color.rgb = RGBColor.from_string(color) + cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER + + +def set_table_width(table, widths_cm): + table.autofit = False + table.alignment = WD_TABLE_ALIGNMENT.CENTER + for row in table.rows: + for idx, width in enumerate(widths_cm): + row.cells[idx].width = Cm(width) + + +def add_table(doc, headers, rows, widths_cm): + table = doc.add_table(rows=1, cols=len(headers)) + table.style = "Table Grid" + set_table_width(table, widths_cm) + for idx, header in enumerate(headers): + set_cell_text(table.rows[0].cells[idx], header, bold=True, color="0B2545") + set_cell_shading(table.rows[0].cells[idx], "F2F4F7") + for row in rows: + cells = table.add_row().cells + for idx, value in enumerate(row): + set_cell_text(cells[idx], str(value)) + doc.add_paragraph() + return table + + +def add_flow(doc, title, steps): + doc.add_heading(title, level=3) + table = doc.add_table(rows=1, cols=len(steps)) + table.style = "Table Grid" + table.alignment = WD_TABLE_ALIGNMENT.CENTER + width = 16.0 / len(steps) + set_table_width(table, [width] * len(steps)) + for idx, step in enumerate(steps): + cell = table.rows[0].cells[idx] + set_cell_text(cell, step, bold=True) + set_cell_shading(cell, "E8EEF5" if idx % 2 == 0 else "F4F6F9") + p = doc.add_paragraph() + p.paragraph_format.space_after = Pt(4) + + +def add_bullet(doc, text): + p = doc.add_paragraph(style="List Bullet") + p.paragraph_format.space_after = Pt(3) + run = p.add_run(text) + run.font.name = "Microsoft YaHei" + run._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei") + run.font.size = Pt(10.5) + + +def add_para(doc, text, bold_prefix=None): + p = doc.add_paragraph() + p.paragraph_format.space_after = Pt(6) + if bold_prefix and text.startswith(bold_prefix): + run = p.add_run(bold_prefix) + run.bold = True + run.font.name = "Microsoft YaHei" + run._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei") + run.font.size = Pt(10.5) + text = text[len(bold_prefix):] + run = p.add_run(text) + run.font.name = "Microsoft YaHei" + run._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei") + run.font.size = Pt(10.5) + + +def build(): + doc = Document() + section = doc.sections[0] + section.top_margin = Inches(0.85) + section.bottom_margin = Inches(0.85) + section.left_margin = Inches(0.85) + section.right_margin = Inches(0.85) + + styles = doc.styles + normal = styles["Normal"] + normal.font.name = "Microsoft YaHei" + normal._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei") + normal.font.size = Pt(10.5) + normal.paragraph_format.line_spacing = 1.1 + normal.paragraph_format.space_after = Pt(6) + + for style_name, size, color, before, after in [ + ("Heading 1", 16, "2E74B5", 16, 8), + ("Heading 2", 13, "2E74B5", 12, 6), + ("Heading 3", 12, "1F4D78", 8, 4), + ]: + style = styles[style_name] + style.font.name = "Microsoft YaHei" + style._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei") + style.font.size = Pt(size) + style.font.bold = True + style.font.color.rgb = RGBColor.from_string(color) + style.paragraph_format.space_before = Pt(before) + style.paragraph_format.space_after = Pt(after) + + title = doc.add_paragraph() + title.alignment = WD_ALIGN_PARAGRAPH.CENTER + title.paragraph_format.space_after = Pt(8) + run = title.add_run("生产计划组件补充需求方案") + run.bold = True + run.font.name = "Microsoft YaHei" + run._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei") + run.font.size = Pt(22) + run.font.color.rgb = RGBColor.from_string("0B2545") + + subtitle = doc.add_paragraph() + subtitle.alignment = WD_ALIGN_PARAGRAPH.CENTER + subtitle.paragraph_format.space_after = Pt(14) + run = subtitle.add_run("周计划、设备小时级计划、销售合同计划、设备门牌看板") + run.font.name = "Microsoft YaHei" + run._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei") + run.font.size = Pt(11) + run.font.color.rgb = RGBColor.from_string("555555") + + add_para(doc, "本次先做方案,不修改业务页面和数据库过程。围绕生产计划组件的四项补充需求,建议拆成三个前端能力和一组后端数据源。") + for item in [ + "生产计划支持“周计划”显示。", + "点击设备查看后续工作时,模块时间显示到“小时/分钟”。", + "在生产任务计划之外,增加“销售合同计划”视角。", + "增加类似医院诊室门口屏幕的“设备当前生产/下一项生产”直观展示。", + ]: + add_bullet(doc, item) + + doc.add_heading("一、总体设计", level=1) + add_para(doc, "建议新增一个“计划看板”入口,保留现有生产计划表格页作为明细查询和导出页面,在其上扩展三种视图。") + add_table( + doc, + ["视图", "主要用途", "展示粒度", "用户动作"], + [ + ["月计划", "复用现有生产计划表格", "月", "查询、导出、打开可视化"], + ["周计划", "查看本周投产、派工、交付压力", "周、天", "周次切换、按天筛选、查看明细"], + ["设备门牌看板", "现场快速查看每台设备当前和下一项", "设备、当前任务、下一任务", "自动刷新、点击设备查看后续队列"], + ["销售合同计划", "从合同交付节点倒推生产风险", "合同、订单、产品、计划节点", "查看合同进度、跳转生产计划/订单进度"], + ], + [3.0, 5.0, 3.8, 4.2], + ) + + doc.add_heading("二、功能方案", level=1) + doc.add_heading("2.1 周计划显示", level=2) + add_para(doc, "现有生产计划页面已经按月份查询,建议周计划不新增单独页面,先在当前生产计划页面增加“视图模式”。") + for item in [ + "月计划:保持现有表格。", + "周计划:按选中月份自动生成第 1 周到第 5/6 周。", + "周计划筛选规则:按投产时间或精工期限两种口径切换,默认按投产时间。", + "顶部显示本周计划数、生产中、已完成、逾期风险、完成率。", + "中部按周一到周日分列,每列列出订单/零件卡片;底部保留明细表格,便于导出。", + ]: + add_bullet(doc, item) + add_para(doc, "最小改造方案:继续调用现有 `车间生产管理_生产计划_查询数据`,前端按日期过滤并分组。") + add_para(doc, "推荐方案:后端过程增加开始时间、结束时间参数,由 SQL Server 过滤,减少月份数据量过大时的前端压力。") + + doc.add_heading("2.2 设备后续工作时间显示到小时", level=2) + add_para(doc, "现有生产计划页面点击设备后,会打开设备后续已派工任务弹窗,样式接近 APS 时间轴。建议增强为小时级展示。") + for item in [ + "显示字段从日期改为 yyyy-MM-dd HH:mm。", + "时间轴横向粒度由“天”增强为“天 + 小时刻度”。", + "任务卡片显示订单号/合同号、零件名称、图号、工序、操作者、设备、分配时间、预计完成时间、开始加工时间、完成时间。", + "如果没有预计完成时间,则按分配时间 + 计划工时/设备能力计算临时结束时间,并标记为“估算”。", + ]: + add_bullet(doc, item) + + doc.add_heading("2.3 销售合同计划", level=2) + add_para(doc, "销售合同计划不建议等同于生产任务计划。它应从“合同交付承诺”看“生产是否支撑交付”,核心不是设备排产,而是合同节点和生产状态对齐。") + add_para(doc, "建议层级:销售合同 -> 订单 -> 产品/部件 -> 生产计划 -> 工艺/派工/完工。") + add_table( + doc, + ["字段", "来源", "用途"], + [ + ["合同编号", "PDM_项目名称或合同信息相关视图", "合同主键展示"], + ["客户/收货人", "客户关系或订单关联客户", "识别交付对象"], + ["合同签订日期", "合同信息", "计划起点"], + ["交货日期/精工期限", "订单或生产计划", "风险判断"], + ["订单编号", "PDM_订单信息_视图、合同管理_订单信息_基础表", "关联生产"], + ["产品名称", "PDM 产品/组件视图", "合同产品范围"], + ["计划数量", "生产计划视图", "生产负荷"], + ["完成率", "生产计划或工艺完工统计", "进度展示"], + ["当前工序/设备", "工艺计划、派工数据", "当前进展"], + ["风险状态", "计算字段", "正常、临期、逾期、无生产计划"], + ], + [3.0, 6.5, 6.5], + ) + add_table( + doc, + ["状态", "判断"], + [ + ["正常", "精工期限未到,生产进度匹配"], + ["临期", "距交付日期小于等于 7 天且未完成"], + ["逾期", "当前日期超过交付日期且未完成"], + ["无计划", "合同/订单已存在但没有生产计划"], + ["已完成", "生产计划全部完成"], + ], + [3.0, 13.0], + ) + + doc.add_heading("2.4 设备门牌看板", level=2) + add_para(doc, "“医院诊室门口样式”建议做成现场大屏/看板页面,不放在复杂表格里。页面以设备为单位,每台设备一张门牌卡,重点展示“正在生产什么、下一项生产什么”。") + add_table( + doc, + ["模块", "展示内容"], + [ + ["设备抬头", "设备名称 / 工位号 / 状态灯"], + ["正在生产", "订单号、零件名称、图号、工序、操作者、已用时/计划工时"], + ["下一项", "订单号、零件名称、图号、工序、计划开始时间"], + ["辅助信息", "后续队列数、更新时间、异常状态"], + ], + [3.0, 13.0], + ) + for item in [ + "设备状态颜色复用现有设备监控状态:运行、等待、关机、报警、断网。", + "当前任务优先取 MES 实时加工/工位零件接口。", + "下一项任务取该设备未完成、未开始或已派工未加工的最早任务。", + "看板自动刷新,建议 30 秒一次。", + "点击卡片进入设备后续工作 APS 弹窗。", + ]: + add_bullet(doc, item) + + doc.add_heading("三、流程图", level=1) + add_flow(doc, "3.1 周计划查询流程", ["进入生产计划", "选择月份", "生成周次", "选择周次/口径", "查询数据", "按日期过滤", "分组展示", "导出周计划"]) + add_flow(doc, "3.2 设备后续工作流程", ["点击设备", "传入设备/工位", "查询后续派工", "补齐时间字段", "格式化到小时", "分组", "渲染 APS 轴"]) + add_flow(doc, "3.3 销售合同计划流程", ["销售合同", "关联订单", "关联产品", "关联生产计划", "关联工艺派工", "计算风险", "合同计划看板", "跳转明细"]) + add_flow(doc, "3.4 设备门牌看板流程", ["设备清单", "实时状态", "当前加工", "后续任务", "合并门牌数据", "当前任务", "下一任务", "自动刷新"]) + + doc.add_heading("四、数据源设计", level=1) + doc.add_heading("4.1 已有前端页面和接口", level=2) + add_table( + doc, + ["功能", "文件/接口", "说明"], + [ + ["生产计划", "src/views/SeikoWorkshop/ProductionPlan/index.vue", "当前生产计划主页面"], + ["生产任务查询", "src/views/SeikoWorkshop/ProductionTaskQuery/index.vue", "生产任务、工艺、派工入口"], + ["设备监控", "src/views/SeikoWorkshop/EquipmentMonitoringNew/index.vue;src/views/DeviceManagement/EquipmentStatusMonitoring/index.vue", "设备实时状态和设备跳转"], + ["合同查询", "src/views/SalesManagement/ContractSearch/index.vue;src/views/SalesManagement/ContractSearchNew/index.vue", "销售合同信息"], + ["订单进度", "src/views/SalesManagement/OrderProgress/index.vue", "销售订单进度展示"], + ], + [3.0, 8.0, 5.0], + ) + doc.add_heading("4.2 已有后端过程/视图", level=2) + add_table( + doc, + ["数据用途", "已识别数据源"], + [ + ["生产计划主数据", "车间生产管理_生产计划_查询数据"], + ["生产计划视图", "车间生产管理_生产计划_视图_新"], + ["生产任务查询", "精工车间_生成任务_查询数据"], + ["订单下拉", "生产任务查询_订单信息_列表_查询数据"], + ["订单产品", "订单信息_产品信息_查询数据"], + ["零件追溯工序", "车间生产管理工艺_追溯加工_查询工序"], + ["设备当前零件", "MES_机加工MES_工位零件图号查询_设备监控"], + ["设备待加工队列", "MES_机加工MES_待加工零件_查询_设备监控"], + ["设备状态", "MES_机加工MES_设备数据采集_工位状态_查询_新;MES_机加工MES_设备状态查询_初始化"], + ["合同/项目", "PDM_项目名称_全部_查询数据;合同信息管理_合同信息_查询_分页"], + ["订单基础关联", "合同管理_订单信息_基础表;PDM_订单信息_视图"], + ], + [4.0, 12.0], + ) + doc.add_heading("4.3 建议新增后端接口", level=2) + add_table( + doc, + ["接口", "name", "核心返回字段"], + [ + ["周计划查询", "车间生产管理_生产计划_周计划_查询数据", "周次、日期、状态、合同编号、订单号、投产时间、精工期限、完成率、当前设备、OP010~OP110"], + ["设备小时级任务", "车间生产管理_设备后续任务_小时计划_查询数据", "设备名称、工位号、订单号、合同编号、工序、操作者、分配时间、开始加工、预计完成、完成时间、计划工时M"], + ["销售合同计划", "销售管理_销售合同计划_查询数据", "合同编号、客户、交付日期、订单号、产品名称、计划数量、完成率、当前工序、当前设备、风险状态"], + ["设备门牌看板", "车间生产管理_设备门牌看板_查询数据", "设备状态、当前任务、下一任务、后续队列数、更新时间"], + ], + [3.0, 6.0, 7.0], + ) + + doc.add_heading("五、实施顺序", level=1) + for item in [ + "先做设备后续任务时间显示到小时,只改显示和查询字段,风险最低。", + "做周计划前端视图,先复用月计划数据过滤,确认业务口径。", + "做设备门牌看板,先复用设备监控和待加工队列接口,后续再合并成单接口。", + "做销售合同计划,需要合同、订单、生产计划多源联查,建议最后做。", + ]: + add_bullet(doc, item) + + doc.add_heading("六、验收口径", level=1) + add_table( + doc, + ["需求", "验收方式"], + [ + ["周计划", "选择月份和周次后,只显示该周对应计划;周一到周日分组正确"], + ["设备后续小时", "点击设备后,分配时间、开始加工、预计完成、完成时间显示到小时分钟"], + ["销售合同计划", "能按合同看到关联订单、生产完成率、风险状态,并能跳转明细"], + ["设备门牌看板", "每台设备清楚显示当前任务、下一项任务、状态颜色和更新时间"], + ], + [4.0, 12.0], + ) + + doc.add_heading("七、注意事项", level=1) + for item in [ + "周计划必须确认日期口径:按投产时间、精工期限,还是两者都支持。", + "销售合同计划需要统一合同编号来源,优先使用已补充的关联合同编号,其次再使用订单备注/MK 关联逻辑。", + "设备门牌看板若用于现场大屏,建议单独配置自动刷新间隔,避免频繁查询影响 MES 采集接口。", + "所有新增接口仍按项目规范 POST 到 MESCommonBase.ashx,携带 UserID 和 ModularID。", + ]: + add_bullet(doc, item) + + doc.add_paragraph() + p = doc.add_paragraph() + p.alignment = WD_ALIGN_PARAGRAPH.RIGHT + run = p.add_run("修改人:Ld 修改时间:2026-08-12 14:24:23;") + run.font.name = "Microsoft YaHei" + run._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei") + run.font.size = Pt(9) + run.font.color.rgb = RGBColor.from_string("555555") + + doc.save(OUT) + + +if __name__ == "__main__": + build() diff --git a/sql/PDA采购扫码入库_测试库_20260907.sql b/sql/PDA采购扫码入库_测试库_20260907.sql new file mode 100644 index 00000000..c23e1ac7 --- /dev/null +++ b/sql/PDA采购扫码入库_测试库_20260907.sql @@ -0,0 +1,416 @@ +/* +修改人:Ld 修改时间:2026-09-07 15:42:36; +用途: 测试库新增仓库 PDA 扫码采购入库后端过程。 +数据库: ERPTOOL_JY_20250826Back +说明: 仅部署测试库;PDA 入库提交复用现有 dbo.仓储管理_采购件入库_循环执行,保持库存和采购合同状态更新口径一致。 +*/ + +IF COL_LENGTH(N'dbo.仓储管理_入库单标签', N'入库状态') IS NULL +BEGIN + -- 修改人:Ld 修改时间:2026-09-07 15:42:36; 标签主表增加PDA入库状态:0待入库、1部分入库、2已入库。 + ALTER TABLE dbo.仓储管理_入库单标签 ADD 入库状态 INT NOT NULL CONSTRAINT DF_仓储管理_入库单标签_入库状态 DEFAULT(0) +END +GO + +IF COL_LENGTH(N'dbo.仓储管理_入库单标签', N'入库人') IS NULL +BEGIN + -- 修改人:Ld 修改时间:2026-09-07 15:42:36; 标签主表记录PDA最终入库人。 + ALTER TABLE dbo.仓储管理_入库单标签 ADD 入库人 INT NULL +END +GO + +IF COL_LENGTH(N'dbo.仓储管理_入库单标签', N'入库时间') IS NULL +BEGIN + -- 修改人:Ld 修改时间:2026-09-07 15:42:36; 标签主表记录PDA最终入库时间。 + ALTER TABLE dbo.仓储管理_入库单标签 ADD 入库时间 DATETIME NULL +END +GO + +IF COL_LENGTH(N'dbo.仓储管理_入库单标签明细', N'标准件和外购件流水号') IS NULL +BEGIN + -- 修改人:Ld 修改时间:2026-09-07 15:42:36; 标签明细补充原采购入库过程所需标准件/外购件流水号。 + ALTER TABLE dbo.仓储管理_入库单标签明细 ADD 标准件和外购件流水号 INT NULL +END +GO + +IF COL_LENGTH(N'dbo.仓储管理_入库单标签明细', N'采购类型') IS NULL +BEGIN + -- 修改人:Ld 修改时间:2026-09-07 15:42:36; 标签明细补充采购类型:1普通采购、2耗材采购。 + ALTER TABLE dbo.仓储管理_入库单标签明细 ADD 采购类型 INT NULL +END +GO + +IF COL_LENGTH(N'dbo.仓储管理_入库单标签明细', N'批号') IS NULL +BEGIN + -- 修改人:Ld 修改时间:2026-09-07 15:42:36; 标签明细补充批号,兼容主轴入库。 + ALTER TABLE dbo.仓储管理_入库单标签明细 ADD 批号 INT NULL +END +GO + +IF COL_LENGTH(N'dbo.仓储管理_入库单标签明细', N'批次编码') IS NULL +BEGIN + -- 修改人:Ld 修改时间:2026-09-07 15:42:36; 标签明细补充批次编码,用于PDA入库和后续条码追溯。 + ALTER TABLE dbo.仓储管理_入库单标签明细 ADD 批次编码 NVARCHAR(100) NULL +END +GO + +IF COL_LENGTH(N'dbo.仓储管理_入库单标签明细', N'已入库数量') IS NULL +BEGIN + -- 修改人:Ld 修改时间:2026-09-07 15:42:36; 标签明细记录PDA已入库数量,支持防重复入库和后续部分入库。 + ALTER TABLE dbo.仓储管理_入库单标签明细 ADD 已入库数量 DECIMAL(18,4) NOT NULL CONSTRAINT DF_仓储管理_入库单标签明细_已入库数量 DEFAULT(0) +END +GO + +IF COL_LENGTH(N'dbo.仓储管理_入库单标签明细', N'货位流水号') IS NULL +BEGIN + -- 修改人:Ld 修改时间:2026-09-07 15:42:36; 标签明细记录PDA入库选择的货位流水号。 + ALTER TABLE dbo.仓储管理_入库单标签明细 ADD 货位流水号 INT NULL +END +GO + +IF COL_LENGTH(N'dbo.仓储管理_入库单标签明细', N'货位名称') IS NULL +BEGIN + -- 修改人:Ld 修改时间:2026-09-07 15:42:36; 标签明细记录PDA入库选择的货位名称。 + ALTER TABLE dbo.仓储管理_入库单标签明细 ADD 货位名称 NVARCHAR(100) NULL +END +GO + +IF COL_LENGTH(N'dbo.仓储管理_入库单标签明细', N'入库状态') IS NULL +BEGIN + -- 修改人:Ld 修改时间:2026-09-07 15:42:36; 标签明细增加PDA入库状态:0待入库、1部分入库、2已入库。 + ALTER TABLE dbo.仓储管理_入库单标签明细 ADD 入库状态 INT NOT NULL CONSTRAINT DF_仓储管理_入库单标签明细_入库状态 DEFAULT(0) +END +GO + +IF COL_LENGTH(N'dbo.仓储管理_入库单标签明细', N'入库人') IS NULL +BEGIN + -- 修改人:Ld 修改时间:2026-09-07 15:42:36; 标签明细记录PDA入库人。 + ALTER TABLE dbo.仓储管理_入库单标签明细 ADD 入库人 INT NULL +END +GO + +IF COL_LENGTH(N'dbo.仓储管理_入库单标签明细', N'入库时间') IS NULL +BEGIN + -- 修改人:Ld 修改时间:2026-09-07 15:42:36; 标签明细记录PDA入库时间。 + ALTER TABLE dbo.仓储管理_入库单标签明细 ADD 入库时间 DATETIME NULL +END +GO + +IF OBJECT_ID(N'dbo.TR_仓储管理_入库单标签明细_补充采购入库参数', N'TR') IS NOT NULL + DROP TRIGGER dbo.TR_仓储管理_入库单标签明细_补充采购入库参数 +GO + +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +-- 修改人:Ld 修改时间:2026-09-07 15:42:36; 标签明细新增后自动补齐原采购入库过程所需参数。 +CREATE TRIGGER dbo.TR_仓储管理_入库单标签明细_补充采购入库参数 +ON dbo.仓储管理_入库单标签明细 +AFTER INSERT +AS +BEGIN + SET NOCOUNT ON; + + UPDATE d + SET 标准件和外购件流水号 = ISNULL(d.标准件和外购件流水号, ISNULL(cg.标准件和外购件流水号, hc.标准件和外购件流水号)), + 采购类型 = ISNULL(d.采购类型, CASE WHEN cg.采购合同明细流水号 IS NOT NULL THEN 1 WHEN hc.采购合同明细流水号 IS NOT NULL THEN 2 ELSE NULL END), + 批号 = ISNULL(d.批号, ISNULL(cg.批号, hc.批号)), + 批次编码 = ISNULL(d.批次编码, ISNULL(cg.批次编码, hc.批次编码)) + FROM dbo.仓储管理_入库单标签明细 d + INNER JOIN inserted i ON d.入库单标签明细流水号 = i.入库单标签明细流水号 + INNER JOIN dbo.仓储管理_入库单标签 t ON d.入库单标签流水号 = t.入库单标签流水号 + OUTER APPLY ( + SELECT TOP 1 + v.采购合同明细流水号, + v.标准件和外购件流水号, + v.批号, + (CONVERT(VARCHAR(10), GETDATE(), 23) + '-CG' + CONVERT(NVARCHAR(50), v.采购合同明细流水号)) + + CASE WHEN ISNULL(v.是否主轴, 0) = 1 THEN '.' + CONVERT(NVARCHAR(50), v.批号) ELSE '' END AS 批次编码 + FROM dbo.采购管理_采购合同明细_视图 v + WHERE v.采购合同流水号 = t.采购合同流水号 + AND v.物料流水号 = d.物料流水号 + AND (d.采购合同明细流水号 IS NULL OR v.采购合同明细流水号 = d.采购合同明细流水号) + ORDER BY v.采购合同明细流水号 + ) cg + OUTER APPLY ( + SELECT TOP 1 + v.采购合同明细流水号, + 0 AS 标准件和外购件流水号, + 1 AS 批号, + CONVERT(VARCHAR(10), GETDATE(), 23) + '-HC' + CONVERT(NVARCHAR(50), v.采购合同明细流水号) AS 批次编码 + FROM dbo.采购管理_耗材采购合同明细_查询视图 v + WHERE v.采购合同流水号 = t.采购合同流水号 + AND v.物料流水号 = d.物料流水号 + AND (d.采购合同明细流水号 IS NULL OR v.采购合同明细流水号 = d.采购合同明细流水号) + ORDER BY v.采购合同明细流水号 + ) hc +END +GO + +IF OBJECT_ID(N'dbo.仓储管理_PDA货位_查询', N'P') IS NOT NULL + DROP PROCEDURE dbo.仓储管理_PDA货位_查询 +GO + +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +-- 修改人:Ld 修改时间:2026-09-07 15:42:36; PDA查询可用货位,供扫码入库选择库位。 +CREATE PROCEDURE dbo.仓储管理_PDA货位_查询 +@货位名称 NVARCHAR(100) = NULL +AS +BEGIN + SET NOCOUNT ON; + + SELECT TOP 200 + 货位流水号, + 货位名称, + 仓库流水号 + FROM dbo.库存管理_货位主文件 + WHERE ISNULL(是否启用, 1) = 1 + AND (ISNULL(@货位名称, N'') = N'' OR 货位名称 LIKE N'%' + @货位名称 + N'%') + ORDER BY 货位名称 +END +GO + +IF OBJECT_ID(N'dbo.仓储管理_PDA采购扫码入库_查询', N'P') IS NOT NULL + DROP PROCEDURE dbo.仓储管理_PDA采购扫码入库_查询 +GO + +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +-- 修改人:Ld 修改时间:2026-09-07 15:42:36; PDA扫码后查询标签和剩余待入库数量。 +CREATE PROCEDURE dbo.仓储管理_PDA采购扫码入库_查询 +@扫码内容 NVARCHAR(500) = NULL, +@标签ID INT = NULL, +@入库单号 NVARCHAR(100) = NULL +AS +BEGIN + SET NOCOUNT ON; + + DECLARE @标签编号 NVARCHAR(100) + SET @标签编号 = @扫码内容 + + IF @标签编号 LIKE N'JYRK|%' + BEGIN + SET @标签编号 = SUBSTRING(@标签编号, 6, 100) + END + + SELECT + t.入库单标签流水号 AS 标签ID, + t.标签编号, + t.入库单号, + t.采购合同流水号, + t.采购合同号, + t.供应商流水号, + t.供应商, + t.批次号, + t.入库状态 AS 标签入库状态, + d.入库单标签明细流水号 AS 标签明细ID, + d.物料流水号, + d.采购合同明细流水号, + d.标准件和外购件流水号, + d.采购类型, + d.批号, + d.批次编码, + d.物料名称, + d.图号, + d.数量 AS 标签数量, + d.已入库数量, + CONVERT(DECIMAL(18,4), ISNULL(d.数量, 0) - ISNULL(d.已入库数量, 0)) AS 剩余入库数量, + d.货位流水号, + ISNULL(d.货位名称, h.货位名称) AS 货位名称, + d.入库状态 AS 明细入库状态, + d.是否需要质检 + FROM dbo.仓储管理_入库单标签 t + INNER JOIN dbo.仓储管理_入库单标签明细 d + ON t.入库单标签流水号 = d.入库单标签流水号 + LEFT JOIN dbo.库存管理_货位主文件 h + ON d.货位流水号 = h.货位流水号 + WHERE t.是否启用 = 1 + AND ( + (@标签ID IS NOT NULL AND t.入库单标签流水号 = @标签ID) + OR (ISNULL(@标签编号, N'') <> N'' AND t.标签编号 = @标签编号) + OR (ISNULL(@入库单号, N'') <> N'' AND t.入库单号 = @入库单号) + OR (ISNULL(@扫码内容, N'') <> N'' AND t.入库单号 = @扫码内容) + ) + ORDER BY d.入库单标签明细流水号 +END +GO + +IF OBJECT_ID(N'dbo.仓储管理_PDA采购扫码入库_提交', N'P') IS NOT NULL + DROP PROCEDURE dbo.仓储管理_PDA采购扫码入库_提交 +GO + +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +-- 修改人:Ld 修改时间:2026-09-07 15:42:36; PDA确认入库提交,复用原采购入库循环过程并更新标签入库状态。 +CREATE PROCEDURE dbo.仓储管理_PDA采购扫码入库_提交 +@扫码内容 NVARCHAR(500) = NULL, +@标签ID INT = NULL, +@标签明细流水号组 NVARCHAR(4000) = NULL, +@入库数量组 NVARCHAR(4000) = NULL, +@货位流水号组 NVARCHAR(4000) = NULL, +@入库人 INT = NULL +AS +BEGIN + SET NOCOUNT ON; + + DECLARE @实际标签ID INT + DECLARE @标签编号 NVARCHAR(100) + + SET @标签编号 = @扫码内容 + + IF @标签编号 LIKE N'JYRK|%' + BEGIN + SET @标签编号 = SUBSTRING(@标签编号, 6, 100) + END + + SELECT TOP 1 @实际标签ID = 入库单标签流水号 + FROM dbo.仓储管理_入库单标签 + WHERE 是否启用 = 1 + AND ( + (@标签ID IS NOT NULL AND 入库单标签流水号 = @标签ID) + OR (ISNULL(@标签编号, N'') <> N'' AND 标签编号 = @标签编号) + OR (ISNULL(@扫码内容, N'') <> N'' AND 入库单号 = @扫码内容) + ) + + IF @实际标签ID IS NULL + BEGIN + SELECT '0' AS result, N'未找到有效入库标签' AS message + RETURN + END + + DECLARE @提交明细 TABLE + ( + RowNum INT NOT NULL, + 标签明细ID INT NULL, + 入库数量 DECIMAL(18,4) NULL, + 货位流水号 INT NULL + ) + + ;WITH 明细表 AS ( + SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS RowNum, CAST(Value AS INT) AS 标签明细ID + FROM dbo.SplitString(@标签明细流水号组, ',') + ), + 数量表 AS ( + SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS RowNum, CAST(Value AS DECIMAL(18,4)) AS 入库数量 + FROM dbo.SplitString(@入库数量组, ',') + ), + 货位表 AS ( + SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS RowNum, CAST(Value AS INT) AS 货位流水号 + FROM dbo.SplitString(@货位流水号组, ',') + ) + INSERT INTO @提交明细(RowNum, 标签明细ID, 入库数量, 货位流水号) + SELECT m.RowNum, m.标签明细ID, q.入库数量, h.货位流水号 + FROM 明细表 m + LEFT JOIN 数量表 q ON m.RowNum = q.RowNum + LEFT JOIN 货位表 h ON m.RowNum = h.RowNum + + IF NOT EXISTS (SELECT 1 FROM @提交明细 WHERE ISNULL(入库数量, 0) > 0) + BEGIN + SELECT '0' AS result, N'请提交至少一条入库数量大于0的明细' AS message + RETURN + END + + IF EXISTS (SELECT 1 FROM @提交明细 WHERE ISNULL(入库数量, 0) <= 0 OR 货位流水号 IS NULL) + BEGIN + SELECT '0' AS result, N'存在入库数量为空、数量小于等于0或未选择货位的明细' AS message + RETURN + END + + IF EXISTS ( + SELECT 1 + FROM @提交明细 s + LEFT JOIN dbo.仓储管理_入库单标签明细 d ON s.标签明细ID = d.入库单标签明细流水号 + WHERE d.入库单标签明细流水号 IS NULL + OR d.入库单标签流水号 <> @实际标签ID + OR s.入库数量 > CONVERT(DECIMAL(18,4), ISNULL(d.数量, 0) - ISNULL(d.已入库数量, 0)) + ) + BEGIN + SELECT '0' AS result, N'存在无效明细或入库数量超过标签剩余数量' AS message + RETURN + END + + IF EXISTS ( + SELECT 1 + FROM @提交明细 s + LEFT JOIN dbo.库存管理_货位主文件 h ON s.货位流水号 = h.货位流水号 + WHERE h.货位流水号 IS NULL OR ISNULL(h.是否启用, 1) <> 1 + ) + BEGIN + SELECT '0' AS result, N'存在无效或停用货位' AS message + RETURN + END + + DECLARE @物料流水号组 NVARCHAR(4000) + DECLARE @实际到货数量组 NVARCHAR(4000) + DECLARE @标准件和外购件流水号组 NVARCHAR(4000) + DECLARE @采购合同明细流水号组 NVARCHAR(4000) + DECLARE @是否采购组 NVARCHAR(4000) + DECLARE @批号组 NVARCHAR(4000) + DECLARE @批次编码组 NVARCHAR(4000) + + SELECT + @物料流水号组 = STUFF((SELECT ',' + CONVERT(NVARCHAR(50), d.物料流水号) FROM @提交明细 s INNER JOIN dbo.仓储管理_入库单标签明细 d ON s.标签明细ID = d.入库单标签明细流水号 ORDER BY s.RowNum FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, ''), + @实际到货数量组 = STUFF((SELECT ',' + CONVERT(NVARCHAR(50), CONVERT(FLOAT, s.入库数量)) FROM @提交明细 s ORDER BY s.RowNum FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, ''), + @标准件和外购件流水号组 = STUFF((SELECT ',' + CONVERT(NVARCHAR(50), ISNULL(d.标准件和外购件流水号, 0)) FROM @提交明细 s INNER JOIN dbo.仓储管理_入库单标签明细 d ON s.标签明细ID = d.入库单标签明细流水号 ORDER BY s.RowNum FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, ''), + @采购合同明细流水号组 = STUFF((SELECT ',' + CONVERT(NVARCHAR(50), ISNULL(d.采购合同明细流水号, 0)) FROM @提交明细 s INNER JOIN dbo.仓储管理_入库单标签明细 d ON s.标签明细ID = d.入库单标签明细流水号 ORDER BY s.RowNum FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, ''), + @是否采购组 = STUFF((SELECT ',' + CONVERT(NVARCHAR(50), ISNULL(d.采购类型, 1)) FROM @提交明细 s INNER JOIN dbo.仓储管理_入库单标签明细 d ON s.标签明细ID = d.入库单标签明细流水号 ORDER BY s.RowNum FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, ''), + @批号组 = STUFF((SELECT ',' + CONVERT(NVARCHAR(50), ISNULL(d.批号, 1)) FROM @提交明细 s INNER JOIN dbo.仓储管理_入库单标签明细 d ON s.标签明细ID = d.入库单标签明细流水号 ORDER BY s.RowNum FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, ''), + @批次编码组 = STUFF((SELECT ',' + ISNULL(d.批次编码, t.批次号) FROM @提交明细 s INNER JOIN dbo.仓储管理_入库单标签明细 d ON s.标签明细ID = d.入库单标签明细流水号 INNER JOIN dbo.仓储管理_入库单标签 t ON d.入库单标签流水号 = t.入库单标签流水号 ORDER BY s.RowNum FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '') + + BEGIN TRY + BEGIN TRAN + + EXEC dbo.仓储管理_采购件入库_循环执行 + @物料流水号组 = @物料流水号组, + @实际到货数量组 = @实际到货数量组, + @货位流水号组 = @货位流水号组, + @入库人员流水号 = @入库人, + @采购合同明细流水号组 = @采购合同明细流水号组, + @标准件和外购件流水号组 = @标准件和外购件流水号组, + @是否采购组 = @是否采购组, + @批号组 = @批号组, + @批次编码组 = @批次编码组 + + UPDATE d + SET 已入库数量 = CONVERT(DECIMAL(18,4), ISNULL(d.已入库数量, 0)) + s.入库数量, + 货位流水号 = s.货位流水号, + 货位名称 = h.货位名称, + 入库状态 = CASE WHEN CONVERT(DECIMAL(18,4), ISNULL(d.已入库数量, 0)) + s.入库数量 >= CONVERT(DECIMAL(18,4), ISNULL(d.数量, 0)) THEN 2 ELSE 1 END, + 入库人 = @入库人, + 入库时间 = GETDATE() + FROM dbo.仓储管理_入库单标签明细 d + INNER JOIN @提交明细 s ON d.入库单标签明细流水号 = s.标签明细ID + INNER JOIN dbo.库存管理_货位主文件 h ON s.货位流水号 = h.货位流水号 + + UPDATE t + SET 入库状态 = CASE + WHEN NOT EXISTS (SELECT 1 FROM dbo.仓储管理_入库单标签明细 d WHERE d.入库单标签流水号 = t.入库单标签流水号 AND CONVERT(DECIMAL(18,4), ISNULL(d.已入库数量, 0)) < CONVERT(DECIMAL(18,4), ISNULL(d.数量, 0))) THEN 2 + WHEN EXISTS (SELECT 1 FROM dbo.仓储管理_入库单标签明细 d WHERE d.入库单标签流水号 = t.入库单标签流水号 AND CONVERT(DECIMAL(18,4), ISNULL(d.已入库数量, 0)) > 0) THEN 1 + ELSE 0 + END, + 入库人 = @入库人, + 入库时间 = CASE + WHEN NOT EXISTS (SELECT 1 FROM dbo.仓储管理_入库单标签明细 d WHERE d.入库单标签流水号 = t.入库单标签流水号 AND CONVERT(DECIMAL(18,4), ISNULL(d.已入库数量, 0)) < CONVERT(DECIMAL(18,4), ISNULL(d.数量, 0))) THEN GETDATE() + ELSE t.入库时间 + END + FROM dbo.仓储管理_入库单标签 t + WHERE t.入库单标签流水号 = @实际标签ID + + COMMIT TRAN + + SELECT '1' AS result, N'入库成功' AS message, @实际标签ID AS 标签ID + END TRY + BEGIN CATCH + IF @@TRANCOUNT > 0 ROLLBACK TRAN + SELECT '0' AS result, ERROR_MESSAGE() AS message, @实际标签ID AS 标签ID + END CATCH +END +GO diff --git a/sql/PDA采购扫码入库页面菜单_测试库_20260908.sql b/sql/PDA采购扫码入库页面菜单_测试库_20260908.sql new file mode 100644 index 00000000..4d5f557d --- /dev/null +++ b/sql/PDA采购扫码入库页面菜单_测试库_20260908.sql @@ -0,0 +1,129 @@ +/* 修改人:Ld 修改时间:2026-09-08 10:04:25; 测试库新增PDA采购扫码入库页面菜单,并跟随物料入库权限授权 */ +SET XACT_ABORT ON; +BEGIN TRAN; + +DECLARE @ModuleId INT; + +SELECT @ModuleId = id +FROM dbo.基础表_模块信息 +WHERE [path] = N'WarehouseManagement/PDAPurchaseInbound' + OR component = N'/WarehouseManagement/PDAPurchaseInbound' + OR name = N'PDAPurchaseInbound' + OR title = N'PDA扫码入库'; + +IF @ModuleId IS NULL +BEGIN + INSERT INTO dbo.基础表_模块信息 + ( + [path], + component, + redirect, + name, + title, + icon, + 是否通知, + 消息通知来源, + 通知条件, + dashboardIcon, + 是否禁用 + ) + VALUES + ( + N'WarehouseManagement/PDAPurchaseInbound', + N'/WarehouseManagement/PDAPurchaseInbound', + NULL, + N'PDAPurchaseInbound', + N'PDA扫码入库', + N'PurchasePartsStorage', + NULL, + NULL, + NULL, + NULL, + 0 + ); + + SET @ModuleId = SCOPE_IDENTITY(); +END +ELSE +BEGIN + UPDATE dbo.基础表_模块信息 + SET [path] = N'WarehouseManagement/PDAPurchaseInbound', + component = N'/WarehouseManagement/PDAPurchaseInbound', + redirect = NULL, + name = N'PDAPurchaseInbound', + title = N'PDA扫码入库', + icon = N'PurchasePartsStorage', + 是否禁用 = 0 + WHERE id = @ModuleId; +END; + +;WITH RoleList AS +( + SELECT + r.角色编号, + r.pid, + r.角色模块顺序 AS 物料入库顺序 + FROM dbo.基础表_角色模块信息 r + WHERE r.id = 44 + AND ISNULL(r.是否启用, 1) = 1 +) +INSERT INTO dbo.基础表_角色模块信息 +( + id, + pid, + 模块顺序, + 角色编号, + 是否启用, + 角色模块顺序 +) +SELECT + @ModuleId, + RoleList.pid, + @ModuleId, + RoleList.角色编号, + 1, + ISNULL(RoleOrder.MaxOrder, RoleList.物料入库顺序) + 1 +FROM RoleList +OUTER APPLY +( + SELECT MAX(角色模块顺序) AS MaxOrder + FROM dbo.基础表_角色模块信息 + WHERE 角色编号 = RoleList.角色编号 + AND pid = RoleList.pid +) RoleOrder +WHERE NOT EXISTS +( + SELECT 1 + FROM dbo.基础表_角色模块信息 + WHERE id = @ModuleId + AND pid = RoleList.pid + AND 角色编号 = RoleList.角色编号 +); + +UPDATE r +SET 是否启用 = 1 +FROM dbo.基础表_角色模块信息 r +WHERE r.id = @ModuleId + AND EXISTS + ( + SELECT 1 + FROM dbo.基础表_角色模块信息 sourceRole + WHERE sourceRole.id = 44 + AND sourceRole.角色编号 = r.角色编号 + AND sourceRole.pid = r.pid + AND ISNULL(sourceRole.是否启用, 1) = 1 + ); + +SELECT @ModuleId AS PDA扫码入库模块ID; + +SELECT id, [path], component, name, title, icon, 是否禁用 +FROM dbo.基础表_模块信息 +WHERE id = @ModuleId; + +SELECT r.IDD, r.id, r.pid, r.角色编号, r.是否启用, r.角色模块顺序, m.title, m.component +FROM dbo.基础表_角色模块信息 r +INNER JOIN dbo.基础表_模块信息 m ON r.id = m.id +WHERE r.id = @ModuleId +ORDER BY r.角色编号, r.pid, r.角色模块顺序; + +COMMIT TRAN; diff --git a/sql/PDM_组件名称_确认更改新_BOM数量重算_20260812.sql b/sql/PDM_组件名称_确认更改新_BOM数量重算_20260812.sql new file mode 100644 index 00000000..582c2327 --- /dev/null +++ b/sql/PDM_组件名称_确认更改新_BOM数量重算_20260812.sql @@ -0,0 +1,80 @@ +USE [ERPTOOL_JY] +GO + +DECLARE @sql NVARCHAR(MAX) +DECLARE @new NVARCHAR(MAX) +DECLARE @start INT +DECLARE @afterStatus INT +DECLARE @finish INT +DECLARE @replaceLength INT + +SELECT @sql = OBJECT_DEFINITION(OBJECT_ID(N'dbo.PDM_组件名称_确认更改新')) + +IF @sql IS NULL +BEGIN + RAISERROR(N'未找到存储过程 PDM_组件名称_确认更改新', 16, 1) + RETURN +END + +SET @new = N' -- 修改人:Ld 修改时间:2026-08-12 13:16:31; 合同查询修改数量时按产品基础BOM重新计算订单BOM,避免在已乘组件数量的订单BOM上再次相乘。 + IF EXISTS ( + SELECT 1 + FROM PDM_零件明细表_基本件 b + INNER JOIN 产品信息_基本件_基础表 p ON p.产品流水号 = @产品流水号临时 AND p.物料流水号 = b.物料流水号 + WHERE b.组件流水号 = @orderN AND ISNULL(b.零件数量, 0) <> ISNULL(CONVERT(INT, p.零件数量 * @数量临时), 0) + ) + OR EXISTS ( + SELECT 1 + FROM PDM_零件明细表_标准件和外购件 w + INNER JOIN 产品信息_外购件_基础表 p ON p.产品流水号 = @产品流水号临时 AND p.物料流水号 = w.物料流水号 + WHERE w.组件流水号 = @orderN AND ISNULL(w.零件数量, 0) <> ISNULL(CONVERT(INT, p.零件数量 * @数量临时), 0) + ) + begin + update b + set b.零件数量 = CONVERT(INT, p.零件数量 * @数量临时), + b.零件类型 = p.零件类型, + b.材料流水号 = p.材料流水号, + b.导入人员编号 = p.导入人员编号 + from PDM_零件明细表_基本件 b + inner join 产品信息_基本件_基础表 p on p.产品流水号 = @产品流水号临时 and p.物料流水号 = b.物料流水号 + where b.组件流水号 = @orderN + + update w + set w.零件数量 = CONVERT(INT, p.零件数量 * @数量临时), + w.零件类型 = p.零件类型, + w.材料流水号 = p.材料流水号, + w.导入人员编号 = p.导入人员编号 + from PDM_零件明细表_标准件和外购件 w + inner join 产品信息_外购件_基础表 p on p.产品流水号 = @产品流水号临时 and p.物料流水号 = w.物料流水号 + where w.组件流水号 = @orderN + + -- 只有修改数量才将合同打回至 订单分配界面 重新分配 且有物料待分配 + update PDM_组件名称 SET 是否分配 = 0 where 组件流水号 = @orderN + update 合同管理_订单信息_基础表 set 是否下达 = 0,是否提交=1 where 项目流水号=@项目流水号 + end' + +SET @start = CHARINDEX(N'declare @零件数量改前 int', @sql) +SET @afterStatus = CHARINDEX(N'update 合同管理_订单信息_基础表 set 是否下达 = 0,是否提交=1 where 项目流水号=@项目流水号', @sql, @start) +SET @finish = CASE WHEN @afterStatus > 0 THEN CHARINDEX(N'end', @sql, @afterStatus) ELSE 0 END + +IF @start = 0 OR @afterStatus = 0 OR @finish = 0 +BEGIN + IF CHARINDEX(N'合同查询修改数量时按产品基础BOM重新计算订单BOM', @sql) > 0 + BEGIN + PRINT N'过程已包含本次BOM数量重算修复,无需重复修改' + RETURN + END + + RAISERROR(N'未找到预期的BOM数量缩放旧片段,未执行修改', 16, 1) + RETURN +END + +SET @replaceLength = @finish - @start + LEN(N'end') +SET @sql = STUFF(@sql, @start, @replaceLength, @new) +SET @sql = REPLACE(@sql, N'CREATE PROCEDURE [dbo].[PDM_组件名称_确认更改新]', N'ALTER PROCEDURE [dbo].[PDM_组件名称_确认更改新]') +SET @sql = REPLACE(@sql, N'CREATE PROCEDURE [dbo].[PDM_组件名称_确认更改新]', N'ALTER PROCEDURE [dbo].[PDM_组件名称_确认更改新]') +SET @sql = REPLACE(@sql, N'CREATE PROCEDURE [dbo].[PDM_组件名称_确认更改新]', N'ALTER PROCEDURE [dbo].[PDM_组件名称_确认更改新]') +SET @sql = REPLACE(@sql, N'CREATE PROCEDURE [dbo].[PDM_组件名称_确认更改新]', N'ALTER PROCEDURE [dbo].[PDM_组件名称_确认更改新]') + +EXEC sp_executesql @sql +GO diff --git a/sql/PDM_组件名称_确认更改新_ERPTOOL_JY_before_20260812.sql b/sql/PDM_组件名称_确认更改新_ERPTOOL_JY_before_20260812.sql new file mode 100644 index 00000000..ce05bd05 --- /dev/null +++ b/sql/PDM_组件名称_确认更改新_ERPTOOL_JY_before_20260812.sql @@ -0,0 +1,341 @@ +CREATE PROCEDURE [dbo].[PDM_×é¼þÃû³Æ_ȷÈϸü¸ÄÐÂ] +@ÏîĿÁ÷ˮºÅ int = '17412', +@»ú´²Á÷ˮºÅ int = '17448', +@ÐÄÈË int = '5', +@ºÏͬ±¸ע nvarchar(200)=null + AS +declare @ºÏͬÀàÐÍ int +declare @¶©µ¥Á÷ˮºÅ int +declare @×é¼þÁ÷ˮºÅ int +declare @²úƷÁ÷ˮºÅ int +declare @»ú´²Á÷ˮºÅÓαê int +declare @²úƷÃû³Æ nvarchar(200) = null +declare @ÊýÁ¿ float = null +declare @µ¥λ nvarchar(50) = null +declare @µ¥¼Û float = null +declare @²úƷÏêÇé nvarchar(500) = null +declare @²úƷλÖà nvarchar(50) = null +declare @ÊǷñ¿Éѡ int +declare @ÎïÁÏÁ÷ˮºÅ int +declare @ÊǷñ»¬̨ int +declare @ÊǷñ·ÖÅä int +declare @ÊǷñ½ÓÊÕ int +declare @˳Ðò int + +declare @×é¼þÁ÷ˮºÅÁÙʱ int +declare @²úƷÁ÷ˮºÅÁÙʱ int +declare @»ú´²Á÷ˮºÅÓαêÁÙʱ int +declare @²úƷÃû³ÆÁÙʱ nvarchar(200) = null +declare @ÊýÁ¿ÁÙʱ float = null +declare @ÅäÖÃÊýÁÙʱ float = null +declare @µ¥λÁÙʱ nvarchar(50) = null +declare @µ¥¼ÛÁÙʱ float = null +declare @²úƷÏêÇéÁÙʱ nvarchar(500) = null +declare @²úƷλÖÃÁÙʱ nvarchar(50) = null +declare @ÊǷñ¿ÉѡÁÙʱ int +declare @ÎïÁÏÁ÷ˮºÅÁÙʱ int +declare @ÊǷñ»¬̨ÁÙʱ int +declare @˳ÐòÁÙʱ int + +select @ºÏͬÀàÐÍ=ºÏͬÀàÐÍ from PDM_ÏîĿÃû³Æ where ÏîĿÁ÷ˮºÅ=@ÏîĿÁ÷ˮºÅ +select @¶©µ¥Á÷ˮºÅ=¶©µ¥Á÷ˮºÅ from ºÏͬ¹ÜÀí_¶©µ¥ÐÅϢ_»ù´¡±í where ÏîĿÁ÷ˮºÅ=@ÏîĿÁ÷ˮºÅ + +declare @¸ÄǰÊýÁ¿ int +select top 1 @×é¼þÁ÷ˮºÅ = ×é¼þÁ÷ˮºÅ from PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í where PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í.»ú´²Á÷ˮºÅ = @»ú´²Á÷ˮºÅ +select @¸ÄǰÊýÁ¿ = count(1) from PDM_×é¼þÃû³Æ where ×é¼þÁ÷ˮºÅ = @×é¼þÁ÷ˮºÅ + +declare @ÏîĿÐļǼÁ÷ˮºÅ int + +insert into PDM_ÏîĿÃû³Æ_ÐļǼ(ÏîĿÁ÷ˮºÅ,ÐÄÈË,ºÏͬ±¸ע)values(@ÏîĿÁ÷ˮºÅ,@ÐÄÈË,@ºÏͬ±¸ע) +set @ÏîĿÐļǼÁ÷ˮºÅ = @@IDENTITY + +if @ºÏͬÀàÐÍ = 2 +begin + insert into PDM_»ú´²Ãû³Æ_ÐļǼ(ÏîĿÐļǼÁ÷ˮºÅ,»ú´²Á÷ˮºÅ,»ú´²Ãû³Æ,ÊýÁ¿,µ¥λ,µ¥¼Û,ÏêÇé) + select @ÏîĿÐļǼÁ÷ˮºÅ,»ú´²Á÷ˮºÅ,»ú´²Ãû³Æ,ÊýÁ¿,µ¥λ,µ¥¼Û,ÏêÇé from PDM_»ú´²Ãû³Æ where ÏîĿÁ÷ˮºÅ=@ÏîĿÁ÷ˮºÅ + + update PDM_»ú´²Ãû³Æ set PDM_»ú´²Ãû³Æ.»ú´²Ãû³Æ=a.»ú´²Ãû³Æ,PDM_»ú´²Ãû³Æ.ÊýÁ¿=a.ÊýÁ¿,PDM_»ú´²Ãû³Æ.µ¥λ=a.µ¥λ, + PDM_»ú´²Ãû³Æ.µ¥¼Û=a.µ¥¼Û,PDM_»ú´²Ãû³Æ.ÏêÇé=a.ÏêÇé from PDM_»ú´²Ãû³Æ_ÐļǼ_ÁÙʱ±í as a where PDM_»ú´²Ãû³Æ.»ú´²Á÷ˮºÅ=a.»ú´²Á÷ˮºÅ + + declare @»ú´²Êý int + select @»ú´²Êý = ÊýÁ¿ from PDM_»ú´²Ãû³Æ_ÐļǼ_ÁÙʱ±í where »ú´²Á÷ˮºÅ = @»ú´²Á÷ˮºÅ + update PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í set ÊýÁ¿ = ÅäÖÃÊý * @»ú´²Êý where »ú´²Á÷ˮºÅ = @»ú´²Á÷ˮºÅ + + -- Ȼºóɾ³ý»ú´² + --DELETE FROM PDM_»ú´²Ãû³Æ + --WHERE ÏîĿÁ÷ˮºÅ = @ÏîĿÁ÷ˮºÅ + -- AND »ú´²Á÷ˮºÅ NOT IN (SELECT »ú´²Á÷ˮºÅ FROM PDM_»ú´²Ãû³Æ_ÐļǼ_ÁÙʱ±í WHERE ÏîĿÁ÷ˮºÅ = @ÏîĿÁ÷ˮºÅ) + + -- ÓÉÓڿ¼Âǵ½ר»úºÏͬɾ³ýÎÊÌâ ʵ¼Êɾ³ýÁÙʱ±í·ŵ½ºóÃæ + + -- ÐÄÈË:Ld ÐÄʱ¼ä:2026-07-23 ÔÊÐíºÏͬÐÄʱɾ³ýδÁìÁϻú´²£¬ÒÑÁìÁϻú´²±£Áô£¬±ÜÃâÎóɾÒÑÁìÁÏÊý¾Ý + IF EXISTS (SELECT 1 FROM PDM_»ú´²Ãû³Æ_ÐļǼ_ÁÙʱ±í WHERE ÏîĿÁ÷ˮºÅ = @ÏîĿÁ÷ˮºÅ) + BEGIN + DELETE r FROM ³µ¼äװÅä¹ÜÀí_װÅäÈÎÎñ r + INNER JOIN PDM_×é¼þÃû³Æ c ON c.×é¼þÁ÷ˮºÅ = r.×é¼þÁ÷ˮºÅ + INNER JOIN PDM_»ú´²Ãû³Æ m ON m.»ú´²Á÷ˮºÅ = c.»ú´²Á÷ˮºÅ + WHERE m.ÏîĿÁ÷ˮºÅ = @ÏîĿÁ÷ˮºÅ + AND NOT EXISTS (SELECT 1 FROM PDM_»ú´²Ãû³Æ_ÐļǼ_ÁÙʱ±í t WHERE t.ÏîĿÁ÷ˮºÅ = @ÏîĿÁ÷ˮºÅ AND t.»ú´²Á÷ˮºÅ = m.»ú´²Á÷ˮºÅ) + AND NOT EXISTS (SELECT 1 FROM PDM_×é¼þÃû³Æ c2 WHERE c2.»ú´²Á÷ˮºÅ = m.»ú´²Á÷ˮºÅ AND ISNULL(c2.ÊǷñÁìÁÏ, 0) <> 0) + + DELETE r FROM ³µ¼äװÅä¹ÜÀí_װÅäִÐÐ_ÁÙʱÁìÁÏÃ÷ϸ r + INNER JOIN PDM_×é¼þÃû³Æ c ON c.×é¼þÁ÷ˮºÅ = r.×é¼þÁ÷ˮºÅ + INNER JOIN PDM_»ú´²Ãû³Æ m ON m.»ú´²Á÷ˮºÅ = c.»ú´²Á÷ˮºÅ + WHERE m.ÏîĿÁ÷ˮºÅ = @ÏîĿÁ÷ˮºÅ + AND NOT EXISTS (SELECT 1 FROM PDM_»ú´²Ãû³Æ_ÐļǼ_ÁÙʱ±í t WHERE t.ÏîĿÁ÷ˮºÅ = @ÏîĿÁ÷ˮºÅ AND t.»ú´²Á÷ˮºÅ = m.»ú´²Á÷ˮºÅ) + AND NOT EXISTS (SELECT 1 FROM PDM_×é¼þÃû³Æ c2 WHERE c2.»ú´²Á÷ˮºÅ = m.»ú´²Á÷ˮºÅ AND ISNULL(c2.ÊǷñÁìÁÏ, 0) <> 0) + + DELETE r FROM ³µ¼äװÅä¹ÜÀí_ÁìÁϵ¥Ã÷ϸ r + INNER JOIN PDM_×é¼þÃû³Æ c ON c.×é¼þÁ÷ˮºÅ = r.×é¼þÁ÷ˮºÅ + INNER JOIN PDM_»ú´²Ãû³Æ m ON m.»ú´²Á÷ˮºÅ = c.»ú´²Á÷ˮºÅ + WHERE m.ÏîĿÁ÷ˮºÅ = @ÏîĿÁ÷ˮºÅ + AND NOT EXISTS (SELECT 1 FROM PDM_»ú´²Ãû³Æ_ÐļǼ_ÁÙʱ±í t WHERE t.ÏîĿÁ÷ˮºÅ = @ÏîĿÁ÷ˮºÅ AND t.»ú´²Á÷ˮºÅ = m.»ú´²Á÷ˮºÅ) + AND NOT EXISTS (SELECT 1 FROM PDM_×é¼þÃû³Æ c2 WHERE c2.»ú´²Á÷ˮºÅ = m.»ú´²Á÷ˮºÅ AND ISNULL(c2.ÊǷñÁìÁÏ, 0) <> 0) + + DELETE r FROM ³µ¼äװÅä¹ÜÀí_ÁìÁϵ¥ r + INNER JOIN PDM_×é¼þÃû³Æ c ON c.×é¼þÁ÷ˮºÅ = r.×é¼þÁ÷ˮºÅ + INNER JOIN PDM_»ú´²Ãû³Æ m ON m.»ú´²Á÷ˮºÅ = c.»ú´²Á÷ˮºÅ + WHERE m.ÏîĿÁ÷ˮºÅ = @ÏîĿÁ÷ˮºÅ + AND NOT EXISTS (SELECT 1 FROM PDM_»ú´²Ãû³Æ_ÐļǼ_ÁÙʱ±í t WHERE t.ÏîĿÁ÷ˮºÅ = @ÏîĿÁ÷ˮºÅ AND t.»ú´²Á÷ˮºÅ = m.»ú´²Á÷ˮºÅ) + AND NOT EXISTS (SELECT 1 FROM PDM_×é¼þÃû³Æ c2 WHERE c2.»ú´²Á÷ˮºÅ = m.»ú´²Á÷ˮºÅ AND ISNULL(c2.ÊǷñÁìÁÏ, 0) <> 0) + + DELETE r FROM PDM_Áã¼þÃ÷ϸ±í_»ù±¾¼þ r + INNER JOIN PDM_×é¼þÃû³Æ c ON c.×é¼þÁ÷ˮºÅ = r.×é¼þÁ÷ˮºÅ + INNER JOIN PDM_»ú´²Ãû³Æ m ON m.»ú´²Á÷ˮºÅ = c.»ú´²Á÷ˮºÅ + WHERE m.ÏîĿÁ÷ˮºÅ = @ÏîĿÁ÷ˮºÅ + AND NOT EXISTS (SELECT 1 FROM PDM_»ú´²Ãû³Æ_ÐļǼ_ÁÙʱ±í t WHERE t.ÏîĿÁ÷ˮºÅ = @ÏîĿÁ÷ˮºÅ AND t.»ú´²Á÷ˮºÅ = m.»ú´²Á÷ˮºÅ) + AND NOT EXISTS (SELECT 1 FROM PDM_×é¼þÃû³Æ c2 WHERE c2.»ú´²Á÷ˮºÅ = m.»ú´²Á÷ˮºÅ AND ISNULL(c2.ÊǷñÁìÁÏ, 0) <> 0) + + DELETE r FROM PDM_Áã¼þÃ÷ϸ±í_±ê¼þºÍͼþ r + INNER JOIN PDM_×é¼þÃû³Æ c ON c.×é¼þÁ÷ˮºÅ = r.×é¼þÁ÷ˮºÅ + INNER JOIN PDM_»ú´²Ãû³Æ m ON m.»ú´²Á÷ˮºÅ = c.»ú´²Á÷ˮºÅ + WHERE m.ÏîĿÁ÷ˮºÅ = @ÏîĿÁ÷ˮºÅ + AND NOT EXISTS (SELECT 1 FROM PDM_»ú´²Ãû³Æ_ÐļǼ_ÁÙʱ±í t WHERE t.ÏîĿÁ÷ˮºÅ = @ÏîĿÁ÷ˮºÅ AND t.»ú´²Á÷ˮºÅ = m.»ú´²Á÷ˮºÅ) + AND NOT EXISTS (SELECT 1 FROM PDM_×é¼þÃû³Æ c2 WHERE c2.»ú´²Á÷ˮºÅ = m.»ú´²Á÷ˮºÅ AND ISNULL(c2.ÊǷñÁìÁÏ, 0) <> 0) + + DELETE c FROM PDM_×é¼þÃû³Æ c + INNER JOIN PDM_»ú´²Ãû³Æ m ON m.»ú´²Á÷ˮºÅ = c.»ú´²Á÷ˮºÅ + WHERE m.ÏîĿÁ÷ˮºÅ = @ÏîĿÁ÷ˮºÅ + AND NOT EXISTS (SELECT 1 FROM PDM_»ú´²Ãû³Æ_ÐļǼ_ÁÙʱ±í t WHERE t.ÏîĿÁ÷ˮºÅ = @ÏîĿÁ÷ˮºÅ AND t.»ú´²Á÷ˮºÅ = m.»ú´²Á÷ˮºÅ) + AND NOT EXISTS (SELECT 1 FROM PDM_×é¼þÃû³Æ c2 WHERE c2.»ú´²Á÷ˮºÅ = m.»ú´²Á÷ˮºÅ AND ISNULL(c2.ÊǷñÁìÁÏ, 0) <> 0) + + DELETE m FROM PDM_»ú´²Ãû³Æ m + WHERE m.ÏîĿÁ÷ˮºÅ = @ÏîĿÁ÷ˮºÅ + AND NOT EXISTS (SELECT 1 FROM PDM_»ú´²Ãû³Æ_ÐļǼ_ÁÙʱ±í t WHERE t.ÏîĿÁ÷ˮºÅ = @ÏîĿÁ÷ˮºÅ AND t.»ú´²Á÷ˮºÅ = m.»ú´²Á÷ˮºÅ) + AND NOT EXISTS (SELECT 1 FROM PDM_×é¼þÃû³Æ c WHERE c.»ú´²Á÷ˮºÅ = m.»ú´²Á÷ˮºÅ AND ISNULL(c.ÊǷñÁìÁÏ, 0) <> 0) + END + +delete from PDM_»ú´²Ãû³Æ_ÐļǼ_ÁÙʱ±í where ÏîĿÁ÷ˮºÅ = @ÏîĿÁ÷ˮºÅ +end + +insert into PDM_×é¼þÃû³Æ_ÐļǼ(ÏîĿÐļǼÁ÷ˮºÅ,×é¼þÁ÷ˮºÅ,²úƷÁ÷ˮºÅ,»ú´²Á÷ˮºÅ,²úƷÃû³Æ,ÊýÁ¿,µ¥λ,µ¥¼Û,²úƷÏêÇé) +select @ÏîĿÐļǼÁ÷ˮºÅ,×é¼þÁ÷ˮºÅ,²úƷÁ÷ˮºÅ,»ú´²Á÷ˮºÅ,²úƷÃû³Æ,ÊýÁ¿,µ¥λ,µ¥¼Û,²úƷÏêÇé from PDM_×é¼þÃû³Æ where »ú´²Á÷ˮºÅ=@»ú´²Á÷ˮºÅ and ÊǷñºÏͬ´´½¨ = 1 and ÒÑɾ= 0 + + +declare @orderN int--ÁÙʱ±äÁ¿£¬ÓÃÀ´±£´æÓαêֵ +declare y_curr cursor for --ÉêÃ÷Óαê ΪorderNum +select ×é¼þÁ÷ˮºÅ from PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í where PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í.»ú´²Á÷ˮºÅ = @»ú´²Á÷ˮºÅ +open y_curr --´ò¿ªÓαê +fetch next from y_curr into @orderN ----¿ªʼѭ»·Óαê±äÁ¿ +while(@@fetch_status=0)---·µ»ر» FETCH Óï¾äִÐеÄ×îºóÓαêµÄ״̬£¬¶ø²»ÊÇÈκε±ǰ±»Á¬½ӴÄÓαêµÄ״̬¡£ +begin + select @²úƷÁ÷ˮºÅÁÙʱ=ISNULL([PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í].²úƷÁ÷ˮºÅ,0), + @»ú´²Á÷ˮºÅÓαêÁÙʱ =[PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í].»ú´²Á÷ˮºÅ, + @²úƷÃû³ÆÁÙʱ=[PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í].²úƷÃû³Æ, + @ÊýÁ¿ÁÙʱ=[PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í].ÊýÁ¿, + @ÅäÖÃÊýÁÙʱ=[PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í].ÅäÖÃÊý, + @µ¥λÁÙʱ=[PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í].µ¥λ, + @µ¥¼ÛÁÙʱ=[PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í].µ¥¼Û, + @²úƷÏêÇéÁÙʱ=[PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í].²úƷÏêÇé, + @²úƷλÖÃÁÙʱ=[PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í].²úƷλÖÃ, + @ÊǷñ¿ÉѡÁÙʱ=[PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í].ÊǷñ¿Éѡ, + @ÎïÁÏÁ÷ˮºÅÁÙʱ=ISNULL( [PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í].ÎïÁÏÁ÷ˮºÅ,0), + @ÊǷñ»¬̨ÁÙʱ=ISNULL( ²úƷÐÅϢ_»ù´¡±í.ÊǷñ»¬̨,0 ), + @˳ÐòÁÙʱ=[PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í].˳Ðò + from [dbo].[PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í] LEFT JOIN ²úƷÐÅϢ_»ù´¡±í + ON ²úƷÐÅϢ_»ù´¡±í.²úƷÁ÷ˮºÅ = [PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í].²úƷÁ÷ˮºÅ where ×é¼þÁ÷ˮºÅ = @orderN + + select @²úƷÁ÷ˮºÅ=ISNULL( PDM_×é¼þÃû³Æ.²úƷÁ÷ˮºÅ,0), + @»ú´²Á÷ˮºÅÓαê =PDM_×é¼þÃû³Æ.»ú´²Á÷ˮºÅ, + @²úƷÃû³Æ=PDM_×é¼þÃû³Æ.²úƷÃû³Æ, + @ÊýÁ¿=PDM_×é¼þÃû³Æ.ÊýÁ¿, + @ÊǷñ·ÖÅä=PDM_×é¼þÃû³Æ.ÊǷñ·ÖÅä, + @ÊǷñ½ÓÊÕ = ÊǷñ½ÓÊÕ, + --@µ¥λ=PDM_×é¼þÃû³Æ.µ¥λ, + --@²úƷÏêÇé=PDM_×é¼þÃû³Æ.²úƷÏêÇé, + --@²úƷλÖÃ=PDM_×é¼þÃû³Æ.²úƷλÖÃ, + --@ÊǷñ¿Éѡ=PDM_×é¼þÃû³Æ.ÊǷñ¿Éѡ, + @ÎïÁÏÁ÷ˮºÅ=ISNULL( PDM_×é¼þÃû³Æ.ÎïÁÏÁ÷ˮºÅ,0), + @ÊǷñ»¬̨=ISNULL( ²úƷÐÅϢ_»ù´¡±í.ÊǷñ»¬̨,0) + from [dbo].PDM_×é¼þÃû³Æ LEFT JOIN ²úƷÐÅϢ_»ù´¡±í + ON ²úƷÐÅϢ_»ù´¡±í.²úƷÁ÷ˮºÅ = PDM_×é¼þÃû³Æ.²úƷÁ÷ˮºÅ where ×é¼þÁ÷ˮºÅ = @orderN + + + if @²úƷÁ÷ˮºÅÁÙʱ <> @²úƷÁ÷ˮºÅ + begin + update dbo.PDM_×é¼þÃû³Æ set ÐÄ״̬ = 2,ÊǷñ·ÖÅä = 0 where ×é¼þÁ÷ˮºÅ = @orderN + delete from ³µ¼äװÅä¹ÜÀí_ÁìÁϵ¥Ã÷ϸ where ×é¼þÁ÷ˮºÅ = @orderN + delete from ³µ¼äװÅä¹ÜÀí_ÁìÁϵ¥ where ×é¼þÁ÷ˮºÅ = @orderN + delete from ³µ¼äװÅä¹ÜÀí_װÅäִÐÐ_ÁÙʱÁìÁÏÃ÷ϸ where ×é¼þÁ÷ˮºÅ=@orderN + delete from PDM_Áã¼þÃ÷ϸ±í_»ù±¾¼þ where ×é¼þÁ÷ˮºÅ = @orderN + delete from PDM_Áã¼þÃ÷ϸ±í_»ù±¾¼þ_Êý¾ݵ¼È뱣´æ where ¶©µ¥Á÷ˮºÅ = @¶©µ¥Á÷ˮºÅ and ²úƷÃû³Æ = @²úƷÃû³Æ + delete from PDM_Áã¼þÃ÷ϸ±í_±ê¼þºÍͼþ where ×é¼þÁ÷ˮºÅ = @orderN + delete from PDM_Áã¼þÃ÷ϸ±í_ͼþºͱê¼þ_Êý¾ݵ¼È뱣´æ where ¶©µ¥Á÷ˮºÅ = @¶©µ¥Á÷ˮºÅ and ²úƷÃû³Æ = @²úƷÃû³Æ + end + else + begin + -- ֻÓÐÊýÁ¿·¢Éú¸Ķ¯ ²ŻáÐÄ ÊǷñ·ÖÅä״̬ + --update dbo.PDM_×é¼þÃû³Æ set ÐÄ״̬ = 1,ÊǷñ·ÖÅä = 0 where ×é¼þÁ÷ˮºÅ = @orderN + update dbo.PDM_×é¼þÃû³Æ set ÐÄ״̬ = 1 where ×é¼þÁ÷ˮºÅ = @orderN + if @ÊýÁ¿ÁÙʱ <> @ÊýÁ¿ and @ÊǷñ·ÖÅä = 1 + begin + if @ÊýÁ¿ÁÙʱ <> @ÊýÁ¿ and @ÊǷñ·ÖÅä = 1 + begin + declare @Áã¼þÊýÁ¿¸Äǰ int + declare @Áã¼þÊýÁ¿¸ĺó int + SELECT @Áã¼þÊýÁ¿¸Äǰ = Áã¼þÊýÁ¿ FROM PDM_Áã¼þÃ÷ϸ±í_»ù±¾¼þ where ×é¼þÁ÷ˮºÅ = @orderN + SET @Áã¼þÊýÁ¿¸ĺó = @Áã¼þÊýÁ¿¸Äǰ/@ÊýÁ¿ * @ÊýÁ¿ÁÙʱ + IF(@Áã¼þÊýÁ¿¸Äǰ != @Áã¼þÊýÁ¿¸ĺó) + begin + update PDM_Áã¼þÃ÷ϸ±í_»ù±¾¼þ set Áã¼þÊýÁ¿ = Áã¼þÊýÁ¿/@ÊýÁ¿ * @ÊýÁ¿ÁÙʱ where ×é¼þÁ÷ˮºÅ = @orderN + update PDM_Áã¼þÃ÷ϸ±í_±ê¼þºÍͼþ set Áã¼þÊýÁ¿ = Áã¼þÊýÁ¿/@ÊýÁ¿ * @ÊýÁ¿ÁÙʱ where ×é¼þÁ÷ˮºÅ = @orderN + -- ֻÓÐÐÄÊýÁ¿²Ž«ºÏͬ´ò»ØÖÁ ¶©µ¥·ÖÅä½çÃæ ÖØÐ·ÖÅä ÇÒÓÐÎïÁϴý·ÖÅä + update PDM_×é¼þÃû³Æ SET ÊǷñ·ÖÅä = 0 where ×é¼þÁ÷ˮºÅ = @orderN + update ºÏͬ¹ÜÀí_¶©µ¥ÐÅϢ_»ù´¡±í set ÊǷñÏ´ï = 0,ÊǷñÌύ=1 where ÏîĿÁ÷ˮºÅ=@ÏîĿÁ÷ˮºÅ + end + end + end + end + + + + if ( + ((@ÊǷñ»¬̨ÁÙʱ = 2 or @ÊǷñ»¬̨ÁÙʱ =4) and @ÎïÁÏÁ÷ˮºÅÁÙʱ = 0 and @²úƷÁ÷ˮºÅÁÙʱ <> 0 and (@ÊǷñ»¬̨ = 2 or @ÊǷñ»¬̨ =4) and @ÎïÁÏÁ÷ˮºÅ = 0 and @²úƷÁ÷ˮºÅ <> 0) + OR ((@ÊǷñ»¬̨ÁÙʱ = 1 or @ÊǷñ»¬̨ÁÙʱ =3) and @ÎïÁÏÁ÷ˮºÅÁÙʱ = 0 and @²úƷÁ÷ˮºÅÁÙʱ <> 0 and (@ÊǷñ»¬̨ = 1 or @ÊǷñ»¬̨ =3) and @ÎïÁÏÁ÷ˮºÅ = 0 and @²úƷÁ÷ˮºÅ <> 0) + OR (@ÊǷñ»¬̨ÁÙʱ = 0 and @ÎïÁÏÁ÷ˮºÅÁÙʱ = 0 and @²úƷÁ÷ˮºÅÁÙʱ = 0 and @ÊǷñ»¬̨ = 0 and @ÎïÁÏÁ÷ˮºÅ = 0 and @²úƷÁ÷ˮºÅ = 0) + OR (@ÊǷñ»¬̨ÁÙʱ = 0 and @ÎïÁÏÁ÷ˮºÅÁÙʱ <> 0 and @²úƷÁ÷ˮºÅÁÙʱ = 0 and @ÊǷñ»¬̨ = 0 and @ÎïÁÏÁ÷ˮºÅ <> 0 and @²úƷÁ÷ˮºÅ = 0) + OR (@ÊǷñ»¬̨ÁÙʱ = 0 and @ÎïÁÏÁ÷ˮºÅÁÙʱ = 0 and @²úƷÁ÷ˮºÅÁÙʱ <> 0 and @ÊǷñ»¬̨ = 0 and @ÎïÁÏÁ÷ˮºÅ = 0 and @²úƷÁ÷ˮºÅ <> 0) + OR (@ÊǷñ»¬̨ÁÙʱ = 5 and @ÎïÁÏÁ÷ˮºÅÁÙʱ = 0 and @²úƷÁ÷ˮºÅÁÙʱ <> 0 and @ÊǷñ»¬̨ = 5 and @ÎïÁÏÁ÷ˮºÅ = 0 and @²úƷÁ÷ˮºÅ <> 0) + ) + begin + update PDM_×é¼þÃû³Æ set PDM_×é¼þÃû³Æ.²úƷÁ÷ˮºÅ=@²úƷÁ÷ˮºÅÁÙʱ, + PDM_×é¼þÃû³Æ.²úƷÃû³Æ=@²úƷÃû³ÆÁÙʱ, + PDM_×é¼þÃû³Æ.ÊýÁ¿=@ÊýÁ¿ÁÙʱ, + PDM_×é¼þÃû³Æ.ÅäÖÃÊý=@ÅäÖÃÊýÁÙʱ, + PDM_×é¼þÃû³Æ.µ¥λ=@µ¥λÁÙʱ, + PDM_×é¼þÃû³Æ.µ¥¼Û=@µ¥¼ÛÁÙʱ, + PDM_×é¼þÃû³Æ.²úƷÏêÇé=@²úƷÏêÇéÁÙʱ, + PDM_×é¼þÃû³Æ.²úƷλÖÃ=@²úƷλÖÃÁÙʱ, + PDM_×é¼þÃû³Æ.ÎïÁÏÁ÷ˮºÅ=@ÎïÁÏÁ÷ˮºÅÁÙʱ, + ˳Ðò = @˳ÐòÁÙʱ + where PDM_×é¼þÃû³Æ.×é¼þÁ÷ˮºÅ = @orderN + END + ELSE + begin + -- ÏÈÅжÏÊǷñ½ÓÊգ¬Èç¹û½ÓÊչýµľͲ»ÐÄËüµÄ״̬µ½δÏ´ï Èç¹ûû½ÓÊܹý Á㲿¼þÎïÁϱäΪ δ·ÖÅä״̬ ¶©µ¥ҲÐèҪͬ²½δ·ÖÅä + --if(@ÊǷñ½ÓÊÕ = 1) + --begin + --update PDM_×é¼þÃû³Æ set PDM_×é¼þÃû³Æ.²úƷÁ÷ˮºÅ=@²úƷÁ÷ˮºÅÁÙʱ, + -- PDM_×é¼þÃû³Æ.²úƷÃû³Æ=@²úƷÃû³ÆÁÙʱ, + -- PDM_×é¼þÃû³Æ.ÊýÁ¿=@ÊýÁ¿ÁÙʱ, + -- PDM_×é¼þÃû³Æ.ÅäÖÃÊý=@ÅäÖÃÊýÁÙʱ, + -- PDM_×é¼þÃû³Æ.µ¥λ=@µ¥λÁÙʱ, + -- PDM_×é¼þÃû³Æ.µ¥¼Û=@µ¥¼ÛÁÙʱ, + -- PDM_×é¼þÃû³Æ.²úƷÏêÇé=@²úƷÏêÇéÁÙʱ, + -- PDM_×é¼þÃû³Æ.²úƷλÖÃ=@²úƷλÖÃÁÙʱ, + -- PDM_×é¼þÃû³Æ.ÎïÁÏÁ÷ˮºÅ=@ÎïÁÏÁ÷ˮºÅÁÙʱ,[µç»úÁª½ӰåÎı¾]=NULL,[ÁªÖáÆ÷Îı¾]=NULL, + -- Öá³ÐλÖÃ=NULL,Öá³ÐλÖÃÎı¾=NULL,°²װ·½Ïò=NULL,µç»úλÖÃ=NULL,µç»úλÖÃÎı¾=NULL, + -- ´«¶¯·½ʽλÖÃ=NULL,´«¶¯·½ʽλÖÃÎı¾=NULL, + -- [»¬̨µç»úλÖÃ]=NULL, [»¬̨µç»úÎı¾]=NULL, Ö÷ÖáÂÖ=NULL,µç»úÂÖ=NULL,Ƥ´øÂÖ=NULL,ÆäËü=NULL,Êä³öתËÙ=NULL, + -- ÖÐÐÄÄÚÀä=NULL,·À»¤ÀàÐÍ=NULL,µç»úÁª½Ӱå=NULL,ÁªÖáÆ÷=NULL,×é¼þ²ɹº=0, + -- ×é¼þ²ֿâ=0,×é¼þ¶¯Á¦ͷ=0,×é¼þ»¬̨=0,×é¼þ¾«¹¤³µ¼ä=0,×é¼þר»ú=0,ÊǷñ·ÖÅä=0,ÊǷñ½ÓÊÕ=0,ÊǷñÁìÁÏ=0,װÅä½ø¶È=0,²úƷ״̬=0, ˳Ðò = @˳ÐòÁÙʱ + -- where PDM_×é¼þÃû³Æ.×é¼þÁ÷ˮºÅ = @orderN + --end + --else + --begin + update PDM_×é¼þÃû³Æ set PDM_×é¼þÃû³Æ.²úƷÁ÷ˮºÅ=@²úƷÁ÷ˮºÅÁÙʱ, + PDM_×é¼þÃû³Æ.²úƷÃû³Æ=@²úƷÃû³ÆÁÙʱ, + PDM_×é¼þÃû³Æ.ÊýÁ¿=@ÊýÁ¿ÁÙʱ, + PDM_×é¼þÃû³Æ.ÅäÖÃÊý=@ÅäÖÃÊýÁÙʱ, + PDM_×é¼þÃû³Æ.µ¥λ=@µ¥λÁÙʱ, + PDM_×é¼þÃû³Æ.µ¥¼Û=@µ¥¼ÛÁÙʱ, + PDM_×é¼þÃû³Æ.²úƷÏêÇé=@²úƷÏêÇéÁÙʱ, + PDM_×é¼þÃû³Æ.²úƷλÖÃ=@²úƷλÖÃÁÙʱ, + PDM_×é¼þÃû³Æ.ÎïÁÏÁ÷ˮºÅ=@ÎïÁÏÁ÷ˮºÅÁÙʱ,[µç»úÁª½ӰåÎı¾]=NULL,[ÁªÖáÆ÷Îı¾]=NULL, + Öá³ÐλÖÃ=NULL,Öá³ÐλÖÃÎı¾=NULL,°²װ·½Ïò=NULL,µç»úλÖÃ=NULL,µç»úλÖÃÎı¾=NULL, + ´«¶¯·½ʽλÖÃ=NULL,´«¶¯·½ʽλÖÃÎı¾=NULL, + [»¬̨µç»úλÖÃ]=NULL, [»¬̨µç»úÎı¾]=NULL, Ö÷ÖáÂÖ=NULL,µç»úÂÖ=NULL,Ƥ´øÂÖ=NULL,ÆäËü=NULL,Êä³öתËÙ=NULL, + ÖÐÐÄÄÚÀä=NULL,·À»¤ÀàÐÍ=NULL,µç»úÁª½Ӱå=NULL,ÁªÖáÆ÷=NULL,×é¼þ²ɹº=0, + ×é¼þ²ֿâ=0,×é¼þ¶¯Á¦ͷ=0,×é¼þ»¬̨=0,×é¼þ¾«¹¤³µ¼ä=0,×é¼þר»ú=0,ÊǷñ·ÖÅä=0,ÊǷñ½ÓÊÕ=0,ÊǷñÁìÁÏ=0,װÅä½ø¶È=0,²úƷ״̬=0, ˳Ðò = @˳ÐòÁÙʱ + where PDM_×é¼þÃû³Æ.×é¼þÁ÷ˮºÅ = @orderN + update ºÏͬ¹ÜÀí_¶©µ¥ÐÅϢ_»ù´¡±í set ÊǷñÏ´ï = 0,ÊǷñÌύ=1 where ÏîĿÁ÷ˮºÅ=@ÏîĿÁ÷ˮºÅ + --end + END + +--end +fetch next from y_curr into @orderN --¿ªʼѭ»·Óαê±äÁ¿ +end +close y_curr--¹رÕÓαê +deallocate y_curr --ÊͷÅÓαê + +--update PDM_×é¼þÃû³Æ set PDM_×é¼þÃû³Æ.²úƷÁ÷ˮºÅ=a.²úƷÁ÷ˮºÅ,PDM_×é¼þÃû³Æ.²úƷÃû³Æ=a.²úƷÃû³Æ,PDM_×é¼þÃû³Æ.ÊýÁ¿=a.ÊýÁ¿,PDM_×é¼þÃû³Æ.µ¥λ=a.µ¥λ, +--PDM_×é¼þÃû³Æ.µ¥¼Û=a.µ¥¼Û,PDM_×é¼þÃû³Æ.²úƷÏêÇé=a.²úƷÏêÇé,PDM_×é¼þÃû³Æ.ÎïÁÏÁ÷ˮºÅ=a.ÎïÁÏÁ÷ˮºÅ,Öá³ÐλÖÃ=NULL,Öá³ÐλÖÃÎı¾=NULL,°²װ·½Ïò=NULL,µç»úλÖÃ=NULL,µç»úλÖÃÎı¾=NULL,´«¶¯·½ʽλÖÃ=NULL,´«¶¯·½ʽλÖÃÎı¾=NULL, +--Ö÷ÖáÂÖ=NULL,µç»úÂÖ=NULL,Ƥ´øÂÖ=NULL,ÆäËü=NULL,Êä³öתËÙ=NULL,ÖÐÐÄÄÚÀä=NULL,·À»¤ÀàÐÍ=NULL,µç»úÁª½Ӱå=NULL,ÁªÖáÆ÷=NULL,×é¼þ²ɹº=0,×é¼þ²ֿâ=0,×é¼þ¶¯Á¦ͷ=0,×é¼þ»¬̨=0,×é¼þ¾«¹¤³µ¼ä=0, +--×é¼þר»ú=0,ÊǷñ·ÖÅä=0,ÊǷñ½ÓÊÕ=0,ÊǷñÁìÁÏ=0,װÅä½ø¶È=0,²úƷ״̬=0 from PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í as a +--where PDM_×é¼þÃû³Æ.×é¼þÁ÷ˮºÅ=a.×é¼þÁ÷ˮºÅ and PDM_×é¼þÃû³Æ.»ú´²Á÷ˮºÅ = @»ú´²Á÷ˮºÅ +delete from ³µ¼äװÅä¹ÜÀí_װÅäÈÎÎñ where ×é¼þÁ÷ˮºÅ in (select ×é¼þÁ÷ˮºÅ from PDM_×é¼þÃû³Æ where ×é¼þÁ÷ˮºÅ not in (select ×é¼þÁ÷ˮºÅ from PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í where »ú´²Á÷ˮºÅ=@»ú´²Á÷ˮºÅ and ×é¼þÁ÷ˮºÅ is not null) and »ú´²Á÷ˮºÅ=@»ú´²Á÷ˮºÅ and ÊǷñºÏͬ´´½¨ = 1 and ²úƷ״̬ = 0) +delete from ³µ¼äװÅä¹ÜÀí_װÅäִÐÐ_ÁÙʱÁìÁÏÃ÷ϸ where ×é¼þÁ÷ˮºÅ in (select ×é¼þÁ÷ˮºÅ from PDM_×é¼þÃû³Æ where ×é¼þÁ÷ˮºÅ not in (select ×é¼þÁ÷ˮºÅ from PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í where »ú´²Á÷ˮºÅ=@»ú´²Á÷ˮºÅ and ×é¼þÁ÷ˮºÅ is not null) and »ú´²Á÷ˮºÅ=@»ú´²Á÷ˮºÅ and ÊǷñºÏͬ´´½¨ = 1 and ²úƷ״̬ = 0) + +delete from ³µ¼äװÅä¹ÜÀí_ÁìÁϵ¥Ã÷ϸ where ×é¼þÁ÷ˮºÅ in (select ×é¼þÁ÷ˮºÅ from PDM_×é¼þÃû³Æ where ×é¼þÁ÷ˮºÅ not in (select ×é¼þÁ÷ˮºÅ from PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í where »ú´²Á÷ˮºÅ=@»ú´²Á÷ˮºÅ and ×é¼þÁ÷ˮºÅ is not null) and »ú´²Á÷ˮºÅ=@»ú´²Á÷ˮºÅ and ÊǷñºÏͬ´´½¨ = 1 and ²úƷ״̬ = 0) +delete from ³µ¼äװÅä¹ÜÀí_ÁìÁϵ¥ where ×é¼þÁ÷ˮºÅ in (select ×é¼þÁ÷ˮºÅ from PDM_×é¼þÃû³Æ where ×é¼þÁ÷ˮºÅ not in (select ×é¼þÁ÷ˮºÅ from PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í where »ú´²Á÷ˮºÅ=@»ú´²Á÷ˮºÅ and ×é¼þÁ÷ˮºÅ is not null) and »ú´²Á÷ˮºÅ=@»ú´²Á÷ˮºÅ and ÊǷñºÏͬ´´½¨ = 1 and ²úƷ״̬ = 0) +delete from PDM_Áã¼þÃ÷ϸ±í_»ù±¾¼þ where ×é¼þÁ÷ˮºÅ in (select ×é¼þÁ÷ˮºÅ from PDM_×é¼þÃû³Æ where ×é¼þÁ÷ˮºÅ not in (select ×é¼þÁ÷ˮºÅ from PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í where »ú´²Á÷ˮºÅ=@»ú´²Á÷ˮºÅ and ×é¼þÁ÷ˮºÅ is not null) and »ú´²Á÷ˮºÅ=@»ú´²Á÷ˮºÅ and ÊǷñºÏͬ´´½¨ = 1 and ²úƷ״̬ = 0) +delete from PDM_Áã¼þÃ÷ϸ±í_»ù±¾¼þ_Êý¾ݵ¼È뱣´æ where ¶©µ¥Á÷ˮºÅ = @¶©µ¥Á÷ˮºÅ and ²úƷÃû³Æ not in (select ²úƷÃû³Æ from PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í where »ú´²Á÷ˮºÅ=@»ú´²Á÷ˮºÅ and ×é¼þÁ÷ˮºÅ is not null) +delete from PDM_Áã¼þÃ÷ϸ±í_±ê¼þºÍͼþ where ×é¼þÁ÷ˮºÅ in (select ×é¼þÁ÷ˮºÅ from PDM_×é¼þÃû³Æ where ×é¼þÁ÷ˮºÅ not in (select ×é¼þÁ÷ˮºÅ from PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í where »ú´²Á÷ˮºÅ=@»ú´²Á÷ˮºÅ and ×é¼þÁ÷ˮºÅ is not null) and »ú´²Á÷ˮºÅ=@»ú´²Á÷ˮºÅ and ÊǷñºÏͬ´´½¨ = 1 and ²úƷ״̬ = 0) +delete from PDM_Áã¼þÃ÷ϸ±í_ͼþºͱê¼þ_Êý¾ݵ¼È뱣´æ where ¶©µ¥Á÷ˮºÅ = @¶©µ¥Á÷ˮºÅ and ²úƷÃû³Æ not in (select ²úƷÃû³Æ from PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í where »ú´²Á÷ˮºÅ=@»ú´²Á÷ˮºÅ and ×é¼þÁ÷ˮºÅ is not null) +delete from PDM_×é¼þÃû³Æ where ×é¼þÁ÷ˮºÅ not in (select ×é¼þÁ÷ˮºÅ from PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í where »ú´²Á÷ˮºÅ=@»ú´²Á÷ˮºÅ and ×é¼þÁ÷ˮºÅ is not null) and »ú´²Á÷ˮºÅ=@»ú´²Á÷ˮºÅ and ÊǷñºÏͬ´´½¨ = 1 and ²úƷ״̬ = 0 + +update PDM_×é¼þÃû³Æ set ÒÑɾ = 1 where ×é¼þÁ÷ˮºÅ not in (select ×é¼þÁ÷ˮºÅ from PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í where »ú´²Á÷ˮºÅ=@»ú´²Á÷ˮºÅ and ×é¼þÁ÷ˮºÅ is not null) and »ú´²Á÷ˮºÅ=@»ú´²Á÷ˮºÅ and ÊǷñºÏͬ´´½¨ = 1 and ²úƷ״̬ > 0 + +insert into PDM_×é¼þÃû³Æ(²úƷÁ÷ˮºÅ,»ú´²Á÷ˮºÅ,²úƷÃû³Æ,²úƷÏêÇé,µ¥λ,µ¥¼Û,ÊýÁ¿,ÊǷñºÏͬ´´½¨,²úƷλÖÃ,ÊǷñ¿Éѡ,ÎïÁÏÁ÷ˮºÅ,ÅäÖÃÊý,˳Ðò) +select ²úƷÁ÷ˮºÅ,»ú´²Á÷ˮºÅ,²úƷÃû³Æ,²úƷÏêÇé,µ¥λ,µ¥¼Û,ÊýÁ¿,1,²úƷλÖÃ,ÊǷñ¿Éѡ,ÎïÁÏÁ÷ˮºÅ,ÅäÖÃÊý,˳Ðò from PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í where »ú´²Á÷ˮºÅ=@»ú´²Á÷ˮºÅ and ×é¼þÁ÷ˮºÅ is null +-- Èç¹ûÓÐ insert into ¾ͽ«Õâ¸ö¶©µ¥¸ÄΪδÏ·¢ Ôö¼Óʱ½«¶©µ¥ÕûÌå´ò»ØδÏ·¢ +if(select count(1) from PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í where »ú´²Á÷ˮºÅ=@»ú´²Á÷ˮºÅ and ×é¼þÁ÷ˮºÅ is null) > 0 +begin + update ºÏͬ¹ÜÀí_¶©µ¥ÐÅϢ_»ù´¡±í set ÊǷñÏ´ï = 0,ÊǷñÌύ=1 where ÏîĿÁ÷ˮºÅ=@ÏîĿÁ÷ˮºÅ +end + + +-- ²»ÔÚ×îºóÅжϣ¬ÔÚǰÃæÈç¹ûÔÚÓαê±éÀúÖÐ ÊýÁ¿¸ıäÁ˲ÅÖØÖÃÊǷñÏ´ï +--declare @n int +--select @n=COUNT(*) from PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í where »ú´²Á÷ˮºÅ=@»ú´²Á÷ˮºÅ and ×é¼þÁ÷ˮºÅ is null +--if @n > 0 +--begin +-- update ºÏͬ¹ÜÀí_¶©µ¥ÐÅϢ_»ù´¡±í set ÊǷñÏ´ï = 0,ÊǷñÌύ=1 where ÏîĿÁ÷ˮºÅ=@ÏîĿÁ÷ˮºÅ +--end +declare @n int +select @n=COUNT(*) from PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í where ×é¼þÁ÷ˮºÅ = @×é¼þÁ÷ˮºÅ--»ú´²Á÷ˮºÅ=@»ú´²Á÷ˮºÅ --and ×é¼þÁ÷ˮºÅ is null +if @n > @¸ÄǰÊýÁ¿ -- ÐÂÔöÁËÎïÁÏ +begin + update ºÏͬ¹ÜÀí_¶©µ¥ÐÅϢ_»ù´¡±í set ÊǷñÏ´ï = 0,ÊǷñÌύ=1 where ÏîĿÁ÷ˮºÅ=@ÏîĿÁ÷ˮºÅ +end + + +declare @½ð¶î float +if @ºÏͬÀàÐÍ = 2 +begin +select @½ð¶î=SUM(ISNULL(µ¥¼Û,0)*ISNULL(ÊýÁ¿,0)) from PDM_»ú´²Ãû³Æ where ÏîĿÁ÷ˮºÅ = @ÏîĿÁ÷ˮºÅ + +update PDM_ÏîĿÃû³Æ set ºÏͬ½ð¶î = @½ð¶î,ºÏͬ±¸ע=@ºÏͬ±¸ע where ÏîĿÁ÷ˮºÅ=@ÏîĿÁ÷ˮºÅ +end +else +begin +select @½ð¶î=SUM(ISNULL(µ¥¼Û,0)*ISNULL(ÊýÁ¿,0)) from PDM_×é¼þÃû³Æ where »ú´²Á÷ˮºÅ = @»ú´²Á÷ˮºÅ and ÒÑɾ = 0 + +update PDM_ÏîĿÃû³Æ set ºÏͬ½ð¶î = @½ð¶î,ºÏͬ±¸ע=@ºÏͬ±¸ע where ÏîĿÁ÷ˮºÅ=@ÏîĿÁ÷ˮºÅ +end + + +delete from PDM_×é¼þÃû³Æ_ÐļǼ_ÁÙʱ±í where »ú´²Á÷ˮºÅ = @»ú´²Á÷ˮºÅ + + update ºÏͬ¹ÜÀí_¶©µ¥ÐÅϢ_»ù´¡±í set ȷÈÏÈÕÆÚ = NULL,ÊǷñȷÈÏ=0,¼¼ÊõÉóºË=1 where ÏîĿÁ÷ˮºÅ=@ÏîĿÁ÷ˮºÅ + diff --git a/sql/after_sales_contract_commission_type_prod_20260813.sql b/sql/after_sales_contract_commission_type_prod_20260813.sql new file mode 100644 index 00000000..129b1678 --- /dev/null +++ b/sql/after_sales_contract_commission_type_prod_20260813.sql @@ -0,0 +1,53 @@ +-- 售后合同提成类型保存支持(正式库) +-- 修改人:Ld 修改时间:2026-08-13 07:47:17; + +USE [ERPTOOL_JY] +GO + +IF OBJECT_ID(N'dbo.PDM_项目名称_售后合同_编辑数据', N'P') IS NOT NULL + DROP PROCEDURE [dbo].[PDM_项目名称_售后合同_编辑数据] +GO + +--CREATE 李显 +--2021-08-31 +-- 修改人:Ld 修改时间:2026-08-13 07:47:17; 增加售后合同提成类型参数并保存到项目主表 +CREATE PROCEDURE [dbo].[PDM_项目名称_售后合同_编辑数据] +@项目流水号 int, +@客户流水号 int=null, +@售后客户流水号 int=null, +@付款方式流水号 int=null, +@交货期限 nvarchar(50)=null, +@客户要求 nvarchar(200)=null, +@操作者 int=null, +@原项目流水号 int=null, +@收货人 nvarchar(50)=null, +@签订日期 nvarchar(50)=null, +@税率 float=null, +@售后原因 nvarchar(MAX)=null, +@解决方案 nvarchar(MAX)=null, +@合同备注 nvarchar(50)=null, +@提成类型 nvarchar(50)=null +AS +BEGIN + SET NOCOUNT ON; + + UPDATE PDM_项目名称 + SET 客户流水号=@客户流水号, + 付款方式流水号=@付款方式流水号, + 交货期限=@交货期限, + 操作者=@操作者, + 客户要求=@客户要求, + 合同备注=@合同备注, + 提成类型=@提成类型, + 签订日期=@签订日期, + 税率=@税率, + 收货人员=@收货人, + 售后原因=@售后原因, + 解决方案=@解决方案, + 原项目流水号=@原项目流水号, + 售后客户流水号=@售后客户流水号 + WHERE 项目流水号=@项目流水号; + + SELECT '1' AS result; +END +GO diff --git a/sql/after_sales_contract_commission_type_test_20260812.sql b/sql/after_sales_contract_commission_type_test_20260812.sql new file mode 100644 index 00000000..b1917240 --- /dev/null +++ b/sql/after_sales_contract_commission_type_test_20260812.sql @@ -0,0 +1,53 @@ +-- 售后合同提成类型保存支持 +-- 修改人:Ld 修改时间:2026-08-12 17:07:03; + +USE [ERPTOOL_JY_20250826Back] +GO + +IF OBJECT_ID(N'dbo.PDM_项目名称_售后合同_编辑数据', N'P') IS NOT NULL + DROP PROCEDURE [dbo].[PDM_项目名称_售后合同_编辑数据] +GO + +--CREATE 李显 +--2021-08-31 +-- 修改人:Ld 修改时间:2026-08-12 17:07:03; 增加售后合同提成类型参数并保存到项目主表 +CREATE PROCEDURE [dbo].[PDM_项目名称_售后合同_编辑数据] +@项目流水号 int, +@客户流水号 int=null, +@售后客户流水号 int=null, +@付款方式流水号 int=null, +@交货期限 nvarchar(50)=null, +@客户要求 nvarchar(200)=null, +@操作者 int=null, +@原项目流水号 int=null, +@收货人 nvarchar(50)=null, +@签订日期 nvarchar(50)=null, +@税率 float=null, +@售后原因 nvarchar(MAX)=null, +@解决方案 nvarchar(MAX)=null, +@合同备注 nvarchar(50)=null, +@提成类型 nvarchar(50)=null +AS +BEGIN + SET NOCOUNT ON; + + UPDATE PDM_项目名称 + SET 客户流水号=@客户流水号, + 付款方式流水号=@付款方式流水号, + 交货期限=@交货期限, + 操作者=@操作者, + 客户要求=@客户要求, + 合同备注=@合同备注, + 提成类型=@提成类型, + 签订日期=@签订日期, + 税率=@税率, + 收货人员=@收货人, + 售后原因=@售后原因, + 解决方案=@解决方案, + 原项目流水号=@原项目流水号, + 售后客户流水号=@售后客户流水号 + WHERE 项目流水号=@项目流水号; + + SELECT '1' AS result; +END +GO diff --git a/sql/replenishment_contract_link_test_20260803.sql b/sql/replenishment_contract_link_test_20260803.sql index eb060996..47509fe6 100644 --- a/sql/replenishment_contract_link_test_20260803.sql +++ b/sql/replenishment_contract_link_test_20260803.sql @@ -16,6 +16,7 @@ AS BEGIN SET NOCOUNT ON; + -- 修改人:Ld 修改时间:2026-08-11 10:09:42; 合同查询改为按合同去重,并将合同编号前缀匹配优先,避免BH开头合同被同合同多订单记录挤出列表。 SELECT TOP 50 p.项目流水号, p.合同编号, @@ -28,8 +29,23 @@ BEGIN FROM dbo.PDM_项目名称 AS p LEFT JOIN dbo.客户关系管理系统_客户名称 AS c ON p.客户流水号 = c.客户流水号 - LEFT JOIN dbo.合同管理_订单信息_基础表 AS o - ON p.项目流水号 = o.项目流水号 + OUTER APPLY ( + SELECT TOP 1 + oi.订单流水号, + oi.订单编号, + oi.完成期限 + FROM dbo.合同管理_订单信息_基础表 AS oi + WHERE oi.项目流水号 = p.项目流水号 + AND (ISNULL(@关键字, N'') = N'' + OR ISNULL(oi.订单编号, N'') LIKE N'%' + @关键字 + N'%' + OR p.合同编号 LIKE N'%' + @关键字 + N'%' + OR ISNULL(c.客户名称, N'') LIKE N'%' + @关键字 + N'%' + OR ISNULL(c.简称, N'') LIKE N'%' + @关键字 + N'%') + AND (ISNULL(@订单编号, N'') = N'' OR ISNULL(oi.订单编号, N'') LIKE N'%' + @订单编号 + N'%') + ORDER BY + CASE WHEN ISNULL(@关键字, N'') <> N'' AND ISNULL(oi.订单编号, N'') LIKE @关键字 + N'%' THEN 0 ELSE 1 END, + oi.订单流水号 DESC + ) AS o WHERE ISNULL(p.是否启用, 1) = 1 AND ISNULL(p.合同编号, N'') <> N'' AND (ISNULL(@关键字, N'') = N'' @@ -40,7 +56,10 @@ BEGIN AND (ISNULL(@合同编号, N'') = N'' OR p.合同编号 LIKE N'%' + @合同编号 + N'%') AND (ISNULL(@客户, N'') = N'' OR ISNULL(c.客户名称, N'') LIKE N'%' + @客户 + N'%' OR ISNULL(c.简称, N'') LIKE N'%' + @客户 + N'%') AND (ISNULL(@订单编号, N'') = N'' OR ISNULL(o.订单编号, N'') LIKE N'%' + @订单编号 + N'%') - ORDER BY p.项目流水号 DESC, o.订单流水号 DESC; + ORDER BY + CASE WHEN ISNULL(@关键字, N'') <> N'' AND p.合同编号 LIKE @关键字 + N'%' THEN 0 ELSE 1 END, + CASE WHEN ISNULL(@合同编号, N'') <> N'' AND p.合同编号 LIKE @合同编号 + N'%' THEN 0 ELSE 1 END, + p.项目流水号 DESC; END; GO @@ -71,6 +90,8 @@ BEGIN DECLARE @仓库备货合同编号 NVARCHAR(50); DECLARE @补货类型名称 NVARCHAR(50); DECLARE @订单类型 INT = 3; + DECLARE @补货锁资源 NVARCHAR(255); + DECLARE @补货锁结果 INT; IF @补货期限 IS NULL BEGIN @@ -108,6 +129,41 @@ BEGIN BEGIN TRY BEGIN TRANSACTION; + -- 修改人:Ld 修改时间:2026-08-11 09:42:28; 同一类补货提交加事务级应用锁,避免重复点击或并发请求消费同一份补货单生成多张订单。 + SET @补货锁资源 = N'报缺补货_提交_关联合同_' + CASE WHEN @是否外购 = 1 THEN N'外购' ELSE N'自制' END; + EXEC @补货锁结果 = sys.sp_getapplock + @Resource = @补货锁资源, + @LockMode = 'Exclusive', + @LockOwner = 'Transaction', + @LockTimeout = 10000; + + IF @补货锁结果 < 0 + BEGIN + SELECT '0' AS result, N'补货单正在提交,请稍后重试' AS message; + ROLLBACK TRANSACTION; + RETURN; + END; + + -- 修改人:Ld 修改时间:2026-08-11 09:42:28; 获得锁后重新检查中间表,第一笔提交删除后,后续重复请求不再继续创建订单。 + IF @是否外购 = 1 + BEGIN + IF NOT EXISTS (SELECT 1 FROM dbo.外购件补货明细中间表 WITH (UPDLOCK, HOLDLOCK)) + BEGIN + SELECT '0' AS result, N'外购补货单为空' AS message; + ROLLBACK TRANSACTION; + RETURN; + END; + END + ELSE + BEGIN + IF NOT EXISTS (SELECT 1 FROM dbo.自制件补货明细中间表 WITH (UPDLOCK, HOLDLOCK)) + BEGIN + SELECT '0' AS result, N'自制补货单为空' AS message; + ROLLBACK TRANSACTION; + RETURN; + END; + END; + IF @来源类型 = N'仓库备货' BEGIN -- 仓库备货每次创建独立CKBH合同,编号规则按补货单日期+三位序号生成;修改人:Ld 修改时间:2026-08-04 08:29:13; diff --git a/sql/修复_MK202607210883_BOM数量_按组件数量_20260817.sql b/sql/修复_MK202607210883_BOM数量_按组件数量_20260817.sql new file mode 100644 index 00000000..442e6f9b --- /dev/null +++ b/sql/修复_MK202607210883_BOM数量_按组件数量_20260817.sql @@ -0,0 +1,143 @@ +USE [ERPTOOL_JY] +GO + +BEGIN TRANSACTION + +BEGIN TRY + -- 修改人:Ld 修改时间:2026-08-17 08:35:19; 备份订单MK202607210883修复前BOM数量,恢复口径为新增保存数量乘当前组件数量。 + IF OBJECT_ID(N'dbo.GPT_BOM数量修复备份_20260817', N'U') IS NULL + BEGIN + CREATE TABLE dbo.GPT_BOM数量修复备份_20260817 + ( + 备份流水号 int IDENTITY(1,1) NOT NULL PRIMARY KEY, + 订单编号 nvarchar(50) NULL, + 组件流水号 int NULL, + 来源表 nvarchar(100) NULL, + 明细流水号 int NULL, + 物料流水号 int NULL, + 产品名称 nvarchar(200) NULL, + 零件名称 nvarchar(200) NULL, + 图号或型号 nvarchar(200) NULL, + 修复前数量 int NULL, + 新增保存数量 float NULL, + 组件数量 float NULL, + 应改数量 int NULL, + 已领数量 int NULL, + 备份时间 datetime NOT NULL DEFAULT(GETDATE()), + 修改人 nvarchar(50) NOT NULL DEFAULT(N'Ld'), + 备注 nvarchar(500) NULL + ) + END + + INSERT INTO dbo.GPT_BOM数量修复备份_20260817 + ( + 订单编号, 组件流水号, 来源表, 明细流水号, 物料流水号, + 产品名称, 零件名称, 图号或型号, 修复前数量, 新增保存数量, + 组件数量, 应改数量, 已领数量, 备注 + ) + SELECT + c.订单编号, + c.组件流水号, + N'PDM_零件明细表_基本件', + b.基本件流水号, + b.物料流水号, + c.产品名称, + m.名称, + m.代号, + b.零件数量, + s.数量, + c.数量, + CONVERT(int, s.数量 * c.数量), + b.已领数量, + N'按新增保存数量乘当前组件数量恢复订单BOM' + FROM dbo.PDM_零件明细表_基本件 b + INNER JOIN dbo.PDM_组件名称_视图 c ON c.组件流水号 = b.组件流水号 + INNER JOIN dbo.PDM_零件明细表_基本件_数据导入保存 s ON s.订单流水号 = c.订单流水号 AND s.产品名称 = c.产品名称 AND s.物料流水号 = b.物料流水号 + LEFT JOIN dbo.库存管理_物料主文件_基本 m ON m.物料流水号 = b.物料流水号 + WHERE c.订单编号 = N'MK202607210883' + AND c.组件流水号 IN (31253, 31254) + AND ISNULL(b.零件数量, 0) <> ISNULL(CONVERT(int, s.数量 * c.数量), 0) + AND NOT EXISTS + ( + SELECT 1 + FROM dbo.GPT_BOM数量修复备份_20260817 bak + WHERE bak.订单编号 = c.订单编号 + AND bak.来源表 = N'PDM_零件明细表_基本件' + AND bak.明细流水号 = b.基本件流水号 + AND bak.备注 = N'按新增保存数量乘当前组件数量恢复订单BOM' + ) + + INSERT INTO dbo.GPT_BOM数量修复备份_20260817 + ( + 订单编号, 组件流水号, 来源表, 明细流水号, 物料流水号, + 产品名称, 零件名称, 图号或型号, 修复前数量, 新增保存数量, + 组件数量, 应改数量, 已领数量, 备注 + ) + SELECT + c.订单编号, + c.组件流水号, + N'PDM_零件明细表_标准件和外购件', + w.标准件和外购件流水号, + w.物料流水号, + c.产品名称, + m.名称, + m.代号, + w.零件数量, + s.数量, + c.数量, + CONVERT(int, s.数量 * c.数量), + w.已领数量, + N'按新增保存数量乘当前组件数量恢复订单BOM' + FROM dbo.PDM_零件明细表_标准件和外购件 w + INNER JOIN dbo.PDM_组件名称_视图 c ON c.组件流水号 = w.组件流水号 + INNER JOIN dbo.PDM_零件明细表_外购件和标准件_数据导入保存 s ON s.订单流水号 = c.订单流水号 AND s.产品名称 = c.产品名称 AND s.物料流水号 = w.物料流水号 + LEFT JOIN dbo.库存管理_物料主文件_基本 m ON m.物料流水号 = w.物料流水号 + WHERE c.订单编号 = N'MK202607210883' + AND c.组件流水号 IN (31253, 31254) + AND ISNULL(w.零件数量, 0) <> ISNULL(CONVERT(int, s.数量 * c.数量), 0) + AND NOT EXISTS + ( + SELECT 1 + FROM dbo.GPT_BOM数量修复备份_20260817 bak + WHERE bak.订单编号 = c.订单编号 + AND bak.来源表 = N'PDM_零件明细表_标准件和外购件' + AND bak.明细流水号 = w.标准件和外购件流水号 + AND bak.备注 = N'按新增保存数量乘当前组件数量恢复订单BOM' + ) + + -- 修改人:Ld 修改时间:2026-08-17 08:35:19; 自制基本件按新增保存数量乘当前组件数量恢复。 + UPDATE b + SET b.零件数量 = CONVERT(int, s.数量 * c.数量), + b.修改人员 = 0, + b.修改时间 = GETDATE() + FROM dbo.PDM_零件明细表_基本件 b + INNER JOIN dbo.PDM_组件名称_视图 c ON c.组件流水号 = b.组件流水号 + INNER JOIN dbo.PDM_零件明细表_基本件_数据导入保存 s ON s.订单流水号 = c.订单流水号 AND s.产品名称 = c.产品名称 AND s.物料流水号 = b.物料流水号 + WHERE c.订单编号 = N'MK202607210883' + AND c.组件流水号 IN (31253, 31254) + AND ISNULL(b.零件数量, 0) <> ISNULL(CONVERT(int, s.数量 * c.数量), 0) + + -- 修改人:Ld 修改时间:2026-08-17 08:35:19; 标准件和外购件按新增保存数量乘当前组件数量恢复。 + UPDATE w + SET w.零件数量 = CONVERT(int, s.数量 * c.数量), + w.修改人员 = 0, + w.修改时间 = GETDATE() + FROM dbo.PDM_零件明细表_标准件和外购件 w + INNER JOIN dbo.PDM_组件名称_视图 c ON c.组件流水号 = w.组件流水号 + INNER JOIN dbo.PDM_零件明细表_外购件和标准件_数据导入保存 s ON s.订单流水号 = c.订单流水号 AND s.产品名称 = c.产品名称 AND s.物料流水号 = w.物料流水号 + WHERE c.订单编号 = N'MK202607210883' + AND c.组件流水号 IN (31253, 31254) + AND ISNULL(w.零件数量, 0) <> ISNULL(CONVERT(int, s.数量 * c.数量), 0) + + COMMIT TRANSACTION +END TRY +BEGIN CATCH + IF @@TRANCOUNT > 0 + BEGIN + ROLLBACK TRANSACTION + END + + DECLARE @ErrorMessage nvarchar(4000) = ERROR_MESSAGE() + RAISERROR(@ErrorMessage, 16, 1) +END CATCH +GO diff --git a/sql/修复_MK202608070966_BOM数量_20260812.sql b/sql/修复_MK202608070966_BOM数量_20260812.sql new file mode 100644 index 00000000..4028bce2 --- /dev/null +++ b/sql/修复_MK202608070966_BOM数量_20260812.sql @@ -0,0 +1,101 @@ +USE [ERPTOOL_JY] +GO + +BEGIN TRANSACTION + +BEGIN TRY + -- 修改人:Ld 修改时间:2026-08-12 13:27:21; 备份订单MK202608070966修复前BOM数量,便于回溯。 + IF OBJECT_ID(N'dbo.GPT_BOM数量修复备份_20260812', N'U') IS NULL + BEGIN + CREATE TABLE dbo.GPT_BOM数量修复备份_20260812 + ( + 备份流水号 int IDENTITY(1,1) NOT NULL PRIMARY KEY, + 订单编号 nvarchar(50) NULL, + 组件流水号 int NULL, + 来源表 nvarchar(100) NULL, + 明细流水号 int NULL, + 物料流水号 int NULL, + 产品流水号 int NULL, + 产品名称 nvarchar(200) NULL, + 零件名称 nvarchar(200) NULL, + 图号或型号 nvarchar(200) NULL, + 修复前数量 int NULL, + 应改数量 int NULL, + 组件数量 float NULL, + 产品基础BOM数量 float NULL, + 备份时间 datetime NOT NULL DEFAULT(GETDATE()), + 修改人 nvarchar(50) NOT NULL DEFAULT(N'Ld'), + 备注 nvarchar(500) NULL + ) + END + + INSERT INTO dbo.GPT_BOM数量修复备份_20260812 + ( + 订单编号, 组件流水号, 来源表, 明细流水号, 物料流水号, 产品流水号, + 产品名称, 零件名称, 图号或型号, 修复前数量, 应改数量, + 组件数量, 产品基础BOM数量, 备注 + ) + SELECT + c.订单编号, + c.组件流水号, + CASE WHEN v.类型 = N'自制' THEN N'PDM_零件明细表_基本件' ELSE N'PDM_零件明细表_标准件和外购件' END, + v.流水号, + v.物料流水号, + c.产品流水号, + c.产品名称, + v.零件名称, + v.图号或型号, + v.数量, + CONVERT(int, p.数量 * c.数量), + c.数量, + p.数量, + N'修复合同查询修改数量导致订单BOM重复乘组件数量' + FROM dbo.PDM_组件名称_视图 c + INNER JOIN dbo.PDM_零件明细表_所有视图 v ON v.组件流水号 = c.组件流水号 + INNER JOIN dbo.产品信息_零件视图 p ON p.产品流水号 = c.产品流水号 AND p.物料流水号 = v.物料流水号 + WHERE c.订单编号 = N'MK202608070966' + AND ISNULL(v.数量, 0) <> ISNULL(CONVERT(int, p.数量 * c.数量), 0) + AND NOT EXISTS + ( + SELECT 1 + FROM dbo.GPT_BOM数量修复备份_20260812 b + WHERE b.订单编号 = c.订单编号 + AND b.组件流水号 = c.组件流水号 + AND b.明细流水号 = v.流水号 + AND b.备注 = N'修复合同查询修改数量导致订单BOM重复乘组件数量' + ) + + -- 修改人:Ld 修改时间:2026-08-12 13:27:21; 自制基本件按产品基础BOM数量乘组件数量修回正常订单BOM总数量。 + UPDATE b + SET b.零件数量 = CONVERT(int, p.零件数量 * c.数量), + b.修改人员 = 0, + b.修改时间 = GETDATE() + FROM dbo.PDM_零件明细表_基本件 b + INNER JOIN dbo.PDM_组件名称_视图 c ON c.组件流水号 = b.组件流水号 + INNER JOIN dbo.产品信息_基本件_基础表 p ON p.产品流水号 = c.产品流水号 AND p.物料流水号 = b.物料流水号 + WHERE c.订单编号 = N'MK202608070966' + AND ISNULL(b.零件数量, 0) <> ISNULL(CONVERT(int, p.零件数量 * c.数量), 0) + + -- 修改人:Ld 修改时间:2026-08-12 13:27:21; 标准件和外购件按产品基础BOM数量乘组件数量修回正常订单BOM总数量。 + UPDATE w + SET w.零件数量 = CONVERT(int, p.零件数量 * c.数量), + w.修改人员 = 0, + w.修改时间 = GETDATE() + FROM dbo.PDM_零件明细表_标准件和外购件 w + INNER JOIN dbo.PDM_组件名称_视图 c ON c.组件流水号 = w.组件流水号 + INNER JOIN dbo.产品信息_外购件_基础表 p ON p.产品流水号 = c.产品流水号 AND p.物料流水号 = w.物料流水号 + WHERE c.订单编号 = N'MK202608070966' + AND ISNULL(w.零件数量, 0) <> ISNULL(CONVERT(int, p.零件数量 * c.数量), 0) + + COMMIT TRANSACTION +END TRY +BEGIN CATCH + IF @@TRANCOUNT > 0 + BEGIN + ROLLBACK TRANSACTION + END + + DECLARE @ErrorMessage nvarchar(4000) = ERROR_MESSAGE() + RAISERROR(@ErrorMessage, 16, 1) +END CATCH +GO diff --git a/sql/修正_三个毛坯物料超退库存_正式库_20260812.sql b/sql/修正_三个毛坯物料超退库存_正式库_20260812.sql new file mode 100644 index 00000000..4e04ff82 --- /dev/null +++ b/sql/修正_三个毛坯物料超退库存_正式库_20260812.sql @@ -0,0 +1,143 @@ +USE [ERPTOOL_JY]; +GO + +SET NOCOUNT ON; +SET XACT_ABORT ON; + +-- 修正三个毛坯物料因取消派工重复/超量退料导致的库存虚增;修改人:Ld 修改时间:2026-08-12 14:48:00; +DECLARE @修改时间 DATETIME = GETDATE(); + +IF OBJECT_ID(N'dbo.GPT_三个毛坯物料超退修正备份_20260812_出库记录', N'U') IS NULL +BEGIN + SELECT * + INTO dbo.GPT_三个毛坯物料超退修正备份_20260812_出库记录 + FROM dbo.库存管理_物料出库_出库记录 + WHERE 出库记录流水号 IN (181876, 150374, 191087); +END; + +IF OBJECT_ID(N'dbo.GPT_三个毛坯物料超退修正备份_20260812_退料入库记录', N'U') IS NULL +BEGIN + SELECT * + INTO dbo.GPT_三个毛坯物料超退修正备份_20260812_退料入库记录 + FROM dbo.库存管理_退料_入库记录 + WHERE 入库记录流水号 IN (3903, 3774, 3775, 3779, 3780, 3781); +END; + +IF OBJECT_ID(N'dbo.GPT_三个毛坯物料超退修正备份_20260812_库位库存', N'U') IS NULL +BEGIN + SELECT * + INTO dbo.GPT_三个毛坯物料超退修正备份_20260812_库位库存 + FROM dbo.库存管理_物料与货位对照表 + WHERE 物料与货位流水号 IN (79925, 73361, 89701); +END; + +IF OBJECT_ID(N'dbo.GPT_三个毛坯物料超退修正备份_20260812_累计库存', N'U') IS NULL +BEGIN + SELECT * + INTO dbo.GPT_三个毛坯物料超退修正备份_20260812_累计库存 + FROM dbo.库存管理_外购件累计库存 + WHERE 物料流水号 IN (12350, 3627, 2215); +END; + +BEGIN TRY + BEGIN TRANSACTION; + + -- 修改人:Ld 修改时间:2026-08-12 14:48:00; 前置校验,避免当前数据已变化时误修正。 + IF NOT EXISTS (SELECT 1 FROM dbo.库存管理_外购件累计库存 WHERE 物料流水号 = 12350 AND 累计库存 = 537) + RAISERROR(N'01.026.001.0007 当前累计库存不是 537,停止修正。', 16, 1); + IF NOT EXISTS (SELECT 1 FROM dbo.库存管理_外购件累计库存 WHERE 物料流水号 = 3627 AND 累计库存 = 660) + RAISERROR(N'01.026.001.0030 当前累计库存不是 660,停止修正。', 16, 1); + IF NOT EXISTS (SELECT 1 FROM dbo.库存管理_外购件累计库存 WHERE 物料流水号 = 2215 AND 累计库存 = 1072) + RAISERROR(N'01.026.001.0043 当前累计库存不是 1072,停止修正。', 16, 1); + + IF NOT EXISTS (SELECT 1 FROM dbo.库存管理_物料与货位对照表 WHERE 物料与货位流水号 = 79925 AND 货位存量 = 500) + RAISERROR(N'01.026.001.0007 异常库位行当前库存不是 500,停止修正。', 16, 1); + IF NOT EXISTS (SELECT 1 FROM dbo.库存管理_物料与货位对照表 WHERE 物料与货位流水号 = 73361 AND 货位存量 = 636) + RAISERROR(N'01.026.001.0030 异常库位行当前库存不是 636,停止修正。', 16, 1); + IF NOT EXISTS (SELECT 1 FROM dbo.库存管理_物料与货位对照表 WHERE 物料与货位流水号 = 89701 AND 货位存量 = 900) + RAISERROR(N'01.026.001.0043 异常库位行当前库存不是 900,停止修正。', 16, 1); + + IF NOT EXISTS (SELECT 1 FROM dbo.库存管理_物料出库_出库记录 WHERE 出库记录流水号 = 181876 AND 出库数量 = 6 AND 退料数量 = 500) + RAISERROR(N'出库记录 181876 当前数量不符合预期,停止修正。', 16, 1); + IF NOT EXISTS (SELECT 1 FROM dbo.库存管理_物料出库_出库记录 WHERE 出库记录流水号 = 150374 AND 出库数量 = 17 AND 退料数量 = 317) + RAISERROR(N'出库记录 150374 当前数量不符合预期,停止修正。', 16, 1); + IF NOT EXISTS (SELECT 1 FROM dbo.库存管理_物料出库_出库记录 WHERE 出库记录流水号 = 191087 AND 出库数量 = 156 AND 退料数量 = 300) + RAISERROR(N'出库记录 191087 当前数量不符合预期,停止修正。', 16, 1); + + IF NOT EXISTS (SELECT 1 FROM dbo.库存管理_退料_入库记录 WHERE 入库记录流水号 = 3903 AND 实际到货数量 = 500) + RAISERROR(N'退料入库记录 3903 当前数量不符合预期,停止修正。', 16, 1); + IF NOT EXISTS (SELECT 1 FROM dbo.库存管理_退料_入库记录 WHERE 入库记录流水号 = 3774 AND 实际到货数量 = 317) + RAISERROR(N'退料入库记录 3774 当前数量不符合预期,停止修正。', 16, 1); + IF NOT EXISTS (SELECT 1 FROM dbo.库存管理_退料_入库记录 WHERE 入库记录流水号 = 3775 AND 实际到货数量 = 317) + RAISERROR(N'退料入库记录 3775 当前数量不符合预期,停止修正。', 16, 1); + IF NOT EXISTS (SELECT 1 FROM dbo.库存管理_退料_入库记录 WHERE 入库记录流水号 = 3779 AND 实际到货数量 = 300) + RAISERROR(N'退料入库记录 3779 当前数量不符合预期,停止修正。', 16, 1); + IF NOT EXISTS (SELECT 1 FROM dbo.库存管理_退料_入库记录 WHERE 入库记录流水号 = 3780 AND 实际到货数量 = 300) + RAISERROR(N'退料入库记录 3780 当前数量不符合预期,停止修正。', 16, 1); + IF NOT EXISTS (SELECT 1 FROM dbo.库存管理_退料_入库记录 WHERE 入库记录流水号 = 3781 AND 实际到货数量 = 300) + RAISERROR(N'退料入库记录 3781 当前数量不符合预期,停止修正。', 16, 1); + + -- 修改人:Ld 修改时间:2026-08-12 14:48:00; 出库记录退料数量修正为该出库记录实际可退数量。 + UPDATE dbo.库存管理_物料出库_出库记录 SET 退料数量 = 6 WHERE 出库记录流水号 = 181876; + UPDATE dbo.库存管理_物料出库_出库记录 SET 退料数量 = 17 WHERE 出库记录流水号 = 150374; + UPDATE dbo.库存管理_物料出库_出库记录 SET 退料数量 = 156 WHERE 出库记录流水号 = 191087; + + -- 修改人:Ld 修改时间:2026-08-12 14:48:00; 保留历史退料记录流水号,将重复超退记录数量归零,最后一笔保留正常退料数量。 + UPDATE dbo.库存管理_退料_入库记录 SET 实际到货数量 = 6 WHERE 入库记录流水号 = 3903; + UPDATE dbo.库存管理_退料_入库记录 SET 实际到货数量 = 0 WHERE 入库记录流水号 = 3774; + UPDATE dbo.库存管理_退料_入库记录 SET 实际到货数量 = 17 WHERE 入库记录流水号 = 3775; + UPDATE dbo.库存管理_退料_入库记录 SET 实际到货数量 = 0 WHERE 入库记录流水号 = 3779; + UPDATE dbo.库存管理_退料_入库记录 SET 实际到货数量 = 0 WHERE 入库记录流水号 = 3780; + UPDATE dbo.库存管理_退料_入库记录 SET 实际到货数量 = 156 WHERE 入库记录流水号 = 3781; + + -- 修改人:Ld 修改时间:2026-08-12 14:48:00; 同步扣减异常虚增库存到毛坯库对应明细行。 + UPDATE dbo.库存管理_物料与货位对照表 SET 货位存量 = 6, 操作日期 = @修改时间 WHERE 物料与货位流水号 = 79925; + UPDATE dbo.库存管理_物料与货位对照表 SET 货位存量 = 19, 操作日期 = @修改时间 WHERE 物料与货位流水号 = 73361; + UPDATE dbo.库存管理_物料与货位对照表 SET 货位存量 = 156, 操作日期 = @修改时间 WHERE 物料与货位流水号 = 89701; + + -- 修改人:Ld 修改时间:2026-08-12 14:48:00; 累计库存按库位合计的正常库存同步修正。 + UPDATE dbo.库存管理_外购件累计库存 SET 累计库存 = 43 WHERE 物料流水号 = 12350; + UPDATE dbo.库存管理_外购件累计库存 SET 累计库存 = 43 WHERE 物料流水号 = 3627; + UPDATE dbo.库存管理_外购件累计库存 SET 累计库存 = 328 WHERE 物料流水号 = 2215; + + COMMIT TRANSACTION; +END TRY +BEGIN CATCH + IF @@TRANCOUNT > 0 + ROLLBACK TRANSACTION; + DECLARE @错误信息 NVARCHAR(4000) = ERROR_MESSAGE(); + RAISERROR(@错误信息, 16, 1); +END CATCH; + +SELECT N'修正后库存' AS 类型, + m.物料编码, + m.物料流水号, + k.累计库存 AS 累计库存, + SUM(d.货位存量) AS 货位库存合计 +FROM dbo.库存管理_物料主文件_基本 m +LEFT JOIN dbo.库存管理_外购件累计库存 k ON m.物料流水号 = k.物料流水号 +LEFT JOIN dbo.库存管理_物料与货位对照表 d ON m.物料流水号 = d.物料流水号 +WHERE m.物料流水号 IN (12350, 3627, 2215) +GROUP BY m.物料编码, m.物料流水号, k.累计库存 +ORDER BY m.物料编码; + +SELECT N'修正后出库记录' AS 类型, + 出库记录流水号, + 物料流水号, + 出库数量, + 退料数量, + 订单流水号, + 退料时间 +FROM dbo.库存管理_物料出库_出库记录 +WHERE 出库记录流水号 IN (181876, 150374, 191087) +ORDER BY 出库记录流水号; + +SELECT N'修正后退料入库记录' AS 类型, + 入库记录流水号, + 物料流水号, + 实际到货数量, + 入库时间, + 货位流水号 +FROM dbo.库存管理_退料_入库记录 +WHERE 入库记录流水号 IN (3903, 3774, 3775, 3779, 3780, 3781) +ORDER BY 入库记录流水号; diff --git a/sql/出库单展示页面菜单_测试库_20260825.sql b/sql/出库单展示页面菜单_测试库_20260825.sql new file mode 100644 index 00000000..9d90003c --- /dev/null +++ b/sql/出库单展示页面菜单_测试库_20260825.sql @@ -0,0 +1,115 @@ +/* 修改人:Ld 修改时间:2026-08-25 17:18:00; 测试库新增出库单展示页面菜单,并跟随已有出库记录权限授权 */ +SET XACT_ABORT ON; +BEGIN TRAN; + +DECLARE @ModuleId INT; + +SELECT @ModuleId = id +FROM dbo.基础表_模块信息 +WHERE [path] = N'WarehouseManagement/OutboundOrder' + OR component = N'/WarehouseManagement/OutboundOrder' + OR title = N'出库单'; + +IF @ModuleId IS NULL +BEGIN + INSERT INTO dbo.基础表_模块信息 + ( + [path], + component, + redirect, + name, + title, + icon, + 是否通知, + 消息通知来源, + 通知条件, + dashboardIcon, + 是否禁用 + ) + VALUES + ( + N'WarehouseManagement/OutboundOrder', + N'/WarehouseManagement/OutboundOrder', + NULL, + N'OutboundOrder', + N'出库单', + N'PurchaseOutRecord', + NULL, + NULL, + NULL, + NULL, + 0 + ); + + SET @ModuleId = SCOPE_IDENTITY(); +END +ELSE +BEGIN + UPDATE dbo.基础表_模块信息 + SET [path] = N'WarehouseManagement/OutboundOrder', + component = N'/WarehouseManagement/OutboundOrder', + redirect = NULL, + name = N'OutboundOrder', + title = N'出库单', + icon = N'PurchaseOutRecord', + 是否禁用 = 0 + WHERE id = @ModuleId; +END; + +;WITH RoleList AS +( + SELECT + r.角色编号, + r.pid, + MAX(r.角色模块顺序) AS 出库记录顺序 + FROM dbo.基础表_角色模块信息 r + WHERE r.id = 48 + AND ISNULL(r.是否启用, 1) = 1 + GROUP BY r.角色编号, r.pid +) +INSERT INTO dbo.基础表_角色模块信息 +( + id, + pid, + 模块顺序, + 角色编号, + 是否启用, + 角色模块顺序 +) +SELECT + @ModuleId, + RoleList.pid, + @ModuleId, + RoleList.角色编号, + 1, + ISNULL(RoleOrder.MaxOrder, RoleList.出库记录顺序) + 1 +FROM RoleList +OUTER APPLY +( + SELECT MAX(角色模块顺序) AS MaxOrder + FROM dbo.基础表_角色模块信息 + WHERE 角色编号 = RoleList.角色编号 + AND pid = RoleList.pid +) RoleOrder +WHERE NOT EXISTS +( + SELECT 1 + FROM dbo.基础表_角色模块信息 + WHERE id = @ModuleId + AND pid = RoleList.pid + AND 角色编号 = RoleList.角色编号 +); + +SELECT @ModuleId AS 出库单模块ID; + +SELECT id, [path], component, name, title, icon, 是否禁用 +FROM dbo.基础表_模块信息 +WHERE id = @ModuleId; + +SELECT r.IDD, r.id, r.pid, r.角色编号, r.是否启用, r.角色模块顺序, m.title, m.component +FROM dbo.基础表_角色模块信息 r +INNER JOIN dbo.基础表_模块信息 m ON r.id = m.id +WHERE r.id = @ModuleId +ORDER BY r.角色编号, r.pid, r.角色模块顺序; + +COMMIT TRAN; diff --git a/sql/机加工MES_加工完成整修审核_查询审核.sql b/sql/机加工MES_加工完成整修审核_查询审核.sql index 8465dae2..4911f489 100644 --- a/sql/机加工MES_加工完成整修审核_查询审核.sql +++ b/sql/机加工MES_加工完成整修审核_查询审核.sql @@ -232,7 +232,9 @@ ALTER PROCEDURE [dbo].[机加工MES_加工完成整修审核_审核数据] @审核整修开始时间 DATETIME = NULL, @审核整修结束时间 DATETIME = NULL, @审核整修方案 NVARCHAR(1000) = NULL, - @计价方式 NVARCHAR(20) = NULL + -- 修改人:Ld 修改时间:2026-08-20 13:20:11; 传入角色编号以支持系统管理员重审已审核记录 + @计价方式 NVARCHAR(20) = NULL, + @角色编号 INT = NULL AS BEGIN SET NOCOUNT ON; @@ -258,6 +260,8 @@ BEGIN DECLARE @单时工价 DECIMAL(18, 4); DECLARE @是否修改加工 BIT = 0; DECLARE @是否修改整修 BIT = 0; + -- 修改人:Ld 修改时间:2026-08-20 13:20:11; 系统管理员可对已审核记录再次提交修改 + DECLARE @是否管理员重审 BIT = CASE WHEN ISNULL(@角色编号, 0) = 2 THEN 1 ELSE 0 END; DECLARE @是否本过程开启事务 BIT; SET @目标审核状态 = CASE WHEN @审核状态 IN (N'审核通过', N'已审核') THEN N'已审核' ELSE @审核状态 END; @@ -272,7 +276,8 @@ BEGIN SELECT 1 FROM [dbo].[MES_机加工MES_加工完成整修审核表] WHERE id = @审核流水号 - AND 审核状态 = N'待审核' + -- 修改人:Ld 修改时间:2026-08-20 13:20:11; 管理员重审时允许命中已审核记录 + AND (审核状态 = N'待审核' OR (@是否管理员重审 = 1 AND 审核状态 = N'已审核')) ) BEGIN SELECT N'0' AS result, N'该审核记录不存在或已审核' AS message; @@ -292,7 +297,8 @@ BEGIN @单时工价 = ISNULL(单时工价, 0) FROM [dbo].[MES_机加工MES_加工完成整修审核表] WHERE id = @审核流水号 - AND 审核状态 = N'待审核'; + -- 修改人:Ld 修改时间:2026-08-20 13:20:11; 管理员重审时允许读取已审核记录 + AND (审核状态 = N'待审核' OR (@是否管理员重审 = 1 AND 审核状态 = N'已审核')); IF @Safe计价方式 NOT IN (N'计件', N'计时') SET @Safe计价方式 = N'计件'; @@ -451,7 +457,8 @@ BEGIN [修改人] = N'Ld', [修改时间] = GETDATE() WHERE [id] = @审核流水号 - AND [审核状态] = N'待审核'; + -- 修改人:Ld 修改时间:2026-08-20 13:20:11; 管理员重审时允许更新已审核记录 + AND ([审核状态] = N'待审核' OR (@是否管理员重审 = 1 AND [审核状态] = N'已审核')); IF @是否本过程开启事务 = 1 COMMIT TRAN; diff --git a/sql/物料管理_增加_批量_物料类型按编码前缀_20260903.sql b/sql/物料管理_增加_批量_物料类型按编码前缀_20260903.sql new file mode 100644 index 00000000..41c64203 --- /dev/null +++ b/sql/物料管理_增加_批量_物料类型按编码前缀_20260903.sql @@ -0,0 +1,314 @@ +/* +用途:修改 dbo.物料管理_增加_批量,根据物料编码前两位写入物料类型,并修正现有物料类型。 +规则:01毛坯,02自制,03采购,04原材料,05耗材,06设备,07质检,08半成品,09模具,10成品。 +备份:执行前备份原存储过程定义、物料类型基础表、物料主文件全表快照。 +修改人:Ld 修改时间:2026-09-03 13:47:51; +*/ + +SET NOCOUNT ON; +SET XACT_ABORT ON; + +BEGIN TRY + BEGIN TRAN; + + IF OBJECT_ID(N'dbo.GPT备份_物料管理_增加_批量_过程_20260903_134751', N'U') IS NULL + BEGIN + SELECT + DB_NAME() AS 数据库名, + SCHEMA_NAME(o.schema_id) AS 架构名, + o.name AS 过程名, + m.definition AS 过程定义, + GETDATE() AS 备份时间, + N'修改人:Ld 修改时间:2026-09-03 13:47:51; 物料管理_增加_批量修改前过程定义备份' AS 备份说明 + INTO dbo.GPT备份_物料管理_增加_批量_过程_20260903_134751 + FROM sys.objects o + INNER JOIN sys.sql_modules m ON o.object_id = m.object_id + WHERE o.type = 'P' + AND o.object_id = OBJECT_ID(N'dbo.物料管理_增加_批量'); + END + + IF OBJECT_ID(N'dbo.GPT备份_物料类型_基础表_20260903_134751', N'U') IS NULL + BEGIN + SELECT + *, + GETDATE() AS 备份时间, + N'修改人:Ld 修改时间:2026-09-03 13:47:51; 物料类型基础表修改前备份' AS 备份说明 + INTO dbo.GPT备份_物料类型_基础表_20260903_134751 + FROM dbo.物料类型_基础表; + END + + IF OBJECT_ID(N'dbo.GPT备份_库存管理_物料主文件_基本_20260903_134751', N'U') IS NULL + BEGIN + SELECT + *, + GETDATE() AS 备份时间, + N'修改人:Ld 修改时间:2026-09-03 13:47:51; 按物料编码前两位修正类型前全表备份' AS 备份说明 + INTO dbo.GPT备份_库存管理_物料主文件_基本_20260903_134751 + FROM dbo.库存管理_物料主文件_基本; + END + + UPDATE t + SET t.类型 = v.类型 + FROM dbo.物料类型_基础表 t + INNER JOIN (VALUES + (1, N'毛坯'), + (2, N'自制'), + (3, N'采购'), + (4, N'原材料'), + (5, N'耗材'), + (6, N'设备'), + (7, N'质检'), + (8, N'半成品'), + (9, N'模具'), + (10, N'成品') + ) v(类型流水号, 类型) ON t.类型流水号 = v.类型流水号; -- 修改人:Ld 修改时间:2026-09-03 13:47:51; 同步编码前缀对应的物料类型名称。 + + INSERT INTO dbo.物料类型_基础表(类型流水号, 类型) + SELECT v.类型流水号, v.类型 + FROM (VALUES + (1, N'毛坯'), + (2, N'自制'), + (3, N'采购'), + (4, N'原材料'), + (5, N'耗材'), + (6, N'设备'), + (7, N'质检'), + (8, N'半成品'), + (9, N'模具'), + (10, N'成品') + ) v(类型流水号, 类型) + WHERE NOT EXISTS ( + SELECT 1 + FROM dbo.物料类型_基础表 t + WHERE t.类型流水号 = v.类型流水号 + ); -- 修改人:Ld 修改时间:2026-09-03 13:47:51; 补齐编码前缀对应的物料类型字典。 + + UPDATE m + SET m.类型 = r.规则类型, + m.修改日期 = GETDATE() + FROM dbo.库存管理_物料主文件_基本 m + CROSS APPLY ( + SELECT CASE LEFT(LTRIM(RTRIM(ISNULL(m.物料编码, N''))), 2) + WHEN N'01' THEN 1 + WHEN N'02' THEN 2 + WHEN N'03' THEN 3 + WHEN N'04' THEN 4 + WHEN N'05' THEN 5 + WHEN N'06' THEN 6 + WHEN N'07' THEN 7 + WHEN N'08' THEN 8 + WHEN N'09' THEN 9 + WHEN N'10' THEN 10 + END AS 规则类型 + ) r + WHERE r.规则类型 IS NOT NULL + AND ISNULL(m.类型, -1) <> r.规则类型; -- 修改人:Ld 修改时间:2026-09-03 13:47:51; 按物料编码前两位回写现有物料类型。 + + COMMIT TRAN; +END TRY +BEGIN CATCH + IF @@TRANCOUNT > 0 + ROLLBACK TRAN; + DECLARE @错误消息 nvarchar(4000); + DECLARE @错误严重级别 int; + DECLARE @错误状态 int; + SELECT + @错误消息 = ERROR_MESSAGE(), + @错误严重级别 = ERROR_SEVERITY(), + @错误状态 = ERROR_STATE(); + RAISERROR(@错误消息, @错误严重级别, @错误状态); -- 修改人:Ld 修改时间:2026-09-03 13:47:51; 兼容当前 SQL Server 版本的异常抛出方式。 +END CATCH; +GO + +ALTER PROCEDURE [dbo].[物料管理_增加_批量] +@材料 nvarchar(50)=null, +@货位 nvarchar(50)=null, +@单位 nvarchar(50)=null, +@类型 nvarchar(50)=null, +@物料名称 nvarchar(50)=null, +@图号 nvarchar(50)=null, +@物料说明 nvarchar(MAX)=null, +@物料库 nvarchar(50) =null, +@人员编号 int = null, +@曾用物料编码 nvarchar(50) = null, +@物料编码 nvarchar(50) = null, +@规格 nvarchar(50) = null, +@创建时间 DATETIME = NULL + + AS + +DECLARE @物料流水号 INT +DECLARE @材料流水号 INT +DECLARE @货位流水号 INT +DECLARE @单位流水号 INT +DECLARE @类型流水号 INT +DECLARE @物料库流水号 INT +DECLARE @物料编码前缀 nvarchar(2) -- 修改人:Ld 修改时间:2026-09-03 13:47:51; 用物料编码前两位判断物料类型。 +--DECLARE @物料编码1 nvarchar(50) = null +--DECLARE @物料编码2 nvarchar(50) = null + +SET @物料编码前缀 = LEFT(LTRIM(RTRIM(ISNULL(@物料编码, N''))), 2) -- 修改人:Ld 修改时间:2026-09-03 13:47:51; 统一取物料编码前缀。 +SET @类型流水号 = CASE @物料编码前缀 -- 修改人:Ld 修改时间:2026-09-03 13:47:51; 01毛坯、02自制、03采购、04原材料、05耗材、06设备、07质检、08半成品、09模具、10成品。 + WHEN N'01' THEN 1 + WHEN N'02' THEN 2 + WHEN N'03' THEN 3 + WHEN N'04' THEN 4 + WHEN N'05' THEN 5 + WHEN N'06' THEN 6 + WHEN N'07' THEN 7 + WHEN N'08' THEN 8 + WHEN N'09' THEN 9 + WHEN N'10' THEN 10 +END + +IF @类型流水号 IS NULL +BEGIN + IF @类型 = N'自制' + BEGIN + SET @类型流水号 = 2 + END + ELSE + BEGIN + SET @类型流水号 = 1 + END +END + + IF @曾用物料编码 IS NOT NULL AND @曾用物料编码 <> '' + BEGIN + -- 检查是否存在物料编码 = @曾用物料编码 的记录 + IF EXISTS (SELECT 1 FROM 库存管理_物料主文件_基本 WHERE 物料编码 = @曾用物料编码) + BEGIN + -- 更新该记录的物料编码为新编码,同时记录曾用物料编码(可选,也可以将旧编码存入曾用物料编码列) + UPDATE 库存管理_物料主文件_基本 + SET 物料编码 = @物料编码, + 类型 = @类型流水号, -- 修改人:Ld 修改时间:2026-09-03 13:47:51; 编码变更时同步按新编码前两位更新物料类型。 + 曾用物料编码 = @曾用物料编码, -- 将旧编码存入曾用物料编码字段,便于追溯 + 修改人 = @人员编号, + 修改日期 = GETDATE() + WHERE 物料编码 = @曾用物料编码; + + -- 注意:如果同一个物料编码出现在多个表中(如库存表),可能需要同步更新,此处仅更新主文件 + -- 如果有需要,也可以更新 库存管理_物料与货位对照表 或 库存管理_外购件累计库存 中的关联字段(通常不需要,因为流水号不变) + + PRINT '物料编码更新成功:' + @曾用物料编码 + ' -> ' + @物料编码; + RETURN; -- 更新完成后直接退出,不再执行后面的新增逻辑 + END + ELSE + BEGIN + -- 如果曾用物料编码不存在,可以报错或者继续执行新增逻辑,这里选择报错 + RAISERROR('曾用物料编码 %s 在系统中不存在,无法更新。', 16, 1, @曾用物料编码); + RETURN; + END + END + +--获得材料流水号 +select @材料流水号 = 材料流水号 from dbo.PDM_零件明细表_材料 +where 材料=@材料 + +if @材料流水号 is null +begin +insert into PDM_零件明细表_材料(材料,操作日期) values (@材料,getdate()) +set @材料流水号=IDENT_CURRENT('PDM_零件明细表_材料') +end + +--获得货位流水号 +select @货位流水号 = 货位流水号 from dbo.库存管理_货位主文件 +where 货位名称=@货位 + +if @货位流水号 is null +begin +set @货位流水号 = 2514 +end + +--获得单位流水号 +select @单位流水号 = 单位流水号 from dbo.单位名称_基础表 +where 单位=@单位 + +if @单位流水号 is null +begin +set @单位流水号 = 1 +end + +--获得物料库流水号 +if @物料库 = '通用' +begin +set @物料库流水号 = 1 +end +else +begin +set @物料库流水号 = 2 +end + +IF EXISTS (SELECT 1 FROM 库存管理_物料主文件_基本 WHERE 物料编码 = @物料编码) +BEGIN + -- 存在则更新(覆盖) + UPDATE 库存管理_物料主文件_基本 + SET 名称 = @物料名称, + 代号 = @图号, + 单位流水号 = @单位流水号, + 材料流水号 = @材料流水号, + 类型 = @类型流水号, + 货位流水号 = @货位流水号, + 物料库流水号 = @物料库流水号, + 修改人 = @人员编号, + 修改日期 = GETDATE(), + 物料说明 = @物料说明, + 规格 = @规格, + 曾用物料编码 = ISNULL(曾用物料编码, @曾用物料编码) -- 保留原有曾用编码,如果没有则设置 + WHERE 物料编码 = @物料编码; + + -- 获取流水号用于更新关联表 + SELECT @物料流水号 = 物料流水号 FROM 库存管理_物料主文件_基本 WHERE 物料编码 = @物料编码; + + PRINT '物料编码 ' + @物料编码 + ' 已存在,已执行覆盖更新。'; +END +ELSE +BEGIN + --select @物料编码2 = 'LJ'+ right(cast(power(10,8) as varchar) + (SUBSTRING((select 物料编码 from 库存管理_物料主文件_基本 WHERE 物料流水号 = (select Max(物料流水号) from 库存管理_物料主文件_基本)),3,8) + 1),8) + insert into 库存管理_物料主文件_基本(名称,代号,单位流水号,材料流水号,类型,物料编码,货位流水号,物料库流水号,修改人,修改日期,物料说明,曾用物料编码,规格,创建人) + values(@物料名称,@图号,@单位流水号,@材料流水号,@类型流水号,@物料编码,@货位流水号,@物料库流水号,@人员编号,GETDATE(),@物料说明,@曾用物料编码,@规格,@人员编号) + set @物料流水号 = IDENT_CURRENT(N'库存管理_物料主文件_基本') + insert into 库存管理_物料与货位对照表(物料流水号,货位存量,货位流水号)values(@物料流水号,0,@货位流水号) + insert into 库存管理_外购件累计库存(物料流水号,累计库存)values(@物料流水号,0) +END +GO + +SET NOCOUNT ON; + +SELECT N'物料类型字典' AS 检查项, 类型流水号, 类型 +FROM dbo.物料类型_基础表 +WHERE 类型流水号 BETWEEN 1 AND 10 +ORDER BY 类型流水号; + +WITH R AS ( + SELECT + LEFT(LTRIM(RTRIM(ISNULL(物料编码, N''))), 2) AS 前两位, + 类型, + CASE LEFT(LTRIM(RTRIM(ISNULL(物料编码, N''))), 2) + WHEN N'01' THEN 1 + WHEN N'02' THEN 2 + WHEN N'03' THEN 3 + WHEN N'04' THEN 4 + WHEN N'05' THEN 5 + WHEN N'06' THEN 6 + WHEN N'07' THEN 7 + WHEN N'08' THEN 8 + WHEN N'09' THEN 9 + WHEN N'10' THEN 10 + END AS 规则类型 + FROM dbo.库存管理_物料主文件_基本 +) +SELECT + 前两位, + 规则类型, + COUNT(*) AS 总数, + SUM(CASE WHEN ISNULL(类型, -1) <> 规则类型 THEN 1 ELSE 0 END) AS 未匹配数量 +FROM R +WHERE 规则类型 IS NOT NULL +GROUP BY 前两位, 规则类型 +ORDER BY 前两位; + +SELECT + OBJECT_ID(N'dbo.GPT备份_物料管理_增加_批量_过程_20260903_134751', N'U') AS 过程备份表ID, + OBJECT_ID(N'dbo.GPT备份_物料类型_基础表_20260903_134751', N'U') AS 类型备份表ID, + OBJECT_ID(N'dbo.GPT备份_库存管理_物料主文件_基本_20260903_134751', N'U') AS 物料备份表ID; diff --git a/sql/物料管理_增加_批量_物料类型按编码前缀_回滚_20260903.sql b/sql/物料管理_增加_批量_物料类型按编码前缀_回滚_20260903.sql new file mode 100644 index 00000000..52795c69 --- /dev/null +++ b/sql/物料管理_增加_批量_物料类型按编码前缀_回滚_20260903.sql @@ -0,0 +1,85 @@ +/* +用途:回滚 2026-09-03 13:47:51 物料类型按物料编码前缀修正。 +说明:请在需要回滚的数据库中执行,本脚本依赖同库备份表: +1. dbo.GPT备份_物料管理_增加_批量_过程_20260903_134751 +2. dbo.GPT备份_物料类型_基础表_20260903_134751 +3. dbo.GPT备份_库存管理_物料主文件_基本_20260903_134751 +修改人:Ld 修改时间:2026-09-03 13:47:51; +*/ + +SET NOCOUNT ON; +SET XACT_ABORT ON; + +IF OBJECT_ID(N'dbo.GPT备份_物料管理_增加_批量_过程_20260903_134751', N'U') IS NULL + OR OBJECT_ID(N'dbo.GPT备份_物料类型_基础表_20260903_134751', N'U') IS NULL + OR OBJECT_ID(N'dbo.GPT备份_库存管理_物料主文件_基本_20260903_134751', N'U') IS NULL +BEGIN + RAISERROR(N'缺少本次变更备份表,无法自动回滚。', 16, 1); + RETURN; +END + +BEGIN TRY + BEGIN TRAN; + + UPDATE m + SET m.类型 = b.类型, + m.修改日期 = b.修改日期 + FROM dbo.库存管理_物料主文件_基本 m + INNER JOIN dbo.GPT备份_库存管理_物料主文件_基本_20260903_134751 b + ON m.物料流水号 = b.物料流水号 + WHERE ISNULL(m.类型, -1) <> ISNULL(b.类型, -1); -- 修改人:Ld 修改时间:2026-09-03 13:47:51; 使用备份恢复物料主文件类型。 + + DELETE t + FROM dbo.物料类型_基础表 t + WHERE NOT EXISTS ( + SELECT 1 + FROM dbo.GPT备份_物料类型_基础表_20260903_134751 b + WHERE b.类型流水号 = t.类型流水号 + ); -- 修改人:Ld 修改时间:2026-09-03 13:47:51; 删除本次新增的类型字典行。 + + UPDATE t + SET t.类型 = b.类型 + FROM dbo.物料类型_基础表 t + INNER JOIN dbo.GPT备份_物料类型_基础表_20260903_134751 b + ON t.类型流水号 = b.类型流水号; -- 修改人:Ld 修改时间:2026-09-03 13:47:51; 恢复原类型字典名称。 + + COMMIT TRAN; +END TRY +BEGIN CATCH + IF @@TRANCOUNT > 0 + ROLLBACK TRAN; + DECLARE @错误消息 nvarchar(4000); + DECLARE @错误严重级别 int; + DECLARE @错误状态 int; + SELECT + @错误消息 = ERROR_MESSAGE(), + @错误严重级别 = ERROR_SEVERITY(), + @错误状态 = ERROR_STATE(); + RAISERROR(@错误消息, @错误严重级别, @错误状态); -- 修改人:Ld 修改时间:2026-09-03 13:47:51; 兼容当前 SQL Server 版本的异常抛出方式。 +END CATCH; +GO + +DECLARE @过程定义 nvarchar(max); +SELECT TOP 1 @过程定义 = 过程定义 +FROM dbo.GPT备份_物料管理_增加_批量_过程_20260903_134751 +ORDER BY 备份时间 DESC; + +IF @过程定义 IS NULL +BEGIN + RAISERROR(N'未找到原存储过程定义,无法恢复过程。', 16, 1); + RETURN; +END + +SET @过程定义 = REPLACE(@过程定义, N'CREATE PROCEDURE', N'ALTER PROCEDURE'); +SET @过程定义 = REPLACE(@过程定义, N'CREATE PROCEDURE', N'ALTER PROCEDURE'); +SET @过程定义 = REPLACE(@过程定义, N'CREATE PROCEDURE', N'ALTER PROCEDURE'); +SET @过程定义 = REPLACE(@过程定义, N'CREATE PROCEDURE', N'ALTER PROCEDURE'); +SET @过程定义 = REPLACE(@过程定义, N'CREATE PROC', N'ALTER PROC'); + +EXEC sp_executesql @过程定义; -- 修改人:Ld 修改时间:2026-09-03 13:47:51; 使用备份定义恢复存储过程。 +GO + +SELECT N'回滚检查-类型字典' AS 检查项, 类型流水号, 类型 +FROM dbo.物料类型_基础表 +ORDER BY 类型流水号; + diff --git a/sql/物料视图_类型名称CASE安全版_20260903.sql b/sql/物料视图_类型名称CASE安全版_20260903.sql new file mode 100644 index 00000000..e7dc4052 --- /dev/null +++ b/sql/物料视图_类型名称CASE安全版_20260903.sql @@ -0,0 +1,89 @@ +/* +用途:安全修正物料标准维护页面的类型名称显示。 +设计:不改变 dbo.物料视图 的字段名和主要关联结构,不新增 dbo.物料类型_基础表 关联,仅将原 CASE 扩展为 1-10 类型。 +规则:1毛坯、2自制、3采购、4原材料、5耗材、6设备、7质检、8半成品、9模具、10成品。 +修改人:Ld 修改时间:2026-09-03 14:18:27; +*/ + +SET NOCOUNT ON; + +IF OBJECT_ID(N'dbo.GPT备份_物料视图_CASE安全版前_20260903_141827', N'U') IS NULL +BEGIN + SELECT + DB_NAME() AS 数据库名, + OBJECT_SCHEMA_NAME(object_id) AS 架构名, + name AS 对象名, + type_desc AS 对象类型, + OBJECT_DEFINITION(object_id) AS 对象定义, + GETDATE() AS 备份时间, + N'修改人:Ld 修改时间:2026-09-03 14:18:27; 物料视图改为CASE安全版前备份' AS 备份说明 + INTO dbo.GPT备份_物料视图_CASE安全版前_20260903_141827 + FROM sys.objects + WHERE object_id = OBJECT_ID(N'dbo.物料视图'); +END +GO + +ALTER VIEW dbo.物料视图 +AS +SELECT dbo.库存管理_物料主文件_基本.名称, dbo.库存管理_物料主文件_基本.代号, dbo.PDM_零件明细表_材料.材料, + dbo.单位名称_基础表.单位, CONVERT(varchar(10), dbo.库存管理_物料主文件_基本.修改日期, 23) AS 修改日期, + dbo.人事档案管理_人员名单.姓名 AS 修改人, dbo.库存管理_物料主文件_基本.物料流水号, + dbo.库存管理_物料主文件_基本.是否禁用, dbo.库存管理_物料主文件_基本.类型, + CASE dbo.库存管理_物料主文件_基本.类型 + WHEN 1 THEN N'毛坯' + WHEN 2 THEN N'自制' + WHEN 3 THEN N'采购' + WHEN 4 THEN N'原材料' + WHEN 5 THEN N'耗材' + WHEN 6 THEN N'设备' + WHEN 7 THEN N'质检' + WHEN 8 THEN N'半成品' + WHEN 9 THEN N'模具' + WHEN 10 THEN N'成品' + END AS 类型名称, -- 修改人:Ld 修改时间:2026-09-03 14:18:27; 原位置扩展CASE类型名称,避免新增JOIN影响页面。 + dbo.库存管理_物料主文件_基本.操作日期, + dbo.库存管理_物料主文件_基本.材料流水号, dbo.库存管理_物料主文件_基本.单位流水号, + dbo.库存管理_物料主文件_基本.物料编码, dbo.库存管理_物料_图片.文件后缀, dbo.库存管理_物料_图片.是否启用, + dbo.库存管理_物料_图片.文件内容, dbo.库存管理_物料主文件_基本.货位流水号, + dbo.库存管理_货位主文件.货位名称 AS 库位, dbo.库存管理_物料主文件_基本.物料库流水号, + dbo.物料库_基础表.物料类型, dbo.库存管理_物料主文件_基本.物料说明, + dbo.库存管理_物料主文件_基本.曾用物料编码, dbo.库存管理_物料主文件_基本.规格, ISNULL(creator.姓名, + dbo.库存管理_物料主文件_基本.创建人) AS Expr1, dbo.库存管理_物料主文件_基本.最高库存, + dbo.库存管理_物料主文件_基本.安全库存, dbo.库存管理_物料主文件_基本.最低库存 +FROM dbo.库存管理_物料主文件_基本 LEFT OUTER JOIN + dbo.物料库_基础表 ON + dbo.库存管理_物料主文件_基本.物料库流水号 = dbo.物料库_基础表.物料库流水号 LEFT OUTER JOIN + dbo.库存管理_货位主文件 ON + dbo.库存管理_物料主文件_基本.货位流水号 = dbo.库存管理_货位主文件.货位流水号 LEFT OUTER JOIN + dbo.库存管理_物料_图片 ON + dbo.库存管理_物料主文件_基本.物料流水号 = dbo.库存管理_物料_图片.物料流水号 LEFT OUTER JOIN + dbo.PDM_零件明细表_材料 ON + dbo.库存管理_物料主文件_基本.材料流水号 = dbo.PDM_零件明细表_材料.材料流水号 LEFT OUTER JOIN + dbo.单位名称_基础表 ON + dbo.库存管理_物料主文件_基本.单位流水号 = dbo.单位名称_基础表.单位流水号 LEFT OUTER JOIN + dbo.人事档案管理_人员名单 ON + dbo.库存管理_物料主文件_基本.修改人 = dbo.人事档案管理_人员名单.人员编号 LEFT OUTER JOIN + dbo.人事档案管理_人员名单 AS creator ON dbo.库存管理_物料主文件_基本.创建人 = creator.人员编号 +GO + +SELECT TOP 20 + 物料编码, + 名称, + 类型, + 类型名称, + 物料类型 +FROM dbo.物料视图 +WHERE LEFT(LTRIM(RTRIM(ISNULL(物料编码, N''))), 2) IN (N'01', N'02', N'03', N'04', N'05', N'06', N'07', N'08', N'09', N'10') +ORDER BY 物料编码; + +DECLARE @PageCount int; +DECLARE @ItemCount int; +EXEC dbo.物料管理_查询数据_分页 + @PageCurrent = 1, + @PageSize = 20, + @PageCount = @PageCount OUTPUT, + @ItemCount = @ItemCount OUTPUT; +SELECT @PageCount AS PageCount, @ItemCount AS ItemCount; + +SELECT OBJECT_ID(N'dbo.GPT备份_物料视图_CASE安全版前_20260903_141827', N'U') AS CASE安全版前备份表ID; + diff --git a/sql/物料视图_类型名称CASE安全版_回滚_20260903.sql b/sql/物料视图_类型名称CASE安全版_回滚_20260903.sql new file mode 100644 index 00000000..203cd6e0 --- /dev/null +++ b/sql/物料视图_类型名称CASE安全版_回滚_20260903.sql @@ -0,0 +1,33 @@ +/* +用途:回滚 2026-09-03 14:18:27 物料视图类型名称 CASE 安全版修正。 +说明:请在需要回滚的数据库中执行,本脚本依赖同库备份表 dbo.GPT备份_物料视图_CASE安全版前_20260903_141827。 +修改人:Ld 修改时间:2026-09-03 14:18:27; +*/ + +SET NOCOUNT ON; + +IF OBJECT_ID(N'dbo.GPT备份_物料视图_CASE安全版前_20260903_141827', N'U') IS NULL +BEGIN + RAISERROR(N'缺少物料视图 CASE 安全版前备份表,无法自动回滚。', 16, 1); + RETURN; +END + +DECLARE @视图定义 nvarchar(max); +SELECT TOP 1 @视图定义 = 对象定义 +FROM dbo.GPT备份_物料视图_CASE安全版前_20260903_141827 +ORDER BY 备份时间 DESC; + +IF @视图定义 IS NULL +BEGIN + RAISERROR(N'未找到备份的物料视图定义,无法恢复视图。', 16, 1); + RETURN; +END + +SET @视图定义 = REPLACE(@视图定义, N'CREATE VIEW', N'ALTER VIEW'); +EXEC sp_executesql @视图定义; -- 修改人:Ld 修改时间:2026-09-03 14:18:27; 使用安全版前备份恢复物料视图。 +GO + +SELECT TOP 20 物料编码, 名称, 类型, 类型名称, 物料类型 +FROM dbo.物料视图 +ORDER BY 物料编码; + diff --git a/sql/生产审核_通过仅更新审核状态.sql b/sql/生产审核_通过仅更新审核状态.sql index c8be4574..e27e5224 100644 --- a/sql/生产审核_通过仅更新审核状态.sql +++ b/sql/生产审核_通过仅更新审核状态.sql @@ -10,7 +10,9 @@ ALTER PROCEDURE [dbo].[机加工MES_加工完成整修审核_审核数据] @审核整修开始时间 DATETIME = NULL, @审核整修结束时间 DATETIME = NULL, @审核整修方案 NVARCHAR(1000) = NULL, - @计价方式 NVARCHAR(20) = NULL + -- 修改人:Ld 修改时间:2026-08-20 13:20:11; 传入角色编号以支持系统管理员重审已审核记录 + @计价方式 NVARCHAR(20) = NULL, + @角色编号 INT = NULL AS BEGIN SET NOCOUNT ON; @@ -36,6 +38,8 @@ BEGIN DECLARE @单时工价 DECIMAL(18, 4); DECLARE @是否修改加工 BIT = 0; DECLARE @是否修改整修 BIT = 0; + -- 修改人:Ld 修改时间:2026-08-20 13:20:11; 系统管理员可对已审核记录再次提交修改 + DECLARE @是否管理员重审 BIT = CASE WHEN ISNULL(@角色编号, 0) = 2 THEN 1 ELSE 0 END; DECLARE @是否本过程开启事务 BIT; SET @目标审核状态 = CASE WHEN @审核状态 IN (N'审核通过', N'已审核') THEN N'已审核' ELSE @审核状态 END; @@ -50,7 +54,8 @@ BEGIN SELECT 1 FROM [dbo].[MES_机加工MES_加工完成整修审核表] WHERE id = @审核流水号 - AND 审核状态 = N'待审核' + -- 修改人:Ld 修改时间:2026-08-20 13:20:11; 管理员重审时允许命中已审核记录 + AND (审核状态 = N'待审核' OR (@是否管理员重审 = 1 AND 审核状态 = N'已审核')) ) BEGIN SELECT N'0' AS result, N'该审核记录不存在或已审核' AS message; @@ -70,7 +75,8 @@ BEGIN @单时工价 = ISNULL(单时工价, 0) FROM [dbo].[MES_机加工MES_加工完成整修审核表] WHERE id = @审核流水号 - AND 审核状态 = N'待审核'; + -- 修改人:Ld 修改时间:2026-08-20 13:20:11; 管理员重审时允许读取已审核记录 + AND (审核状态 = N'待审核' OR (@是否管理员重审 = 1 AND 审核状态 = N'已审核')); IF @Safe计价方式 NOT IN (N'计件', N'计时') SET @Safe计价方式 = N'计件'; @@ -229,7 +235,8 @@ BEGIN [修改人] = N'Ld', [修改时间] = GETDATE() WHERE [id] = @审核流水号 - AND [审核状态] = N'待审核'; + -- 修改人:Ld 修改时间:2026-08-20 13:20:11; 管理员重审时允许更新已审核记录 + AND ([审核状态] = N'待审核' OR (@是否管理员重审 = 1 AND [审核状态] = N'已审核')); IF @是否本过程开启事务 = 1 COMMIT TRAN; diff --git a/sql/生产计划后端开发_测试库_20260820.sql b/sql/生产计划后端开发_测试库_20260820.sql new file mode 100644 index 00000000..8f68c0f5 --- /dev/null +++ b/sql/生产计划后端开发_测试库_20260820.sql @@ -0,0 +1,147 @@ +-- 生产计划后端开发测试库脚本;修改人:Ld 修改时间:2026-08-20 13:24:00; +USE [ERPTOOL_JY_20250826Back]; +GO + +/* 修改人:Ld 修改时间:2026-08-20 13:24:00; 工况查询增加计划开始时间字段,保留原有返回字段,兼容现有前端。 */ +ALTER PROCEDURE [dbo].[精工车间_工况_分页查询] +@人员编号 int = null, +@人员编号_check int = null, +@设备流水号 nvarchar(50) = null, +@设备流水号_check int = null, +@零件名称_check int = null, +@零件名称 nvarchar(50) = null, +@排序名称 int = null, +@排序方式 int = null, +@时间_check bit = null, +@开始时间 datetime = null, +@结束时间 datetime = null, +@PageCurrent int = 1, +@PageSize int = 20, +@PageCount int OUTPUT, +@ItemCount int OUTPUT +AS +BEGIN + SET NOCOUNT ON; + + DECLARE @selectStrWhere nvarchar(4000); + SET @selectStrWhere = N'数量 > 完成数'; + + IF (@人员编号_check = 1) + SET @selectStrWhere += N' AND 人员编号 = ' + CONVERT(nvarchar(20), @人员编号); + + IF (@设备流水号_check = 1 AND ISNULL(@设备流水号, N'') <> N'') + SET @selectStrWhere += N' AND 设备 LIKE N''%' + REPLACE(@设备流水号, N'''', N'''''') + N'%'''; + + IF (@零件名称_check = 1 AND ISNULL(@零件名称, N'') <> N'') + SET @selectStrWhere += N' AND 零件名称 LIKE N''%' + REPLACE(@零件名称, N'''', N'''''') + N'%'''; + + IF (@时间_check = 1) + SET @selectStrWhere += N' AND 分配时间 >= ''' + CONVERT(nvarchar(30), @开始时间, 120) + N''' AND 分配时间 <= ''' + CONVERT(nvarchar(30), @结束时间, 120) + N''''; + + DECLARE @fieldOrder nvarchar(1000); + IF (@排序名称 = 1) + SET @fieldOrder = CASE WHEN @排序方式 = 1 THEN N'零件名称 DESC' ELSE N'零件名称 ASC' END; + ELSE IF (@排序名称 = 2) + SET @fieldOrder = CASE WHEN @排序方式 = 1 THEN N'工序 DESC' ELSE N'工序 ASC' END; + ELSE IF (@排序名称 = 3) + SET @fieldOrder = CASE WHEN @排序方式 = 1 THEN N'姓名 DESC' ELSE N'姓名 ASC' END; + ELSE IF (@排序名称 = 4) + SET @fieldOrder = CASE WHEN @排序方式 = 1 THEN N'设备 DESC' ELSE N'设备 ASC' END; + ELSE + SET @fieldOrder = N'分配时间 DESC'; + + EXEC sp_xt_pagesplit + N'车间生产管理工艺_零件工序_已派工_视图', + N'工艺任务流水号', + @selectStrWhere, + N'[工艺任务流水号], [工序顺序], [数量], [姓名], [设备], [分配时间], [计划开始日期] AS [计划开始时间], [工艺计划流水号], [工序], [工序流水号], [人员编号], [设备流水号], [完成数], [是否加工中], [零件图号], [零件名称], [订单号], [精工期限], [报废数量], [工序状态], [加工开始时间], [加工完成时间]', + @fieldOrder, + N'', + @PageCurrent, + @PageSize, + @PageCount OUTPUT, + @ItemCount OUTPUT; +END; +GO + +/* 修改人:Ld 修改时间:2026-08-20 13:24:00; 新增设备门牌队列查询,按设备返回当前任务、下一项任务和后续队列。 */ +CREATE OR ALTER PROCEDURE [dbo].[车间生产管理_设备门牌看板_查询数据] + @设备流水号 nvarchar(50) = NULL, + @设备流水号_check bit = 0, + @仅未完成 bit = 1 +AS +BEGIN + SET NOCOUNT ON; + + ;WITH BaseTask AS ( + SELECT + v.工艺任务流水号, + v.工艺计划流水号, + v.工序流水号, + v.设备流水号, + v.设备, + v.姓名, + v.订单号, + v.零件名称, + v.零件图号, + v.工序顺序, + v.工序, + v.数量, + v.完成数, + v.是否加工中, + v.工序状态, + v.分配时间, + v.计划开始日期 AS 计划开始时间, + v.精工期限, + v.加工开始时间, + v.加工完成时间, + ROW_NUMBER() OVER ( + PARTITION BY v.设备流水号 + ORDER BY + CASE WHEN ISNULL(v.是否加工中, 0) = 1 THEN 0 ELSE 1 END, + ISNULL(v.计划开始日期, TRY_CONVERT(datetime, v.分配时间)), + ISNULL(v.精工期限, N'9999-12-31'), + v.工序顺序, + v.工艺任务流水号 + ) AS 设备队列序号, + COUNT(1) OVER (PARTITION BY v.设备流水号) AS 后续任务数 + FROM dbo.车间生产管理工艺_零件工序_已派工_视图 v + WHERE (@仅未完成 = 0 OR ISNULL(v.数量, 0) > ISNULL(v.完成数, 0)) + AND (@设备流水号_check = 0 OR CONVERT(nvarchar(50), v.设备流水号) LIKE N'%' + ISNULL(@设备流水号, N'') + N'%') + ) + SELECT + 工艺任务流水号, + 工艺计划流水号, + 工序流水号, + 设备流水号, + 设备, + 姓名, + 订单号, + 零件名称, + 零件图号, + 工序顺序, + 工序, + 数量, + 完成数, + 是否加工中, + 工序状态, + 分配时间, + 计划开始时间, + 精工期限, + 加工开始时间, + 加工完成时间, + 设备队列序号, + 后续任务数, + CASE + WHEN 设备队列序号 = 1 AND ISNULL(是否加工中, 0) = 1 THEN N'生产中' + WHEN 设备队列序号 = 1 THEN N'下一项' + ELSE N'排队中' + END AS 门牌状态, + CASE WHEN 设备队列序号 = 1 THEN 1 ELSE 0 END AS 是否当前任务, + CASE WHEN 设备队列序号 = 2 THEN 1 ELSE 0 END AS 是否下一任务 + FROM BaseTask + ORDER BY 设备流水号, 设备队列序号; +END; +GO + +-- 修改人:Ld 修改时间:2026-08-20 13:24:00; diff --git a/sql/生产计划销售合同字段_测试库_20260910.sql b/sql/生产计划销售合同字段_测试库_20260910.sql new file mode 100644 index 00000000..9feac622 --- /dev/null +++ b/sql/生产计划销售合同字段_测试库_20260910.sql @@ -0,0 +1,232 @@ +-- 生产计划查询补充销售合同计划字段测试库脚本;修改人:Ld 修改时间:2026-09-10 08:34:52; +USE [ERPTOOL_JY_20250826Back]; +GO + +/* 修改人:Ld 修改时间:2026-09-10 08:34:52; 生产计划查询返回部件名称和买方名称,供销售合同计划展示使用。 */ +ALTER PROCEDURE [dbo].[车间生产管理_生产计划_查询数据] + @合同编号_check bit = null, + @合同编号 nvarchar(50) = null, + @零件名称_check bit = null, + @零件名称 nvarchar(50) = null, + @产品名称_check bit = null, + @产品名称 nvarchar(50) = null, + @状态_check bit = null, + @状态 nvarchar(50) = null, + @月份 nvarchar(50) = '2026-5' +AS +BEGIN + SET NOCOUNT ON; + + DECLARE @年 nvarchar(50); + DECLARE @月 nvarchar(50); + DECLARE @selectStr nvarchar(MAX); + DECLARE @selectStrWhere nvarchar(MAX); + + IF CHARINDEX('-', @月份) > 0 + BEGIN + SET @年 = LEFT(@月份, CHARINDEX('-', @月份) - 1); + SET @月 = SUBSTRING(@月份, CHARINDEX('-', @月份) + 1, LEN(@月份) - CHARINDEX('-', @月份)); + END + ELSE + BEGIN + SET @年 = LEFT(@月份, 4); + SET @月 = RIGHT(@月份, 2); + END; + + SELECT TOP (0) * + INTO #生产计划 + FROM dbo.车间生产管理_生产计划_视图_新; + + SET @selectStr = N'INSERT INTO #生产计划 SELECT * FROM dbo.车间生产管理_生产计划_视图_新 '; + SET @selectStrWhere = N' WHERE 年 = @年 AND 月 = @月 '; + + IF (@零件名称_check = 1 AND ISNULL(@零件名称, N'') <> N'') + SET @selectStrWhere += N' AND (零件名称 + ISNULL(零件图号, N'''')) LIKE N''%'' + @零件名称 + N''%'' '; + + IF (@合同编号_check = 1 AND ISNULL(@合同编号, N'') <> N'') + SET @selectStrWhere += N' AND 订单号 LIKE N''%'' + @合同编号 + N''%'' '; + + IF (@产品名称_check = 1 AND ISNULL(@产品名称, N'') <> N'') + SET @selectStrWhere += N' AND 产品名称 LIKE N''%'' + @产品名称 + N''%'' '; + + IF (@状态_check = 1 AND ISNULL(@状态, N'') <> N'') + SET @selectStrWhere += N' AND 状态 LIKE N''%'' + @状态 + N''%'' '; + + SET @selectStr += @selectStrWhere + N';'; + + EXEC sp_executesql + @selectStr, + N'@零件名称 nvarchar(50), @合同编号 nvarchar(50), @产品名称 nvarchar(50), @状态 nvarchar(50), @年 nvarchar(50), @月 nvarchar(50)', + @零件名称 = @零件名称, + @合同编号 = @合同编号, + @产品名称 = @产品名称, + @状态 = @状态, + @年 = @年, + @月 = @月; + + CREATE TABLE #BHZZOrders ( + 订单流水号 int, + 订单编号 nvarchar(100), + 订单备注 nvarchar(500), + 合同日期 date, + 备注中数字 nvarchar(50), + 备注中人名 nvarchar(50) + ); + + CREATE TABLE #MKOrders ( + 订单流水号 int, + 订单编号 nvarchar(100), + 订单备注 nvarchar(500), + 合同日期 date, + 备注数字部分 nvarchar(50), + 备注人名部分 nvarchar(50) + ); + + CREATE TABLE #收货人信息 ( + 订单流水号 int, + 订单编号 nvarchar(100), + 收货人 nvarchar(100), + 地址 nvarchar(500) + ); + + INSERT INTO #BHZZOrders + SELECT DISTINCT + o.订单流水号, + o.订单编号, + o.订单备注, + CAST(o.合同日期 AS date) AS 合同日期, + dbo.提取备注中的数字(o.订单备注) AS 备注中数字, + dbo.提取备注中的中文(o.订单备注) AS 备注中人名 + FROM dbo.PDM_订单信息_视图 o + WHERE o.订单编号 LIKE N'BHZZ%' + AND EXISTS ( + SELECT 1 + FROM #生产计划 p + WHERE NULLIF(LTRIM(RTRIM(CONVERT(nvarchar(100), p.订单号))), N'') = o.订单编号 + ); + + INSERT INTO #MKOrders + SELECT + o.订单流水号, + o.订单编号, + o.订单备注, + CAST(o.合同日期 AS date) AS 合同日期, + dbo.提取备注中的数字(o.订单备注) AS 备注数字部分, + dbo.提取备注中的中文(o.订单备注) AS 备注人名部分 + FROM dbo.PDM_订单信息_视图 o + WHERE o.订单编号 LIKE N'%MK%'; + + INSERT INTO #收货人信息 + SELECT DISTINCT + o.订单流水号, + o.订单编号, + c.收货人, + c.地址 + FROM dbo.PDM_订单信息_视图 o + LEFT JOIN dbo.客户关系管理系统_客户名称 c ON o.客户流水号 = c.客户流水号 + WHERE o.订单编号 LIKE N'%MK%' + OR EXISTS (SELECT 1 FROM #BHZZOrders b WHERE b.订单编号 = o.订单编号); + + ;WITH AllMatches AS ( + SELECT + B.订单流水号 AS BHZZ订单流水号, + B.订单编号 AS BHZZ订单编号, + B.合同日期 AS BHZZ合同日期, + B.订单备注 AS BHZZ订单备注, + B.备注中数字 AS BHZZ备注提取数字, + B.备注中人名 AS BHZZ备注提取人名, + M.订单流水号 AS MK订单流水号, + M.订单编号 AS MK订单编号, + M.合同日期 AS MK合同日期, + M.订单备注 AS MK订单备注, + M.备注数字部分 AS MK备注数字部分, + M.备注人名部分 AS MK备注提取人名, + R.收货人 AS MK订单收货人, + R.地址 AS MK订单收货地址, + DATEDIFF(DAY, M.合同日期, B.合同日期) AS 日期差天数, + CASE + WHEN B.备注中数字 IS NOT NULL AND M.备注数字部分 IS NOT NULL + AND B.备注中数字 = M.备注数字部分 THEN N'数字匹配' + WHEN B.备注中数字 IS NOT NULL AND CHARINDEX(B.备注中数字, M.订单编号) > 0 THEN N'订单编号包含数字' + WHEN B.备注中人名 IS NOT NULL AND M.备注人名部分 IS NOT NULL + AND B.备注中人名 = M.备注人名部分 THEN N'人名匹配' + WHEN B.备注中人名 IS NOT NULL AND R.收货人 IS NOT NULL + AND B.备注中人名 = R.收货人 THEN N'人名与收货人匹配' + WHEN M.备注人名部分 IS NOT NULL AND R.收货人 IS NOT NULL + AND M.备注人名部分 = R.收货人 THEN N'MK备注人名与收货人匹配' + ELSE N'其他关联' + END AS 关联类型 + FROM #BHZZOrders B + INNER JOIN #MKOrders M ON + (B.备注中数字 IS NOT NULL AND M.备注数字部分 IS NOT NULL AND B.备注中数字 = M.备注数字部分) + OR (B.备注中数字 IS NOT NULL AND CHARINDEX(B.备注中数字, M.订单编号) > 0) + OR (B.备注中人名 IS NOT NULL AND M.备注人名部分 IS NOT NULL AND B.备注中人名 = M.备注人名部分) + LEFT JOIN #收货人信息 R ON M.订单流水号 = R.订单流水号 + ), + RankedMatches AS ( + SELECT + *, + ROW_NUMBER() OVER ( + PARTITION BY BHZZ订单流水号 + ORDER BY + CASE + WHEN 关联类型 = N'人名与收货人匹配' THEN 1 + WHEN 关联类型 = N'数字匹配' THEN 2 + WHEN 关联类型 = N'订单编号包含数字' THEN 3 + WHEN 关联类型 = N'人名匹配' THEN 4 + WHEN 关联类型 = N'MK备注人名与收货人匹配' THEN 5 + ELSE 6 + END, + ABS(日期差天数) + ) AS rn + FROM AllMatches + ) + SELECT * + INTO #ClosestMatches + FROM RankedMatches + WHERE rn = 1; + + -- 修改人:Ld 修改时间:2026-09-10 08:34:52; 从组件视图按MK订单补充部件名称和买方名称,客户名称不再取收货人。 + EXEC sp_executesql N' + SELECT + p.*, + ISNULL(componentInfo.部件名称, p.产品名称) AS 部件名称, + componentInfo.买方名称, + linkProject.合同编号 AS 关联合同编号, + c.BHZZ订单流水号, + c.BHZZ订单编号, + c.BHZZ合同日期, + c.BHZZ订单备注, + c.BHZZ备注提取数字, + c.BHZZ备注提取人名, + c.MK订单流水号, + c.MK订单编号, + c.MK合同日期, + c.MK订单备注, + c.MK备注数字部分, + c.MK备注提取人名, + c.MK订单收货人, + c.MK订单收货地址, + c.日期差天数, + c.关联类型 + FROM #生产计划 p + LEFT JOIN #ClosestMatches c ON c.BHZZ订单编号 = CONVERT(nvarchar(100), p.订单号) + LEFT JOIN dbo.合同管理_订单信息_基础表 linkOrder + ON linkOrder.订单编号 = CONVERT(nvarchar(100), p.订单号) + LEFT JOIN dbo.PDM_项目名称 linkProject + ON linkOrder.项目流水号 = linkProject.项目流水号 + OUTER APPLY ( + SELECT TOP (1) + comp.产品名称 AS 部件名称, + comp.买方名称 + FROM dbo.PDM_组件名称_视图 comp + WHERE comp.订单编号 = ISNULL(NULLIF(c.MK订单编号, N''''), CONVERT(nvarchar(100), p.订单号)) + ORDER BY + CASE WHEN comp.产品名称 = p.产品名称 THEN 0 ELSE 1 END, + comp.组件流水号 + ) componentInfo + ORDER BY p.订单号, p.工序顺序;'; +END; +GO + +-- 修改人:Ld 修改时间:2026-09-10 08:34:52; diff --git a/sql/设备门牌看板存储过程_正式库_20260910.sql b/sql/设备门牌看板存储过程_正式库_20260910.sql new file mode 100644 index 00000000..6d8d71ba --- /dev/null +++ b/sql/设备门牌看板存储过程_正式库_20260910.sql @@ -0,0 +1,248 @@ +-- 设备门牌看板存储过程从测试库同步到正式库;修改人:Ld 修改时间:2026-09-10 08:18:13; +USE [ERPTOOL_JY]; +GO + +/* 修改人:Ld 修改时间:2026-09-10 08:18:13; 同步测试库设备门牌看板过程,下一项按待加工区原过程口径,由任务分配设备流水号匹配工位后取可以加工第一项。 */ +ALTER PROCEDURE [dbo].[车间生产管理_设备门牌看板_查询数据] + @设备流水号 nvarchar(50) = NULL, + @设备流水号_check bit = 0, + @仅未完成 bit = 1 +AS +BEGIN + SET NOCOUNT ON; + /* 修改人:Ld 修改时间:2026-09-10 08:18:13; 正式库同步测试库设备门牌看板逻辑,过程体内保留追溯注释。 */ + + ;WITH WorkStation AS ( + SELECT + sb.设备流水号, + sb.工位号, + sb.设备名称, + rt.工艺计划流水号 AS 当前工艺计划流水号, + rt.工序流水号 AS 当前工序流水号, + rt.人员编号 AS 当前人员编号, + rt.操作时间 AS 当前操作时间 + FROM dbo.基础数据_设备工位点检表 sb + LEFT JOIN dbo.MES_机加工MES_实时监控信息表 rt + ON rt.终端编号 = sb.工位号 + WHERE sb.工位号 IS NOT NULL + AND (@设备流水号_check = 0 + OR CONVERT(nvarchar(50), sb.设备流水号) LIKE N'%' + ISNULL(@设备流水号, N'') + N'%' + OR sb.工位号 LIKE N'%' + ISNULL(@设备流水号, N'') + N'%' + OR sb.设备名称 LIKE N'%' + ISNULL(@设备流水号, N'') + N'%') + ), + CurrentTask AS ( + SELECT * + FROM ( + SELECT + ws.设备流水号, + ws.工位号, + ws.设备名称, + ws.当前操作时间, + v.工艺任务流水号, + ws.当前工艺计划流水号 AS 工艺计划流水号, + ws.当前工序流水号 AS 工序流水号, + ws.当前人员编号 AS 人员编号, + v.操作者 AS 姓名, + v.订单号, + v.零件名称, + v.零件图号, + v.工序顺序, + v.工序, + v.数量, + v.已完成数 AS 完成数, + v.剩余数量, + v.工序状态, + v.派工日期, + ROW_NUMBER() OVER ( + PARTITION BY ws.工位号 + ORDER BY v.订单号, v.工艺任务流水号 + ) AS rn + FROM WorkStation ws + INNER JOIN dbo.车间生产管理工艺_零件工序_派工任务_加工视图 v + ON v.工位号 = ws.工位号 + AND v.工艺计划流水号 = ws.当前工艺计划流水号 + AND v.工序流水号 = ws.当前工序流水号 + WHERE ISNULL(ws.当前工艺计划流水号, 0) > 0 + AND ISNULL(ws.当前工序流水号, 0) > 0 + ) c + WHERE c.rn = 1 + ), + CanProcess AS ( + SELECT DISTINCT + gx1.工艺计划流水号, + 1 AS 可以加工 + FROM dbo.车间生产管理工艺_零件工序 gx1 + WHERE gx1.工序顺序 = 1 + AND ( + ISNULL(gx1.完成数量, 0) > 0 + OR EXISTS ( + SELECT 1 + FROM dbo.MES_机加工MES_加工完成整修审核表 aud1 + WHERE aud1.工序流水号 = gx1.工序流水号 + AND aud1.审核类型 = N'加工完成' + AND aud1.审核状态 = N'待审核' + AND ISNULL(aud1.完成数量, 0) > 0 + ) + ) + ), + PendingArea AS ( + SELECT + ws.设备流水号, + ws.工位号, + ws.设备名称, + fp.工艺任务流水号, + v.工艺计划流水号, + v.工序流水号, + fp.人员编号, + v.操作者 AS 姓名, + ISNULL(gz.改制订单编号, v.订单号) AS 订单号, + v.零件名称, + v.零件图号, + v.工序顺序, + v.工序, + fp.数量, + ISNULL(fp.加工数量, 0) AS 完成数, + fp.数量 - ISNULL(fp.加工数量, 0) AS 剩余数量, + v.工序状态, + fp.分配时间 AS 派工日期, + v.精工期限, + v.计划完成日期, + CASE WHEN v.工序顺序 = 1 THEN 1 ELSE ISNULL(cp.可以加工, 0) END AS 可以加工 + FROM WorkStation ws + INNER JOIN dbo.车间生产管理工艺_零件工序_任务分配 fp + ON fp.设备流水号 = ws.设备流水号 + INNER JOIN dbo.车间生产管理_零件工序_视图 v + ON v.工序流水号 = fp.工序流水号 + LEFT JOIN CanProcess cp + ON cp.工艺计划流水号 = v.工艺计划流水号 + LEFT JOIN dbo.技术中心_改制订单记录 gz + ON gz.工艺计划流水号 = v.工艺计划流水号 + AND ISNULL(gz.是否删除, 0) = 0 + WHERE v.工艺编号 IS NOT NULL + AND v.考核状态 = 2 + AND ISNULL(v.工序状态, 0) < 3 + AND (@仅未完成 = 0 OR fp.数量 - ISNULL(fp.加工数量, 0) > 0) + AND CASE WHEN v.工序顺序 = 1 THEN 1 ELSE ISNULL(cp.可以加工, 0) END = 1 + AND NOT ( + ISNULL(v.工艺计划流水号, 0) = ISNULL(ws.当前工艺计划流水号, 0) + AND ISNULL(v.工序流水号, 0) = ISNULL(ws.当前工序流水号, 0) + ) + AND NOT EXISTS ( + SELECT 1 + FROM dbo.MES_机加工MES_加工完成整修审核表 aud + WHERE aud.工序流水号 = v.工序流水号 + AND aud.录工票人员编号 = fp.人员编号 + AND aud.审核类型 = N'加工完成' + AND aud.审核状态 = N'待审核' + AND ISNULL(aud.完成类型, 0) = 1 + ) + ), + NextTask AS ( + SELECT * + FROM ( + SELECT + p.*, + ROW_NUMBER() OVER ( + PARTITION BY p.工位号 + ORDER BY + p.计划完成日期, + p.派工日期, + p.工艺任务流水号 + ) AS rn + FROM PendingArea p + ) n + WHERE n.rn = 1 + ), + DoorTask AS ( + SELECT + c.工艺任务流水号, + c.工艺计划流水号, + c.工序流水号, + c.设备流水号, + c.工位号 + N':' + ISNULL(c.设备名称, N'') AS 设备, + c.姓名, + c.订单号, + c.零件名称, + c.零件图号, + c.工序顺序, + c.工序, + c.数量, + c.完成数, + 1 AS 是否加工中, + c.工序状态, + CONVERT(varchar(19), c.派工日期, 120) AS 分配时间, + c.当前操作时间 AS 计划开始时间, + CONVERT(varchar(10), NULL) AS 精工期限, + c.当前操作时间 AS 加工开始时间, + CONVERT(datetime, NULL) AS 加工完成时间, + 1 AS 设备队列序号, + c.工位号, + N'生产中' AS 门牌状态, + 1 AS 是否当前任务, + 0 AS 是否下一任务 + FROM CurrentTask c + + UNION ALL + + SELECT + n.工艺任务流水号, + n.工艺计划流水号, + n.工序流水号, + n.设备流水号, + n.工位号 + N':' + ISNULL(n.设备名称, N'') AS 设备, + n.姓名, + n.订单号, + n.零件名称, + n.零件图号, + n.工序顺序, + n.工序, + n.数量, + n.完成数, + 0 AS 是否加工中, + n.工序状态, + CONVERT(varchar(19), n.派工日期, 120) AS 分配时间, + n.派工日期 AS 计划开始时间, + n.精工期限, + CONVERT(datetime, NULL) AS 加工开始时间, + CONVERT(datetime, NULL) AS 加工完成时间, + CASE WHEN c.工位号 IS NULL THEN 1 ELSE 2 END AS 设备队列序号, + n.工位号, + N'下一项' AS 门牌状态, + CASE WHEN c.工位号 IS NULL THEN 1 ELSE 0 END AS 是否当前任务, + CASE WHEN c.工位号 IS NULL THEN 0 ELSE 1 END AS 是否下一任务 + FROM NextTask n + LEFT JOIN CurrentTask c + ON c.工位号 = n.工位号 + ) + SELECT + 工艺任务流水号, + 工艺计划流水号, + 工序流水号, + 设备流水号, + 设备, + 姓名, + 订单号, + 零件名称, + 零件图号, + 工序顺序, + 工序, + 数量, + 完成数, + 是否加工中, + 工序状态, + 分配时间, + 计划开始时间, + 精工期限, + 加工开始时间, + 加工完成时间, + 设备队列序号, + COUNT(1) OVER (PARTITION BY 工位号) - 1 AS 后续任务数, + 门牌状态, + 是否当前任务, + 是否下一任务 + FROM DoorTask + ORDER BY 工位号, 设备队列序号; +END; +GO + +-- 修改人:Ld 修改时间:2026-09-10 08:18:13; diff --git a/sql/采购入库单标签_测试库_20260903.sql b/sql/采购入库单标签_测试库_20260903.sql new file mode 100644 index 00000000..bd338612 --- /dev/null +++ b/sql/采购入库单标签_测试库_20260903.sql @@ -0,0 +1,361 @@ +/* +修改人:Ld 修改时间:2026-09-03 14:56:40; +用途: 测试库采购生成入库单时同步生成入库单标签信息,并提供扫码查询过程。 +数据库: ERPTOOL_JY_20250826Back +说明: 本脚本只部署测试库,不包含正式库发布。 +*/ + +IF OBJECT_ID(N'dbo.仓储管理_入库单标签明细', N'U') IS NULL +BEGIN + -- 修改人:Ld 修改时间:2026-09-03 14:56:40; 新增入库单标签明细表,保存扫码展示所需物料信息。 + CREATE TABLE dbo.仓储管理_入库单标签明细 + ( + 入库单标签明细流水号 INT IDENTITY(1,1) NOT NULL PRIMARY KEY, + 入库单标签流水号 INT NOT NULL, + 物料流水号 INT NULL, + 采购合同明细流水号 INT NULL, + 物料名称 NVARCHAR(100) NULL, + 图号 NVARCHAR(100) NULL, + 数量 DECIMAL(18,4) NULL, + 是否需要质检 BIT NULL, + 创建时间 DATETIME NOT NULL CONSTRAINT DF_仓储管理_入库单标签明细_创建时间 DEFAULT(GETDATE()) + ) +END +GO + +IF OBJECT_ID(N'dbo.仓储管理_入库单标签', N'U') IS NULL +BEGIN + -- 修改人:Ld 修改时间:2026-09-03 14:56:40; 新增入库单标签主表,二维码以标签ID或入库单号查询该表。 + CREATE TABLE dbo.仓储管理_入库单标签 + ( + 入库单标签流水号 INT IDENTITY(1,1) NOT NULL PRIMARY KEY, + 标签编号 NVARCHAR(100) NOT NULL, + 入库单号 NVARCHAR(100) NULL, + 批次号 NVARCHAR(100) NULL, + 采购合同流水号 INT NULL, + 采购合同号 NVARCHAR(100) NULL, + 供应商流水号 NVARCHAR(100) NULL, + 供应商 NVARCHAR(100) NULL, + 二维码内容 NVARCHAR(500) NULL, + 创建人 INT NULL, + 创建时间 DATETIME NOT NULL CONSTRAINT DF_仓储管理_入库单标签_创建时间 DEFAULT(GETDATE()), + 是否启用 BIT NOT NULL CONSTRAINT DF_仓储管理_入库单标签_是否启用 DEFAULT(1) + ) +END +GO + +IF NOT EXISTS ( + SELECT 1 + FROM sys.foreign_keys + WHERE name = N'FK_仓储管理_入库单标签明细_标签' + AND parent_object_id = OBJECT_ID(N'dbo.仓储管理_入库单标签明细') +) +BEGIN + -- 修改人:Ld 修改时间:2026-09-03 14:56:40; 为标签明细增加主表外键,便于后续重打和追溯。 + ALTER TABLE dbo.仓储管理_入库单标签明细 + ADD CONSTRAINT FK_仓储管理_入库单标签明细_标签 + FOREIGN KEY (入库单标签流水号) REFERENCES dbo.仓储管理_入库单标签(入库单标签流水号) +END +GO + +IF NOT EXISTS ( + SELECT 1 + FROM sys.indexes + WHERE name = N'IX_仓储管理_入库单标签_入库单号' + AND object_id = OBJECT_ID(N'dbo.仓储管理_入库单标签') +) +BEGIN + -- 修改人:Ld 修改时间:2026-09-03 14:56:40; 增加入库单号索引,提升扫码查询速度。 + CREATE INDEX IX_仓储管理_入库单标签_入库单号 ON dbo.仓储管理_入库单标签(入库单号) +END +GO + +IF NOT EXISTS ( + SELECT 1 + FROM sys.indexes + WHERE name = N'IX_仓储管理_入库单标签_标签编号' + AND object_id = OBJECT_ID(N'dbo.仓储管理_入库单标签') +) +BEGIN + -- 修改人:Ld 修改时间:2026-09-03 14:56:40; 增加标签编号索引,支持二维码按标签编号查询。 + CREATE INDEX IX_仓储管理_入库单标签_标签编号 ON dbo.仓储管理_入库单标签(标签编号) +END +GO + +-- 修改人:Ld 修改时间:2026-09-03 14:56:40; 改造生成入库单过程,同步写入标签主表和明细表,并返回标签字段。 +ALTER PROCEDURE [dbo].[采购管理_到货内容_新增] +@发起人 int = null, +@通知内容 nvarchar(500) = null, +@采购合同流水号 int = null, +@到货数组 varchar(500) = null, +@物料流水号组 varchar(500) = null, +@质检标志组 varchar(500) = null, +@采购合同 nvarchar(50) = null, +@供应商流水号 nvarchar(50) = null, +@入库单号 nvarchar(50) = null + +AS +BEGIN + SET NOCOUNT ON; + + update 采购管理_采购合同 set 是否到货 = 3 where 采购合同流水号 = @采购合同流水号 + + DECLARE @实际入库单号 NVARCHAR(100) + DECLARE @批次号 NVARCHAR(100) + DECLARE @标签编号 NVARCHAR(100) + DECLARE @入库单标签流水号 INT + DECLARE @供应商 NVARCHAR(100) + + SET @实际入库单号 = NULLIF(LTRIM(RTRIM(@入库单号)), N'') + + IF @实际入库单号 IS NULL + BEGIN + DECLARE @TodayDate VARCHAR(8) = CONVERT(VARCHAR(8), GETDATE(), 112) + DECLARE @Sequence INT + + -- 修改人:Ld 修改时间:2026-09-03 14:56:40; 兼容测试库旧SQL Server版本,不使用TRY_CAST。 + SELECT @Sequence = ISNULL(MAX(CASE WHEN ISNUMERIC(RIGHT(入库单号, 3)) = 1 THEN CAST(RIGHT(入库单号, 3) AS INT) ELSE 0 END), 0) + 1 + FROM 仓储管理_入库单 + WHERE 入库单号 LIKE 'RK' + @TodayDate + CAST(@采购合同流水号 AS VARCHAR(20)) + '%' + + SET @实际入库单号 = 'RK' + @TodayDate + CAST(@采购合同流水号 AS VARCHAR(20)) + RIGHT('000' + CAST(@Sequence AS VARCHAR(10)), 3) + END + + SET @批次号 = @实际入库单号 + SET @标签编号 = 'JYRK待生成' + + SELECT TOP 1 @供应商 = 供应商名称 + FROM 采购管理_采购合同明细_视图 + WHERE 采购合同流水号 = @采购合同流水号 + + IF @供应商 IS NULL + BEGIN + SELECT TOP 1 @供应商 = 供应商 + FROM 采购管理_耗材采购合同明细_查询视图 + WHERE 采购合同流水号 = @采购合同流水号 + END + + -- 声明临时表变量 + DECLARE @物料明细表 TABLE ( + RowNum INT, + 到货数 INT, + 物料流水号 INT, + 需要质检 INT + ) + + -- 解析质检标志数组 + ;WITH 质检标志表 AS ( + SELECT + ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS RowNum, + CAST(Value AS INT) AS 需要质检 + FROM dbo.SplitString(@质检标志组, ',') + ), + -- 解析到货数组 + 到货表 AS ( + SELECT + ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS RowNum, + CAST(Value AS INT) AS 到货数 + FROM dbo.SplitString(@到货数组, ',') + ), + -- 解析物料流水号组 + 物料表 AS ( + SELECT + ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS RowNum, + CAST(Value AS INT) AS 物料流水号 + FROM dbo.SplitString(@物料流水号组, ',') + ) + -- 插入到物料明细表 + INSERT INTO @物料明细表 + SELECT + 到货表.RowNum, + 到货表.到货数, + 物料表.物料流水号, + ISNULL(质检标志表.需要质检, 0) AS 需要质检 + FROM 到货表 + INNER JOIN 物料表 ON 到货表.RowNum = 物料表.RowNum + LEFT JOIN 质检标志表 ON 到货表.RowNum = 质检标志表.RowNum + WHERE 到货表.到货数 > 0 + + -- 修改人:Ld 修改时间:2026-09-03 14:56:40; 先生成标签主表,明细按本次提交物料写入,扫码可直接读取。 + IF EXISTS (SELECT 1 FROM @物料明细表) + BEGIN + INSERT INTO dbo.仓储管理_入库单标签 + ( + 标签编号, + 入库单号, + 批次号, + 采购合同流水号, + 采购合同号, + 供应商流水号, + 供应商, + 二维码内容, + 创建人 + ) + VALUES + ( + @标签编号, + @实际入库单号, + @批次号, + @采购合同流水号, + @采购合同, + @供应商流水号, + @供应商, + N'JYRK|' + @标签编号, + @发起人 + ) + + SET @入库单标签流水号 = SCOPE_IDENTITY() + + -- 修改人:Ld 修改时间:2026-09-03 14:56:40; 标签编号使用自增标签ID生成,避免同一秒并发生成重复编号。 + SET @标签编号 = 'JYRK' + RIGHT('0000000000' + CAST(@入库单标签流水号 AS VARCHAR(20)), 10) + + UPDATE dbo.仓储管理_入库单标签 + SET 标签编号 = @标签编号, + 二维码内容 = N'JYRK|' + @标签编号 + WHERE 入库单标签流水号 = @入库单标签流水号 + + INSERT INTO dbo.仓储管理_入库单标签明细 + ( + 入库单标签流水号, + 物料流水号, + 采购合同明细流水号, + 物料名称, + 图号, + 数量, + 是否需要质检 + ) + SELECT + @入库单标签流水号, + m.物料流水号, + ISNULL(d1.采购合同明细流水号, d2.采购合同明细流水号), + ISNULL(d1.物料名称, d2.采购件), + ISNULL(d1.图号或型号, d2.图号或型号), + m.到货数, + m.需要质检 + FROM @物料明细表 m + OUTER APPLY ( + SELECT TOP 1 采购合同明细流水号, 物料名称, 图号或型号 + FROM 采购管理_采购合同明细_视图 + WHERE 采购合同流水号 = @采购合同流水号 + AND 物料流水号 = m.物料流水号 + ORDER BY 采购合同明细流水号 + ) d1 + OUTER APPLY ( + SELECT TOP 1 采购合同明细流水号, 采购件, 图号或型号 + FROM 采购管理_耗材采购合同明细_查询视图 + WHERE 采购合同流水号 = @采购合同流水号 + AND 物料流水号 = m.物料流水号 + ORDER BY 采购合同明细流水号 + ) d2 + END + + -- 判断是否有质检物料(需要质检的物料) + IF EXISTS (SELECT 1 FROM @物料明细表 WHERE 需要质检 = 1) + BEGIN + -- 发送通知给质检部门 + INSERT INTO 采购管理_到货通知记录(通知内容,通知日期,发起人,接收角色) + VALUES(@通知内容, GETDATE(), @发起人, 20) -- 20为质检部门角色ID + + -- 质检物料到货记录 + INSERT INTO 采购管理_采购到货(采购合同流水号, 到货数, 物料流水号, 是否需要质检, 质检状态) + SELECT + @采购合同流水号, + 到货数, + 物料流水号, + 1, -- 需要质检 + '待质检' + FROM @物料明细表 + WHERE 需要质检 = 1 + END + + -- 判断是否有免检物料(不需要质检的物料) + IF EXISTS (SELECT 1 FROM @物料明细表 WHERE 需要质检 = 0) + BEGIN + -- 发送通知给仓库部门 + INSERT INTO 采购管理_到货通知记录(通知内容,通知日期,发起人,接收角色) + VALUES(@通知内容, GETDATE(), @发起人, 7) -- 7为仓库部门角色ID + + -- 免检物料到货记录(直接入库) + INSERT INTO 采购管理_采购到货(采购合同流水号,到货数,物料流水号,是否需要质检,质检状态,等待入库数量) + SELECT + @采购合同流水号, + 到货数, + 物料流水号, + 0, -- 不需要质检 + '已入库', + 到货数 + FROM @物料明细表 + WHERE 需要质检 = 0 + + -- 插入入库单,并生成带序号的入库单号 + INSERT INTO 仓储管理_入库单(入库单号,采购合同流水号,采购合同号,供应商流水号,供应商名称,到货数,是否入库) + SELECT + @实际入库单号, + @采购合同流水号, + @采购合同, + @供应商流水号, + @供应商, + 到货数, + 0 + FROM @物料明细表 + WHERE 需要质检 = 0 + END + + -- 返回执行结果 + SELECT + '1' AS result, + @实际入库单号 AS 入库单号, + @批次号 AS 批次号, + @入库单标签流水号 AS 标签ID, + @标签编号 AS 标签编号, + N'JYRK|' + @标签编号 AS 二维码内容 +END +GO + +IF OBJECT_ID(N'dbo.采购管理_入库单标签_扫码查询', N'P') IS NOT NULL + DROP PROCEDURE dbo.采购管理_入库单标签_扫码查询 +GO + +-- 修改人:Ld 修改时间:2026-09-03 14:56:40; 新增扫码查询过程,扫码后按标签编号、标签ID或入库单号返回入库明细。 +CREATE PROCEDURE dbo.采购管理_入库单标签_扫码查询 +@扫码内容 NVARCHAR(500) = NULL, +@标签ID INT = NULL, +@入库单号 NVARCHAR(100) = NULL +AS +BEGIN + SET NOCOUNT ON; + + DECLARE @标签编号 NVARCHAR(100) + + SET @标签编号 = @扫码内容 + + IF @标签编号 LIKE N'JYRK|%' + BEGIN + SET @标签编号 = SUBSTRING(@标签编号, 6, 100) + END + + SELECT + t.入库单标签流水号 AS 标签ID, + t.标签编号, + t.入库单号, + t.采购合同号, + t.供应商, + t.批次号, + d.物料名称, + d.图号, + d.数量, + d.是否需要质检, + t.创建时间 + FROM dbo.仓储管理_入库单标签 t + INNER JOIN dbo.仓储管理_入库单标签明细 d + ON t.入库单标签流水号 = d.入库单标签流水号 + WHERE t.是否启用 = 1 + AND ( + (@标签ID IS NOT NULL AND t.入库单标签流水号 = @标签ID) + OR (ISNULL(@标签编号, N'') <> N'' AND t.标签编号 = @标签编号) + OR (ISNULL(@入库单号, N'') <> N'' AND t.入库单号 = @入库单号) + OR (ISNULL(@扫码内容, N'') <> N'' AND t.入库单号 = @扫码内容) + ) + ORDER BY d.入库单标签明细流水号 +END +GO diff --git a/src.zip b/src.zip deleted file mode 100644 index 583f1d76..00000000 Binary files a/src.zip and /dev/null differ diff --git a/src/api/BasicData/PersonnelManagement.js b/src/api/BasicData/PersonnelManagement.js index 50410873..f658a7ae 100644 --- a/src/api/BasicData/PersonnelManagement.js +++ b/src/api/BasicData/PersonnelManagement.js @@ -56,6 +56,20 @@ export function getTablePeopleForName(name) { } }) } +// 修改人:Ld 修改时间:2026-09-09 15:30:17; 新增人员前校验考勤编号是否重复并返回同前缀最大序号 +export function checkAttendanceNumber(AccountNumber) { + return request({ + url: '', + method: 'post', + data: { + UserID: state.state.user.id, + ModularID: router.currentRoute.path, + type: 1, + name: '人事档案管理_人员名单_考勤编号重复最大序号_查询_MESWORK', + param: '考勤编号=' + AccountNumber + '=string' + } + }) +} // 新增部门 export function addDepartmentName(num1, num2, num3) { return request({ diff --git a/src/vendor/xlsx-style-cptable.js b/src/vendor/xlsx-style-cptable.js new file mode 100644 index 00000000..eb23b337 --- /dev/null +++ b/src/vendor/xlsx-style-cptable.js @@ -0,0 +1,2 @@ +// 修改人:Ld 修改时间:2026-08-05 08:13:25; 兼容 xlsx-style 打包时解析缺失的 cptable 可选编码表模块。 +module.exports = {} diff --git a/src/views/BasicData/PersonnelManagement/index.vue b/src/views/BasicData/PersonnelManagement/index.vue index 67151b38..fb6cc242 100644 --- a/src/views/BasicData/PersonnelManagement/index.vue +++ b/src/views/BasicData/PersonnelManagement/index.vue @@ -656,6 +656,7 @@ import { tree, getTablePeople, getTablePeopleForName, + checkAttendanceNumber, addDepartmentName, delList, editList, @@ -1151,17 +1152,39 @@ export default { submitAddPeople() { this.addPeople_disable = true this.btnLoading = true - addPeople(this.id, this.people_form.Sex, this.people_form.Education, this.people_form.Address, this.people_form.Nation, this.people_form.Post, this.people_form.AccountNumber, this.people_form.Password, this.people_form.Name, this.people_form.IDcard, this.people_form.TimeOfEntry, this.people_form.Birthday, this.people_form.ContactInformation, this.people_form.TeamValue).then(response => { - this.btnLoading = false - if (response.data[0].result === '1') { - this.people_DFV = false - this.i = 0 - this.handleNodeClick() - this.$message.success('添加成功') - } else { - this.$message.error('添加失败') + // 修改人:Ld 修改时间:2026-09-09 15:30:17; 先查考勤编号是否重复,重复时拦截新增避免接口返回添加成功 + checkAttendanceNumber(this.people_form.AccountNumber).then(response => { + if (response.data[0].是否重复 === 1 || response.data[0].是否重复 === '1') { + this.btnLoading = false this.addPeople_disable = false + this.$message.error('考勤编号已有,现在已到' + response.data[0].最大考勤编号) + } else { + addPeople(this.id, this.people_form.Sex, this.people_form.Education, this.people_form.Address, this.people_form.Nation, this.people_form.Post, this.people_form.AccountNumber, this.people_form.Password, this.people_form.Name, this.people_form.IDcard, this.people_form.TimeOfEntry, this.people_form.Birthday, this.people_form.ContactInformation, this.people_form.TeamValue).then(response => { + this.btnLoading = false + if (response.data[0].result === '1') { + this.people_DFV = false + this.i = 0 + this.handleNodeClick() + this.$message.success('添加成功') + } else { + // 修改人:Ld 修改时间:2026-09-09 15:19:32; 考勤编号重复时显示测试库返回的同前缀最大编号 + if (response.data[0].失败原因 === '考勤编号重复' && response.data[0].最大考勤编号) { + this.$message.error('考勤编号已有,现在已到' + response.data[0].最大考勤编号) + } else { + this.$message.error('添加失败') + } + this.addPeople_disable = false + } + }).catch(() => { + this.btnLoading = false + this.addPeople_disable = false + this.$message.error('添加失败') + }) } + }).catch(() => { + this.btnLoading = false + this.addPeople_disable = false + this.$message.error('考勤编号校验失败') }) }, handleEditPeople(row) { @@ -1320,4 +1343,3 @@ export default { - diff --git a/src/views/PurchasingManagement/OrderInquiry/index.vue b/src/views/PurchasingManagement/OrderInquiry/index.vue index de4d60af..129d9a9f 100644 --- a/src/views/PurchasingManagement/OrderInquiry/index.vue +++ b/src/views/PurchasingManagement/OrderInquiry/index.vue @@ -62,7 +62,6 @@ placeholder="订单备注" @keyup.enter.native="pageCurrent=1;searchLeftTable()"/> 导出 - 生成入库单 @@ -145,13 +144,22 @@ {{ getApproverName(scope.row.审批人) }} - + + + + + + - + - - - - - + + + + 采购合同号: + {{ arrivalContractLabel || '-' }} - - - - - - - 查询 + + 供应商: + {{ arrivalSupplierLabel || '-' }} 入库单号: @@ -586,10 +590,19 @@ - + + + - {{ scope.row.采购合同编号 }} + {{ scope.row.采购合同编号 || arrivalContractLabel }} @@ -616,11 +629,12 @@ + controls-position="right" + @change="onArrivalCountChange(scope.row)"/> @@ -646,9 +660,11 @@ 到货汇总 + 本次到货物料数:{{ arrivalCount }} 个, - 其中需质检:{{ qualityCheckCount }} 个 → 推送质检部, - 免检直接入库:{{ noQualityCheckCount }} 个 → 推送仓库 + 本次数量合计:{{ arrivalTotalQuantity }}, + 其中需质检:{{ qualityCheckCount }} 个 / {{ qualityCheckTotalQuantity }} → 推送质检部, + 免检直接入库:{{ noQualityCheckCount }} 个 / {{ noQualityCheckTotalQuantity }} → 推送仓库 @@ -658,6 +674,30 @@ 确 定 + + + + 采购入库标签 + + + 采购合同号{{ arrivalLabelInfo.采购合同号 }} + 供应商{{ arrivalLabelInfo.供应商 }} + 批次号{{ arrivalLabelInfo.批次号 }} + 入库单号{{ arrivalLabelInfo.入库单号 }} + + + + + + {{ index + 1 }}. {{ item.物料名称 }} / {{ item.图号 }} / {{ item.数量 }} + + + + + @@ -666,6 +706,7 @@ import { mapGetters } from 'vuex' import $ from 'jquery' import request, { MESDownloadFile, MESUploadFileNew, MESDownloadFileNew, MESDeleteFileNew, MESUploadFileNew_BasePath, url } from '@/utils/request' import axios from 'axios' +import QRCode from 'qrcode' export default { data() { @@ -744,6 +785,17 @@ export default { arrivalContractNo: '', arrivalContract: [], arrivalContractLabel: '', + arrivalSupplierLabel: '', + arrivalSelectedRows: [], + arrivalLabelVisible: false, + arrivalLabelInfo: { + 采购合同号: '', + 供应商: '', + 批次号: '', + 入库单号: '', + 二维码: '', + 明细: [] + }, arrivalNoticeLabel: '', arrivalTableData: [], 入库单号: '' @@ -755,16 +807,27 @@ export default { 'token' ]), hasArrivalData() { - return this.arrivalTableData.some(item => item.到货数量 > 0) + // 修改人:Ld 修改时间:2026-09-03 14:37:23; 到货汇总按勾选行统计,和提交口径保持一致。 + return this.arrivalSelectedRows.some(item => item.到货数量 > 0) }, arrivalCount() { - return this.arrivalTableData.filter(item => item.到货数量 > 0).length + return this.arrivalSelectedRows.filter(item => item.到货数量 > 0).length }, qualityCheckCount() { - return this.arrivalTableData.filter(item => item.到货数量 > 0 && item.需要质检).length + return this.arrivalSelectedRows.filter(item => item.到货数量 > 0 && item.需要质检).length }, noQualityCheckCount() { - return this.arrivalTableData.filter(item => item.到货数量 > 0 && !item.需要质检).length + return this.arrivalSelectedRows.filter(item => item.到货数量 > 0 && !item.需要质检).length + }, + // 修改人:Ld 修改时间:2026-09-03 15:10:12; 按勾选行实时合计本次到货数量,避免只看物料行数。 + arrivalTotalQuantity() { + return this.sumArrivalQuantity(this.arrivalSelectedRows.filter(item => item.到货数量 > 0)) + }, + qualityCheckTotalQuantity() { + return this.sumArrivalQuantity(this.arrivalSelectedRows.filter(item => item.到货数量 > 0 && item.需要质检)) + }, + noQualityCheckTotalQuantity() { + return this.sumArrivalQuantity(this.arrivalSelectedRows.filter(item => item.到货数量 > 0 && !item.需要质检)) } }, updated() { @@ -1128,14 +1191,35 @@ export default { } }).then(() => { const htmlNode = $('#WGBLD').html() - const body = $('body') - body.children().hide() - const printNode = $(htmlNode) - body.append(printNode) - window.print() - body.children().not('script').show() - body.children().not('#app').hide() - printNode.remove() + // 修改人:Ld 修改时间:2026-08-19 09:16:26; 使用隐藏iframe承载采购合同打印内容 + const printTitle = (row.采购合同号 || this.orderNumber || '采购合同').replace(/[\\/:*?"<>|]/g, '_') + // 修改人:Ld 修改时间:2026-08-19 09:21:49; PDF默认文件名取主页面临时title,打印显示title取原页面title + const oldTitle = document.title + const frameTitleHtml = oldTitle.replace(/[&<>"']/g, function(value) { + return { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[value] + }) + const printFrame = document.createElement('iframe') + printFrame.style.position = 'fixed' + printFrame.style.right = '0' + printFrame.style.bottom = '0' + printFrame.style.width = '0' + printFrame.style.height = '0' + printFrame.style.border = '0' + document.body.appendChild(printFrame) + const printWindow = printFrame.contentWindow + const printDocument = printWindow.document + printDocument.open() + printDocument.write('' + frameTitleHtml + '') + printDocument.close() + printDocument.body.innerHTML = htmlNode + try { + document.title = printTitle + printWindow.focus() + printWindow.print() + } finally { + document.title = oldTitle + document.body.removeChild(printFrame) + } }) }, getSuppliers() { @@ -1440,22 +1524,43 @@ export default { } return approverId }, - addArrivalNotice() { - this.arrivalSupplierName = '' - this.arrivalContractNo = '' - this.arrivalContractLabel = '' - this.arrivalNoticeLabel = '' - this.arrivalContract = [] + // 修改人:Ld 修改时间:2026-09-03 14:37:23; 从左侧合同列表打开生成入库单弹窗,自动带入当前合同上下文。 + addArrivalNotice(row) { + if (!row || !row.采购合同流水号) { + this.$message.warning('请从左侧合同列表选择合同生成入库单') + return + } + this.arrivalSupplierName = row.供应商流水号 || this.getSupplierValueByName(row.供应商) + this.arrivalSupplierLabel = row.供应商 || '' + this.arrivalContractNo = row.采购合同流水号 + this.arrivalContractLabel = row.采购合同号 || row.采购合同编号 || '' + this.arrivalNoticeLabel = this.arrivalContractLabel + this.arrivalContract = [{ + label: this.arrivalContractLabel, + value: this.arrivalContractNo + }] + this.arrivalSelectedRows = [] + this.arrivalLabelVisible = false + this.arrivalLabelInfo = { + 采购合同号: '', + 供应商: '', + 批次号: '', + 入库单号: '', + 二维码: '', + 明细: [] + } this.arrivalTableData = [] this.入库单号 = '' this.dialogFormVisible4 = true + this.searchArrivalDetail() }, getArrivalContract() { if (!this.arrivalSupplierName) { this.arrivalContract = [] return } - let check = this.arrivalSupplierName ? 1 : 0 + // 修改人:Ld 修改时间:2026-09-03 14:37:23; 修正变量声明以满足项目ESLint规则。 + const check = this.arrivalSupplierName ? 1 : 0 this.arrivalContract = [] this.arrivalContractNo = '' var param = [] @@ -1478,11 +1583,11 @@ export default { }, searchArrivalDetail() { if (!this.arrivalSupplierName) { - this.$message.warning('请先选择供应商') + this.$message.warning('当前合同缺少供应商流水号') return } if (!this.arrivalContractNo) { - this.$message.warning('请先选择合同号') + this.$message.warning('当前合同缺少合同流水号') return } var param = [] @@ -1492,7 +1597,7 @@ export default { this.ExecDatabase(Data).then(response => { this.arrivalTableData = response.data.map(item => ({ ...item, - 到货数量: 0, + 到货数量: this.getCanArrivalCount(item), 需要质检: false })) if (this.arrivalTableData.length === 0) { @@ -1502,13 +1607,60 @@ export default { if (response.data.length > 0 && response.data[0].入库单号) { this.入库单号 = response.data[0].入库单号 } + this.$nextTick(() => { + if (this.$refs.arrivalTable) { + this.arrivalTableData.forEach(item => { + if (this.getCanArrivalCount(item) > 0) { + this.$refs.arrivalTable.toggleRowSelection(item, true) + } + }) + } + }) }) }, + // 修改人:Ld 修改时间:2026-09-03 14:37:23; 合同列表未返回供应商流水号时,按供应商名称从已加载选项中兜底匹配。 + getSupplierValueByName(name) { + if (!name) { + return '' + } + const selected = this.suppliers.find(item => item.label === name) + return selected ? selected.value : '' + }, + // 修改人:Ld 修改时间:2026-09-03 14:37:23; 记录本次用户勾选的入库明细。 + handleArrivalSelectionChange(val) { + this.arrivalSelectedRows = val + }, + // 修改人:Ld 修改时间:2026-09-03 14:37:23; 统一计算可入库数量,避免前端出现负数或超入。 + getCanArrivalCount(row) { + var purchaseCount = Number(row.采购数 || 0) + var arrivedCount = Number(row.已到数 || 0) + var canArrivalCount = purchaseCount - arrivedCount + return canArrivalCount > 0 ? canArrivalCount : 0 + }, + // 修改人:Ld 修改时间:2026-09-03 14:37:23; 数量清零时同步取消质检标志。 + onArrivalCountChange(row) { + if (Number(row.到货数量) === 0) { + row.需要质检 = false + } + }, + // 修改人:Ld 修改时间:2026-09-03 15:10:12; 汇总勾选明细的本次到货数量。 + sumArrivalQuantity(list) { + var total = list.reduce(function(sum, item) { + var value = Number(item.到货数量 || 0) + return sum + (isNaN(value) ? 0 : value) + }, 0) + return Number(total.toFixed(4)) + }, submitArrivalNotice() { - const arrivalData = this.arrivalTableData.filter(item => item.到货数量 > 0) + const arrivalData = this.arrivalSelectedRows.filter(item => Number(item.到货数量) > 0) if (arrivalData.length === 0) { - this.$message.warning('请至少填写一个物料的到货数量!') + this.$message.warning('请至少勾选一个物料并填写到货数量!') + return + } + const invalidArrival = arrivalData.some(item => Number(item.到货数量) > this.getCanArrivalCount(item)) + if (invalidArrival) { + this.$message.warning('存在超出可入库数量的物料,请检查') return } const toQualityCheck = arrivalData.filter(item => item.需要质检 === true) @@ -1538,6 +1690,7 @@ export default { type: 'success', duration: 3000 }) + this.createArrivalLabel(response.data[0], arrivalData) this.searchLeftTable() this.dialogFormVisible4 = false } else { @@ -1551,6 +1704,57 @@ export default { this.dialogFormVisible4 = false this.$message.warning('已取消') }, + // 修改人:Ld 修改时间:2026-09-03 14:37:23; 生成前端入库标签二维码,暂用现有入库单号和合同号承载扫码内容。 + createArrivalLabel(result, arrivalData) { + var inboundNo = result.入库单号 || this.入库单号 || '' + var batchNo = result.批次号 || result.批次编号 || inboundNo + // 修改人:Ld 修改时间:2026-09-03 14:56:40; 后端返回标签二维码内容后优先使用后端值,兼容未部署后端时的前端占位内容。 + var qrContent = result.二维码内容 || JSON.stringify({ + type: 'purchaseInbound', + 标签ID: result.标签ID || '', + 标签编号: result.标签编号 || '', + 入库单号: inboundNo, + 采购合同号: this.arrivalContractLabel, + 批次号: batchNo + }) + QRCode.toDataURL(qrContent, { margin: 1, width: 150 }).then(url => { + this.arrivalLabelInfo = { + 采购合同号: this.arrivalContractLabel, + 供应商: this.arrivalSupplierLabel, + 批次号: batchNo, + 入库单号: inboundNo, + 二维码: url, + 明细: arrivalData.map(item => ({ + 物料名称: item.物料名称 || item.采购件 || '', + 图号: item.图号或型号 || item.图号 || '', + 数量: item.到货数量 + })) + } + this.arrivalLabelVisible = true + }).catch(() => { + this.$message.error('二维码生成失败') + }) + }, + // 修改人:Ld 修改时间:2026-09-03 14:37:23; 使用隐藏iframe打印入库单标签,避免影响当前页面显示状态。 + printArrivalLabel() { + const htmlNode = $('#purchaseInboundLabel').html() + const printFrame = document.createElement('iframe') + printFrame.style.position = 'fixed' + printFrame.style.right = '0' + printFrame.style.bottom = '0' + printFrame.style.width = '0' + printFrame.style.height = '0' + printFrame.style.border = '0' + document.body.appendChild(printFrame) + const printWindow = printFrame.contentWindow + const printDocument = printWindow.document + printDocument.open() + printDocument.write('入库单标签' + htmlNode + '') + printDocument.close() + printWindow.focus() + printWindow.print() + document.body.removeChild(printFrame) + }, showHistoryPrice(row) { var param = [] param[0] = ['采购合同流水号', row.采购合同流水号] @@ -1648,4 +1852,82 @@ a { display: inline-block; color: #999; } + +/* 修改人:Ld 修改时间:2026-09-03 14:37:23; 当前合同入库弹窗和标签预览样式。 */ +.arrival-current-contract { + display: flex; + align-items: center; + margin-bottom: 10px; + padding: 10px; + border: 1px solid #dcdfe6; + border-radius: 4px; + background: #f5f7fa; + font-size: 14px; +} + +.arrival-current-contract span { + color: #606266; +} + +.arrival-current-contract strong { + color: #303133; +} + +.purchase-inbound-label { + width: 360px; + margin: 0 auto; + padding: 12px; + border: 1px solid #303133; + color: #303133; + font-family: Arial, "Microsoft YaHei", sans-serif; +} + +.label-title { + margin-bottom: 10px; + text-align: center; + font-size: 18px; + font-weight: bold; +} + +.label-body { + display: flex; + align-items: center; + justify-content: space-between; +} + +.label-info { + max-width: 220px; + font-size: 12px; + line-height: 1.8; +} + +.label-info span { + display: inline-block; + width: 70px; + color: #606266; +} + +.label-info strong { + display: inline-block; + max-width: 140px; + overflow: hidden; + color: #303133; + font-size: 13px; + text-overflow: ellipsis; + vertical-align: top; + white-space: nowrap; +} + +.label-qrcode { + width: 120px; + height: 120px; +} + +.label-detail { + margin-top: 8px; + padding-top: 8px; + border-top: 1px solid #dcdfe6; + font-size: 11px; + line-height: 1.6; +} diff --git a/src/views/SalesManagement/SalesPerformance/index.vue b/src/views/SalesManagement/SalesPerformance/index.vue index 9494bfec..fd130fef 100644 --- a/src/views/SalesManagement/SalesPerformance/index.vue +++ b/src/views/SalesManagement/SalesPerformance/index.vue @@ -52,9 +52,13 @@ @click="exportExcel">导出 + - + + {{ formatMoney(scope.row.合同金额) }} - + {{ formatMoney(scope.row.累计回款金额) }} - + {{ formatMoney(scope.row.本月回款金额) }} @@ -105,7 +110,7 @@ {{ formatPercent(scope.row.提成比例) }} - + {{ formatMoney(scope.row.本月绩效金额) }} @@ -179,6 +184,7 @@ export default { this.ExecDatabase(Data).then(response => { this.tableData = response.data || [] this.loading = false + this.refreshTableLayout() }).catch(() => { this.loading = false this.$message.error('销售绩效查询失败') @@ -216,14 +222,45 @@ export default { handleSizeChanges(val) { this.pageSize = val this.pageCurrent = 1 + this.refreshTableLayout() }, handleCurrentChanges(val) { this.pageCurrent = val + this.refreshTableLayout() }, formatMoney(value) { const num = Number(value || 0) return num.toFixed(2) }, + getSummaries(param) { + // 修改人:Ld 修改时间:2026-09-11 14:05:14; 表格底部仅汇总合同金额、累计回款金额、本月回款金额、本月绩效金额。 + const summaryFields = ['合同金额', '累计回款金额', '本月回款金额', '本月绩效金额'] + const sums = [] + param.columns.forEach((column, index) => { + if (column.type === 'index') { + sums[index] = '合计' + return + } + if (summaryFields.indexOf(column.property) === -1) { + sums[index] = '' + return + } + const total = this.tableData.reduce((sum, row) => { + const value = Number(row[column.property]) + return sum + (isNaN(value) ? 0 : value) + }, 0) + sums[index] = this.formatMoney(total) + }) + return sums + }, + refreshTableLayout() { + // 修改人:Ld 修改时间:2026-09-11 14:14:13; 数据加载和分页切换后刷新表格布局,保证汇总行默认显示。 + this.$nextTick(() => { + if (this.$refs.performanceTable) { + this.$refs.performanceTable.doLayout() + } + }) + }, formatPercent(value) { const num = Number(value || 0) return num.toFixed(2) + '%' diff --git a/src/views/SeikoWorkshop/ProductionCompletionAudit/index.vue b/src/views/SeikoWorkshop/ProductionCompletionAudit/index.vue index e0244572..dda7f33d 100644 --- a/src/views/SeikoWorkshop/ProductionCompletionAudit/index.vue +++ b/src/views/SeikoWorkshop/ProductionCompletionAudit/index.vue @@ -3,6 +3,14 @@ + + 查看 + 通过 + { - this.tableData = response.data.rows || [] + this.tableData = (response.data.rows || []).map(row => { + // 修改人:Ld 修改时间:2026-08-20 13:20:11; 加工完成记录默认按计时显示和提交 + if (row && row.审核类型 === '加工完成' && !row.计价方式) { + row.计价方式 = '计时' + } + return row + }) this.total = Number(response.data.total || 0) }).catch(() => { this.tableData = [] @@ -315,6 +345,8 @@ export default { }, resetForm() { this.searchForm = { + // 生产审核添加订单号查询 修改人:Ld 修改时间:2026-08-11 10:08:01; + 订单号: '', 操作者: '', 审核类型: '', 审核状态: '待审核' @@ -393,7 +425,8 @@ export default { 审核类型: row.审核类型, // 保留 0 完成数量,避免审核修改弹窗将 0 自动改成 1;修改人:Ld 修改时间:2026-07-15 10:06:11; 完成数量: row.完成数量 === null || row.完成数量 === undefined || row.完成数量 === '' ? 1 : Number(row.完成数量), - 计价方式: row.计价方式 || '计件', + // 修改人:Ld 修改时间:2026-08-20 13:20:11; 计价方式默认选项改为计时 + 计价方式: row.计价方式 || '计时', 加工开始时间: row.开始时间 || '', 加工完成时间: row.结束时间 || '', 整修开始时间: row.开始时间 || '', @@ -443,6 +476,8 @@ export default { param[1] = ['审核状态', state] param[2] = ['审核人', this.id] param[3] = ['审核意见', opinion] + // 修改人:Ld 修改时间:2026-08-20 13:20:11; 传入角色编号供后端区分系统管理员重审 + param[4] = ['角色编号', this.token] if (editData && editData.finishQuantity !== undefined) { // 仅修改数量通过时传审核完成数量,普通通过只改审核状态。修改人:Ld 修改时间:2026-07-17 09:10:08; param.push(['审核完成数量', editData.finishQuantity]) diff --git a/src/views/SeikoWorkshop/ProductionPlan/index.vue b/src/views/SeikoWorkshop/ProductionPlan/index.vue index df678ebc..4207f6cb 100644 --- a/src/views/SeikoWorkshop/ProductionPlan/index.vue +++ b/src/views/SeikoWorkshop/ProductionPlan/index.vue @@ -9,6 +9,18 @@ size="small" value-format="yyyy-M" placeholder="选择月"/> + + + {{ selectedDateRangeText }} @@ -25,7 +37,19 @@ 导出 - + + + + + 生产计划 + 销售合同计划 + 设备门牌看板 + + {{ currentPlanViewSummary }} + + + + {{ scope.$index + 1 }} @@ -39,12 +63,12 @@ - + {{ getProductionPlanContractNo(scope.row) }} - + {{ scope.row.MK订单编号 || scope.row.订单号 }} @@ -160,6 +184,93 @@ + + + + + + 合同/订单数 + {{ salesContractStats.total }} + + + + + 临期 + {{ salesContractStats.warning }} + + + + + 逾期 + {{ salesContractStats.overdue }} + + + + + 已完成 + {{ salesContractStats.completed }} + + + + + + + + {{ scope.row.风险状态 }} + + + + + + + + + + + + + + + + + + + + + {{ deviceDoorLoading ? '设备门牌看板:真实数据加载中...' : '设备门牌看板:当前显示 ' + displayDeviceDoorCards.length + ' 台设备,真实数据;每30分钟自动刷新;自动向下滚动轮播' }} + + 暂无设备生产队列 + + + + + + + + {{ card.deviceName }} + 后续队列:{{ card.queueCount }} 项 + + + + + {{ card.current.状态 === '生产中' ? '正在生产' : '当前任务' }} + {{ card.current.订单编号 }} + {{ card.current.零件名称 }} / {{ card.current.零件图号 }} + 工序:{{ card.current.当前工序 }} 完成率:{{ card.current.完成率 }} + + + 下一项 + {{ card.next ? card.next.订单编号 : '暂无下一项' }} + {{ card.next ? card.next.零件名称 + ' / ' + card.next.零件图号 : '当前设备暂无后续任务' }} + 计划:{{ card.next ? card.next.投产日期 + ' 至 ' + card.next.交货日期 : '-' }} + + 更新时间:{{ doorBoardUpdateTime }} + + + + + + @@ -233,56 +344,70 @@ 暂无后续已派工任务 - - - - 操作者 - - - {{ day.label }} + + + + {{ machineApsScaleText }} + + + + + + 操作者 + + + {{ tick.dateLabel }} + {{ tick.hourLabel }} + - - - - {{ person.name }} - 任务数:{{ person.tasks.length }} - - - - - - {{ task.订单号 }} - {{ task.零件名称 }} / {{ task.零件图号 }} - {{ task.工序顺序 }}-{{ task.工序 }} {{ task.数量 }}/{{ task.完成数 }} - {{ formatApsDateText(task.分配时间) }} 至 {{ formatApsDateText(task.精工期限) }} - + + + {{ person.name }} + 任务数:{{ person.tasks.length }} + + - {{ task.订单号 }} - {{ task.零件名称 }} / {{ task.工序 }} - {{ task.完成数 }} / {{ task.数量 }} - {{ formatApsDateText(task.精工期限) }} - - + v-for="tick in machineApsVisibleTicks" + :key="person.name + '_' + tick.key" + :style="{ left: tick.left + 'px' }" + class="machine-aps-grid-line"/> + + + {{ task.订单号 }} + {{ task.零件名称 }} / {{ task.零件图号 }} + {{ task.工序顺序 }}-{{ task.工序 }} {{ task.数量 }}/{{ task.完成数 }} + {{ formatApsDateTimeText(task.分配时间) }} 至 {{ formatApsDateTimeText(task.精工期限) }} + + + {{ task.订单号 }} + {{ task.零件名称 }} / {{ task.工序 }} + {{ task.完成数 }} / {{ task.数量 }} + {{ formatApsDateTimeText(task.精工期限) }} + + + @@ -300,12 +425,24 @@ export default { data() { return { monthValue: '', + // 修改人:Ld 修改时间:2026-09-10 08:09:11; 使用投产日期范围替代第几周筛选。 + planDateRange: [], orderNumberTypeValue: '', partNameValue: '', productNameValue: '', statusValue: '', loading: false, tableData2: [], + // 修改人:Ld 修改时间:2026-08-14 09:57:40; 默认显示生产计划。 + planViewMode: 'month', + // 修改人:Ld 修改时间:2026-08-13 15:55:13; 设备门牌看板使用缓存数组渲染,避免切换时计算属性异常导致无法进入看板。 + deviceDoorCardList: [], + // 修改人:Ld 修改时间:2026-08-21 15:35:39; 设备门牌看板加载真实后端数据时显示加载状态。 + deviceDoorLoading: false, + // 修改人:Ld 修改时间:2026-09-10 09:51:58; 设备门牌看板每半小时刷新一次,并按页自动轮播。 + deviceDoorRefreshTimer: null, + deviceDoorCarouselTimer: null, + deviceDoorRefreshInterval: 30 * 60 * 1000, processConfig: { maxProcessCount: 11, processNamePattern: 'OP0{index}0', @@ -327,8 +464,12 @@ export default { machineTaskData: [], // 修改人:Ld 修改时间:2026-08-04 09:16:54; APS排产弹窗的固定轴尺寸,保持展示稳定。 machineApsDayWidth: 88, + // 修改人:Ld 修改时间:2026-08-24 08:18:00; 当前状态甘特图按刻度比例缩放,0为小时级,越大每格跨度越大。 + machineApsHourWidth: 64, + machineApsScaleIndex: 0, machineApsPersonWidth: 118, - machineApsMaxDays: 60 + machineApsMaxDays: 60, + machineApsMaxHours: 720 } }, computed: { @@ -345,13 +486,103 @@ export default { var avg = Math.round(completed / this.tableData2.length * 100) return avg + '%' }, + selectedDateRangeText() { + if (!this.planDateRange || this.planDateRange.length < 2) return '' + return this.planDateRange[0] + ' 至 ' + this.planDateRange[1] + }, filteredTableData() { - if (!this.statusValue) return this.tableData2 + var data = this.tableData2 var val = this.statusValue - return this.tableData2.filter(function(row) { - return row.状态 === val + if (val) { + data = data.filter(function(row) { + return row.状态 === val + }) + } + if (this.planDateRange && this.planDateRange.length === 2) { + var self = this + // 修改人:Ld 修改时间:2026-09-10 08:09:11; 顶部时间范围筛选联动生产计划表格,只显示对应投产日期计划。 + data = data.filter(function(row) { + return self.isProductionPlanInDateRange(row, self.planDateRange) + }) + } + return data + }, + // 修改人:Ld 修改时间:2026-08-13 07:57:17; 当前视图顶部摘要,帮助用户快速理解筛选后数据范围。 + currentPlanViewSummary() { + if (this.planViewMode === 'sales') { + return '参考订单进度跟踪表字段:订单编号、交货日期、产品、规格、订单要求' + } + if (this.planViewMode === 'device') { + return '按设备显示当前生产和下一项生产' + } + return this.selectedDateRangeText ? '当前投产日期:' + this.selectedDateRangeText : '' + }, + // 修改人:Ld 修改时间:2026-08-13 07:57:17; 销售合同计划行按订单进度跟踪表字段从生产计划派生。 + salesContractRows() { + var self = this + return this.filteredTableData.map(function(row, index) { + var deliveryDate = self.parseProductionPlanDate(row.精工期限) + var riskStatus = self.getSalesRiskStatus(row, deliveryDate) + return { + 序号: index + 1, + 风险状态: riskStatus, + // 修改人:Ld 修改时间:2026-08-20 14:13:02; 销售合同计划订单编号优先显示关联合同编号,其次显示MK订单编号。 + 订单编号: self.getSalesContractPlanOrderNo(row), + 收货人: row.收货人 || '仓库', + 投产日期: self.formatPlanDate(row.投产时间), + 交货日期: self.formatPlanDate(row.精工期限), + 数量: row.计划数 || 0, + // 修改人:Ld 修改时间:2026-09-10 08:34:52; 销售合同计划产品名称内容使用部件名称,项目中部件名称通常由产品名称字段承载。 + 产品名称: row.部件名称 || row.产品名称 || '', + 规格型号: row.零件图号 || row.材料 || '', + 订单要求: row.订单要求 || row.零件名称 || '', + 下单人: row.下单人 || '', + // 修改人:Ld 修改时间:2026-09-10 08:34:52; 客户名称按买方名称展示,不再用收货人兜底。 + 客户名称: row.买方名称 || '', + _source: row + } + }).sort(function(a, b) { + var ad = self.parseProductionPlanDate(a.交货日期) + var bd = self.parseProductionPlanDate(b.交货日期) + if (!ad && !bd) return 0 + if (!ad) return 1 + if (!bd) return -1 + return ad.getTime() - bd.getTime() }) }, + salesContractStats() { + var stats = { total: this.salesContractRows.length, warning: 0, overdue: 0, completed: 0 } + this.salesContractRows.forEach(function(row) { + if (row.风险状态 === '临期') stats.warning++ + if (row.风险状态 === '逾期') stats.overdue++ + if (row.风险状态 === '已完成') stats.completed++ + }) + return stats + }, + doorBoardUpdateTime() { + var now = new Date() + return this.zeroFill(now.getHours()) + ':' + this.zeroFill(now.getMinutes()) + }, + // 修改人:Ld 修改时间:2026-08-21 15:35:39; 看板切换为真实数据展示,空数据时不返回静态卡片。 + // 修改人:Ld 修改时间:2026-08-22 10:21:36; 删除设备看板静态数据兜底,现场只允许显示真实接口数据。 + displayDeviceDoorCards() { + return this.deviceDoorCardList || [] + }, + // 修改人:Ld 修改时间:2026-09-10 10:15:47; 少量设备时补足滚动轨道高度,避免内容不溢出导致看板不动。 + scrollDeviceDoorCards() { + var cards = this.displayDeviceDoorCards + if (!cards || cards.length === 0) return [] + var result = [] + while (result.length < 9) { + result = result.concat(cards) + } + return result + }, + // 修改人:Ld 修改时间:2026-09-10 10:21:39; CSS轨道动画按行数计算时长,保证设备少和设备多时都有持续移动效果。 + deviceDoorScrollDuration() { + var rowCount = Math.ceil(this.scrollDeviceDoorCards.length / 3) + return Math.max(24, rowCount * 8) + }, monthCompletionRateTag() { var rate = parseInt(this.monthCompletionRate) || 0 if (rate === 100) return 'info' @@ -401,56 +632,95 @@ export default { } }, // 修改人:Ld 修改时间:2026-08-04 09:16:54; 根据已派工任务日期生成APS时间轴。 + // 修改人:Ld 修改时间:2026-08-24 08:05:00; 时间轴起点精确到小时,支持当前状态甘特图小时刻度。 machineApsStartDate() { var dates = [] this.machineTaskDisplayData.forEach(row => { - var startDate = this.parseApsDate(row.分配时间) - var endDate = this.parseApsDate(row.精工期限) + var startDate = this.parseApsDateTime(row.分配时间) + var endDate = this.parseApsDateTime(row.精工期限) if (startDate) dates.push(startDate) if (endDate) dates.push(endDate) }) - if (dates.length === 0) return this.clearApsDate(new Date()) + if (dates.length === 0) return this.clearApsHour(new Date()) dates.sort(function(a, b) { return a.getTime() - b.getTime() }) - return this.clearApsDate(dates[0]) + return this.clearApsHour(dates[0]) }, machineApsEndDate() { var startDate = this.machineApsStartDate var dates = [] this.machineTaskDisplayData.forEach(row => { - var start = this.parseApsDate(row.分配时间) - var end = this.parseApsDate(row.精工期限) + var start = this.parseApsDateTime(row.分配时间) + var end = this.parseApsDateTime(row.精工期限) if (start) dates.push(start) if (end) dates.push(end) }) - if (dates.length === 0) return this.addApsDays(startDate, 6) + if (dates.length === 0) return this.addApsHours(startDate, 72) dates.sort(function(a, b) { return b.getTime() - a.getTime() }) - var endDate = this.clearApsDate(dates[0]) - var diffDays = this.getApsDayDiff(startDate, endDate) - if (diffDays > this.machineApsMaxDays - 1) { - return this.addApsDays(startDate, this.machineApsMaxDays - 1) + var endDate = this.ceilApsHour(dates[0]) + var diffHours = this.getApsHourDiff(startDate, endDate) + if (diffHours > this.machineApsMaxHours) { + return this.addApsHours(startDate, this.machineApsMaxHours) } return endDate }, - machineApsDays() { - var days = [] - var totalDays = this.getApsDayDiff(this.machineApsStartDate, this.machineApsEndDate) + 1 - if (totalDays < 7) totalDays = 7 - for (let i = 0; i < totalDays; i++) { - var date = this.addApsDays(this.machineApsStartDate, i) - days.push({ - key: this.formatApsDateKey(date), - label: this.formatApsDateKey(date), - left: i * this.machineApsDayWidth + machineApsTotalHours() { + return Math.max(24, this.getApsHourDiff(this.machineApsStartDate, this.machineApsEndDate)) + }, + machineApsScaleOptions() { + return [ + { label: '1小时/格', hours: 1 }, + { label: '2小时/格', hours: 2 }, + { label: '4小时/格', hours: 4 }, + { label: '8小时/格', hours: 8 }, + { label: '12小时/格', hours: 12 }, + { label: '1天/格', hours: 24 }, + { label: '2天/格', hours: 48 }, + { label: '3天/格', hours: 72 }, + { label: '1周/格', hours: 168 }, + { label: '半个月/格', hours: 360 } + ] + }, + machineApsScaleMax() { + return this.machineApsScaleOptions.length - 1 + }, + machineApsScale() { + var index = Number(this.machineApsScaleIndex) || 0 + if (index < 0) index = 0 + if (index > this.machineApsScaleMax) index = this.machineApsScaleMax + return this.machineApsScaleOptions[index] + }, + machineApsTickHours() { + return this.machineApsScale.hours + }, + machineApsPxPerHour() { + return this.machineApsHourWidth / this.machineApsTickHours + }, + machineApsScaleText() { + return '时间刻度:' + this.machineApsScale.label + }, + machineApsVisibleTicks() { + var ticks = [] + var tickHours = this.machineApsTickHours + var totalHours = this.machineApsTotalHours + for (let i = 0; i <= totalHours; i += tickHours) { + var date = this.addApsHours(this.machineApsStartDate, i) + var left = i * this.machineApsPxPerHour + ticks.push({ + key: this.formatApsDateTimeKey(date), + dateLabel: this.formatMachineApsTickDate(date, tickHours, i), + hourLabel: this.formatMachineApsTickHour(date, tickHours), + isDayStart: date.getHours() === 0, + left: left }) } - return days + return ticks }, machineApsTimelineWidth() { - return this.machineApsDays.length * this.machineApsDayWidth + return Math.max(this.machineApsHourWidth, this.machineApsTotalHours * this.machineApsPxPerHour + this.machineApsHourWidth) }, machineApsInnerWidth() { return this.machineApsPersonWidth + this.machineApsTimelineWidth @@ -461,19 +731,17 @@ export default { this.machineTaskDisplayData.forEach((row, index) => { var personName = row.姓名 || '未指定' if (!grouped[personName]) grouped[personName] = [] - var startDate = this.parseApsDate(row.分配时间) || this.parseApsDate(row.精工期限) || this.addApsDays(this.machineApsStartDate, index) - var endDate = this.parseApsDate(row.精工期限) || startDate + var startDate = this.parseApsDateTime(row.分配时间) || this.parseApsDateTime(row.精工期限) || this.addApsHours(this.machineApsStartDate, index) + var endDate = this.parseApsDateTime(row.精工期限) || startDate if (endDate.getTime() < startDate.getTime()) endDate = startDate - var leftDays = this.getApsDayDiff(this.machineApsStartDate, this.clearApsDate(startDate)) - var durationDays = this.getApsDayDiff(this.clearApsDate(startDate), this.clearApsDate(endDate)) + 1 - if (leftDays < 0) leftDays = 0 - if (leftDays > this.machineApsDays.length - 1) leftDays = this.machineApsDays.length - 1 - if (leftDays + durationDays > this.machineApsDays.length) durationDays = this.machineApsDays.length - leftDays - if (durationDays < 1) durationDays = 1 + var leftHours = this.getApsHourDiff(this.machineApsStartDate, this.clearApsHour(startDate)) + var endHours = this.getApsHourDiff(this.machineApsStartDate, this.ceilApsHour(endDate)) + var durationHours = endHours - leftHours + if (durationHours < 1) durationHours = 1 grouped[personName].push(Object.assign({}, row, { _apsKey: personName + '_' + index + '_' + row.工艺任务流水号, - _apsLeft: leftDays * this.machineApsDayWidth + 4, - _apsWidth: durationDays * this.machineApsDayWidth - 8, + _apsLeft: leftHours * this.machineApsPxPerHour + 4, + _apsWidth: Math.max(60, durationHours * this.machineApsPxPerHour - 8), _apsTop: 8 + grouped[personName].length * 58, _apsColorClass: colorClasses[index % colorClasses.length] })) @@ -490,26 +758,324 @@ export default { machineTaskDisplayData() { var today = this.clearApsDate(new Date()) return this.machineTaskData.filter(row => { - var rowStart = this.parseApsDate(row.分配时间) || this.parseApsDate(row.精工期限) - var rowEnd = this.parseApsDate(row.精工期限) || rowStart + var rowStart = this.parseApsDateTime(row.分配时间) || this.parseApsDateTime(row.精工期限) + var rowEnd = this.parseApsDateTime(row.精工期限) || rowStart if (!rowStart) return false if (!rowEnd) rowEnd = rowStart return this.clearApsDate(rowEnd).getTime() >= today.getTime() }).sort((a, b) => { - var aDate = this.parseApsDate(a.分配时间) || this.parseApsDate(a.精工期限) || today - var bDate = this.parseApsDate(b.分配时间) || this.parseApsDate(b.精工期限) || today - return this.clearApsDate(aDate).getTime() - this.clearApsDate(bDate).getTime() + var aDate = this.parseApsDateTime(a.分配时间) || this.parseApsDateTime(a.精工期限) || today + var bDate = this.parseApsDateTime(b.分配时间) || this.parseApsDateTime(b.精工期限) || today + return aDate.getTime() - bDate.getTime() }) } }, + watch: { + monthValue() { + // 修改人:Ld 修改时间:2026-09-10 08:09:11; 切换月份后清空投产日期范围,避免日期范围与月份查询条件冲突。 + this.planDateRange = [] + }, + // 修改人:Ld 修改时间:2026-08-21 16:03:00; 监听视图切换,确保进入设备门牌看板时一定触发真实数据查询。 + planViewMode: function(val) { + if (val === 'device') { + // 修改人:Ld 修改时间:2026-09-10 09:51:58; 进入设备门牌看板时启动半小时刷新和轮播。 + this.startDeviceDoorAutoRefresh() + this.startDeviceDoorCarousel() + this.fetchDeviceDoorCards() + } else { + this.stopDeviceDoorTimers() + } + } + }, created() { this.getNowMonth() this.searchTable1() }, beforeDestroy() { + // 修改人:Ld 修改时间:2026-09-10 09:51:58; 组件销毁时清理设备门牌看板定时器,避免后台继续刷新。 + this.stopDeviceDoorTimers() this.disposeCharts() }, methods: { + // 修改人:Ld 修改时间:2026-08-14 08:24:39; 本组件补齐数字补零方法,避免设备门牌更新时间渲染时报错。 + zeroFill(value) { + var num = Number(value) || 0 + return num < 10 ? '0' + num : String(num) + }, + // 修改人:Ld 修改时间:2026-08-13 15:45:42; 顶部视图标签统一通过方法切换,保证设备门牌看板可以被明确激活。 + switchPlanView(viewMode) { + this.planViewMode = viewMode + if (viewMode === 'device') { + // 修改人:Ld 修改时间:2026-09-10 09:51:58; 手动切入设备门牌看板时同步启动自动刷新和轮播。 + this.startDeviceDoorAutoRefresh() + this.startDeviceDoorCarousel() + // 修改人:Ld 修改时间:2026-08-21 16:03:00; 视图渲染完成后再补触发一次,避免缓存页面未进入watch链路。 + this.$nextTick(function() { + this.refreshDeviceDoorCards() + }) + } else { + this.stopDeviceDoorTimers() + } + // 修改人:Ld 修改时间:2026-08-13 15:51:04; 手动触发一次刷新,避免缓存页面中视图状态已变但看板区域未重绘。 + this.$forceUpdate() + }, + // 修改人:Ld 修改时间:2026-08-13 15:55:13; 显式刷新设备门牌看板缓存数据,保证切换设备视图时有稳定数据可渲染。 + // 修改人:Ld 修改时间:2026-08-21 15:35:39; 设备门牌看板改为调用后端真实队列数据。 + refreshDeviceDoorCards() { + this.fetchDeviceDoorCards() + }, + // 修改人:Ld 修改时间:2026-09-10 09:51:58; 设备门牌看板每30分钟刷新一次真实队列数据。 + startDeviceDoorAutoRefresh() { + if (this.deviceDoorRefreshTimer) return + this.deviceDoorRefreshTimer = setInterval(() => { + if (this.planViewMode === 'device') { + this.fetchDeviceDoorCards() + } + }, this.deviceDoorRefreshInterval) + }, + // 修改人:Ld 修改时间:2026-09-10 10:21:39; 轮播改由CSS轨道动画实现,这里只在切入看板时触发视图刷新。 + startDeviceDoorCarousel() { + this.$nextTick(function() { + this.$forceUpdate() + }) + }, + // 修改人:Ld 修改时间:2026-09-10 09:51:58; 离开设备门牌看板或销毁组件时统一清理刷新和轮播定时器。 + stopDeviceDoorTimers() { + if (this.deviceDoorRefreshTimer) { + clearInterval(this.deviceDoorRefreshTimer) + this.deviceDoorRefreshTimer = null + } + if (this.deviceDoorCarouselTimer) { + clearInterval(this.deviceDoorCarouselTimer) + this.deviceDoorCarouselTimer = null + } + }, + // 修改人:Ld 修改时间:2026-08-21 15:35:39; 从测试库已同步的设备门牌过程读取真实设备队列。 + fetchDeviceDoorCards() { + if (this.deviceDoorLoading) return + var param = [] + param[0] = ['设备流水号', ''] + param[1] = ['设备流水号_check', 0] + param[2] = ['仅未完成', 1] + var Data = this.CreateData('11', '车间生产管理_设备门牌看板_查询数据', param) + // 修改人:Ld 修改时间:2026-08-21 16:03:00; 保留请求日志,便于现场确认已调用真实存储过程。 + console.log('设备门牌看板调用存储过程:', Data) + this.deviceDoorLoading = true + this.ExecDatabase(Data).then(response => { + var rows = response && response.data ? response.data : [] + this.deviceDoorCardList = this.buildDeviceDoorCardsFromRows(rows) + // 修改人:Ld 修改时间:2026-09-10 10:01:36; 刷新后从顶部重新开始整体滚动轮播。 + this.$nextTick(function() { + if (this.$refs.deviceDoorScrollBody) this.$refs.deviceDoorScrollBody.scrollTop = 0 + this.$forceUpdate() + }) + this.deviceDoorLoading = false + }).catch(() => { + this.deviceDoorCardList = [] + this.$nextTick(function() { + if (this.$refs.deviceDoorScrollBody) this.$refs.deviceDoorScrollBody.scrollTop = 0 + this.$forceUpdate() + }) + this.deviceDoorLoading = false + this.$message.error('设备门牌真实数据加载失败') + }) + }, + // 修改人:Ld 修改时间:2026-08-21 15:35:39; 将后端设备队列行按设备整理成门牌卡片。 + buildDeviceDoorCardsFromRows(rows) { + var self = this + var grouped = {} + if (!rows || !rows.length) return [] + rows.forEach(function(row) { + if (!row || !row.设备) return + if (!grouped[row.设备]) grouped[row.设备] = [] + grouped[row.设备].push(self.buildDoorTaskFromBackend(row)) + }) + return Object.keys(grouped).map(function(deviceName) { + var tasks = grouped[deviceName].sort(function(a, b) { + return (a.设备队列序号 || 9999) - (b.设备队列序号 || 9999) + }) + var current = tasks[0] || self.getEmptyDoorTask(deviceName) + var next = tasks[1] || null + return { + deviceName: deviceName, + current: current, + next: next, + queueCount: Math.max(tasks.length - 1, 0), + isSample: false, + stateClass: current.状态 === '生产中' ? 'state-running' : current.状态 === '已完成' ? 'state-done' : 'state-wait' + } + }) + }, + // 修改人:Ld 修改时间:2026-08-21 15:35:39; 统一后端设备门牌字段为模板展示字段。 + buildDoorTaskFromBackend(row) { + row = row || {} + var quantity = Number(row.数量) || 0 + var completeCount = Number(row.完成数) || 0 + var percent = quantity > 0 ? Math.min(100, Math.max(0, Math.round(completeCount / quantity * 100))) + '%' : '0%' + return { + 订单编号: row.订单号 || '', + 零件名称: row.零件名称 || '', + 零件图号: row.零件图号 || '', + 当前工序: row.工序 || '', + 投产日期: this.formatPlanDateTime(row.计划开始时间 || row.分配时间), + 交货日期: this.formatPlanDateTime(row.精工期限), + 完成率: percent, + 状态: row.门牌状态 || row.工序状态 || '', + 设备: row.设备 || '', + 设备队列序号: Number(row.设备队列序号) || 0, + _source: row + } + }, + // 修改人:Ld 修改时间:2026-08-13 15:55:13; 将设备任务分组转换为门牌卡片,模板只读取已整理好的稳定字段。 + convertDeviceTaskGroups(grouped, isSample) { + var self = this + return Object.keys(grouped).map(function(deviceName) { + var tasks = grouped[deviceName].sort(function(a, b) { + var ad = self.parseProductionPlanDate(a.交货日期) || new Date(2099, 0, 1) + var bd = self.parseProductionPlanDate(b.交货日期) || new Date(2099, 0, 1) + return ad.getTime() - bd.getTime() + }) + var current = null + for (var taskIndex = 0; taskIndex < tasks.length; taskIndex++) { + if (tasks[taskIndex].状态 === '生产中') { + current = tasks[taskIndex] + break + } + } + current = current || tasks[0] || self.getEmptyDoorTask(deviceName) + var next = null + for (var nextIndex = 0; nextIndex < tasks.length; nextIndex++) { + if (tasks[nextIndex] !== current) { + next = tasks[nextIndex] + break + } + } + return { + deviceName: deviceName, + current: current, + next: next, + queueCount: Math.max(tasks.length - 1, 0), + isSample: isSample, + stateClass: current.状态 === '已完成' ? 'state-done' : current.状态 === '生产中' ? 'state-running' : 'state-wait' + } + }) + }, + // 修改人:Ld 修改时间:2026-08-13 15:55:13; 构造空任务兜底对象,避免设备门牌模板访问 current 字段时报错。 + getEmptyDoorTask(deviceName) { + return { + 订单编号: '暂无任务', + 零件名称: deviceName, + 零件图号: '', + 当前工序: '', + 投产日期: '', + 交货日期: '', + 完成率: '0%', + 状态: '待生产', + _source: { 设备: deviceName } + } + }, + // 修改人:Ld 修改时间:2026-08-12 08:06:45; 解析生产计划月份,用于兼容历史月份工具方法。 + getMonthDateInfo(monthValue) { + if (!monthValue) return null + var parts = String(monthValue).split('-') + if (parts.length < 2) return null + var year = parseInt(parts[0], 10) + var month = parseInt(parts[1], 10) + if (isNaN(year) || isNaN(month) || month < 1 || month > 12) return null + return { + year: year, + month: month, + lastDay: new Date(year, month, 0).getDate() + } + }, + parseProductionPlanDate(value) { + if (!value) return null + var text = String(value).replace(/\//g, '-') + if (text.length > 10) text = text.substring(0, 10) + var parts = text.split('-') + if (parts.length < 3) return null + var year = parseInt(parts[0], 10) + var month = parseInt(parts[1], 10) + var day = parseInt(parts[2], 10) + if (isNaN(year) || isNaN(month) || isNaN(day)) return null + return new Date(year, month - 1, day) + }, + isProductionPlanInDateRange(row, dateRange) { + if (!row || !dateRange || dateRange.length < 2) return false + var productionDate = this.parseProductionPlanDate(row.投产时间) + if (!productionDate) return false + var startDate = this.parseProductionPlanDate(dateRange[0]) + var endDate = this.parseProductionPlanDate(dateRange[1]) + if (!startDate || !endDate) return false + var dateTime = productionDate.getTime() + return dateTime >= startDate.getTime() && dateTime <= endDate.getTime() + }, + // 修改人:Ld 修改时间:2026-08-13 07:57:17; 统一生产计划视图中状态标签颜色。 + getPlanStatusTag(status) { + if (status === '已完成') return 'info' + if (status === '生产中') return 'success' + return '' + }, + getSalesRiskTag(status) { + if (status === '已完成') return 'info' + if (status === '逾期') return 'danger' + if (status === '临期') return 'warning' + if (status === '无计划') return 'danger' + return 'success' + }, + getSalesRiskStatus(row, deliveryDate) { + if (row && row.状态 === '已完成') return '已完成' + if (!deliveryDate) return '无计划' + var today = this.clearApsDate(new Date()) + var diff = this.getApsDayDiff(today, deliveryDate) + if (diff < 0) return '逾期' + if (diff <= 7) return '临期' + return '正常' + }, + formatPlanDate(value) { + if (!value) return '' + var date = this.parseProductionPlanDate(value) + if (!date) return String(value) + return this.zeroFill(date.getMonth() + 1) + '.' + this.zeroFill(date.getDate()) + }, + // 修改人:Ld 修改时间:2026-08-21 15:35:39; 设备门牌真实计划时间显示到小时分钟。 + formatPlanDateTime(value) { + if (!value) return '' + var text = String(value).replace(/\//g, '-') + var dateText = text.substring(0, 10) + var timeText = text.length >= 16 ? text.substring(11, 16) : '' + var date = this.parseProductionPlanDate(dateText) + if (!date) return text + return this.zeroFill(date.getMonth() + 1) + '.' + this.zeroFill(date.getDate()) + (timeText ? ' ' + timeText : '') + }, + buildDoorTask(row) { + row = row || {} + return { + 订单编号: this.getProductionPlanContractNo(row), + 零件名称: row.零件名称 || '', + 零件图号: row.零件图号 || '', + 当前工序: this.getCurrentProcessName(row), + 投产日期: this.formatPlanDate(row.投产时间), + 交货日期: this.formatPlanDate(row.精工期限), + 完成率: row.完成率 || '0%', + 状态: row.状态 || '', + 设备: row.设备 || '', + // 修改人:Ld 修改时间:2026-08-13 15:55:13; 门牌任务保留设备字段,点击打开后续任务弹窗时可直接使用。 + _source: row._source || row + } + }, + getCurrentProcessName(row) { + if (!row) return '' + for (let i = 1; i <= this.processConfig.maxProcessCount; i++) { + var opKey = this.processConfig.processNamePattern.replace('{index}', i) + if (row._producingOpMap && row._producingOpMap[opKey]) return row[opKey] + } + for (let j = 1; j <= this.processConfig.maxProcessCount; j++) { + var key = this.processConfig.processNamePattern.replace('{index}', j) + if (row[key]) return row[key] + } + return '' + }, getNowMonth() { const nowDate = new Date() const date = { @@ -543,6 +1109,10 @@ export default { const groupedData = this.groupByOrder(rows) console.log('分组后数据:', groupedData) this.tableData2 = groupedData + if (this.planViewMode === 'device') { + // 修改人:Ld 修改时间:2026-08-13 15:55:13; 查询刷新后同步重建设备门牌缓存数据。 + this.refreshDeviceDoorCards() + } }) } else { this.$message.warning('月份不能为空') @@ -565,8 +1135,15 @@ export default { 关联合同编号: item.关联合同编号, 收货人: item.MK订单收货人, 产品名称: item.产品名称, + // 修改人:Ld 修改时间:2026-09-10 08:34:52; 保留销售合同计划需要的部件名称和买方名称字段。 + 部件名称: item.部件名称 || item.零件名称 || '', + 买方名称: item.买方名称 || item.客户名称 || '', 零件名称: item.零件名称, 零件图号: item.零件图号, + 订单要求: item.订单要求 || item.备注 || item.MK订单备注 || '', + 下单人: item.下单人 || item.销售员 || '', + 客户名称: item.客户名称 || '', + MK订单收货人: item.MK订单收货人, 订单数: item.订单数, 计划数: item.计划数, 剩余数: item.剩余数, @@ -631,6 +1208,20 @@ export default { if (!row) return '' return row.关联合同编号 || row.合同编号 || row.MK订单编号 || row.订单号 || '' }, + // 修改人:Ld 修改时间:2026-08-20 14:13:02; 销售合同计划订单编号不取普通合同编号,避免覆盖MK订单编号。 + getSalesContractPlanOrderNo(row) { + if (!row) return '' + return row.关联合同编号 || row.MK订单编号 || row.订单号 || '' + }, + // 修改人:Ld 修改时间:2026-08-13 09:49:08; 设备门牌卡片点击增加设备名兜底。 + // 修改人:Ld 修改时间:2026-08-22 10:21:36; 删除静态卡片分支,点击只打开真实设备后续任务。 + openDeviceDoorCard(card) { + if (!card || !card.deviceName) { + this.$message.warning('当前设备门牌暂无设备信息') + return + } + this.openMachineTaskDialog(card.current && card.current._source ? card.current._source : { 设备: card.deviceName }) + }, // 修改人:Ld 修改时间:2026-08-04 09:07:29; 复用工况分页查询,按当前机床查看后续未完成的已派工任务。 openMachineTaskDialog(row) { if (!row || !row.设备) { @@ -666,7 +1257,12 @@ export default { } else { this.machineTaskData = [] } - }).finally(() => { + // 修改人:Ld 修改时间:2026-08-24 08:18:00; 任务加载完成后重置甘特图刻度比例,默认按小时查看。 + this.$nextTick(function() { + this.resetMachineApsScale() + }) + this.machineTaskLoading = false + }).catch(() => { this.machineTaskLoading = false }) }, @@ -695,29 +1291,98 @@ export default { if (isNaN(year) || isNaN(month) || isNaN(day)) return null return new Date(year, month - 1, day) }, + // 修改人:Ld 修改时间:2026-08-24 08:05:00; APS甘特图解析完整日期时间,使当前状态弹窗可显示到小时。 + parseApsDateTime(value) { + if (!value) return null + var text = String(value).replace(/\//g, '-') + var parts = text.split(' ') + var dateParts = parts[0].split('-') + if (dateParts.length < 3) return null + var year = parseInt(dateParts[0], 10) + var month = parseInt(dateParts[1], 10) + var day = parseInt(dateParts[2], 10) + var hour = 0 + var minute = 0 + if (parts.length > 1) { + var timeParts = parts[1].split(':') + hour = parseInt(timeParts[0], 10) + minute = parseInt(timeParts[1], 10) + } + if (isNaN(year) || isNaN(month) || isNaN(day)) return null + if (isNaN(hour)) hour = 0 + if (isNaN(minute)) minute = 0 + return new Date(year, month - 1, day, hour, minute) + }, clearApsDate(date) { if (!date) return null return new Date(date.getFullYear(), date.getMonth(), date.getDate()) }, + clearApsHour(date) { + if (!date) return null + return new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours()) + }, + ceilApsHour(date) { + if (!date) return null + var result = this.clearApsHour(date) + if (date.getMinutes() > 0 || date.getSeconds() > 0 || date.getMilliseconds() > 0) { + result.setHours(result.getHours() + 1) + } + return result + }, addApsDays(date, days) { var result = this.clearApsDate(date) result.setDate(result.getDate() + days) return result }, + addApsHours(date, hours) { + var result = this.clearApsHour(date) + result.setHours(result.getHours() + hours) + return result + }, getApsDayDiff(startDate, endDate) { if (!startDate || !endDate) return 0 var oneDay = 24 * 60 * 60 * 1000 return Math.round((this.clearApsDate(endDate).getTime() - this.clearApsDate(startDate).getTime()) / oneDay) }, + getApsHourDiff(startDate, endDate) { + if (!startDate || !endDate) return 0 + var oneHour = 60 * 60 * 1000 + return Math.round((this.clearApsHour(endDate).getTime() - this.clearApsHour(startDate).getTime()) / oneHour) + }, + // 修改人:Ld 修改时间:2026-08-24 08:18:00; 控制条默认回到小时刻度,用户可缩小到天、两天、三天。 + resetMachineApsScale() { + this.machineApsScaleIndex = 0 + }, formatApsDateKey(date) { if (!date) return '' return date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate() }, + formatApsDateTimeKey(date) { + if (!date) return '' + return this.formatApsDateKey(date) + ' ' + this.zeroFill(date.getHours()) + ':00' + }, formatApsDateText(value) { var date = this.parseApsDate(value) if (!date) return '' return this.formatApsDateKey(date) }, + formatApsDateTimeText(value) { + var date = this.parseApsDateTime(value) + if (!date) return '' + return this.formatApsDateKey(date) + ' ' + this.zeroFill(date.getHours()) + ':' + this.zeroFill(date.getMinutes()) + }, + // 修改人:Ld 修改时间:2026-08-24 08:18:00; 根据缩放比例显示刻度日期,天级以上每格都显示日期。 + formatMachineApsTickDate(date, tickHours, hourIndex) { + if (!date) return '' + if (tickHours >= 24) return this.formatApsDateKey(date) + if (date.getHours() === 0 || hourIndex === 0) return this.formatApsDateKey(date) + return '' + }, + formatMachineApsTickHour(date, tickHours) { + if (!date) return '' + if (tickHours >= 24) return tickHours / 24 + '天' + return this.zeroFill(date.getHours()) + ':00' + }, // 计算订单状态 calculateOrderStatus(group) { var rate = 0 @@ -1336,6 +2001,270 @@ export default { white-space: normal; } + /* 修改人:Ld 修改时间:2026-09-10 08:09:11; 日期范围筛选旁显示当前筛选时间,使用灰色小字弱提示。 */ + .date-range-tip { + display: inline-block; + margin-left: 6px; + color: #909399; + font-size: 12px; + vertical-align: middle; + } + + /* 修改人:Ld 修改时间:2026-08-13 07:57:17; 生产计划多视图切换与计划看板样式。 */ + .plan-view-switch { + display: flex; + align-items: center; + height: 36px; + margin-bottom: 8px; + border-bottom: 1px solid #EBEEF5; + } + + .plan-view-summary { + margin-left: 12px; + color: #606266; + font-size: 12px; + } + + /* 修改人:Ld 修改时间:2026-08-13 15:51:04; 原生视图标签样式,避免依赖 Element 按钮组件事件。 */ + .plan-view-tabs { + display: inline-flex; + align-items: center; + border: 1px solid #DCDFE6; + border-radius: 4px; + overflow: hidden; + background: #fff; + } + + .plan-view-tab { + display: inline-block; + min-width: 86px; + height: 30px; + padding: 0 12px; + border-right: 1px solid #DCDFE6; + color: #606266; + font-size: 12px; + line-height: 30px; + text-align: center; + cursor: pointer; + user-select: none; + box-sizing: border-box; + } + + .plan-view-tab:last-child { + border-right: none; + } + + .plan-view-tab.is-active { + color: #fff; + border-color: #409EFF; + background: #409EFF; + } + + .sales-plan-view { + height: 705px; + } + + .sales-plan-stat-row { + margin-bottom: 8px; + } + + .sales-stat { + height: 66px; + padding: 10px 12px; + border: 1px solid #DCDFE6; + border-radius: 4px; + box-sizing: border-box; + background: #fff; + } + + .sales-stat-label { + color: #606266; + font-size: 12px; + line-height: 18px; + } + + .sales-stat-value { + color: #303133; + font-size: 24px; + font-weight: bold; + line-height: 30px; + } + + .sales-stat-warning .sales-stat-value { + color: #E6A23C; + } + + .sales-stat-danger .sales-stat-value { + color: #F56C6C; + } + + .sales-stat-done .sales-stat-value { + color: #909399; + } + + .device-door-board { + display: flex; + flex-direction: column; + height: 705px; + padding: 10px; + overflow: hidden; + border: 1px solid #DCDFE6; + background: #F5F7FA; + box-sizing: border-box; + } + + /* 修改人:Ld 修改时间:2026-08-13 16:11:45; 设备门牌数据来源提示占满整行,便于现场确认真实数据已加载。 */ + .device-door-banner { + flex: none; + height: 32px; + padding: 0 12px; + border: 1px solid #B3D8FF; + border-radius: 4px; + color: #409EFF; + background: #ECF5FF; + font-size: 13px; + line-height: 32px; + box-sizing: border-box; + } + + /* 修改人:Ld 修改时间:2026-09-10 10:06:37; 设备门牌卡片区域独立滚动,轮播时持续匀速向下滚动。 */ + .device-door-scroll-body { + flex: 1; + min-height: 0; + margin-top: 10px; + overflow: hidden; + scroll-behavior: auto; + } + + /* 修改人:Ld 修改时间:2026-09-10 10:15:47; 两段轨道纵向排列,滚到第一段末尾后无缝回到顶部。 */ + .device-door-scroll-track { + min-height: 100%; + animation-name: deviceDoorContinuousScroll; + animation-timing-function: linear; + animation-iteration-count: infinite; + will-change: transform; + } + + /* 修改人:Ld 修改时间:2026-09-10 10:15:47; 固定三列避免宽屏横向铺满后没有纵向滚动空间。 */ + .device-door-card-grid { + display: grid; + padding-bottom: 10px; + grid-template-columns: repeat(3, minmax(0, 1fr)); + grid-auto-rows: 230px; + grid-gap: 10px; + } + + /* 修改人:Ld 修改时间:2026-09-10 10:21:39; 使用轨道位移动画实现看板持续滚动,不依赖滚动条状态。 */ + @keyframes deviceDoorContinuousScroll { + 0% { + transform: translateY(0); + } + + 100% { + transform: translateY(-50%); + } + } + + .device-door-empty { + grid-column: 1 / -1; + color: #909399; + font-size: 13px; + } + + .device-door-card { + padding: 12px; + border: 1px solid #D7E3EA; + border-radius: 4px; + background: #fff; + box-sizing: border-box; + cursor: pointer; + } + + .device-door-head { + display: flex; + justify-content: space-between; + align-items: center; + padding-bottom: 8px; + border-bottom: 1px solid #EBEEF5; + } + + .device-door-name { + overflow: hidden; + color: #303133; + font-size: 16px; + font-weight: bold; + line-height: 22px; + text-overflow: ellipsis; + white-space: nowrap; + } + + .device-door-sub, + .device-door-meta, + .device-door-foot { + color: #606266; + font-size: 12px; + line-height: 18px; + } + + .device-state-dot { + width: 14px; + height: 14px; + border-radius: 50%; + background: #C0C4CC; + } + + .state-running { + background: #67C23A; + } + + .state-wait { + background: #E6A23C; + } + + .state-done { + background: #909399; + } + + .device-door-section { + padding-top: 10px; + } + + .device-door-next { + margin-top: 4px; + padding-top: 8px; + border-top: 1px dashed #DCDFE6; + } + + .device-door-label { + color: #909399; + font-size: 12px; + line-height: 18px; + } + + .device-door-order { + overflow: hidden; + color: #1F2D3D; + font-size: 14px; + font-weight: bold; + line-height: 20px; + text-overflow: ellipsis; + white-space: nowrap; + } + + .device-door-part { + overflow: hidden; + color: #303133; + font-size: 13px; + line-height: 20px; + text-overflow: ellipsis; + white-space: nowrap; + } + + .device-door-foot { + margin-top: 8px; + text-align: right; + } + /* 修改人:Ld 修改时间:2026-08-04 09:16:54; APS排产弹窗样式,按人名分组并保留现有系统的简洁表格风格。 */ .machine-aps { min-height: 460px; @@ -1351,6 +2280,33 @@ export default { font-size: 13px; } + /* 修改人:Ld 修改时间:2026-08-24 08:05:00; 当前状态甘特图增加小时刻度控制区,滚动区只承载时间轴内容。 */ + .machine-aps-gantt { + min-height: 520px; + } + + .machine-aps-toolbar { + display: flex; + align-items: center; + min-height: 48px; + padding: 8px 14px 6px; + border-bottom: 1px solid #DCDFE6; + background: #FAFAFA; + box-sizing: border-box; + } + + .machine-aps-range-text { + width: 260px; + color: #303133; + font-size: 12px; + line-height: 28px; + } + + .machine-aps-range-slider { + flex: 1; + margin-left: 12px; + } + .machine-aps-scroll { width: 100%; height: 520px; @@ -1385,15 +2341,33 @@ export default { display: flex; } - .machine-aps-day { + .machine-aps-hour { height: 46px; - line-height: 46px; text-align: center; font-size: 12px; border-right: 1px solid #DCDFE6; box-sizing: border-box; } + .machine-aps-hour.is-day-start { + border-left: 2px solid #909399; + } + + .machine-aps-hour-date { + height: 20px; + color: #303133; + font-size: 11px; + line-height: 22px; + white-space: nowrap; + } + + .machine-aps-hour-time { + height: 22px; + color: #606266; + font-size: 12px; + line-height: 22px; + } + .machine-aps-row { display: flex; min-height: 76px; diff --git a/src/views/SeikoWorkshop/WorkshopAssignment/index.vue b/src/views/SeikoWorkshop/WorkshopAssignment/index.vue index 5f76b613..0327c879 100644 --- a/src/views/SeikoWorkshop/WorkshopAssignment/index.vue +++ b/src/views/SeikoWorkshop/WorkshopAssignment/index.vue @@ -67,7 +67,7 @@ style="margin-left: 10px" @click="CancelUrgent()">取消加急 - 查看图纸 + 查看图纸 手动报废结单 @@ -482,6 +482,7 @@ export default { productionNum: '', finishNum: '', partTool: '', + selectedPartRow: null, // 修改人:Ld 修改时间:2026-08-12 09:37:10; 保存当前选择零件行,用于查看图纸时读取物料编码。 dateRange: '', // 提交日期 contractStateValue: '', // 合同状态 partNameValue: '', // 零件名称 @@ -653,7 +654,37 @@ export default { console.log('WebSocket连接失败') }, // 查看零件图 - getNum() { + getNum() { // 修改人:Ld 修改时间:2026-08-12 09:37:10; 查看图纸先按选中物料编码查PLM,无有效链接时回落原图纸查询。 + const row = this.selectedPartRow + if (!row) { + this.$message.warning('请先选择零件') + return + } + const msgId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { + const r = Math.random() * 16 | 0 + const v = c === 'x' ? r : (r & 0x3 | 0x8) + return v.toString(16) + }) + request({ + url: 'http://192.168.1.27:9982/api/GetMaterialDrawingUrl', + method: 'post', + data: { + msgId: msgId, + materialCode: row.物料编码 + } + }).then(response => { + if (response.data && response.data.Code === '200' && response.data.Data && response.data.Data.url) { + window.open(response.data.Data.url, '_blank') + } else { + this.$message.warning('PLM未返回有效链接') + this.openLocalDrawing() + } + }).catch(() => { + this.$message.error('PLM请求发送失败') + this.openLocalDrawing() + }) + }, + openLocalDrawing() { // 修改人:Ld 修改时间:2026-08-12 09:37:10; PLM未获取有效链接时调用原本地查看图纸逻辑。 if (this.partTool) { this.dialogVisible = true this.getFileList(this.partTool) @@ -785,6 +816,7 @@ export default { }) }, searchTable1(row) { + this.selectedPartRow = row // 修改人:Ld 修改时间:2026-08-12 09:37:10; 记录查看图纸使用的当前选择物料编码。 this.partTool = row.零件图号 this.processValue = row.工艺计划流水号 this.IsItUrgent = Number(row.是否加急) diff --git a/src/views/WarehouseManagement/InventoryCheck/index.vue b/src/views/WarehouseManagement/InventoryCheck/index.vue index a9243f61..b658eab9 100644 --- a/src/views/WarehouseManagement/InventoryCheck/index.vue +++ b/src/views/WarehouseManagement/InventoryCheck/index.vue @@ -197,6 +197,13 @@ 预校验 + + 导出预校验 = this.inventoryImportDetailChunks.length) { this.inventoryImportData = result diff --git a/src/views/WarehouseManagement/OutboundOrder/index.vue b/src/views/WarehouseManagement/OutboundOrder/index.vue new file mode 100644 index 00000000..436e268d --- /dev/null +++ b/src/views/WarehouseManagement/OutboundOrder/index.vue @@ -0,0 +1,624 @@ + + + + + + + 出库单 + 根据出库记录生成页面展示单据,审批不影响原出库记录数据 + + + 重置 + 查询 + + + + + + + 待审批单据 + {{ summary.待审批 }} + + + + + 出库总数 + {{ summary.出库总数 }} + + + + + 涉及订单 + {{ summary.订单数 }} + + + + + 物料种类 + {{ summary.物料种类 }} + + + + + + + + + + + + + + + + + + + + + + {{ scope.row.出库单号 }} + + + + + {{ scope.row.审批状态 }} + + + + {{ scope.row.类型 }} + + + {{ scope.row.物料名称 }} + + + {{ scope.row.物料编码 }} + + + {{ scope.row.图号或型号 }} + + + {{ scope.row.单位 }} + + + + {{ scope.row.领料数 }} + + + + {{ scope.row.库位 }} + + + {{ scope.row.领料日期 }} + + + {{ scope.row.领料人 }} + + + {{ scope.row.领料单号 }} + + + {{ scope.row.订单号 }} + + + {{ scope.row.产品名称 }} + + + {{ scope.row.批次编码 }} + + + {{ scope.row.备注 }} + + + + 审批 + + + + + + + + + + + + {{ currentRow.出库单号 }} + + + + 物料名称 + {{ currentRow.物料名称 }} + + + + + 出库数量 + {{ currentRow.领料数 }} {{ currentRow.单位 }} + + + + + 领料人 + {{ currentRow.领料人 }} + + + + + 出库日期 + {{ currentRow.领料日期 }} + + + + + 审批后仅从当前出库单页面移除,不保存审批结果,不影响出库记录。 + + + + + + + + + diff --git a/src/views/WarehouseManagement/PDAPurchaseInbound/index.vue b/src/views/WarehouseManagement/PDAPurchaseInbound/index.vue new file mode 100644 index 00000000..bdc1cebf --- /dev/null +++ b/src/views/WarehouseManagement/PDAPurchaseInbound/index.vue @@ -0,0 +1,675 @@ + + + + + + + PDA采购扫码入库 + {{ currentLabelText }} + + {{ labelStateText }} + + + + + + 查询 + + + + + + 入库单号 + {{ labelInfo.入库单号 || '-' }} + + + 采购合同号 + {{ labelInfo.采购合同号 || labelInfo.采购合同 || '-' }} + + + 供应商 + {{ labelInfo.供应商 || '-' }} + + + 待入库数量 + {{ remainingTotal }} + + + + + + + + + 应用货位 + + + + + + + + + + + {{ item.物料名称 || '-' }} + 图号:{{ item.图号 || item.图号型号 || '-' }} + + {{ getRowStateText(item) }} + + + + + 标签数量 + {{ formatNumber(item.标签数量 || item.数量) }} + + + 已入库 + {{ formatNumber(item.已入库数量) }} + + + 剩余 + {{ formatNumber(getRemainingCount(item)) }} + + + + + + 本次入库数量 + + + + 货位 + + + + + + + + 批次号:{{ item.批次号 || item.批号 || '-' }} + 批次编码:{{ item.批次编码 || '-' }} + + + + + + + + 清空 + + 确认入库 + + + + + + + + + + diff --git a/src/views/WarehouseManagement/Replenishment/index.vue b/src/views/WarehouseManagement/Replenishment/index.vue index df73e3d1..bded08f9 100644 --- a/src/views/WarehouseManagement/Replenishment/index.vue +++ b/src/views/WarehouseManagement/Replenishment/index.vue @@ -1,6 +1,7 @@ - - + + + @@ -284,8 +285,9 @@ @@ -403,6 +405,7 @@ export default { // 修改人:Ld 修改时间:2026-08-03 16:35:25; 关联合同补货弹窗数据,独立于原补货提交。 dialogFormVisibleLink: false, linkContractLoading: false, + linkSubmitting: false, // 修改人:Ld 修改时间:2026-08-11 09:42:28; 关联合同补货提交中状态,用于防止重复提交。 linkContractList: [], linkForm: { 来源类型: '合同缺件', @@ -657,6 +660,10 @@ export default { }, // 修改人:Ld 修改时间:2026-08-03 16:35:25; 提交带合同/仓库备货来源的补货单,原 submitOrder 不变。 submitLinkedOrder() { + // 修改人:Ld 修改时间:2026-08-11 09:42:28; 请求未返回前直接拦截后续提交,避免同一补货单重复生成订单。 + if (this.linkSubmitting) { + return + } if (this.linkForm.来源类型 === '合同缺件' && !this.linkForm.项目流水号) { this.$message.warning('请选择关联销售合同') return @@ -680,6 +687,7 @@ export default { param[5] = ['项目流水号', this.linkForm.项目流水号 || 0] param[6] = ['订单流水号', this.linkForm.订单流水号 || 0] var Data = this.CreateData('12', '报缺补货_提交_关联合同', param) + this.linkSubmitting = true this.ExecDatabase(Data).then(response => { if (response.data[0].result === '1') { this.$message.success('提交成功') @@ -688,6 +696,9 @@ export default { } else { this.$message.error(response.data[0].message || '提交失败') } + this.linkSubmitting = false + }).catch(() => { + this.linkSubmitting = false }) }, selectIn(row) { @@ -917,25 +928,26 @@ export default { }