更新人事/采购/销售/精工/仓储/技术等模块,新增出库单/PDA采购入库页面,补充生产计划需求文档及多项SQL脚本

This commit is contained in:
Developer
2026-09-14 07:56:15 +08:00
parent 9fc3aae3e9
commit ffac9fcc61
40 changed files with 6762 additions and 181 deletions

BIN
dist.7z

Binary file not shown.

BIN
dist.zip

Binary file not shown.

Binary file not shown.

View File

@@ -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;

View File

@@ -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()

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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 项目流水号=@项目流水号

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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 入库记录流水号;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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 类型流水号;

View File

@@ -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;

View File

@@ -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 物料编码;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

BIN
src.zip

Binary file not shown.

View File

@@ -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({

2
src/vendor/xlsx-style-cptable.js vendored Normal file
View File

@@ -0,0 +1,2 @@
// 修改人:Ld 修改时间:2026-08-05 08:13:25; 兼容 xlsx-style 打包时解析缺失的 cptable 可选编码表模块。
module.exports = {}

View File

@@ -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 {
<style scoped>
</style>

View File

@@ -62,7 +62,6 @@
placeholder="订单备注"
@keyup.enter.native="pageCurrent=1;searchLeftTable()"/>
<el-button type="success" size="mini" style="margin-left: 100px" @click="exportExcel()">导出</el-button>
<el-button type="distribution" icon="el-icon-plus" size="mini" @click="addArrivalNotice()">生成入库单</el-button>
</div>
<el-row style="display: flex">
<el-col style="margin-left: 7px;width: 571px">
@@ -145,13 +144,22 @@
{{ getApproverName(scope.row.审批人) }}
</template>
</el-table-column>
<el-table-column width="120px" label="操作" align="center" show-overflow-tooltip fixed="right">
<!-- 修改人:Ld 修改时间:2026-09-03 14:37:23; 生成入库单按钮加入后适当加宽左侧合同操作列。 -->
<el-table-column width="150px" label="操作" align="center" show-overflow-tooltip fixed="right">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-printer"
@click="exportTable(scope.row)"/>
<el-tooltip :open-delay="700" effect="dark" content="生成入库单" placement="top">
<!-- 修改人:Ld 修改时间:2026-09-03 14:37:23; 将生成入库单入口移至左侧合同列表当前合同操作列。 -->
<el-button
size="mini"
type="text"
icon="el-icon-plus"
@click.stop="addArrivalNotice(scope.row)"/>
</el-tooltip>
<el-tooltip :open-delay="700" effect="dark" content="删除合同" placement="top">
<el-button
:disabled="Number(scope.row.是否提交) !== 0 && Number(scope.row.审批情况流水号)===1"
@@ -562,21 +570,17 @@
<el-table-column label="最近一次采购单价" align="center" prop="最近单价"/>
</el-table>
</el-dialog>
<el-dialog v-el-drag-dialog title="生成入库单" :visible.sync="dialogFormVisible4" center width="1000px">
<el-dialog v-el-drag-dialog :visible.sync="dialogFormVisible4" center title="生成入库单" width="1000px">
<el-form label-position="left" label-width="100px" class="demo-ruleForm" style="margin: auto">
<el-row style="display: flex; align-items: center;">
<el-col>
<el-select v-model="arrivalSupplierName" filterable clearable placeholder="请选择供应商" size="small" style="width: 200px" @change="getArrivalContract()">
<el-option v-for="item in suppliers" :key="item.value" :label="item.label" :value="item.value"/>
</el-select>
<!-- 修改人:Ld 修改时间:2026-09-03 14:37:23; 弹窗改为展示当前合同信息,不再二次选择供应商和合同。 -->
<el-row class="arrival-current-contract">
<el-col :span="6">
<span>采购合同号:</span>
<strong>{{ arrivalContractLabel || '-' }}</strong>
</el-col>
<el-col>
<el-select v-model="arrivalContractNo" filterable clearable placeholder="请选择合同号" size="small" style="width: 200px" @change="onArrivalContractChange">
<el-option v-for="item in arrivalContract" :key="item.value" :label="item.label" :value="item.value"/>
</el-select>
</el-col>
<el-col>
<el-button icon="el-icon-search" type="primary" plain size="small" @click="searchArrivalDetail()">查询</el-button>
<el-col :span="6">
<span>供应商:</span>
<strong>{{ arrivalSupplierLabel || '-' }}</strong>
</el-col>
<el-col v-if="入库单号" style="margin-left: 20px;">
<span style="font-size: 14px; color: #606266;">入库单号:</span>
@@ -586,10 +590,19 @@
<el-row>
<el-col :span="24">
<div style="max-height: 400px; overflow: auto;">
<el-table :data="arrivalTableData" border stripe size="small" style="width: 100%;">
<el-table
ref="arrivalTable"
:data="arrivalTableData"
border
stripe
size="small"
style="width: 100%;"
@selection-change="handleArrivalSelectionChange">
<!-- 修改人:Ld 修改时间:2026-09-03 14:37:23; 增加明细勾选列,仅提交用户选择且数量大于0的物料。 -->
<el-table-column type="selection" width="45" align="center"/>
<el-table-column label="合同号" align="center" show-overflow-tooltip width="180">
<template slot-scope="scope">
{{ scope.row.采购合同编号 }}
{{ scope.row.采购合同编号 || arrivalContractLabel }}
</template>
</el-table-column>
<el-table-column label="采购件" align="center" show-overflow-tooltip width="150">
@@ -616,11 +629,12 @@
<template slot-scope="scope">
<el-input-number
v-model="scope.row.到货数量"
:max="scope.row.采购数 - (scope.row.已到数 || 0)"
:max="getCanArrivalCount(scope.row)"
:min="0"
size="small"
style="width: 120px"
controls-position="right"/>
controls-position="right"
@change="onArrivalCountChange(scope.row)"/>
</template>
</el-table-column>
<el-table-column label="是否需要质检" align="center" width="120">
@@ -646,9 +660,11 @@
<el-col :span="24">
<el-divider content-position="left">到货汇总</el-divider>
<div style="font-size: 12px; color: #606266; background: #f5f7fa; padding: 10px; border-radius: 4px;">
<!-- 修改人:Ld 修改时间:2026-09-03 15:10:12; 汇总区增加按勾选明细数量变化的数量合计。 -->
<span>本次到货物料数:<span style="color: #409EFF; font-weight: bold;">{{ arrivalCount }}</span> 个,</span>
<span>其中需质检:<span style="color: #E6A23C; font-weight: bold;">{{ qualityCheckCount }}</span> 个 → 推送质检部,</span>
<span>免检直接入库:<span style="color: #67C23A; font-weight: bold;">{{ noQualityCheckCount }}</span> 个 → 推送仓库</span>
<span>本次数量合计:<span style="color: #409EFF; font-weight: bold;">{{ arrivalTotalQuantity }}</span>,</span>
<span>其中需质检:<span style="color: #E6A23C; font-weight: bold;">{{ qualityCheckCount }}</span> 个 / <span style="color: #E6A23C; font-weight: bold;">{{ qualityCheckTotalQuantity }}</span> → 推送质检部,</span>
<span>免检直接入库:<span style="color: #67C23A; font-weight: bold;">{{ noQualityCheckCount }}</span> 个 / <span style="color: #67C23A; font-weight: bold;">{{ noQualityCheckTotalQuantity }}</span> → 推送仓库</span>
</div>
</el-col>
</el-row>
@@ -658,6 +674,30 @@
<el-button type="primary" size="small" @click="submitArrivalNotice()">确 定</el-button>
</div>
</el-dialog>
<el-dialog v-el-drag-dialog :visible.sync="arrivalLabelVisible" center title="入库单标签" width="420px">
<!-- 修改人:Ld 修改时间:2026-09-03 14:37:23; 前端先生成入库单标签预览,后端补充标签ID后可替换二维码内容。 -->
<div id="purchaseInboundLabel" class="purchase-inbound-label">
<div class="label-title">采购入库标签</div>
<div class="label-body">
<div class="label-info">
<div><span>采购合同号</span><strong>{{ arrivalLabelInfo.采购合同号 }}</strong></div>
<div><span>供应商</span><strong>{{ arrivalLabelInfo.供应商 }}</strong></div>
<div><span>批次号</span><strong>{{ arrivalLabelInfo.批次号 }}</strong></div>
<div><span>入库单号</span><strong>{{ arrivalLabelInfo.入库单号 }}</strong></div>
</div>
<img v-if="arrivalLabelInfo.二维码" :src="arrivalLabelInfo.二维码" class="label-qrcode">
</div>
<div class="label-detail">
<div v-for="(item, index) in arrivalLabelInfo.明细" :key="index">
{{ index + 1 }}. {{ item.物料名称 }} / {{ item.图号 }} / {{ item.数量 }}
</div>
</div>
</div>
<div slot="footer" class="dialog-footer">
<el-button size="small" @click="arrivalLabelVisible = false">关闭</el-button>
<el-button type="primary" size="small" icon="el-icon-printer" @click="printArrivalLabel()">打印标签</el-button>
</div>
</el-dialog>
</div>
</template>
@@ -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 { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[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('<!doctype html><html><head><meta charset="utf-8"><title>' + frameTitleHtml + '</title></head><body></body></html>')
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('<!doctype html><html><head><meta charset="utf-8"><title>入库单标签</title><style>.purchase-inbound-label{width:360px;padding:12px;font-family:Arial,\"Microsoft YaHei\",sans-serif;color:#303133;border:1px solid #303133}.label-title{text-align:center;font-size:18px;font-weight:bold;margin-bottom:10px}.label-body{display:flex;align-items:center;justify-content:space-between}.label-info{font-size:12px;line-height:1.8}.label-info span{display:inline-block;width:70px;color:#606266}.label-info strong{font-size:13px;color:#303133}.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}</style></head><body><div class="purchase-inbound-label">' + htmlNode + '</div></body></html>')
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;
}
</style>

View File

@@ -52,9 +52,13 @@
@click="exportExcel">导出</el-button>
</div>
<!-- 修改人:Ld 修改时间:2026-09-11 14:05:14; 开启销售绩效表格底部自定义汇总行。 -->
<el-table
ref="performanceTable"
v-loading="loading"
:data="pageTableData"
:summary-method="getSummaries"
show-summary
border
stripe
size="small"
@@ -89,13 +93,14 @@
<el-table-column width="100px" label="销售员" align="center" prop="销售员" show-overflow-tooltip />
<el-table-column width="160px" label="合同编号" align="center" prop="合同编号" show-overflow-tooltip />
<el-table-column width="220px" label="客户名称" align="center" prop="客户名称" show-overflow-tooltip />
<el-table-column width="120px" label="合同金额" align="right">
<!-- 修改人:Ld 修改时间:2026-09-11 14:05:14; 指定金额列字段用于表格底部汇总。 -->
<el-table-column width="120px" label="合同金额" align="right" prop="合同金额">
<template slot-scope="scope">{{ formatMoney(scope.row.合同金额) }}</template>
</el-table-column>
<el-table-column width="120px" label="累计回款金额" align="right">
<el-table-column width="120px" label="累计回款金额" align="right" prop="累计回款金额">
<template slot-scope="scope">{{ formatMoney(scope.row.累计回款金额) }}</template>
</el-table-column>
<el-table-column width="120px" label="本月回款金额" align="right">
<el-table-column width="120px" label="本月回款金额" align="right" prop="本月回款金额">
<template slot-scope="scope">{{ formatMoney(scope.row.本月回款金额) }}</template>
</el-table-column>
<el-table-column width="100px" label="回款比例" align="right">
@@ -105,7 +110,7 @@
<el-table-column width="100px" label="提成比例" align="right">
<template slot-scope="scope">{{ formatPercent(scope.row.提成比例) }}</template>
</el-table-column>
<el-table-column width="130px" label="本月绩效金额" align="right">
<el-table-column width="130px" label="本月绩效金额" align="right" prop="本月绩效金额">
<template slot-scope="scope">{{ formatMoney(scope.row.本月绩效金额) }}</template>
</el-table-column>
</el-table>
@@ -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) + '%'

View File

@@ -3,6 +3,14 @@
<div class="app-container production-completion-audit">
<el-card>
<div class="search-bar">
<!-- 生产审核添加订单号查询 修改人:Ld 修改时间:2026-08-11 10:08:01; -->
<el-input
v-model="searchForm.订单号"
style="width: 150px"
placeholder="订单号"
size="small"
clearable
@keyup.enter.native="resetSearch"/>
<el-input
v-model="searchForm.操作者"
style="width: 140px"
@@ -107,14 +115,16 @@
<el-table-column label="操作" align="center" width="170" fixed="right">
<template slot-scope="scope">
<el-button type="text" size="mini" icon="el-icon-view" @click="openDetail(scope.row)">查看</el-button>
<!-- 修改人:Ld 修改时间:2026-08-20 13:20:11; 系统管理员可对已审核记录再次审核 -->
<el-button
:disabled="scope.row.审核状态 !== '待审核'"
:disabled="!canAuditAgain(scope.row)"
type="text"
size="mini"
icon="el-icon-check"
@click="approveRow(scope.row)">通过</el-button>
<!-- 修改人:Ld 修改时间:2026-08-20 13:20:11; 系统管理员可对已审核记录再次修改后审核 -->
<el-button
:disabled="scope.row.审核状态 !== '待审核'"
:disabled="!canAuditAgain(scope.row)"
type="text"
size="mini"
icon="el-icon-edit"
@@ -229,7 +239,8 @@ export default {
editForm: {
审核类型: '',
完成数量: 1,
计价方式: '计件',
// 修改人:Ld 修改时间:2026-08-20 13:20:11; 默认计价方式改为计时
计价方式: '计时',
加工开始时间: '',
加工完成时间: '',
整修开始时间: '',
@@ -237,6 +248,8 @@ export default {
整修方案: ''
},
searchForm: {
// 生产审核添加订单号查询 修改人:Ld 修改时间:2026-08-11 10:08:01;
订单号: '',
操作者: '',
审核类型: '',
审核状态: '待审核'
@@ -262,6 +275,14 @@ export default {
this.getPeople()
},
methods: {
// 修改人:Ld 修改时间:2026-08-20 13:20:11; 判断当前角色是否为系统管理员
isSystemAdmin() {
return String(this.token) === '2'
},
// 修改人:Ld 修改时间:2026-08-20 13:20:11; 仅待审核或系统管理员再次审核的记录允许操作
canAuditAgain(row) {
return row && (row.审核状态 === '待审核' || (row.审核状态 === '已审核' && this.isSystemAdmin()))
},
// 生产完成审核查询 修改人:Ld 修改时间:2026-07-02 13:57:18;
getPeople() {
var param = []
@@ -296,10 +317,19 @@ export default {
param[6] = ['时间_check', dateRangeCheck]
param[7] = ['开始时间', dateRangeCheck ? this.dateRange[0] : '']
param[8] = ['结束时间', dateRangeCheck ? this.dateRange[1] : '']
// 生产审核添加订单号查询 修改人:Ld 修改时间:2026-08-11 10:08:01;
param[9] = ['订单号_check', this.searchForm.订单号 ? 1 : 0]
param[10] = ['订单号', this.searchForm.订单号]
this.loading = true
var Data = this.CreateData('11', '机加工MES_加工完成整修审核_查询数据', param, this.pageSize, this.pageCurrent)
this.ExecDatabase(Data).then(response => {
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])

File diff suppressed because it is too large Load Diff

View File

@@ -67,7 +67,7 @@
style="margin-left: 10px"
@click="CancelUrgent()">取消加急
</el-button>
<el-button type="success" plain size="small" style="margin-left: 10px" @click="getNum()">查看图纸
<el-button type="success" plain size="small" style="margin-left: 10px" @click="getNum()">查看图纸<!-- 修改人:Ld 修改时间:2026-08-12 09:37:10; 查看图纸改为使用当前选择零件的物料编码优先查询PLM。 -->
</el-button>
<el-button v-if="Number(token) === 2" type="danger" plain size="small" style="margin-left: 10px" @click="openScrapDialog()">手动报废结单
</el-button>
@@ -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.是否加急)

View File

@@ -197,6 +197,13 @@
</div>
<div style="margin: 12px 0">
<el-button type="primary" size="small" icon="el-icon-search" @click="previewInventoryImport">预校验</el-button>
<!-- 修改人:Ld 修改时间:2026-08-11 13:14:38; 新增导入盘点预校验结果导出按钮。 -->
<el-button
:disabled="inventoryImportData.length === 0"
type="success"
size="small"
icon="el-icon-download"
@click="exportInventoryImportPreview">导出预校验</el-button>
<el-button
:loading="inventoryImportSubmitting"
:disabled="inventoryImportData.length === 0"
@@ -327,6 +334,9 @@ import { ExecDatabase } from '@/main'
import { wsuri } from '@/utils/request'
import { mapGetters } from 'vuex'
import UploadExcelComponent from '@/views/TechnologyCenter/ImportBOM/UploadExcel/index.vue'
// 修改人:Ld 修改时间:2026-08-11 13:14:38; 复用前端 Excel 导出依赖生成导入盘点预校验结果文件。
import XLSX from 'xlsx'
import FileSaver from 'file-saver'
export default {
components: { UploadExcelComponent },
data() {
@@ -789,6 +799,44 @@ export default {
this.inventoryImportDetailChunks = this.buildInventoryImportDetailChunks(detail)
this.requestInventoryImportPreview(0, [])
},
// 修改人:Ld 修改时间:2026-08-11 13:14:38; 将导入盘点预校验表格前端导出为 Excel,便于提交前复核和留存。
exportInventoryImportPreview() {
if (this.inventoryImportData.length === 0) {
this.$message.warning('请先预校验导入盘点数据')
return
}
var data = []
data.push(['行号', '物料编号', '物料名称', '图号型号', '原库位', '调整后库位', '原库存', '导入库存', '盘点库存', '库存变化', '库位变化', '处理结果', '错误原因'])
for (let i = 0; i < this.inventoryImportData.length; i++) {
var row = this.inventoryImportData[i]
data.push([
row.导入序号,
row.物料编码,
row.物料名称,
row.图号或型号,
row.原货位名称,
row.调整后库位,
row.原库存,
row.导入库存,
row.盘点库存,
row.库存变化,
row.库位变化,
row.处理结果,
row.错误原因
])
}
var ws = XLSX.utils.aoa_to_sheet(data)
ws['!cols'] = [
{ wch: 8 }, { wch: 16 }, { wch: 22 }, { wch: 18 }, { wch: 14 },
{ wch: 16 }, { wch: 10 }, { wch: 10 }, { wch: 10 }, { wch: 10 },
{ wch: 10 }, { wch: 12 }, { wch: 30 }
]
var wb = XLSX.utils.book_new()
XLSX.utils.book_append_sheet(wb, ws, '预校验结果')
var wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: false, type: 'array' })
FileSaver.saveAs(new Blob([wbout], { type: 'application/octet-stream' }), '库存盘点预校验结果.xlsx')
this.$message.success('导出成功')
},
requestInventoryImportSubmit(index, result) {
if (index >= this.inventoryImportDetailChunks.length) {
this.inventoryImportData = result

View File

@@ -0,0 +1,624 @@
<template>
<div class="app-container outbound-order-page">
<!-- 修改人:Ld 修改时间:2026-08-25 17:02:01; 新增纯前端出库单展示页面,审批仅删除当前页面展示条目,不写入后端。 -->
<el-card class="outbound-card">
<div class="page-head">
<div>
<div class="page-title">出库单</div>
<div class="page-subtitle">根据出库记录生成页面展示单据,审批不影响原出库记录数据</div>
</div>
<div class="head-actions">
<el-button type="primary" size="small" icon="el-icon-refresh" plain @click="resetSearch">重置</el-button>
<el-button type="success" size="small" icon="el-icon-search" @click="pageCurrent=1;searchTable()">查询</el-button>
</div>
</div>
<el-row :gutter="12" class="summary-row">
<el-col :span="6">
<div class="summary-item summary-blue">
<div class="summary-label">待审批单据</div>
<div class="summary-value">{{ summary.待审批 }}</div>
</div>
</el-col>
<el-col :span="6">
<div class="summary-item summary-green">
<div class="summary-label">出库总数</div>
<div class="summary-value">{{ summary.出库总数 }}</div>
</div>
</el-col>
<el-col :span="6">
<div class="summary-item summary-orange">
<div class="summary-label">涉及订单</div>
<div class="summary-value">{{ summary.订单数 }}</div>
</div>
</el-col>
<el-col :span="6">
<div class="summary-item summary-gray">
<div class="summary-label">物料种类</div>
<div class="summary-value">{{ summary.物料种类 }}</div>
</div>
</el-col>
</el-row>
<div class="search-bar">
<el-select
v-model="typeValue"
class="search-control"
placeholder="类型"
size="small"
filterable
clearable
@change="pageCurrent=1;searchTable()">
<el-option
v-for="item in type"
:key="item.value"
:label="item.label"
:value="item.value"/>
</el-select>
<el-input
v-model="production"
class="search-wide"
size="small"
clearable
placeholder="物料名称/编号/规格/型号"
@keyup.enter.native="pageCurrent=1;searchTable()"/>
<el-select
v-model="pickListValue"
:remote-method="getList"
class="search-control"
size="small"
placeholder="领料单号"
filterable
clearable
remote
@change="pageCurrent=1;searchTable()">
<el-option
v-for="item in pickList"
:key="item.value"
:label="item.label"
:value="item.value"/>
</el-select>
<el-select
v-model="pickPeopleValue"
class="search-control"
size="small"
placeholder="领料人"
filterable
clearable
@change="pageCurrent=1;searchTable()">
<el-option
v-for="item in pickPeople"
:key="item.value"
:label="item.label"
:value="item.value"/>
</el-select>
<el-date-picker
v-model="dateRange"
size="small"
type="daterange"
align="center"
class="search-date"
value-format="yyyy-MM-dd"
format="yyyy-MM-dd"
range-separator="~"
start-placeholder="开始时间"
end-placeholder="结束时间"
@change="pageCurrent=1;searchTable()"/>
</div>
<el-table
v-loading="loading"
ref="table"
:data="tableData"
highlight-current-row
border
stripe
size="small"
class="order-table"
height="600px">
<el-table-column width="148px" label="出库单号" align="center" fixed show-overflow-tooltip>
<template slot-scope="scope">
<span class="order-code">{{ scope.row.出库单号 }}</span>
</template>
</el-table-column>
<el-table-column width="86px" label="审批状态" align="center" fixed>
<template slot-scope="scope">
<el-tag size="mini" type="warning">{{ scope.row.审批状态 }}</el-tag>
</template>
</el-table-column>
<el-table-column width="72px" label="类型" align="center">
<template slot-scope="scope">{{ scope.row.类型 }}</template>
</el-table-column>
<el-table-column width="150px" label="物料名称" align="center" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.物料名称 }}</template>
</el-table-column>
<el-table-column width="130px" label="物料编号" align="center" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.物料编码 }}</template>
</el-table-column>
<el-table-column width="145px" label="图号/型号" align="center" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.图号或型号 }}</template>
</el-table-column>
<el-table-column width="58px" label="单位" align="center">
<template slot-scope="scope">{{ scope.row.单位 }}</template>
</el-table-column>
<el-table-column width="82px" label="出库数量" align="center" prop="领料数">
<template slot-scope="scope">
<span class="number-text">{{ scope.row.领料数 }}</span>
</template>
</el-table-column>
<el-table-column width="95px" label="库位" align="center" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.库位 }}</template>
</el-table-column>
<el-table-column width="102px" label="出库日期" align="center">
<template slot-scope="scope">{{ scope.row.领料日期 }}</template>
</el-table-column>
<el-table-column width="86px" label="领料人" align="center">
<template slot-scope="scope">{{ scope.row.领料人 }}</template>
</el-table-column>
<el-table-column width="110px" label="领料单号" align="center" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.领料单号 }}</template>
</el-table-column>
<el-table-column width="128px" label="订单号" align="center" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.订单号 }}</template>
</el-table-column>
<el-table-column width="150px" label="产品/部件名称" align="center" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.产品名称 }}</template>
</el-table-column>
<el-table-column width="150px" label="批次编码" align="center" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.批次编码 }}</template>
</el-table-column>
<el-table-column min-width="160px" label="备注" align="center" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.备注 }}</template>
</el-table-column>
<el-table-column width="128px" label="操作" align="center" fixed="right">
<template slot-scope="scope">
<el-button type="primary" size="mini" plain @click="openApprove(scope.row)">审批</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination-wrap">
<el-pagination
:current-page="pageCurrent"
:page-sizes="[10, 20, 30, 40, 100]"
:page-size="pageSize"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChanges"
@current-change="handleCurrentChanges"/>
</div>
</el-card>
<el-dialog v-el-drag-dialog :visible.sync="approveDialogVisible" title="出库单审批" center width="520px">
<div v-if="currentRow" class="approve-box">
<div class="approve-title">{{ currentRow.出库单号 }}</div>
<el-row :gutter="10">
<el-col :span="12">
<div class="approve-field">
<span>物料名称</span>
<strong>{{ currentRow.物料名称 }}</strong>
</div>
</el-col>
<el-col :span="12">
<div class="approve-field">
<span>出库数量</span>
<strong>{{ currentRow.领料数 }} {{ currentRow.单位 }}</strong>
</div>
</el-col>
<el-col :span="12">
<div class="approve-field">
<span>领料人</span>
<strong>{{ currentRow.领料人 }}</strong>
</div>
</el-col>
<el-col :span="12">
<div class="approve-field">
<span>出库日期</span>
<strong>{{ currentRow.领料日期 }}</strong>
</div>
</el-col>
</el-row>
<el-input
v-model="approvalRemark"
:rows="3"
type="textarea"
resize="none"
placeholder="审批意见"/>
<div class="approve-tip">审批后仅从当前出库单页面移除,不保存审批结果,不影响出库记录。</div>
</div>
<div slot="footer" class="dialog-footer">
<el-button size="small" @click="approveDialogVisible=false">取消</el-button>
<el-button size="small" type="danger" plain @click="finishApproval('驳回')">驳回</el-button>
<el-button size="small" type="success" @click="finishApproval('通过')">通过</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
data() {
return {
typeValue: '',
type: [{
label: '自制',
value: '自制'
}, {
label: '外购',
value: '外购'
}, {
label: '耗材',
value: '耗材'
}, {
label: '通用',
value: '通用'
}, {
label: '临时',
value: '临时'
}, {
label: '备货',
value: '备货'
}],
pickList: [],
pickListValue: '',
pickPeople: [],
pickPeopleValue: '',
dateRange: '',
production: '',
loading: false,
total: 0,
tableData: [],
pageCurrent: 1,
pageSize: 100,
approveDialogVisible: false,
currentRow: null,
approvalRemark: ''
}
},
computed: {
...mapGetters([
'id'
]),
summary() {
var orderMap = {}
var materialMap = {}
var outTotal = 0
for (let i = 0; i < this.tableData.length; i++) {
var row = this.tableData[i]
if (row.订单号) {
orderMap[row.订单号] = true
}
if (row.物料编码 || row.物料名称) {
materialMap[(row.物料编码 || '') + row.物料名称] = true
}
outTotal += Number(row.领料数) || 0
}
return {
待审批: this.tableData.length,
出库总数: outTotal,
订单数: Object.keys(orderMap).length,
物料种类: Object.keys(materialMap).length
}
}
},
updated() {
this.$nextTick(() => {
if (this.$refs['table']) {
this.$refs['table'].doLayout()
}
})
},
created() {
this.fetchData()
this.searchTable()
},
methods: {
fetchData() {
this.getList('')
this.getPeople()
},
getList(query) {
var param = []
this.pickList = []
param[0] = ['领料单号', query]
var Data = this.CreateData('11', '仓库管理_领料单_查询_BAK', param)
this.ExecDatabase(Data).then(response => {
for (let i = 0; i < response.data.length; i++) {
this.pickList.push({
label: response.data[i].领料单号,
value: response.data[i].领料单号
})
}
})
},
getPeople() {
var param = []
var Data = this.CreateData('11', '仓库管理_领料人_查询', param)
this.ExecDatabase(Data).then(response => {
for (let i = 0; i < response.data.length; i++) {
this.pickPeople.push({
label: response.data[i].领料人,
value: response.data[i].领料人
})
}
})
},
resetSearch() {
this.typeValue = ''
this.pickListValue = ''
this.pickPeopleValue = ''
this.dateRange = ''
this.production = ''
this.pageCurrent = 1
this.searchTable()
},
searchTable() {
let dateRangeCheck, productionCheck, pickPeopleValueCheck, pickListValueCheck, typeValueCheck
this.typeValue ? typeValueCheck = 1 : typeValueCheck = 0
this.dateRange ? dateRangeCheck = 1 : dateRangeCheck = 0
this.production ? productionCheck = 1 : productionCheck = 0
this.pickListValue ? pickListValueCheck = 1 : pickListValueCheck = 0
this.pickPeopleValue ? pickPeopleValueCheck = 1 : pickPeopleValueCheck = 0
var startTime = this.dateRange ? this.dateRange[0] : ''
var endTime = this.dateRange ? this.dateRange[1] : ''
var param = []
param[0] = ['物料名称_check', productionCheck]
param[1] = ['物料名称', this.production]
param[2] = ['订单_check', 0]
param[3] = ['订单流水号', '']
param[4] = ['产品_check', 0]
param[5] = ['组件流水号', '']
param[6] = ['出库时间_check', dateRangeCheck]
param[7] = ['开始时间', startTime]
param[8] = ['结束时间', endTime]
param[9] = ['领料单_check', pickListValueCheck]
param[10] = ['领料单号', this.pickListValue]
param[11] = ['领料人_check', pickPeopleValueCheck]
param[12] = ['领料人', this.pickPeopleValue]
param[13] = ['退料_check', 0]
param[14] = ['类型_check', typeValueCheck]
param[15] = ['类型', this.typeValue]
var Data = this.CreateData('11', '仓储管理_出库记录_查询', param, this.pageSize, this.pageCurrent)
this.loading = true
this.ExecDatabase(Data).then(response => {
var rows = response.data.rows || []
this.tableData = this.buildDisplayRows(rows)
this.total = response.data.total || this.tableData.length
this.loading = false
}).catch(() => {
this.loading = false
this.$message.warning('出库单展示数据加载失败')
})
},
buildDisplayRows(rows) {
var displayRows = []
for (let i = 0; i < rows.length; i++) {
var row = Object.assign({}, rows[i])
row.出库单号 = this.createOrderCode(row, i)
row.审批状态 = '待审批'
displayRows.push(row)
}
return displayRows
},
createOrderCode(row, index) {
var dateText = (row.领料日期 || '').replace(/-/g, '')
if (!dateText) {
dateText = this.formatDate(new Date()).replace(/-/g, '')
}
var serial = row.出库记录流水号 || (this.pageCurrent + '-' + index)
return 'CKD-' + dateText + '-' + serial
},
formatDate(date) {
var month = date.getMonth() + 1
var day = date.getDate()
return date.getFullYear() + '-' + (month < 10 ? '0' + month : month) + '-' + (day < 10 ? '0' + day : day)
},
openApprove(row) {
this.currentRow = row
this.approvalRemark = ''
this.approveDialogVisible = true
},
finishApproval(result) {
if (!this.currentRow) {
return
}
this.$confirm('确认审批' + result + '?审批后该条仅从当前页面移除。', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
var orderCode = this.currentRow.出库单号
this.tableData = this.tableData.filter(function(item) {
return item.出库单号 !== orderCode
})
this.total = this.total > 0 ? this.total - 1 : 0
this.approveDialogVisible = false
this.currentRow = null
this.$message.success('审批' + result + ',已从当前展示列表移除')
}).catch(() => {
this.$message({
type: 'info',
message: '已取消审批'
})
})
},
handleSizeChanges(val) {
this.pageCurrent = 1
this.pageSize = val
this.searchTable()
},
handleCurrentChanges(val) {
this.pageCurrent = val
this.searchTable()
}
}
}
</script>
<style scoped>
.outbound-order-page {
background: #f5f7fb;
}
.outbound-card {
min-height: 850px;
border: 0;
}
.page-head {
display: flex;
align-items: center;
justify-content: space-between;
padding: 4px 2px 16px;
border-bottom: 1px solid #ebeef5;
}
.page-title {
color: #1f2d3d;
font-size: 22px;
font-weight: 600;
line-height: 30px;
}
.page-subtitle {
margin-top: 4px;
color: #7a8499;
font-size: 13px;
}
.head-actions {
display: flex;
align-items: center;
}
.summary-row {
margin-top: 14px;
}
.summary-item {
height: 78px;
padding: 14px 18px;
border: 1px solid #ebeef5;
border-radius: 6px;
background: #fff;
}
.summary-label {
color: #6b7280;
font-size: 13px;
}
.summary-value {
margin-top: 8px;
color: #202b3c;
font-size: 28px;
font-weight: 600;
line-height: 32px;
}
.summary-blue {
border-left: 4px solid #409eff;
}
.summary-green {
border-left: 4px solid #67c23a;
}
.summary-orange {
border-left: 4px solid #e6a23c;
}
.summary-gray {
border-left: 4px solid #909399;
}
.search-bar {
display: flex;
align-items: center;
flex-wrap: wrap;
padding: 14px 0 12px;
}
.search-control {
width: 150px;
margin-right: 10px;
margin-bottom: 8px;
}
.search-wide {
width: 240px;
margin-right: 10px;
margin-bottom: 8px;
}
.search-date {
width: 250px;
margin-bottom: 8px;
}
.order-table {
width: 100%;
}
.order-code {
color: #1f5fae;
font-weight: 600;
}
.number-text {
color: #303133;
font-weight: 600;
}
.pagination-wrap {
margin-top: 12px;
text-align: right;
}
.approve-box {
padding: 4px 8px 0;
}
.approve-title {
margin-bottom: 12px;
color: #1f2d3d;
font-size: 18px;
font-weight: 600;
}
.approve-field {
margin-bottom: 12px;
padding: 10px 12px;
border: 1px solid #ebeef5;
border-radius: 6px;
background: #fafbfc;
}
.approve-field span {
display: block;
color: #8a94a6;
font-size: 12px;
line-height: 18px;
}
.approve-field strong {
display: block;
overflow: hidden;
margin-top: 4px;
color: #303133;
font-size: 14px;
font-weight: 600;
line-height: 20px;
text-overflow: ellipsis;
white-space: nowrap;
}
.approve-tip {
margin-top: 10px;
color: #909399;
font-size: 12px;
line-height: 18px;
}
</style>

