Merge branch '0.8.X' of https://gitee.com/hdka/klp-oa into 0.8.X

This commit is contained in:
砂糖
2026-01-16 10:49:23 +08:00
10 changed files with 361 additions and 108 deletions

View File

@@ -237,7 +237,7 @@
</el-dialog>
<el-dialog title="钢卷信息修正" :visible.sync="correctVisible" width="600px">
<el-form ref="form" :model="form" label-width="100px">
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-form-item label="入场钢卷号" prop="enterCoilNo">
<el-input v-model="form.enterCoilNo" placeholder="请输入入场钢卷号" :disabled="form.coilId" />
</el-form-item>
@@ -284,7 +284,8 @@
<el-option label="C+" value="C+" />
<el-option label="C" value="C" />
<el-option label="C-" value="C-" /> -->
<el-option v-for="item in dict.type.coil_quality_status" :key="item.value" :label="item.label" :value="item.value" />
<el-option v-for="item in dict.type.coil_quality_status" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
@@ -339,9 +340,9 @@
</template>
<script>
import { listMaterialCoil, updateMaterialCoilSimple } from '@/api/wms/coil'
import { listMaterialCoil, updateMaterialCoilSimple, checkCoilNo } from '@/api/wms/coil'
import { listUser } from '@/api/system/user'
import { listPendingAction, startProcess, cancelAction, delPendingAction, addPendingAction } from '@/api/wms/pendingAction'
import { listPendingAction, startProcess, cancelAction, delPendingAction } from '@/api/wms/pendingAction'
import { parseTime } from '@/utils/klp'
import ProductInfo from '@/components/KLPService/Renderer/ProductInfo'
import RawMaterialInfo from '@/components/KLPService/Renderer/RawMaterialInfo'
@@ -417,6 +418,77 @@ export default {
degree: null,
remark: null
},
// 表单校验
rules: {
planId: [
{ required: true, message: "请选择收货计划", trigger: "change" }
],
enterCoilNo: [
{ required: true, message: "入场钢卷号不能为空", trigger: "blur" },
// 自定义校验必须是8位的阿拉伯数字
{
validator: (rule, value, callback) => {
if (!/^\d{8}$/.test(value)) {
callback(new Error('入场钢卷号必须是8位的阿拉伯数字'));
} else {
callback();
}
}, trigger: 'blur'
},
{
validator: (rule, value, callback) => {
if (this.form.coilId) {
// 新增时触发校验
console.log('新增时触发校验');
callback();
} else {
checkCoilNo({ enterCoilNo: value }).then(res => {
const { duplicateType } = res.data;
if (duplicateType === 'enter' || duplicateType === 'both') {
// alert('入场钢卷号重复,请重新输入');
callback(new Error('入场钢卷号重复,请重新输入'));
} else {
callback();
}
})
}
}, trigger: 'blur'
},
],
currentCoilNo: [
{ required: true, message: "当前钢卷号不能为空", trigger: "blur" },
// 远程校验,当前钢卷号不能重复
{
validator: (rule, value, callback) => {
checkCoilNo({ currentCoilNo: value, coilId: this.form.coilId }).then(res => {
const { duplicateType } = res.data;
if (duplicateType === 'current' || duplicateType === 'both') {
// alert('当前钢卷号重复,请重新输入');
callback(new Error('当前钢卷号重复,请重新输入'));
} else {
callback();
}
})
}, trigger: 'blur'
},
],
materialType: [
{ required: true, message: "材料类型不能为空", trigger: "change" }
],
itemId: [
{ required: true, message: "物品ID不能为空", trigger: "blur" }
],
itemType: [
{ required: true, message: "物品类型不能为空", trigger: "change" }
],
// 净重和毛重
netWeight: [
{ required: true, message: "净重不能为空", trigger: "blur" }
],
grossWeight: [
{ required: true, message: "毛重不能为空", trigger: "blur" }
],
},
form: {},
correctVisible: false,
buttonLoading: false,
@@ -433,7 +505,7 @@ export default {
})
return acidAction ? parseInt(acidAction.value) : null
},
// 动态显示标签
// 动态显示标签
getItemLabel() {
if (this.form.materialType === '成品') {
return '产品类型';
@@ -555,36 +627,6 @@ export default {
this.materialQueryParams.currentCoilNo = null
this.handleMaterialQuery()
},
/** 领料操作 */
handlePickMaterial(row) {
if (!this.acidRollingActionType) {
this.$message.error(`未找到${this.label}操作类型,请检查字典配置`)
return
}
this.$set(row, 'picking', true)
const pendingData = {
coilId: row.coilId,
currentCoilNo: row.currentCoilNo,
actionType: this.acidRollingActionType,
actionStatus: 0, // 待处理
sourceType: 'manual', // 手动创建
warehouseId: row.warehouseId,
priority: 0, // 默认普通优先级
remark: `PC端领料创建-${this.label}`
}
this.$modal.confirm(`是否确认从${row.warehouseName || '仓库'}领料${row.currentCoilNo || '物料'}`).then(() => {
// 用户点击确认后执行的操作
return addPendingAction(pendingData)
}).then(response => {
this.$message.success('领料成功,已创建待操作任务')
this.getPendingAction() // 刷新待操作列表
}).finally(() => {
this.$set(row, 'picking', false)
})
},
// ========== 待操作列表相关方法 ==========
/** 查询待操作列表 */
@@ -612,15 +654,6 @@ export default {
this.actionLoading = false
})
},
/** 待操作搜索 */
handleActionQuery() {
this.actionQueryParams.pageNum = 1
// 确保始终使用酸连轧工序的 actionType
if (this.acidRollingActionType) {
this.actionQueryParams.actionType = this.acidRollingActionType
}
this.getPendingAction()
},
handleCorrectMaterial(row) {
this.form = {
...row,
@@ -632,26 +665,20 @@ export default {
},
/** 提交按钮 */
submitForm() {
this.buttonLoading = true;
updateMaterialCoilSimple(this.form).then(_ => {
this.$modal.msgSuccess("修正成功");
this.correctVisible = false;
this.getMaterialCoil();
}).finally(() => {
this.buttonLoading = false;
});
},
/** 重置待操作搜索 */
resetActionQuery() {
this.resetForm('actionQueryForm')
this.actionQueryParams.currentCoilNo = null
this.actionQueryParams.actionStatus = null
// 确保始终使用酸连轧工序的 actionType
if (this.acidRollingActionType) {
this.actionQueryParams.actionType = this.acidRollingActionType
}
this.handleActionQuery()
this.$refs['form'].validate(valid => {
if (!valid) {
this.$message.error('请填写完整信息')
return
}
this.buttonLoading = true;
updateMaterialCoilSimple(this.form).then(_ => {
this.$modal.msgSuccess("修正成功");
this.correctVisible = false;
this.getMaterialCoil();
}).finally(() => {
this.buttonLoading = false;
});
})
},
/** 处理操作 - 跳转到对应页面 */
handleProcess(row) {

View File

@@ -438,7 +438,7 @@ export default {
// 远程校验,当前钢卷号不能重复
{
validator: (rule, value, callback) => {
checkCoilNo({ currentCoilNo: value }).then(res => {
checkCoilNo({ currentCoilNo: value, coilId: this.form.coilId }).then(res => {
const { duplicateType } = res.data;
if (duplicateType === 'current' || duplicateType === 'both') {
// alert('当前钢卷号重复,请重新输入');

View File

@@ -1,5 +1,5 @@
<template>
<BasePage :qrcode="qrcode" :querys="querys" :labelType="labelType" :hideType="hideType" />
<BasePage :qrcode="qrcode" :querys="querys" :labelType="labelType" :hideType="hideType" :showControl="showControl" />
</template>
<script>
@@ -9,12 +9,13 @@ export default {
components: {
BasePage
},
data() {
data() {
return {
qrcode: true,
querys: {
dataType: 0,
},
showControl: false,
labelType: '2',
hideType: false
}

View File

@@ -22,8 +22,8 @@
<el-form-item label="实际库区" prop="actualWarehouseId" v-if="!hideWarehouseQuery">
<actual-warehouse-select v-model="queryParams.actualWarehouseId" placeholder="请选择仓库/库区/库位"
style="width: 100%; display: inline-block;" clearable
:canSelectDisabled="true" :canSelectLevel2="true" :clearInput="false" :showEmpty="true"/>
style="width: 100%; display: inline-block;" clearable :canSelectDisabled="true" :canSelectLevel2="true"
:clearInput="false" :showEmpty="true" />
</el-form-item>
<el-form-item label="产品名称" prop="itemName">
@@ -91,7 +91,8 @@
</el-table-column>
<!-- <el-table-column label="厂家卷号" align="center" prop="supplierCoilNo" /> -->
<el-table-column label="逻辑库位" align="center" prop="warehouseName" v-if="!hideWarehouseQuery" />
<el-table-column label="实际库区" align="center" prop="actualWarehouseName" v-if="!hideWarehouseQuery && !showExportTime" />
<el-table-column label="实际库区" align="center" prop="actualWarehouseName"
v-if="!hideWarehouseQuery && !showExportTime" />
<!-- <el-table-column label="物料类型" align="center" prop="materialType" /> -->
<el-table-column label="产品类型" align="center" width="250">
<template slot-scope="scope">
@@ -111,7 +112,8 @@
</el-table-column>
<el-table-column label="发货人" v-if="showExportTime" align="center" prop="exportByName" width="150">
<template slot-scope="scope">
<el-select v-model="scope.row.exportBy" placeholder="请选择发货人" filterable @change="handleExportByNameChange(scope.row)">
<el-select v-model="scope.row.exportBy" placeholder="请选择发货人" filterable
@change="handleExportByNameChange(scope.row)">
<el-option v-for="item in userList" :key="item.userName" :value="item.userName" :label="item.nickName" />
</el-select>
</template>
@@ -139,7 +141,8 @@
<el-table-column v-if="showGrade" label="质量状态" align="center" prop="qualityStatus">
<template slot-scope="scope">
<el-select v-model="scope.row.qualityStatus" placeholder="请选择质量状态" @change="handleGradeChange(scope.row)">
<el-option v-for="item in dict.type.coil_quality_status" :key="item.value" :value="item.value" :label="item.label" />
<el-option v-for="item in dict.type.coil_quality_status" :key="item.value" :value="item.value"
:label="item.label" />
</el-select>
</template>
</el-table-column>
@@ -190,8 +193,8 @@
<warehouse-select v-model="form.warehouseId" placeholder="请选择仓库/库区/库位" style="width: 100%;" clearable />
</el-form-item>
<el-form-item label="实际库区" prop="actualWarehouseId">
<actual-warehouse-select v-model="form.actualWarehouseId" :clearInput="form.coilId != null" placeholder="请选择实际库区" style="width: 100%;"
clearable />
<actual-warehouse-select v-model="form.actualWarehouseId" :clearInput="form.coilId != null"
placeholder="请选择实际库区" style="width: 100%;" clearable />
</el-form-item>
<el-form-item label="班组" prop="team">
<el-select v-model="form.team" placeholder="请选择班组" style="width: 100%">
@@ -214,7 +217,8 @@
</el-form-item>
<el-form-item label="质量状态" prop="qualityStatus">
<el-select v-model="form.qualityStatus" placeholder="请选择质量状态" style="width: 100%">
<el-option v-for="item in dict.type.coil_quality_status" :key="item.value" :label="item.label" :value="item.value" />
<el-option v-for="item in dict.type.coil_quality_status" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
@@ -407,7 +411,7 @@ export default {
{ label: 'C+', value: 'C+' },
{ label: 'C', value: 'C' },
{ label: 'C-', value: 'C-' },
{ label: 'D+', value: 'D+' },
{ label: 'D+', value: 'D+' },
{ label: 'D', value: 'D' },
{ label: 'D-', value: 'D-' },
],
@@ -503,22 +507,22 @@ export default {
// 仅在新增的时候校验
{
validator: (rule, value, callback) => {
if (this.form.coilId) {
// 修改时会有coilId不触发校验
console.log('修改时会有coilId不触发校验');
callback();
} else {
// 没有coilId则为新增 触发校验
checkCoilNo({ currentCoilNo: value }).then(res => {
const { duplicateType } = res.data;
if (duplicateType === 'current' || duplicateType === 'both') {
// alert('当前钢卷号重复,请重新输入');
callback(new Error('当前钢卷号重复,请重新输入'));
} else {
callback();
}
})
}
// if (this.form.coilId) {
// // 修改时会有coilId不触发校验
// console.log('修改时会有coilId不触发校验');
// callback();
// } else {
// 没有coilId则为新增 触发校验
checkCoilNo({ currentCoilNo: value, coilId: this.form.coilId }).then(res => {
const { duplicateType } = res.data;
if (duplicateType === 'current' || duplicateType === 'both') {
// alert('当前钢卷号重复,请重新输入');
callback(new Error('当前钢卷号重复,请重新输入'));
} else {
callback();
}
})
// }
}, trigger: 'blur'
}
],
@@ -645,16 +649,6 @@ export default {
this.loading = false;
});
},
/** 状态改变时触发 */
// handleStatusChange(row) {
// updateMaterialCoilSimple(row).then(res => {
// this.$message.success('状态更新成功');
// this.getList(); // 刷新列表
// }).catch(err => {
// console.error('状态更新失败:', err);
// this.$message.error('状态更新失败,请重试');
// });
// },
/** 追溯按钮操作 */
handleTrace(row) {
this.traceOpen = true;

View File

@@ -230,7 +230,7 @@
</template>
<script>
import { getMaterialCoil, updateMaterialCoil, getMaterialCoilTrace } from '@/api/wms/coil';
import { getMaterialCoil, updateMaterialCoil, getMaterialCoilTrace, checkCoilNo } from '@/api/wms/coil';
import { completeAction } from '@/api/wms/pendingAction';
import { listWarehouse } from '@/api/wms/warehouse';
import { listRawMaterialWithBom } from '@/api/wms/rawMaterial';
@@ -292,7 +292,22 @@ export default {
},
rules: {
currentCoilNo: [
{ required: true, message: '请输入当前钢卷号', trigger: 'blur' }
{ required: true, message: '请输入当前钢卷号', trigger: 'blur' },
// 仅在新增的时候校验
{
validator: (rule, value, callback) => {
// 没有coilId则为新增 触发校验
checkCoilNo({ currentCoilNo: value, coilId: this.updateForm.coilId }).then(res => {
const { duplicateType } = res.data;
if (duplicateType === 'current' || duplicateType === 'both') {
// alert('当前钢卷号重复,请重新输入');
callback(new Error('当前钢卷号重复,请重新输入'));
} else {
callback();
}
})
}, trigger: 'blur'
}
],
team: [
{ required: true, message: '请输入班组', trigger: 'blur' }

View File

@@ -177,7 +177,7 @@ export default {
pageNum: 1,
dataType: 1,
createBy: 'suanzhakuguan',
warehouseId: '1988150099140866050'
warehouseId: '1988150323162836993'
}),
// 镀锌原料库
listCoilWithIds({

View File

@@ -0,0 +1,198 @@
<template>
<div class="app-container" v-loading="loading">
<el-row>
<el-form label-width="80px" inline>
<el-form-item label="开始时间" prop="startTime">
<el-date-picker style="width: 200px;" v-model="queryParams.byCreateTimeStart" type="datetime"
value-format="yyyy-MM-dd HH:mm:ss" placeholder="选择开始时间"></el-date-picker>
</el-form-item>
<el-form-item label="结束时间" prop="endTime">
<el-date-picker style="width: 200px;" v-model="queryParams.byCreateTimeEnd" type="datetime"
value-format="yyyy-MM-dd HH:mm:ss" placeholder="选择结束时间"></el-date-picker>
</el-form-item>
<el-form-item label="入场钢卷号" prop="endTime">
<el-input style="width: 200px; display: inline-block;" v-model="queryParams.enterCoilNo"
placeholder="请输入入场钢卷号" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="当前钢卷号" prop="endTime">
<el-input style="width: 200px;" v-model="queryParams.currentCoilNo" placeholder="请输入当前钢卷号" clearable
@keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="逻辑库位" prop="endTime">
<warehouse-select v-model="queryParams.warehouseId" placeholder="请选择仓库/库区/库位"
style="width: 100%; display: inline-block; width: 200px;" clearable />
</el-form-item>
<el-form-item label="产品名称" prop="endTime">
<el-input style="width: 200px;" v-model="queryParams.itemName" placeholder="请输入产品名称" clearable
@keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="规格" prop="endTime">
<memo-input style="width: 200px;" v-model="queryParams.itemSpecification" storageKey="coilSpec"
placeholder="请选择规格" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="材质" prop="endTime">
<muti-select style="width: 200px;" v-model="queryParams.itemMaterial" :options="dict.type.coil_material"
placeholder="请选择材质" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="厂家" prop="endTime">
<muti-select style="width: 200px;" v-model="queryParams.itemManufacturer"
:options="dict.type.coil_manufacturer" placeholder="请选择厂家" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item prop="endTime">
<el-button type="primary" @click="getList">查询</el-button>
<el-button type="primary" @click="exportData">导出</el-button>
</el-form-item>
</el-form>
</el-row>
<el-descriptions title="统计信息" :column="3" border>
<el-descriptions-item label="总钢卷数量">{{ summary.totalCount }}</el-descriptions-item>
<el-descriptions-item label="总重">{{ summary.totalWeight }}t</el-descriptions-item>
<el-descriptions-item label="均重">{{ summary.avgWeight }}t</el-descriptions-item>
</el-descriptions>
<el-descriptions title="明细信息" :column="3" border>
</el-descriptions>
<el-table :data="list" border height="calc(100vh - 320px)">
<el-table-column label="入场钢卷号" align="center" prop="enterCoilNo">
<template slot-scope="scope">
<coil-no :coil-no="scope.row.enterCoilNo"></coil-no>
</template>
</el-table-column>
<el-table-column label="当前钢卷号" align="center" prop="currentCoilNo">
<template slot-scope="scope">
<coil-no :coil-no="scope.row.currentCoilNo"></coil-no>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" />
<el-table-column label="逻辑库位" align="center" prop="warehouseName" />
<el-table-column label="实际库区" align="center" prop="actualWarehouseName" />
<el-table-column label="产品类型" align="center" width="250">
<template slot-scope="scope">
<ProductInfo v-if="scope.row.itemType == 'product'" :product="scope.row.product" />
<RawMaterialInfo v-else-if="scope.row.itemType === 'raw_material'" :material="scope.row.rawMaterial" />
</template>
</el-table-column>
<el-table-column label="重量 (吨)" align="center" prop="netWeight" />
<el-table-column label="长度 (米)" align="center" prop="length" />
<el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip />
<el-table-column label="出库状态" align="center" prop="status">
<!-- 0在库1已出库 -->
<template slot-scope="scope">
{{ scope.row.status === 0 ? '在库' : '已出库' }}
</template>
</el-table-column>
<el-table-column label="更新人" align="center" prop="updateByName" />
<el-table-column label="更新时间" align="center" prop="updateTime" />
</el-table>
</div>
</template>
<script>
import { listCoilWithIds } from "@/api/wms/coil";
import ProductInfo from "@/components/KLPService/Renderer/ProductInfo";
import RawMaterialInfo from "@/components/KLPService/Renderer/RawMaterialInfo";
import CoilNo from "@/components/KLPService/Renderer/CoilNo.vue";
import MemoInput from "@/components/MemoInput";
import MutiSelect from "@/components/MutiSelect";
import WarehouseSelect from "@/components/KLPService/WarehouseSelect";
export default {
components: {
ProductInfo,
RawMaterialInfo,
CoilNo,
MemoInput,
MutiSelect,
WarehouseSelect,
},
dicts: ['product_coil_status', 'coil_material', 'coil_itemname', 'coil_manufacturer'],
data() {
// 工具函数:个位数补零,保证格式统一(比如 9 → 095 → 05
const addZero = (num) => num.toString().padStart(2, '0')
const now = new Date() // 当前本地北京时间
// 核心:获取【昨天】的日期对象(自动处理跨月/跨年,无边界问题)
const yesterday = new Date(now)
yesterday.setDate(yesterday.getDate() - 1)
// 昨天的年、月、日(补零格式化)
const yesYear = yesterday.getFullYear()
const yesMonth = addZero(yesterday.getMonth() + 1)
const yesDay = addZero(yesterday.getDate())
// 今天的年、月、日(补零格式化)
const nowYear = now.getFullYear()
const nowMonth = addZero(now.getMonth() + 1)
const nowDay = addZero(now.getDate())
// ✅ 目标时间区间昨天早上6点 至 今天早上6点
const startTime = `${yesYear}-${yesMonth}-${yesDay} 06:00:00`
const endTime = `${nowYear}-${nowMonth}-${nowDay} 06:00:00`
return {
list: [],
queryParams: {
pageNum: 1,
pageSize: 9999,
// status: 1,
byCreateTimeStart: startTime,
byCreateTimeEnd: endTime,
selectType: 'product',
enterCoilNo: '',
currentCoilNo: '',
warehouseId: '',
productName: '',
itemSpecification: '',
itemMaterial: '',
itemManufacturer: '',
},
loading: false,
}
},
computed: {
summary() {
// 总钢卷数量、总重、均重
const totalCount = this.list.length
const totalWeight = this.list.reduce((acc, cur) => acc + parseFloat(cur.netWeight), 0)
const avgWeight = totalCount > 0 ? (totalWeight / totalCount).toFixed(2) : 0
return {
totalCount,
totalWeight: totalWeight.toFixed(2),
avgWeight,
}
}
},
methods: {
getList() {
this.loading = true
// 镀锌原料库,镀锌纵剪分条原料库
listCoilWithIds({
...this.queryParams,
pageSize: 9999,
pageNum: 1,
dataType: 1,
warehouseIds: '1988150263284953089,1988150487185289217'
}).then(res => {
const list = [...res.rows];
// 按照createTime 降序排序
this.list = list.sort(
(a, b) => new Date(b.createTime) - new Date(a.createTime)
)
this.loading = false
})
},
// 导出
exportData() {
this.download('wms/materialCoil/export', {
coilIds: this.list.map(item => item.coilId).join(',')
}, `materialCoil_${new Date().getTime()}.xlsx`)
},
},
mounted() {
this.getList()
}
}
</script>
<style scoped></style>