feat(wpm): improve handover record details

This commit is contained in:
caoqianming 2026-08-07 16:17:34 +08:00
parent 9fcf23f418
commit 722789502e
2 changed files with 240 additions and 170 deletions

View File

@ -98,20 +98,21 @@
></el-table-column> ></el-table-column>
<el-table-column type="expand"> <el-table-column type="expand">
<template #default="props"> <template #default="props">
<div style="padding-left: 50px"> <div class="handover-detail">
<template v-for="item in props.row.handoverb" :key="item.id"> <div class="handover-detail__row handover-detail__header">
<el-descriptions :column="3"> <span>批次</span>
<el-descriptions-item label="批次"> <span>数量</span>
{{item.batch}} <span>不合格标记</span>
</el-descriptions-item> </div>
<el-descriptions-item label="数量"> <div
{{item.count}} v-for="item in props.row.handoverb"
</el-descriptions-item> :key="item.id"
<el-descriptions-item label="不合格标记" v-if="item.defect_name!==null&&item.defect_name!==undefind"> class="handover-detail__row"
{{item.defect_name}} >
</el-descriptions-item> <span>{{ item.batch }}</span>
</el-descriptions> <span>{{ item.count }}</span>
</template> <span>{{ item.defect_name || '-' }}</span>
</div>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
@ -471,21 +472,21 @@ export default {
}); });
}, },
// //
table_edit(row) { async table_edit(row) {
this.type=row.type; this.type=row.type;
this.dialog.save = true; this.dialog.save = true;
this.mode = "edit"; this.mode = "edit";
this.$nextTick(() => { await this.$nextTick();
this.$refs.saveDialog.open("edit").setData(row); this.$refs.saveDialog.open("edit", "", row.mtype);
}); await this.$refs.saveDialog.loadData(row.id);
}, },
table_show(row){ async table_show(row){
this.type=row.type; this.type=row.type;
this.dialog.save = true; this.dialog.save = true;
this.mode = "show"; this.mode = "show";
this.$nextTick(() => { await this.$nextTick();
this.$refs.saveDialog.open("show").setData(row); this.$refs.saveDialog.open("show", "", row.mtype);
}); await this.$refs.saveDialog.loadData(row.id);
}, },
// //
async table_del(row) { async table_del(row) {
@ -603,6 +604,35 @@ export default {
}; };
</script> </script>
<style scoped> <style scoped>
.handover-detail {
padding: 4px 50px;
font-size: 13px;
color: var(--el-text-color-regular);
}
.handover-detail__row {
display: grid;
grid-template-columns: minmax(240px, 2fr) minmax(120px, 1fr) minmax(180px, 1fr);
align-items: center;
min-height: 30px;
border-bottom: 1px solid var(--el-border-color-lighter);
}
.handover-detail__row:last-child {
border-bottom: 0;
}
.handover-detail__header {
min-height: 28px;
font-weight: 500;
color: var(--el-text-color-secondary);
background: var(--el-fill-color-light);
}
.handover-detail__row > span {
padding: 4px 12px;
}
.treeMain { .treeMain {
width: 100%; width: 100%;
height: 280px; height: 280px;

View File

@ -1,12 +1,72 @@
<template> <template>
<el-container> <el-container>
<el-main class="nopadding"> <el-main class="nopadding" v-loading="loading">
<el-form <el-form
ref="dialogForm" ref="dialogForm"
:model="form" :model="form"
:rules="rules" :rules="rules"
label-width="80px" label-width="80px"
> >
<template v-if="mode === 'show'">
<div class="form-section-title">基本信息</div>
<el-descriptions :column="3" border class="handover-summary">
<el-descriptions-item label="交接类别">{{ form.type_name || '-' }}</el-descriptions-item>
<el-descriptions-item label="操作类型">{{ form.mtype_name || '-' }}</el-descriptions-item>
<el-descriptions-item label="交送日期">{{ form.send_date || '-' }}</el-descriptions-item>
<el-descriptions-item label="物料">{{ form.material_name || '-' }}</el-descriptions-item>
<el-descriptions-item label="交接数量">{{ totalCount }}</el-descriptions-item>
<el-descriptions-item label="记录状态">
<el-tag :type="form.submit_time ? 'success' : 'info'" size="small">
{{ form.submit_time ? '已提交' : '未提交' }}
</el-tag>
</el-descriptions-item>
<el-descriptions-item label="交送部门">{{ form.send_dept_name || '-' }}</el-descriptions-item>
<el-descriptions-item label="交送工段">{{ form.send_mgroup_name || '-' }}</el-descriptions-item>
<el-descriptions-item label="交送人">{{ form.send_user_name || '-' }}</el-descriptions-item>
<el-descriptions-item label="接收部门">{{ form.recive_dept_name || '-' }}</el-descriptions-item>
<el-descriptions-item label="接收工段">{{ form.recive_mgroup_name || '-' }}</el-descriptions-item>
<el-descriptions-item label="接收人">{{ form.recive_user_name || '-' }}</el-descriptions-item>
<el-descriptions-item v-if="form.new_batch" label="新批次号">{{ form.new_batch }}</el-descriptions-item>
<el-descriptions-item v-if="form.material_changed_fname" label="变更后物料">{{ form.material_changed_fname }}</el-descriptions-item>
<el-descriptions-item v-if="form.material_changed && form.state_changed_name" label="变更后状态">{{ form.state_changed_name }}</el-descriptions-item>
<el-descriptions-item v-if="form.clear_defect" label="清除批次缺陷"></el-descriptions-item>
<el-descriptions-item v-if="form.submit_time" label="提交时间">{{ form.submit_time }}</el-descriptions-item>
<el-descriptions-item v-if="form.submit_user_name" label="提交人">{{ form.submit_user_name }}</el-descriptions-item>
<el-descriptions-item label="备注" :span="3">{{ form.note || '-' }}</el-descriptions-item>
</el-descriptions>
<div class="form-section-title">交接明细</div>
<el-table :data="form.handoverb" border stripe size="small">
<el-table-column v-if="hasProductDetails" type="expand" width="42">
<template #default="scope">
<div class="product-detail-list" v-if="scope.row.handoverbw && scope.row.handoverbw.length">
<span class="product-detail-label">单件编号</span>
<el-tag v-for="item in scope.row.handoverbw" :key="item.id || item.number" size="small" effect="plain">
{{ item.number }}<template v-if="item.note">{{ item.note }}</template>
</el-tag>
</div>
<el-empty v-else description="无单件编号" :image-size="48" />
</template>
</el-table-column>
<el-table-column label="批次" prop="batch" min-width="150" />
<el-table-column label="物料" prop="material_name" min-width="180">
<template #default="scope">{{ scope.row.material_name || form.material_name || '-' }}</template>
</el-table-column>
<el-table-column label="状态" prop="state_name" width="90" />
<el-table-column label="缺陷等级" prop="defect_grade_name" width="100" />
<el-table-column label="具体缺陷" prop="defect_name" min-width="120">
<template #default="scope">{{ scope.row.defect_name || '-' }}</template>
</el-table-column>
<el-table-column label="不合格标记" prop="notok_sign_name" width="110">
<template #default="scope">{{ scope.row.notok_sign_name || '-' }}</template>
</el-table-column>
<el-table-column label="来源位置" min-width="130">
<template #default="scope">{{ scope.row.mgroup_name || scope.row.belong_dept_name || '全局库存' }}</template>
</el-table-column>
<el-table-column label="交接数量" prop="count" width="100" align="right" />
</el-table>
</template>
<template v-else>
<el-row> <el-row>
<el-form-item label="交接物料"> <el-form-item label="交接物料">
<el-button type="primary" @click="addMaterial" v-if="mode!=='show'">手动添加</el-button> <el-button type="primary" @click="addMaterial" v-if="mode!=='show'">手动添加</el-button>
@ -106,23 +166,18 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :md="12" :sm="24" v-if="mtype!==30"> <el-col :md="12" :sm="24" v-if="mtype!==30">
<el-form-item label="交送人"> <el-form-item label="交送人" prop="send_user">
<span v-if="mode==='show'">{{ form.send_user_name }}</span> <xtSelect
<el-select :apiObj="$API.system.user.list"
v-else :params="sendUserParams"
v-model="form.send_user" v-model="form.send_user"
v-model:label="form.send_user_name"
placeholder="交送人" placeholder="交送人"
clearable
filterable
style="width: 100%" style="width: 100%"
> >
<el-option <el-table-column label="姓名" prop="name" />
v-for="item in userList" <el-table-column label="部门" prop="belong_dept_name" />
:key="item.id" </xtSelect>
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :md="12" :sm="24" v-if="mtype!==30"> <el-col :md="12" :sm="24" v-if="mtype!==30">
@ -133,7 +188,7 @@
clearable clearable
style="width: 100%" style="width: 100%"
:disabled="type==40||mode!=='add'" :disabled="type==40||mode!=='add'"
@change="getUserList2" @change="reciveMgroupChange"
> >
<el-option <el-option
v-for="item in mgroupOptions" v-for="item in mgroupOptions"
@ -146,22 +201,18 @@
</el-col> </el-col>
<el-col :md="12" :sm="24" v-if="mtype!==30"> <el-col :md="12" :sm="24" v-if="mtype!==30">
<el-form-item label="接收人"> <el-form-item label="接收人">
<span v-if="mode==='show'">{{ form.recive_user_name }}</span> <xtSelect
<el-select :apiObj="$API.system.user.list"
v-else :params="reciveUserParams"
v-model="form.recive_user" v-model="form.recive_user"
v-model:label="form.recive_user_name"
:edit="Boolean(form.recive_dept) || type == 40"
placeholder="接收人" placeholder="接收人"
clearable
filterable
style="width: 100%" style="width: 100%"
> >
<el-option <el-table-column label="姓名" prop="name" />
v-for="item in userList2" <el-table-column label="部门" prop="belong_dept_name" />
:key="item.id" </xtSelect>
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :md="12" :sm="24" v-if="type==50"> <el-col :md="12" :sm="24" v-if="type==50">
@ -276,14 +327,15 @@
</el-col> </el-col>
</el-row> </el-row>
</div> </div>
</template>
</el-form> </el-form>
<el-footer> <el-footer>
<template v-if="(route_code=='tuihuo'&&type==10&&mtype==10)||form.ticket!=null"> <template v-if="mode !== 'show' && ((route_code=='tuihuo'&&type==10&&mtype==10)||form.ticket!=null)">
<ticketd_b :workflow_key="'backfire'" :title="'退火交接审批单'" :t_id="form.id" :ticket_="form.ticket_" <ticketd_b :workflow_key="'backfire'" :title="'退火交接审批单'" :t_id="form.id" :ticket_="form.ticket_"
@success="()=>{$emit('success')} " :submit_b_func="submit_b_func" ref="ticketd_b"></ticketd_b> @success="()=>{$emit('success')} " :submit_b_func="submit_b_func" ref="ticketd_b"></ticketd_b>
</template> </template>
<el-button v-else-if="mode!='show'" type="primary" v-loading="isSaveing" @click="submit">确定</el-button> <el-button v-else-if="mode!='show'" type="primary" v-loading="isSaveing" @click="submit">确定</el-button>
<el-button @click="$emit('closed')">取消</el-button> <el-button @click="$emit('closed')">{{ mode === 'show' ? '关闭' : '取消' }}</el-button>
</el-footer> </el-footer>
</el-main> </el-main>
<el-aside width="20%" v-if="form.ticket"> <el-aside width="20%" v-if="form.ticket">
@ -421,8 +473,6 @@ export default {
codeText: "", codeText: "",
batchList:[], batchList:[],
fileList:[], fileList:[],
userList: [],
userList2: [],
handoverbIds:[], handoverbIds:[],
mgroupOptions: [], mgroupOptions: [],
materialOptions: [], materialOptions: [],
@ -436,6 +486,9 @@ export default {
let that = this; let that = this;
that.change_batch = that.changebatch; that.change_batch = that.changebatch;
that.form.type = that.type; that.form.type = that.type;
const userInfo = that.$TOOL.data.get("USER_INFO");
that.form.send_user = userInfo.id;
that.form.send_user_name = userInfo.name;
let materialObj = that.$TOOL.data.get("MATERIAL_OBJECT"); let materialObj = that.$TOOL.data.get("MATERIAL_OBJECT");
that.materialObj = materialObj; that.materialObj = materialObj;
that.form.handle_date = that.form.send_date = this.$TOOL.dateFormat2(new Date()); that.form.handle_date = that.form.send_date = this.$TOOL.dateFormat2(new Date());
@ -448,13 +501,7 @@ export default {
// type=50 // type=50
//mtype 10: 20: 30: //mtype 10: 20: 30:
//state 10:;20:;30:;34:;40:;50: //state 10:;20:;30:;34:;40:;50:
//
if(that.type==20&&that.mgroupName=='废品库'){//
that.getCkUserList();
}else{
that.deptID = that.$TOOL.data.get('gx_deptID'); that.deptID = that.$TOOL.data.get('gx_deptID');
that.getUserList();
}
// //
if(that.type==20&&that.mgroupName!=='废品库'){ if(that.type==20&&that.mgroupName!=='废品库'){
// //
@ -473,14 +520,26 @@ export default {
that.paramsM = {mgroup: that.mgroupId,state:10,tag : 'done'}; that.paramsM = {mgroup: that.mgroupId,state:10,tag : 'done'};
} }
that.apiObjM = this.$API.wpm.wmaterial.list; that.apiObjM = this.$API.wpm.wmaterial.list;
if(that.type==40||that.type==20){
that.getMgroupOptions();
}else{
that.getMgroupOptions();
}
that.getTid(); that.getTid();
}, },
computed: { computed: {
hasProductDetails() {
return (this.form.handoverb || []).some(
(item) => item.handoverbw && item.handoverbw.length > 0
);
},
sendUserParams() {
if (this.type == 20 && this.mgroupName === "废品库") {
return { posts__code: "inm&check" };
}
return { depts: this.deptID };
},
reciveUserParams() {
if (this.type == 40) {
return { posts__code: "inm&check" };
}
return this.form.recive_dept ? { depts: this.form.recive_dept } : {};
},
canClearBatchDefect() { canClearBatchDefect() {
return Number(this.mtype) === 30 || this.change_batch; return Number(this.mtype) === 30 || this.change_batch;
}, },
@ -498,12 +557,6 @@ export default {
} }
}, },
watch: { watch: {
batchList:{
deep:true,
handler (v) {
console.log('batchList',v)
}
},
canClearBatchDefect(val) { canClearBatchDefect(val) {
if (!val) { if (!val) {
this.form.clear_defect = false; this.form.clear_defect = false;
@ -511,21 +564,30 @@ export default {
} }
}, },
methods: { methods: {
getTid (){ async getTid (){
var that = this; if (!this.t_id) {
if (that.t_id) { return;
that.$API.wpm.handover.item.req(that.t_id).then(res=>{
that.setData(res);
if(res.ticket_.state_.type == 1 && res.create_by == that.$TOOL.data.get("USER_INFO").id ) {
that.mode = "edit";
}else{
that.mode = "show";
} }
// that.$nextTick(()=>{ const data = await this.loadData(this.t_id);
// that.$refs.ticketd_b.init(); const userId = this.$TOOL.data.get("USER_INFO").id;
// }) if (data.ticket_?.state_?.type == 1 && data.create_by == userId) {
this.mode = "edit";
}) this.prepareEditor();
}
},
async loadData(id) {
this.loading = true;
try {
const data = await this.$API.wpm.handover.item.req(id);
this.setData(data);
return data;
} finally {
this.loading = false;
}
},
prepareEditor() {
if (this.mode === "add" && this.type == 40) {
this.getMgroupOptions();
} }
}, },
// //
@ -537,9 +599,9 @@ export default {
res.forEach(item=>{ res.forEach(item=>{
if(item.name=="废品库"){ if(item.name=="废品库"){
that.form.recive_mgroup = item.id; that.form.recive_mgroup = item.id;
that.form.recive_dept = item.belong_dept;
} }
}) })
that.getCkUserList();//
} }
}); });
}, },
@ -553,70 +615,15 @@ export default {
that.mgroupOptions = res; that.mgroupOptions = res;
if(res.length==1){ if(res.length==1){
that.form.recive_mgroup = res[0].id; that.form.recive_mgroup = res[0].id;
that.getUserList2(); that.reciveMgroupChange(res[0].id);
} }
}) })
}, },
// reciveMgroupChange(mgroupId) {
getUserList() { const mgroup = this.mgroupOptions.find((item) => item.id == mgroupId);
let that = this; this.form.recive_dept = mgroup?.belong_dept || null;
let userInfo = that.$TOOL.data.get("USER_INFO"); this.form.recive_user = null;
this.$API.system.user.list.req({ depts: that.deptID, page: 0 }).then((res) => { this.form.recive_user_name = "";
that.userList = res;
let arr = res.filter(item=>{
return item.id==userInfo.id;
})
if(arr.length>0){
that.form.send_user = userInfo.id;
}else{
let obj = {};
obj.id = userInfo.id;
obj.name = userInfo.name;
that.userList.push(obj)
that.form.send_user = userInfo.id;
}
});
},
//
getCkUserList() {
let that = this;
this.$API.system.user.list.req({ page: 0, posts__code: "inm&check" })
.then((res) => {
if(that.type==40){
that.userList2 = [];
that.userList2 = res;
}else if(that.type==20&&that.mgroupName=='废品库'){
that.userList = [];
that.userList = res;
}
});
},
//
getUserList2() {
let that = this;
let deptID = '';
if(that.form.recive_dept&&that.form.recive_dept!==''&&that.form.recive_dept!==null){
deptID = that.form.recive_dept;
}else{
that.mgroupOptions.forEach(item => {
if(item.id==that.form.recive_mgroup){
deptID = item.belong_dept;
}
});
}
that.$API.system.user.list.req({ depts: deptID, page: 0 }).then((res) => {
that.userList2 = res;
});
},
//
getUserList3() {
let that = this;
this.$API.system.user.list
.req({ depts: that.form.recive_dept, page: 0 })
.then((res) => {
that.userList2 = res;
});
}, },
remoFun(val){ remoFun(val){
let that = this; let that = this;
@ -665,11 +672,13 @@ export default {
}, },
// //
open(mode = "add",data,mtype) { open(mode = "add",data,mtype) {
console.log(data)
this.mode = mode; this.mode = mode;
this.mtype = mtype; this.mtype = Number(mtype ?? 10);
this.form.clear_defect = false; this.form.clear_defect = false;
if (mtype === 30) { if (mode !== "show") {
this.prepareEditor();
}
if (this.mtype === 30) {
this.paramsM = { this.paramsM = {
...this.paramsM, ...this.paramsM,
state__in: '10,20,34' state__in: '10,20,34'
@ -677,7 +686,6 @@ export default {
delete this.paramsM.state; delete this.paramsM.state;
} }
if(data!==''&&data!==null&&data!==undefined){ if(data!==''&&data!==null&&data!==undefined){
console.log(typeof(data)=='string')
if(typeof(data)=='string'){ if(typeof(data)=='string'){
this.codeText = data.replace(" ",""); this.codeText = data.replace(" ","");
this.codeTextChange(this.codeText) this.codeTextChange(this.codeText)
@ -700,7 +708,7 @@ export default {
}) })
} }
} }
if(mtype==30){// if(this.mtype==30){//
this.change_batch = true; this.change_batch = true;
} }
return this; return this;
@ -796,8 +804,6 @@ export default {
if(res.length>0){ if(res.length>0){
that.form.new_wm = res[0].id; that.form.new_wm = res[0].id;
} }
console.log('that.form.new_wm',that.form.new_wm);
console.log('that.form.new_batch',that.form.new_batch);
that.$API.wpm.handover.createsubmit.req(that.form).then((res) => { that.$API.wpm.handover.createsubmit.req(that.form).then((res) => {
that.isSaveing = false; that.isSaveing = false;
that.$emit("success"); that.$emit("success");
@ -842,26 +848,31 @@ export default {
}, },
// //
setData(data) { setData(data) {
console.log('交接记录查看',data)
let that = this;
Object.assign(this.form, data); Object.assign(this.form, data);
this.mtype = Number(data.mtype ?? 10);
this.change_batch = Boolean(data.new_batch) || this.mtype === 30;
let obj = {}; let obj = {};
if(data.oinfo_json&&data.oinfo_json.test_file){ if(data.oinfo_json&&data.oinfo_json.test_file){
obj.name=data.oinfo_json.test_file; obj.name=data.oinfo_json.test_file;
obj.url=data.oinfo_json.test_file; obj.url=data.oinfo_json.test_file;
this.fileList.push(obj); this.fileList.push(obj);
} }
that.totalCount = 0; this.totalCount = 0;
that.form.handoverb = data.handoverb; this.form.handoverb = data.handoverb || [];
data.handoverb.forEach(item=>{ if (data.recive_mgroup && data.recive_mgroup_name) {
item.label = item.batch; this.mgroupOptions = [{
that.totalCount += Number(item.count); id: data.recive_mgroup,
}) name: data.recive_mgroup_name,
if(data.type==30){ belong_dept: data.recive_dept,
that.getUserList3(); }];
}else{
that.getUserList2();
} }
this.form.handoverb.forEach(item=>{
const details = [item.defect_grade_name, item.defect_name].filter(Boolean);
const materialName = item.material_name || data.material_name || "";
item.label = `${item.batch}${materialName ? `(${materialName})` : ""}${details.length ? ` [${details.join("")}]` : ""}`;
item.count_cando = item.count_available ?? item.count;
this.totalCount += Number(item.count);
})
}, },
// //
setFilters(filters) { setFilters(filters) {
@ -927,6 +938,35 @@ export default {
}; };
</script> </script>
<style scoped> <style scoped>
.form-section-title {
margin: 4px 0 12px;
font-size: 15px;
font-weight: 600;
color: var(--el-text-color-primary);
}
.form-section-title:not(:first-child) {
margin-top: 20px;
}
.handover-summary {
font-size: 13px;
}
.product-detail-list {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
padding: 8px 16px;
}
.product-detail-label {
margin-right: 4px;
font-weight: 500;
color: var(--el-text-color-secondary);
}
.formTitle { .formTitle {
margin-bottom: 10px; margin-bottom: 10px;
font-weight: 600; font-weight: 600;