View File

@@ -0,0 +1,675 @@
<template>
<!-- 修改人:Ld 修改时间:2026-09-08 10:04:25; 新增仓库PDA采购扫码入库页面 -->
<div class="app-container pda-purchase-inbound">
<el-card class="pda-shell">
<div class="pda-header">
<div>
<div class="pda-title">PDA采购扫码入库</div>
<div class="pda-subtitle">{{ currentLabelText }}</div>
</div>
<el-tag :type="labelStateType" size="small">{{ labelStateText }}</el-tag>
</div>
<div class="scan-panel">
<el-input
ref="scanInput"
v-model="scanContent"
class="scan-input"
size="medium"
clearable
placeholder="扫描或输入入库标签二维码"
prefix-icon="el-icon-full-screen"
@keyup.enter.native="scanLabel"/>
<el-button
:loading="loading"
class="scan-button"
type="primary"
icon="el-icon-search"
size="medium"
@click="scanLabel">
查询
</el-button>
</div>
<div class="summary-grid">
<div class="summary-item">
<span>入库单号</span>
<strong>{{ labelInfo.入库单号 || '-' }}</strong>
</div>
<div class="summary-item">
<span>采购合同号</span>
<strong>{{ labelInfo.采购合同号 || labelInfo.采购合同 || '-' }}</strong>
</div>
<div class="summary-item">
<span>供应商</span>
<strong>{{ labelInfo.供应商 || '-' }}</strong>
</div>
<div class="summary-item">
<span>待入库数量</span>
<strong>{{ remainingTotal }}</strong>
</div>
</div>
<div class="batch-location">
<el-select
v-model="batchLocationValue"
:remote-method="getLocationOptions"
:loading="locationLoading"
class="batch-location-select"
size="medium"
filterable
remote
clearable
reserve-keyword
placeholder="批量选择货位">
<el-option
v-for="item in locationOptions"
:key="item.value"
:label="item.label"
:value="item.value"/>
</el-select>
<el-button
:disabled="detailRows.length === 0 || !batchLocationValue"
class="batch-location-button"
type="success"
plain
icon="el-icon-location-outline"
size="medium"
@click="applyBatchLocation">
应用货位
</el-button>
</div>
<div v-loading="loading" class="detail-area">
<el-empty v-if="detailRows.length === 0" description="请先扫描入库标签"/>
<div v-else class="detail-list">
<div v-for="(item, index) in detailRows" :key="getRowKey(item, index)" class="detail-card">
<div class="card-top">
<el-checkbox v-model="item.选中" :disabled="getRemainingCount(item) <= 0"/>
<div class="material-info">
<div class="material-name">{{ item.物料名称 || '-' }}</div>
<div class="material-code">图号:{{ item.图号 || item.图号型号 || '-' }}</div>
</div>
<el-tag :type="getRowStateType(item)" size="mini">{{ getRowStateText(item) }}</el-tag>
</div>
<div class="number-grid">
<div>
<span>标签数量</span>
<strong>{{ formatNumber(item.标签数量 || item.数量) }}</strong>
</div>
<div>
<span>已入库</span>
<strong>{{ formatNumber(item.已入库数量) }}</strong>
</div>
<div>
<span>剩余</span>
<strong>{{ formatNumber(getRemainingCount(item)) }}</strong>
</div>
</div>
<div class="card-form">
<div class="form-item">
<span>本次入库数量</span>
<el-input-number
v-model="item.本次入库数量"
:min="0"
:max="getRemainingCount(item)"
:precision="4"
:controls="false"
size="medium"
@change="onQuantityChange(item)"/>
</div>
<div class="form-item">
<span>货位</span>
<el-select
v-model="item.货位流水号"
:remote-method="getLocationOptions"
:loading="locationLoading"
size="medium"
filterable
remote
clearable
reserve-keyword
placeholder="扫描或选择货位"
@change="onLocationChange(item)">
<el-option
v-for="location in locationOptions"
:key="location.value"
:label="location.label"
:value="location.value"/>
</el-select>
</div>
</div>
<div class="card-bottom">
<span>批次号:{{ item.批次号 || item.批号 || '-' }}</span>
<span>批次编码:{{ item.批次编码 || '-' }}</span>
</div>
</div>
</div>
</div>
</el-card>
<div class="bottom-actions">
<el-button size="medium" icon="el-icon-refresh-left" @click="resetPage">清空</el-button>
<el-button
:disabled="submitDisabled"
:loading="submitLoading"
type="primary"
size="medium"
icon="el-icon-check"
@click="submitInbound">
确认入库
</el-button>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
name: 'PDAPurchaseInbound',
data() {
return {
loading: false,
submitLoading: false,
locationLoading: false,
scanContent: '',
labelInfo: {},
detailRows: [],
locationOptions: [],
batchLocationValue: ''
}
},
computed: {
...mapGetters([
'id',
'token'
]),
currentLabelText() {
if (this.labelInfo.标签编号) {
return this.labelInfo.标签编号
}
return '请扫描入库单标签二维码'
},
labelStateText() {
if (this.detailRows.length === 0) {
return '待扫码'
}
if (this.remainingTotal <= 0) {
return '已完成'
}
return '待入库'
},
labelStateType() {
if (this.detailRows.length === 0) {
return 'info'
}
if (this.remainingTotal <= 0) {
return 'success'
}
return 'warning'
},
remainingTotal() {
var total = 0
this.detailRows.forEach(item => {
total += Number(this.getRemainingCount(item) || 0)
})
return Number(total.toFixed(4))
},
submitDisabled() {
return this.submitRows().length === 0
}
},
mounted() {
// 修改人:Ld 修改时间:2026-09-08 10:04:25; PDA页面进入后自动聚焦扫码框并覆盖全局最小宽度。
document.body.classList.add('pda-purchase-inbound-page')
this.focusScanInput()
this.getLocationOptions('')
},
beforeDestroy() {
document.body.classList.remove('pda-purchase-inbound-page')
},
methods: {
focusScanInput() {
this.$nextTick(() => {
if (this.$refs.scanInput) {
this.$refs.scanInput.focus()
}
})
},
// 修改人:Ld 修改时间:2026-09-08 10:04:25; 调用PDA扫码查询过程加载标签头和明细。
scanLabel() {
if (!this.scanContent) {
this.$message.warning('请先扫描或输入标签二维码')
this.focusScanInput()
return
}
this.loading = true
var param = []
param[0] = ['扫码内容', this.scanContent]
param[1] = ['标签ID', '']
param[2] = ['入库单号', '']
var Data = this.CreateData('11', '仓储管理_PDA采购扫码入库_查询', param)
this.ExecDatabase(Data).then(response => {
var data = response.data.rows || response.data || []
this.setScanResult(data)
if (this.detailRows.length === 0) {
this.$message.warning('未查询到该标签明细')
}
}).catch(() => {
this.$message.error('扫码查询失败')
}).finally(() => {
this.loading = false
})
},
setScanResult(data) {
var firstRow = data.length > 0 ? data[0] : {}
this.labelInfo = Object.assign({}, firstRow)
this.detailRows = data.map(item => {
var remainingCount = Number(item.剩余入库数量 || item.剩余数量 || 0)
return Object.assign({}, item, {
选中: remainingCount > 0,
本次入库数量: remainingCount > 0 ? remainingCount : 0,
货位流水号: item.货位流水号 || '',
货位名称: item.货位名称 || ''
})
})
this.batchLocationValue = ''
},
// 修改人:Ld 修改时间:2026-09-08 10:04:25; 货位采用远程模糊查询,支持PDA扫描货位码后快速选择。
getLocationOptions(query) {
this.locationLoading = true
var param = []
param[0] = ['货位名称', query || '']
var Data = this.CreateData('11', '仓储管理_PDA货位_查询', param)
this.ExecDatabase(Data).then(response => {
var data = response.data.rows || response.data || []
this.locationOptions = data.map(function(item) {
return {
label: item.货位名称,
value: item.货位流水号
}
})
}).finally(() => {
this.locationLoading = false
})
},
applyBatchLocation() {
var selected = this.locationOptions.find(item => {
return item.value === this.batchLocationValue
})
this.detailRows.forEach(item => {
if (item.选中 && this.getRemainingCount(item) > 0) {
item.货位流水号 = this.batchLocationValue
item.货位名称 = selected ? selected.label : item.货位名称
}
})
},
onLocationChange(row) {
var selected = this.locationOptions.find(item => {
return item.value === row.货位流水号
})
row.货位名称 = selected ? selected.label : ''
},
onQuantityChange(row) {
if (Number(row.本次入库数量) > 0) {
row.选中 = true
}
if (Number(row.本次入库数量) === 0) {
row.选中 = false
}
},
submitRows() {
return this.detailRows.filter(item => {
return item.选中 && Number(item.本次入库数量) > 0
})
},
// 修改人:Ld 修改时间:2026-09-08 10:04:25; 提交时按明细、数量、货位三个数组传给测试库PDA入库过程。
submitInbound() {
var rows = this.submitRows()
if (rows.length === 0) {
this.$message.warning('请至少选择一条待入库明细')
return
}
for (let i = 0; i < rows.length; i++) {
if (!rows[i].货位流水号) {
this.$message.warning('请选择货位')
return
}
if (Number(rows[i].本次入库数量) > this.getRemainingCount(rows[i])) {
this.$message.warning('入库数量不能大于剩余数量')
return
}
}
this.submitLoading = true
var param = []
param[0] = ['扫码内容', this.scanContent]
param[1] = ['标签ID', this.labelInfo.标签ID || '']
param[2] = ['标签明细流水号组', rows.map(function(item) { return item.标签明细流水号 || item.明细流水号 }).join(',')]
param[3] = ['入库数量组', rows.map(function(item) { return item.本次入库数量 }).join(',')]
param[4] = ['货位流水号组', rows.map(function(item) { return item.货位流水号 }).join(',')]
param[5] = ['入库人', this.id]
var Data = this.CreateData('12', '仓储管理_PDA采购扫码入库_提交', param)
this.ExecDatabase(Data).then(response => {
var result = response.data && response.data.length > 0 ? response.data[0] : {}
if (String(result.result) === '1') {
this.$message.success(result.message || '入库成功')
this.scanLabel()
} else {
this.$message.error(result.message || '入库失败')
}
}).catch(() => {
this.$message.error('提交失败,请重试')
}).finally(() => {
this.submitLoading = false
})
},
resetPage() {
this.scanContent = ''
this.labelInfo = {}
this.detailRows = []
this.batchLocationValue = ''
this.focusScanInput()
},
getRemainingCount(row) {
var value = row.剩余入库数量
if (value === undefined || value === null || value === '') {
value = Number(row.标签数量 || row.数量 || 0) - Number(row.已入库数量 || 0)
}
value = Number(value || 0)
return value > 0 ? value : 0
},
getRowKey(row, index) {
return row.标签明细流水号 || row.明细流水号 || index
},
getRowStateText(row) {
if (Number(row.入库状态) === 2 || this.getRemainingCount(row) <= 0) {
return '已完成'
}
if (Number(row.入库状态) === 1) {
return '部分入库'
}
return '待入库'
},
getRowStateType(row) {
if (Number(row.入库状态) === 2 || this.getRemainingCount(row) <= 0) {
return 'success'
}
if (Number(row.入库状态) === 1) {
return 'warning'
}
return 'info'
},
formatNumber(value) {
var numberValue = Number(value || 0)
return Number(numberValue.toFixed(4))
}
}
}
</script>
<style scoped>
/* 修改人:Ld 修改时间:2026-09-08 10:04:25; PDA采购扫码入库页面窄屏触控样式 */
.pda-purchase-inbound,
.pda-purchase-inbound * {
box-sizing: border-box;
}
.pda-purchase-inbound {
width: 100%;
min-height: calc(100vh - 84px);
padding: 10px 10px 76px;
overflow-x: hidden;
background: #f3f6fb;
}
.pda-shell {
min-height: calc(100vh - 150px);
border-radius: 6px;
}
.pda-shell >>> .el-card__body {
padding: 12px !important;
}
.pda-header,
.scan-panel,
.batch-location,
.card-top,
.card-bottom {
display: flex;
align-items: center;
gap: 10px;
}
.pda-header {
justify-content: space-between;
margin-bottom: 12px;
}
.pda-title {
font-size: 20px;
font-weight: 700;
color: #1f2d3d;
}
.pda-subtitle {
max-width: 260px;
margin-top: 4px;
overflow: hidden;
font-size: 12px;
color: #8492a6;
text-overflow: ellipsis;
white-space: nowrap;
}
.scan-panel,
.batch-location {
margin-bottom: 10px;
}
.scan-input,
.batch-location-select {
flex: 1;
min-width: 0;
}
.scan-button,
.batch-location-button {
width: 96px;
flex: 0 0 96px;
}
.summary-grid {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 8px;
margin-bottom: 10px;
}
.summary-item {
min-width: 0;
padding: 9px 10px;
border: 1px solid #dcdfe6;
border-radius: 6px;
background: #fff;
}
.summary-item span {
display: block;
margin-bottom: 5px;
color: #909399;
font-size: 12px;
}
.summary-item strong {
display: block;
min-width: 0;
overflow: hidden;
color: #303133;
font-size: 16px;
text-overflow: ellipsis;
white-space: nowrap;
}
.detail-list {
display: grid;
grid-template-columns: repeat(2, minmax(260px, 1fr));
gap: 10px;
}
.detail-card {
min-width: 0;
padding: 12px;
border: 1px solid #dcdfe6;
border-radius: 6px;
background: #fff;
}
.card-top {
align-items: flex-start;
}
.material-info {
flex: 1;
min-width: 0;
}
.material-name {
min-width: 0;
overflow: hidden;
color: #303133;
font-size: 16px;
font-weight: 700;
text-overflow: ellipsis;
white-space: nowrap;
}
.material-code,
.card-bottom {
color: #606266;
font-size: 12px;
}
.number-grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 8px;
margin: 10px 0;
}
.number-grid div {
min-width: 0;
padding: 8px;
border-radius: 4px;
background: #f5f7fa;
}
.number-grid span,
.form-item span {
display: block;
margin-bottom: 5px;
color: #909399;
font-size: 12px;
}
.number-grid strong {
display: block;
color: #303133;
font-size: 16px;
}
.card-form {
display: grid;
grid-template-columns: minmax(120px, 160px) minmax(160px, 1fr);
gap: 10px;
}
.form-item {
min-width: 0;
}
.pda-purchase-inbound >>> .el-select,
.pda-purchase-inbound >>> .el-input,
.pda-purchase-inbound >>> .el-input-number,
.pda-purchase-inbound >>> .el-button {
width: 100%;
max-width: 100%;
min-width: 0;
}
.pda-purchase-inbound >>> .el-input__inner {
height: 40px;
min-width: 0;
font-size: 15px;
}
.card-bottom {
justify-content: space-between;
margin-top: 10px;
}
.card-bottom span {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.bottom-actions {
position: fixed;
right: 16px;
bottom: 14px;
left: 16px;
z-index: 10;
display: grid;
grid-template-columns: 96px 1fr;
gap: 10px;
padding: 10px;
border: 1px solid #dcdfe6;
border-radius: 6px;
background: #fff;
box-shadow: 0 8px 24px rgba(31, 45, 61, 0.14);
}
@media (max-width: 760px) {
.pda-purchase-inbound {
padding: 8px 8px 74px;
}
.summary-grid {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.detail-list,
.card-form {
grid-template-columns: 1fr;
}
.scan-panel,
.batch-location {
align-items: stretch;
flex-direction: column;
}
.scan-button,
.batch-location-button {
width: 100%;
flex-basis: auto;
}
}
</style>
<style>
/* 修改人:Ld 修改时间:2026-09-08 10:04:25; PDA页面覆盖后台布局最小宽度,适配手持终端 */
body.pda-purchase-inbound-page {
min-width: 0 !important;
}
body.pda-purchase-inbound-page .app-main {
min-width: 0 !important;
}
</style>

View File

@@ -1,6 +1,7 @@
<template>
<div class="app-container">
<el-card style="height: 850px ;display:flex">
<!-- 修改人:Ld 修改时间:2026-08-11 09:14:50; 为报缺补货页面增加专用作用域类,避免样式影响其他组件布局。 -->
<div class="app-container replenishment-page">
<el-card class="replenishment-card" style="height: 850px ;display:flex">
<el-col style="width: 930px">
<div style="margin-top: 7px; margin-bottom: 7px">
<el-cascader ref="cascader" :options="product" :show-all-levels="false" placeholder="产品名称" clearable size="small" @clear="clearData" @change="getData"/>
@@ -284,8 +285,9 @@
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button size="small" @click="dialogFormVisibleLink=false">取 消</el-button>
<el-button type="primary" size="small" @click="submitLinkedOrder">确 定</el-button>
<el-button :disabled="linkSubmitting" size="small" @click="dialogFormVisibleLink=false">取 消</el-button>
<!-- 修改人:Ld 修改时间:2026-08-11 09:42:28; 关联合同补货提交期间禁用确认按钮,避免重复点击生成多张订单。 -->
<el-button :loading="linkSubmitting" :disabled="linkSubmitting" type="primary" size="small" @click="submitLinkedOrder">确 定</el-button>
</div>
</el-dialog>
<el-dialog v-el-drag-dialog :visible.sync="dialogFormVisible2" title="上传图片" center style="height: 800px" width="30%">
@@ -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 {
}
</script>
<style>
.is-rotate {
/* 修改人:Ld 修改时间:2026-08-11 09:14:50; 限定报缺补货页面样式作用域,避免全局 el-card__body flex 导致其他页面表格偏移。 */
.replenishment-page .is-rotate {
-webkit-transform: rotate(180deg);
-moz-transform: rotate(180deg);
-o-transform: rotate(180deg);
-ms-transform: rotate(180deg);
transform: rotate(180deg);
}
.Outsourcing {
.replenishment-page .Outsourcing {
background: #D9FFFF!important;
}
.red {
.replenishment-page .red {
color: #e88383!important;
font-weight: bold;
}
.yellow {
.replenishment-page .yellow {
color: orange!important;
font-weight: bold;
}
.el-card__body{
.replenishment-page .replenishment-card > .el-card__body{
display: flex;
}

Binary file not shown.