-
- {{ item.scheduleNo }}
- {{
- statusMap[item.scheduleStatus] || '未知' }}
-
-
- 生产日期:{{ item.prodDate || '-' }} 客户:{{ item.customerName || '-' }} 业务员:{{ item.businessUser || '-' }}
-
-
-
+
+
+
+ {{ item.scheduleNo }}
+ {{
+ statusMap[item.scheduleStatus] || '未知' }}
+
+
+ 生产日期:{{ item.prodDate || '-' }} 客户:{{ item.customerName || '-' }} 业务员:{{ item.businessUser || '-' }}
+
+
+
+
+
+
+ 跳转排产
+
@@ -362,7 +369,7 @@
-
+
@@ -382,6 +389,25 @@
总数量:{{ bindPreviewTotalQty }} 吨
含税总额:{{ bindPreviewTotalAmount }}
+
+
+
+ 该订单已绑定以下产需单:
+
+
+
+ {{ rel.scheduleNo }}
+ {{ bindPreviewRelStatusMap[rel.scheduleStatus] || '' }}
+
+
+
@@ -471,6 +497,10 @@ export default {
bindPreviewProductName: '',
bindPreviewTotalQty: 0,
bindPreviewTotalAmount: 0,
+ // 当前预览订单已绑定的产需单列表
+ bindPreviewExistingRels: [],
+ // 产需单状态映射(用于展示绑定状态)
+ bindPreviewRelStatusMap: { 0: '草稿', 1: '待审核', 2: '已下达', 3: '已退回' },
// 排产明细
detailLoading: false,
@@ -559,6 +589,18 @@ export default {
this.getList()
},
+ // 跳转到排产单页面(路由跳转)
+ handleJumpToSchedule(item) {
+ this.$router.push({
+ path: '/aps/schedule',
+ query: {
+ prodDate: item.prodDate || '',
+ scheduleNo: item.scheduleNo || '',
+ scheduleStatus: item.scheduleStatus
+ }
+ })
+ },
+
statusBadgeType(status) {
return this.statusBadgeMap[status] || 'gray'
},
@@ -738,6 +780,7 @@ export default {
this.bindPreviewProductName = ''
this.bindPreviewTotalQty = 0
this.bindPreviewTotalAmount = 0
+ this.bindPreviewExistingRels = []
this.searchBindOrders()
},
@@ -780,6 +823,29 @@ export default {
this.bindPreviewTotalQty = 0
this.bindPreviewTotalAmount = 0
}
+ // 查询该订单已关联了哪些产需单
+ this.bindPreviewExistingRels = []
+ listRel({ orderId: order.orderId }).then(res => {
+ const rows = res.rows || []
+ // 按 scheduleId 去重,并与当前已有的 reqList 匹配获取单号
+ const seen = new Set()
+ const reqMap = new Map()
+ ;(this.reqList || []).forEach(r => reqMap.set(r.scheduleId, r))
+ const unique = []
+ rows.forEach(r => {
+ const key = r.scheduleId
+ if (!key || seen.has(key)) return
+ seen.add(key)
+ // 从已加载的 reqList 中找单号,找不到则不展示(已删除或不在当前页)
+ const match = reqMap.get(key)
+ if (match) {
+ unique.push({ ...r, scheduleNo: match.scheduleNo, scheduleStatus: match.scheduleStatus })
+ }
+ })
+ this.bindPreviewExistingRels = unique
+ }).catch(() => {
+ this.bindPreviewExistingRels = []
+ })
},
confirmBind() {
@@ -1038,6 +1104,31 @@ export default {
transition: background 0.15s;
}
+.list-item-body {
+ display: flex;
+ align-items: stretch;
+ gap: 8px;
+}
+
+.list-item-left {
+ flex: 1;
+ min-width: 0;
+}
+
+.list-item-right {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-shrink: 0;
+ padding-left: 4px;
+}
+
+.item-actions {
+ display: flex;
+ gap: 8px;
+ margin-top: 4px;
+}
+
.list-item:hover {
background: $aps-silver-1;
}
@@ -1063,10 +1154,6 @@ export default {
margin-bottom: 4px;
}
-.list-item .item-actions {
- display: flex;
- gap: 8px;
-}
// ====== 徽标 ======
.badge {
diff --git a/klp-ui/src/views/wms/post/aps/schedule.vue b/klp-ui/src/views/wms/post/aps/schedule.vue
index 4047323f8..a0f9a42a8 100644
--- a/klp-ui/src/views/wms/post/aps/schedule.vue
+++ b/klp-ui/src/views/wms/post/aps/schedule.vue
@@ -626,7 +626,7 @@
请为每条明细配置工序,所有明细配置完成后才能接收。
-
+
@@ -634,8 +634,8 @@
- handleReceiveProcessChange(scope.row, val, data)"
/>
@@ -682,6 +682,14 @@ import draggable from 'vuedraggable'
export default {
name: 'ApsSchedule',
components: { ProcessSelect, draggable },
+ components: { ProcessSelect },
+ props: {
+ // 由 flow.vue 通过 switchApsPage 传入的参数
+ apsParams: {
+ type: Object,
+ default: null
+ }
+ },
data() {
const today = new Date()
const y = today.getFullYear()
@@ -769,7 +777,49 @@ export default {
this.refreshScheduledStepItems()
}
},
+ watch: {
+ // 接收 flow.vue 传入的参数:设置日期并自动查询
+ apsParams: {
+ handler(val) {
+ if (val && val.prodDate) {
+ this.queryDate = val.prodDate
+ }
+ if (val && val.scheduleStatus !== undefined) {
+ // 根据产需单状态自动切换 Tab
+ // 1=待审核 2=已接收 4=已排产
+ const statusToTab = { 1: 'pending', 2: 'accepted', 4: 'scheduled' }
+ const tab = statusToTab[val.scheduleStatus] || 'pending'
+ this.activeTab = tab
+ }
+ this.$nextTick(() => {
+ this.handleQuery()
+ })
+ },
+ immediate: false
+ }
+ },
created() {
+ // 优先从路由参数获取(产需单点击"跳转排产"通过 $router.push 传参)
+ const query = this.$route.query
+ // 其次从 apsParams prop 获取(弹窗内由 flow.vue 切换组件传入)
+ const params = this.apsParams
+
+ let hasExternal = false
+ if (query && query.prodDate) {
+ this.queryDate = query.prodDate
+ hasExternal = true
+ if (query.scheduleStatus !== undefined) {
+ const statusToTab = { 1: 'pending', 2: 'accepted', 4: 'scheduled' }
+ this.activeTab = statusToTab[Number(query.scheduleStatus)] || 'pending'
+ }
+ } else if (params && params.prodDate) {
+ this.queryDate = params.prodDate
+ hasExternal = true
+ if (params.scheduleStatus !== undefined) {
+ const statusToTab = { 1: 'pending', 2: 'accepted', 4: 'scheduled' }
+ this.activeTab = statusToTab[params.scheduleStatus] || 'pending'
+ }
+ }
this.handleQuery()
},
methods: {
diff --git a/klp-ui/src/views/wms/post/flow.vue b/klp-ui/src/views/wms/post/flow.vue
index 5bcb72160..db3ce6a13 100644
--- a/klp-ui/src/views/wms/post/flow.vue
+++ b/klp-ui/src/views/wms/post/flow.vue
@@ -44,6 +44,7 @@
v-if="dynamicComponent && !dialogLoading"
:is="dynamicComponent"
:key="dialogKey"
+ :aps-params="apsDialogParams"
/>
@@ -129,8 +130,7 @@ const NODE_EVENT_CONFIG = {
{ id: 'H', label: '选择工艺路线', handler: 'handleOpen', params: { componentPath: 'wms/post/aps/schedule' } },
{ id: 'I', label: '自动生成排产项', handler: 'handleOpen', params: { componentPath: 'wms/post/aps/schedule' } },
{ id: 'J', label: '已排产明细管理', handler: 'handleOpen', params: { componentPath: 'wms/post/aps/schedule' } },
- { id: 'K', label: '按工序绑定钢卷', handler: 'handleOpen', params: { componentPath: 'wms/post/aps/compare' } },
- { id: 'L', label: '执行生产', handler: 'handleOpen', params: { componentPath: 'wms/post/aps/schedule' } },
+ { id: 'K', label: '执行生产', handler: 'handleOpen', params: { componentPath: 'wms/post/aps/schedule' } },
],
equipmentRepair: [
{ id: 'A', label: '创建维修计划', handler: 'handleOpen', params: { componentPath: 'wms/post/eqp/index' } },
@@ -164,11 +164,14 @@ const NODE_EVENT_CONFIG = {
inspection: [
{ id: 'A', label: '维护检验方案模板', handler: 'handleOpen', params: { componentPath: 'mes/qc/template/index' } },
- { id: 'B', label: '取样/检验数据录入', handler: 'handleOpen', params: { componentPath: 'mes/qc/inspectionSample/index' } },
- { id: 'D', label: '常规检验录入', handler: 'handleOpen', params: { componentPath: 'mes/qc/inspectionSample/index' } },
+ { id: 'B', label: '检验数据录入', handler: 'handleOpen', params: { componentPath: 'mes/qc/inspectionSample/index' } },
+ { id: 'D', label: '化学检验数据', handler: 'handleOpen', params: { componentPath: 'mes/qc/inspectionSample/index' } },
{ id: 'E', label: '拉伸检验(专项)', handler: 'handleOpen', params: { componentPath: 'mes/qc/inspectionTensile/index' } },
- { id: 'H', label: '生成质量证明书', handler: 'handleOpen', params: { componentPath: 'mes/qc/certificate/book' } },
- { id: 'I', label: '触发质量评审', handler: 'handleOpen', params: { componentPath: 'mes/qc/qualityReview/index' } },
+ { id: 'F', label: '创建审批申请', handler: 'handleOpen', params: { componentPath: 'mes/qc/approval/index' } },
+ { id: 'H', label: '审批中', handler: 'handleOpen', params: { componentPath: 'mes/qc/approval/index' } },
+ { id: 'J', label: '填写检验数据', handler: 'handleOpen', params: { componentPath: 'mes/qc/approval/index' } },
+ { id: 'M', label: '生成质量证明书', handler: 'handleOpen', params: { componentPath: 'mes/qc/certificate/book' } },
+ { id: 'N', label: '触发质量评审', handler: 'handleOpen', params: { componentPath: 'mes/qc/qualityReview/index' } },
],
qualityReview: [
@@ -320,9 +323,8 @@ graph TD
H --> I["
自动生成排产项按工序步骤分组"]:::p7
I --> J["
已排产明细管理按步骤查看/编辑
内联修改排产状态"]:::p7
- J --> K["
按工序绑定钢卷将现存钢卷绑定到
对应的排产明细"]:::p8
- K --> L["
执行生产"]:::p9
- L --> M(["
排产完结"]):::pend
+ J --> K["
执行生产"]:::p8
+ K --> L(["
排产完结"]):::pend
classDef p1 fill:#409eff,stroke:#337ecc,color:#fff,stroke-width:2px
classDef p2 fill:#e6fffa,stroke:#13c2c2,color:#303133,stroke-width:2px
@@ -332,7 +334,6 @@ graph TD
classDef p6 fill:#fffbe6,stroke:#fadb14,color:#606266,stroke-width:2px
classDef p7 fill:#fff0f6,stroke:#eb2f96,color:#303133,stroke-width:2px
classDef p8 fill:#f6ffed,stroke:#52c41a,color:#303133,stroke-width:2px
- classDef p9 fill:#f0f5ff,stroke:#597ef7,color:#303133,stroke-width:2px
classDef dec fill:#f9f0ff,stroke:#722ed1,color:#303133,stroke-width:2px
classDef pend fill:#dcf7e8,stroke:#52c41a,color:#303133,stroke-width:2px,rx:10,ry:10
linkStyle default stroke:#bfbfbf,stroke-width:2px
@@ -427,25 +428,34 @@ graph TD
inspection: `
graph TD
- A["
维护检验方案模板定义检验项/单位/标准"]:::i1
- A --> B["
取样/检验数据录入选择方案模板
动态生成检验项表格"]:::i2
- B --> C{"检验项类型"}:::dec
- C -->|常规项| D["
常规检验录入直接在模板表格
填写检测数据"]:::i3
- C -->|拉伸试验| E["
拉伸检验(专项)独立试验记录
管理明细数据"]:::i4
- D --> F["
汇总检验结果"]:::i5
+ A["
维护检验方案模板定义检验项目/单位/标准值"]:::i1
+ A --> B["
检验数据录入选择方案模板
填写样品信息
录入检验结果"]:::i2
+ B --> C{"检验类型"}:::dec
+ C -->|化学检验| D["
化学检验数据按模板动态生成
检验项表格并填值"]:::i3
+ C -->|物理检验| E["
拉伸检验(专项)独立试验记录
管理明细数据"]:::i4
+ D --> F["
创建审批申请关联检验记录
填写申请信息"]:::i5
E --> F
- F --> G{"判定"}:::dec
- G -->|合格| H["
生成质量证明书汇总全部检验数据"]:::i6
- G -->|不合格| I["
触发质量评审进入评审流程"]:::i7
- H --> J(["检验归档"]):::iend
+ F --> G{"审批流转"}:::dec
+ G -->|送审| H["
审批中待审批"]:::i6
+ H --> I{"审批"}:::dec
+ I -->|通过| J["
填写检验数据录入详细检验结果
含判定"]:::i7
+ I -->|驳回| K["
退回修改重新编辑后送审"]:::i8
+ K --> F
+ J --> L{"判定"}:::dec
+ L -->|合格| M["
生成质量证明书管理/编辑/打印
支持化学/物理模板"]:::i9
+ L -->|不合格| N["
触发质量评审进入评审流程"]:::i10
+ M --> O(["检验归档"]):::iend
classDef i1 fill:#409eff,stroke:#337ecc,color:#fff,stroke-width:2px
classDef i2 fill:#e6fffa,stroke:#13c2c2,color:#303133,stroke-width:2px
classDef i3 fill:#fff7e6,stroke:#fa8c16,color:#303133,stroke-width:2px
classDef i4 fill:#f0f5ff,stroke:#597ef7,color:#303133,stroke-width:2px
classDef i5 fill:#fffbe6,stroke:#fadb14,color:#303133,stroke-width:2px
- classDef i6 fill:#f6ffed,stroke:#52c41a,color:#303133,stroke-width:2px
- classDef i7 fill:#fff1f0,stroke:#f5222d,color:#303133,stroke-width:2px
+ classDef i6 fill:#e6f7ff,stroke:#1890ff,color:#303133,stroke-width:2px
+ classDef i7 fill:#f6ffed,stroke:#52c41a,color:#303133,stroke-width:2px
+ classDef i8 fill:#fff1f0,stroke:#f5222d,color:#303133,stroke-width:2px
+ classDef i9 fill:#f0f5ff,stroke:#597ef7,color:#303133,stroke-width:2px
+ classDef i10 fill:#fff1f0,stroke:#f5222d,color:#303133,stroke-width:2px
classDef dec fill:#f9f0ff,stroke:#722ed1,color:#303133,stroke-width:2px
classDef iend fill:#dcf7e8,stroke:#52c41a,color:#303133,stroke-width:2px,rx:10,ry:10
linkStyle default stroke:#bfbfbf,stroke-width:2px
@@ -524,6 +534,8 @@ export default {
dialogLoading: false,
dynamicComponent: null,
dialogKey: 0,
+ // APS 页面切换参数(传递给子组件)
+ apsDialogParams: null,
}
},
@@ -692,6 +704,7 @@ export default {
this.dialogWidth = dialogWidth
this.dialogLoading = true
this.dynamicComponent = null
+ this.apsDialogParams = params || null
this.resolveImport(componentPath)
.then(module => {
@@ -707,6 +720,36 @@ export default {
})
},
+ /**
+ * APS 页面间切换(由子组件调用 this.$parent.switchApsPage)
+ * @param {string} componentPath - 相对于 @/views/ 的路径,如 'wms/post/aps/schedule'
+ * @param {object} params - 传递给目标组件的参数
+ * @param {string} title - 弹窗标题
+ */
+ switchApsPage(componentPath, params, title) {
+ if (!componentPath) {
+ this.$message.warning('组件路径不能为空')
+ return
+ }
+
+ this.dialogLoading = true
+ this.dynamicComponent = null
+ this.apsDialogParams = params || null
+ if (title) this.dialogTitle = title
+
+ this.resolveImport(componentPath)
+ .then(module => {
+ this.dynamicComponent = module.default || module
+ })
+ .catch(err => {
+ console.error('[FlowChart] switchApsPage error:', err)
+ this.$message.error('组件加载失败: ' + (err.message || '未知错误'))
+ })
+ .finally(() => {
+ this.dialogLoading = false
+ })
+ },
+
resolveImport(componentPath) {
// 与 src/store/modules/permission.js 的 loadView 同款模式
// componentPath 相对于 @/views/,如 'crm/order/index'
@@ -721,6 +764,7 @@ export default {
handleDialogClosed() {
this.dynamicComponent = null
this.dialogKey++
+ this.apsDialogParams = null
},
},
}
diff --git a/klp-wms/src/main/java/com/klp/domain/WmsEmployeeInfo.java b/klp-wms/src/main/java/com/klp/domain/WmsEmployeeInfo.java
index 4875d1859..8d4e35d75 100644
--- a/klp-wms/src/main/java/com/klp/domain/WmsEmployeeInfo.java
+++ b/klp-wms/src/main/java/com/klp/domain/WmsEmployeeInfo.java
@@ -6,6 +6,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
+import java.math.BigDecimal;
import com.fasterxml.jackson.annotation.JsonFormat;
/**
@@ -86,6 +87,18 @@ public class WmsEmployeeInfo extends BaseEntity {
* 社保类型(三险/五险)
*/
private String socialInsuranceType;
+ /**
+ * 底薪(元)
+ */
+ private BigDecimal baseSalary;
+ /**
+ * 岗位绩效基数(元), 默认≈底薪×20%
+ */
+ private BigDecimal perfBase;
+ /**
+ * 默认岗位系数(初始值,后续月度由绩效自动覆盖)
+ */
+ private BigDecimal posCoeffDefault;
/**
* 逻辑删除标识:0=正常,1=已删
*/
diff --git a/klp-wms/src/main/java/com/klp/domain/bo/WmsEmployeeInfoBo.java b/klp-wms/src/main/java/com/klp/domain/bo/WmsEmployeeInfoBo.java
index bd259c6c6..2e8fc3f83 100644
--- a/klp-wms/src/main/java/com/klp/domain/bo/WmsEmployeeInfoBo.java
+++ b/klp-wms/src/main/java/com/klp/domain/bo/WmsEmployeeInfoBo.java
@@ -6,6 +6,7 @@ import lombok.EqualsAndHashCode;
import javax.validation.constraints.*;
import java.util.Date;
+import java.math.BigDecimal;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
@@ -114,6 +115,21 @@ public class WmsEmployeeInfoBo extends BaseEntity {
*/
private String socialInsuranceType;
+ /**
+ * 底薪(元)
+ */
+ private BigDecimal baseSalary;
+
+ /**
+ * 岗位绩效基数(元), 默认≈底薪×20%
+ */
+ private BigDecimal perfBase;
+
+ /**
+ * 默认岗位系数(初始值,后续月度由绩效自动覆盖)
+ */
+ private BigDecimal posCoeffDefault;
+
/**
* 备注
*/
diff --git a/klp-wms/src/main/java/com/klp/domain/vo/WmsEmployeeInfoVo.java b/klp-wms/src/main/java/com/klp/domain/vo/WmsEmployeeInfoVo.java
index 392141374..2ef6e4685 100644
--- a/klp-wms/src/main/java/com/klp/domain/vo/WmsEmployeeInfoVo.java
+++ b/klp-wms/src/main/java/com/klp/domain/vo/WmsEmployeeInfoVo.java
@@ -1,6 +1,7 @@
package com.klp.domain.vo;
import java.util.Date;
+import java.math.BigDecimal;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
@@ -117,6 +118,24 @@ public class WmsEmployeeInfoVo {
*/
private String socialInsuranceType;
+ /**
+ * 底薪(元)
+ */
+ @ExcelProperty(value = "底薪(元)")
+ private BigDecimal baseSalary;
+
+ /**
+ * 岗位绩效基数(元), 默认≈底薪×20%
+ */
+ @ExcelProperty(value = "岗位绩效基数(元)")
+ private BigDecimal perfBase;
+
+ /**
+ * 默认岗位系数(初始值,后续月度由绩效自动覆盖)
+ */
+ @ExcelProperty(value = "默认岗位系数")
+ private BigDecimal posCoeffDefault;
+
/**
* 备注
*/
diff --git a/klp-wms/src/main/java/com/klp/service/impl/WmsEmployeeInfoServiceImpl.java b/klp-wms/src/main/java/com/klp/service/impl/WmsEmployeeInfoServiceImpl.java
index b7f5c8521..bca353ae4 100644
--- a/klp-wms/src/main/java/com/klp/service/impl/WmsEmployeeInfoServiceImpl.java
+++ b/klp-wms/src/main/java/com/klp/service/impl/WmsEmployeeInfoServiceImpl.java
@@ -81,6 +81,9 @@ public class WmsEmployeeInfoServiceImpl implements IWmsEmployeeInfoService {
lqw.eq(StringUtils.isNotBlank(bo.getRelationship()), WmsEmployeeInfo::getRelationship, bo.getRelationship());
lqw.eq(StringUtils.isNotBlank(bo.getEmergencyContactPhone()), WmsEmployeeInfo::getEmergencyContactPhone, bo.getEmergencyContactPhone());
lqw.eq(StringUtils.isNotBlank(bo.getSocialInsuranceType()), WmsEmployeeInfo::getSocialInsuranceType, bo.getSocialInsuranceType());
+ lqw.eq(bo.getBaseSalary() != null, WmsEmployeeInfo::getBaseSalary, bo.getBaseSalary());
+ lqw.eq(bo.getPerfBase() != null, WmsEmployeeInfo::getPerfBase, bo.getPerfBase());
+ lqw.eq(bo.getPosCoeffDefault() != null, WmsEmployeeInfo::getPosCoeffDefault, bo.getPosCoeffDefault());
// 是否离职
lqw.eq(bo.getIsLeave() != null, WmsEmployeeInfo::getIsLeave, bo.getIsLeave());
// 离职时间范围查询
diff --git a/klp-wms/src/main/resources/mapper/klp/WmsEmployeeInfoMapper.xml b/klp-wms/src/main/resources/mapper/klp/WmsEmployeeInfoMapper.xml
index 305120f13..b5c66a4c6 100644
--- a/klp-wms/src/main/resources/mapper/klp/WmsEmployeeInfoMapper.xml
+++ b/klp-wms/src/main/resources/mapper/klp/WmsEmployeeInfoMapper.xml
@@ -21,6 +21,9 @@
+
+
+