# 不合格品处理单模块(QualityUnqualifiedOrder)
## 概述
不合格品处理单是正式的不合格品处置流程模块,替代旧的不合格管理(`/quality/qualityUnqualified`)中的处置功能。旧模块的不合格品发现(新增/列表/详情)继续使用,但**处置操作统一使用本模块**。
### 自动创建机制
当检验单(原材料/过程/出厂检验)提交时,如果**不合格数量 > 0**,系统在创建 `QualityUnqualified` 记录的同时,**自动创建一条不合格品处理单**,`unqualifiedProcess`(不合格工序)根据检验类别自动映射:
| 检验类别 | inspectType | unqualifiedProcess |
|----------|-------------|-------------------|
| 原材料检验 | 0 | 1(来料) |
| 过程检验 | 0 | 2(制程) |
| 出厂检验 | 0 | 3(成品) |
处理单初始状态为 `0`(草稿),后续可编辑处置方式并提交审批。
### 与旧模块的关系
| | 旧:不合格管理 | 新:不合格品处理单 |
|---|---|---|
| 路径 | `/quality/qualityUnqualified` | `/qualityUnqualifiedOrder` |
| 用途 | 不合格品首次记录、查看 | 正式处置流程(含审批) |
| 处置方式 | `dealResult` 自由文本 | `disposalMethod` 结构化枚举 |
| 创建方式 | 检验单提交自动创建 / 手动新增 | 检验单提交自动创建 / 手动新增 |
## 涉及页面
- 不合格品处理单列表页
- 不合格品处理单新增/编辑页
- 不合格品处理单详情页
## API
### 1. 新增处理单
| 方法 | 路径 | 说明 |
|------|------|------|
| POST | /qualityUnqualifiedOrder/save | 新增不合格品处理单 |
**请求参数:**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| unqualifiedId | Long | 是 | 关联不合格品ID |
| projectName | String | 否 | 项目名称 |
| projectNo | String | 否 | 项目编号 |
| equipmentId | Long | 否 | 关联设备ID |
| equipmentName | String | 否 | 设备名称 |
| equipmentDrawingNo | String | 否 | 设备图号 |
| materialName | String | 否 | 物料/部件名称 |
| productModelId | Long | 否 | 关联产品型号ID |
| materialDrawingNo | String | 否 | 物料图号 |
| specificationModel | String | 否 | 型号规格 |
| materialQuality | String | 否 | 材质 |
| quantity | BigDecimal | 否 | 总数量 |
| unqualifiedQuantity | BigDecimal | 否 | 不合格数量 |
| unqualifiedProcess | Integer | 否 | 不合格工序:1=来料, 2=制程, 3=成品 |
| supplierName | String | 否 | 供应商名称 |
| inspectorName | String | 否 | 检验员 |
| inspectDate | Date | 否 | 检验日期 (yyyy-MM-dd) |
| responsiblePerson | String | 否 | 责任人 |
| responsibleDept | String | 否 | 责任部门 |
| problemDescription | String | 否 | 问题描述 |
| reasonAnalysis | String | 否 | 原因分析及建议 |
| correctionAction | String | 否 | 纠正措施 |
| **disposalMethod** | **Integer** | **是** | **处置方式:1=让步接收, 2=厂内维修, 3=返厂维修, 4=换货, 5=退货, 6=报废** |
| repairEvaluation | String | 否 | 厂内/返厂维修评估 |
| preventiveAction | String | 否 | 预防措施 |
| remark | String | 否 | 备注 |
| deptOpinion | String | 否 | 责任部门主管意见 |
| companyDecision | String | 否 | 公司处理决定 |
| generalManagerOpinion | String | 否 | 总经理意见 |
| storageBlobDTOs | List | 否 | 附件列表 |
**自动行为:**
- 自动生成处理单编号(`BHGyyMMdd+流水号`)
- **手动新增时**:选了处置方式 → 状态自动为 `3`(已完成);没选 → 状态为 `0`(草稿)
- **质检自动创建时**:状态初始为 `0`(草稿),需通过处理接口补充处置方式
- **当 `disposalMethod` 选择 2(厂内维修)或 3(返厂维修)时,自动创建返修生产订单**
**响应:** `{ "code": 200, "msg": "操作成功", "data": true }`
### 2. 修改处理单
| 方法 | 路径 | 说明 |
|------|------|------|
| PUT | /qualityUnqualifiedOrder/update | 修改不合格品处理单 |
**请求参数:** 与新增相同,额外需要 `id` 字段。
### 3. 删除处理单
| 方法 | 路径 | 说明 |
|------|------|------|
| DELETE | /qualityUnqualifiedOrder/delete | 删除不合格品处理单 |
**请求参数:** `[id1, id2, ...]` — ID 数组
### 4. 分页查询
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | /qualityUnqualifiedOrder/listPage | 分页查询 |
**查询参数:**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| page | int | 否 | 页码(默认1) |
| size | int | 否 | 每页条数(默认10) |
| status | Integer | 否 | 状态:0=草稿, 1=待审批, 2=审批中, 3=已完成, 4=已驳回 |
| projectName | String | 否 | 项目名称(模糊匹配) |
| orderNo | String | 否 | 处理单编号(模糊匹配) |
| entryDateStart | String | 否 | 创建时间起 (yyyy-MM-dd) |
| entryDateEnd | String | 否 | 创建时间止 (yyyy-MM-dd) |
**响应字段:** 返回 `QualityUnqualifiedOrder` 全部字段,含 `storageBlobVOs`(附件列表)。
### 5. 详情查询
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | /qualityUnqualifiedOrder/{id} | 处理单详情 |
**响应:** 返回单条 `QualityUnqualifiedOrder` 全部字段,含附件。
### 6. 处理(处置)
| 方法 | 路径 | 说明 |
|------|------|------|
| POST | /qualityUnqualifiedOrder/deal | 对草稿状态的处理单补充处置方式并完成 |
**请求参数:**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| **id** | **Long** | **是** | 处理单ID |
| **disposalMethod** | **Integer** | **是** | **处置方式:1=让步接收, 2=厂内维修, 3=返厂维修, 4=换货, 5=退货, 6=报废** |
| repairEvaluation | String | 否 | 厂内/返厂维修评估 |
| reasonAnalysis | String | 否 | 原因分析及建议 |
| correctionAction | String | 否 | 纠正措施 |
| preventiveAction | String | 否 | 预防措施 |
| remark | String | 否 | 备注 |
| deptOpinion | String | 否 | 责任部门主管意见 |
| companyDecision | String | 否 | 公司处理决定 |
| generalManagerOpinion | String | 否 | 总经理意见 |
**自动行为:**
- 状态更新为 `3`(已完成)
- 处置方式为 2(厂内维修)或 3(返厂维修)时,自动创建返修生产订单
**响应:** `{ "code": 200, "msg": "操作成功", "data": true }`
### 7. 导出处理单
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | /qualityUnqualifiedOrder/export/{id} | 导出不合格品处理单为 Excel |
**请求参数:** `id` — 处理单ID(路径参数)
**响应:** 文件流,`Content-Type: application/vnd.ms-excel`,文件名 `不合格品处理单_{编号}.xls`
**模板字段映射:**
| 模板位置 | 字段 |
|----------|------|
| 项目名称 | projectName |
| 项目编号 | projectNo |
| 设备名称 | equipmentName |
| 设备图号 | equipmentDrawingNo |
| 物料名称 | materialName |
| 物料图号 | materialDrawingNo |
| 型号规格 | specificationModel |
| 材质 | materialQuality |
| 总数量 | quantity |
| 不合格数 | unqualifiedQuantity |
| 不合格工序 | unqualifiedProcess(勾选来料/制程/成品) |
| 供货商名称 | supplierName |
| 检验员 | inspectorName |
| 检验日期 | inspectDate |
| 责任人 | responsiblePerson |
| 责任部门 | responsibleDept |
| 问题描述 | problemDescription |
| 原因分析及建议 | reasonAnalysis |
| 纠正措施 | correctionAction |
| 处置方式 | disposalMethod(勾选对应选项) |
| 厂内/返厂维修评估 | repairEvaluation |
| 预防措施 | preventiveAction |
| 责任部门主管意见 | deptOpinion |
| 公司处理决定 | companyDecision |
| 总经理意见 | generalManagerOpinion |
**前端调用示例:**
```js
// 列表页操作列增加导出按钮
导出
// 详情页增加导出按钮
导出
methods: {
handleExport(id) {
window.open(`/api/qualityUnqualifiedOrder/export/${id}`);
},
}
```
## 前端修改点
### 1. 处理单列表页
```html
查询
重置
新增处理单
删除
{{ disposalMethodMap[row.disposalMethod] }}
{{ statusMap[row.status] }}
详情
编辑
```
```js
data() {
return {
list: [],
total: 0,
page: 1,
size: 10,
selectedIds: [],
dateRange: [],
queryParams: {
orderNo: '',
projectName: '',
status: null,
},
disposalMethodMap: { 1: '让步接收', 2: '厂内维修', 3: '返厂维修', 4: '换货', 5: '退货', 6: '报废' },
statusMap: { 0: '草稿', 1: '待审批', 2: '审批中', 3: '已完成', 4: '已驳回' },
}
},
methods: {
statusTagType(status) {
const map = { 0: 'info', 1: 'warning', 2: '', 3: 'success', 4: 'danger' };
return map[status] || 'info';
},
loadList() {
const params = { ...this.queryParams, page: this.page, size: this.size };
if (this.dateRange && this.dateRange.length === 2) {
params.entryDateStart = this.dateRange[0];
params.entryDateEnd = this.dateRange[1];
}
listPage(params).then(res => {
this.list = res.rows;
this.total = res.total;
});
},
handleQuery() { this.page = 1; this.loadList(); },
resetQuery() {
this.queryParams = { orderNo: '', projectName: '', status: null };
this.dateRange = [];
this.handleQuery();
},
handleSelectionChange(selection) { this.selectedIds = selection.map(i => i.id); },
handleAdd() { this.$router.push('/quality/unqualified-order/add'); },
handleEdit(row) { this.$router.push({ path: '/quality/unqualified-order/edit', query: { id: row.id } }); },
handleDetail(id) { this.$router.push({ path: '/quality/unqualified-order/detail', query: { id } }); },
handleDelete() {
this.$confirm('确认删除选中的处理单?').then(() => {
deleteOrders(this.selectedIds).then(() => {
this.$message.success('删除成功');
this.loadList();
});
});
},
}
```
### 2. 新增/编辑处理单页
```html
基本信息
不合格信息
处置决策
让步接收
厂内维修
返厂维修
换货
退货
报废
审批意见
附件
提交
取消
```
```js
data() {
return {
form: {
unqualifiedId: null,
disposalMethod: null,
},
rules: {
unqualifiedId: [{ required: true, message: '请选择关联不合格品', trigger: 'change' }],
disposalMethod: [{ required: true, message: '请选择处置方式', trigger: 'change' }],
},
unqualifiedList: [],
}
},
mounted() {
// 加载待处理的不合格品列表
loadUnqualifiedList({ inspectState: 0 }).then(res => this.unqualifiedList = res.rows);
if (this.$route.query.id) {
getDetail(this.$route.query.id).then(res => this.form = res.data);
}
},
methods: {
handleSubmit() {
this.$refs.form.validate(valid => {
if (!valid) return;
const api = this.form.id ? updateOrder : saveOrder;
api(this.form).then(() => {
this.$message.success(this.form.id ? '修改成功' : '新增成功');
this.$router.back();
});
});
},
handleCancel() { this.$router.back(); },
}
```
## 处置方式说明
| 值 | 含义 | 系统自动行为 |
|----|------|------------|
| 1 | 让步接收 | 无自动操作,需人工后续处理 |
| 2 | 厂内维修 | **自动创建返修生产订单**(FG 开头 NPS 编号),克隆原工序路线 |
| 3 | 返厂维修 | **自动创建返修生产订单**(FG 开头 NPS 编号),克隆原工序路线 |
| 4 | 换货 | 无自动操作 |
| 5 | 退货 | 无自动操作 |
| 6 | 报废 | 无自动操作(库存扣减由旧模块 `/quality/qualityUnqualified/deal` 处理) |
## 状态流转
```
质检自动创建 ──> 0(草稿) ──> 调用 /deal 选择处置方式 ──> 3(已完成)
手动新增(没选处置方式) ──> 0(草稿) ──> 调用 /deal ──> 3(已完成)
手动新增(选了处置方式) ──> 3(已完成)
```
## 注意事项
- 检验单提交时,不合格数量 > 0 会自动创建处理单(状态为草稿),**无需手动新增**
- 手动新增处理单时,选了处置方式直接完成,没选则保持草稿
- 草稿状态的处理单通过 `/qualityUnqualifiedOrder/deal` 接口补充处置方式
- 旧的不合格管理(`/quality/qualityUnqualified`)继续用于不合格品首次记录和列表查看
- 处置操作统一使用本模块(`/qualityUnqualifiedOrder`)
- 选择"厂内维修"或"返厂维修"时,系统自动创建返修生产订单,无需手动操作
- 返修生产订单的 `disposalMethod` 字段标记了处置方式,可在生产订单列表区分普通订单和返修订单
- 处理单编号自动生成,前缀为 `BHG`
- 附件通过 `storageBlobDTOs` 字段上传,查询时返回 `storageBlobVOs`