Compare commits

..

4 Commits

7 changed files with 478 additions and 345 deletions

View File

@ -45,12 +45,12 @@
/* ============================================================ /* ============================================================
* 工作流表单结构化样式 * 工作流表单结构化样式
* 抽屉内打开的所有 *_form.vue 流程表单统一布局规范 * 仅对显式声明 workflow-form-drawer 的流程抽屉生效避免影响普通业务抽屉
* - 主区: el-main > el-form 内容卡片化分组分区 * - 主区: el-main > el-form 内容卡片化分组分区
* - 底部: 操作按钮 sticky 底栏 * - 底部: 操作按钮 sticky 底栏
* - 侧栏: 提升与正文的视觉区分 * - 侧栏: 提升与正文的视觉区分
* ============================================================ */ * ============================================================ */
.el-drawer__body { .workflow-form-drawer .el-drawer__body {
.el-container { .el-container {
height: 100%; height: 100%;
background: var(--el-fill-color-light); background: var(--el-fill-color-light);

View File

@ -64,7 +64,7 @@
{{ item.name }} {{ item.name }}
</el-card> </el-card>
</el-dialog> </el-dialog>
<el-drawer v-model="drawer" size="90%" :show-close="false"> <el-drawer v-model="drawer" size="90%" :show-close="false" class="workflow-form-drawer">
<template #header="{ close, titleId, titleClass }"> <template #header="{ close, titleId, titleClass }">
<h4 :id="titleId" :class="titleClass">{{drawerName}}</h4> <h4 :id="titleId" :class="titleClass">{{drawerName}}</h4>
<el-button type="danger" @click="close">关闭</el-button> <el-button type="danger" @click="close">关闭</el-button>

View File

@ -132,7 +132,7 @@
</el-table-column> </el-table-column>
</scTable> </scTable>
</el-main> </el-main>
<el-drawer v-model="drawer" size="90%" :show-close="false"> <el-drawer v-model="drawer" size="90%" :show-close="false" class="workflow-form-drawer">
<template #header="{ close, titleId, titleClass }"> <template #header="{ close, titleId, titleClass }">
<h4 :id="titleId" :class="titleClass">{{drawerName}}</h4> <h4 :id="titleId" :class="titleClass">{{drawerName}}</h4>
<el-button type="danger" @click="close">关闭</el-button> <el-button type="danger" @click="close">关闭</el-button>

View File

@ -69,26 +69,28 @@
></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">
<div v-if="props.row.new_batch&&props.row.new_batch!= null" style="font-size: 14px;"> <div v-if="props.row.new_batch" class="handover-detail__batch">
新批次号{{ props.row.new_batch }}<span v-if="props.row.material_changed!==null">({{ props.row.material_changed_fname }})</span> 新批次号{{ props.row.new_batch }}
<span v-if="props.row.material_changed_fname">{{ props.row.material_changed_fname }}</span>
</div> </div>
<template v-for="item in props.row.handoverb" :key="item.id"> <div class="handover-detail__row handover-detail__header">
<el-descriptions :column="3" style="margin-top: 10px;"> <span>批次</span>
<el-descriptions-item label="批次"> <span>数量</span>
{{item.batch}} <span>不合格标记</span>
</el-descriptions-item> <span>板段号</span>
<el-descriptions-item label="数量">
{{item.count}}
</el-descriptions-item>
<el-descriptions-item label="不合格标记" v-if="item.defect_name!==null">
{{item.defect_name}}
</el-descriptions-item>
</el-descriptions>
<div v-if="item.handoverbw&&item.handoverbw.length>0" style="margin-top: -10px;">
板段号:<span v-for="bwItem in item.handoverbw" :key="bwItem.id">{{ bwItem.number }}</span>
</div> </div>
<div v-for="item in props.row.handoverb" :key="item.id" class="handover-detail__row">
<span>{{ item.batch || '-' }}</span>
<span>{{ item.count }}</span>
<span>{{ item.defect_name || item.notok_sign_name || '-' }}</span>
<span class="handover-detail__numbers">
<template v-if="item.handoverbw && item.handoverbw.length">
{{ item.handoverbw.map(bw => bw.number).filter(Boolean).join('、') || '-' }}
</template> </template>
<template v-else>-</template>
</span>
</div>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
@ -365,19 +367,19 @@ 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.$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.$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) {
@ -508,4 +510,32 @@ export default {
border: 1px solid #dcdfe6; border: 1px solid #dcdfe6;
margin-bottom: 10px; margin-bottom: 10px;
} }
.handover-detail {
padding: 8px 24px 8px 50px;
font-size: 13px;
color: var(--el-text-color-regular);
}
.handover-detail__batch {
margin-bottom: 6px;
line-height: 24px;
color: var(--el-text-color-primary);
}
.handover-detail__row {
display: grid;
grid-template-columns: minmax(180px, 1.5fr) 90px minmax(130px, 1fr) minmax(260px, 2fr);
align-items: center;
min-height: 30px;
border-bottom: 1px solid var(--el-border-color-lighter);
}
.handover-detail__row > span {
padding: 4px 12px;
}
.handover-detail__header {
font-weight: 600;
background: var(--el-fill-color-light);
}
.handover-detail__numbers {
line-height: 20px;
word-break: break-all;
}
</style> </style>

View File

@ -1,6 +1,6 @@
<template> <template>
<el-dialog <el-dialog
:title="titleMap[mode+type]" :title="dialogTitle"
v-model="visible" v-model="visible"
width="1000px" width="1000px"
:size="1000" :size="1000"
@ -12,7 +12,68 @@
:model="form" :model="form"
:rules="rules" :rules="rules"
label-width="80px" label-width="80px"
v-loading="loading"
> >
<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 v-if="scope.row.handoverbw && scope.row.handoverbw.length" class="product-detail-list">
<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>
@ -144,20 +205,17 @@
</el-col> </el-col>
<el-col :md="12" :sm="24"> <el-col :md="12" :sm="24">
<el-form-item label="交送人"> <el-form-item label="交送人">
<el-select <xtSelect
:apiObj="$API.system.user.list"
: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"> <el-col :md="12" :sm="24">
@ -169,7 +227,7 @@
filterable filterable
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"
@ -182,20 +240,18 @@
</el-col> </el-col>
<el-col :md="12" :sm="24"> <el-col :md="12" :sm="24">
<el-form-item label="接收人"> <el-form-item label="接收人">
<el-select <xtSelect
:apiObj="$API.system.user.list"
: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="(mtype==30||type==50)&&new_wm==''"> <el-col :md="12" :sm="24" v-if="(mtype==30||type==50)&&new_wm==''">
@ -237,10 +293,11 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
</template>
</el-form> </el-form>
<el-footer v-if="mode!=='show'"> <el-footer>
<el-button type="primary" v-loading="isSaveing" @click="submit">确定</el-button> <el-button v-if="mode!=='show'" type="primary" v-loading="isSaveing" @click="submit">确定</el-button>
<el-button @click="visible = false">取消</el-button> <el-button @click="visible = false">{{ mode === 'show' ? '关闭' : '取消' }}</el-button>
</el-footer> </el-footer>
</el-dialog> </el-dialog>
</template> </template>
@ -386,8 +443,6 @@ export default {
deptID:'', deptID:'',
bwIndex:0, bwIndex:0,
checkedStatus:[], checkedStatus:[],
userList: [],
userList2: [],
deptOptions:[], deptOptions:[],
mgroupOptions: [], mgroupOptions: [],
materialOptions: [], materialOptions: [],
@ -417,6 +472,10 @@ export default {
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());
that.form.send_mgroup = that.mgroupId; that.form.send_mgroup = that.mgroupId;
that.deptID = that.$TOOL.data.get('gx_deptID');
const userInfo = that.$TOOL.data.get("USER_INFO") || {};
that.form.send_user = userInfo.id || null;
that.form.send_user_name = userInfo.name || "";
if(that.new_wm!==''){ if(that.new_wm!==''){
that.mtype==30; that.mtype==30;
that.form.new_wm = that.new_wm; that.form.new_wm = that.new_wm;
@ -440,31 +499,23 @@ export default {
that.form.new_batch = 'HP'+that.Mmodel+year+month+day; that.form.new_batch = 'HP'+that.Mmodel+year+month+day;
} }
}) })
// type=10
// type=20
// type=30
// type=40
// type=50
///
if(that.type==20&&that.mgroupName=='废品库'){//
that.getCkUserList();
}else{
that.deptID = that.$TOOL.data.get('gx_deptID');
that.getUserList();
}
//
if(that.type==10){//
that.getMaterial();
}else if(that.type==20){//
that.getMaterialOkFangong();
}else if(that.type==40){//
that.getMaterialNotok();
}else if(that.type==50){//
that.getMaterialFP();
}
that.getMgroupOptions();
}, },
computed: { computed: {
dialogTitle() {
return this.mode === "show" ? "查看交接记录" : (this.titleMap[this.mode + this.type] || "交接记录");
},
sendUserParams() {
return this.type == 20 && this.mgroupName === "废品库"
? { posts__code: "inm&check" }
: { depts: this.deptID };
},
reciveUserParams() {
if (this.type == 40) return { posts__code: "inm&check" };
return this.form.recive_dept ? { depts: this.form.recive_dept } : {};
},
hasProductDetails() {
return (this.form.handoverb || []).some(item => item.handoverbw && item.handoverbw.length);
},
// handoverb // handoverb
totalCount() { totalCount() {
if (!this.form.handoverb || this.form.handoverb.length === 0) return 0; if (!this.form.handoverb || this.form.handoverb.length === 0) return 0;
@ -494,6 +545,24 @@ export default {
} }
}, },
methods: { methods: {
prepareEditor() {
if (this.type == 10) {
this.getMaterial();
} else if (this.type == 20) {
this.getMaterialOkFangong();
} else if (this.type == 40) {
this.getMaterialNotok();
} else if (this.type == 50) {
this.getMaterialFP();
}
this.getMgroupOptions();
},
reciveMgroupChange(id) {
const group = this.mgroupOptions.find(item => String(item.id) === String(id));
this.form.recive_dept = group ? group.belong_dept : null;
this.form.recive_user = null;
this.form.recive_user_name = "";
},
deletebw(index){ deletebw(index){
let that = this; let that = this;
that.checkedStatus.splice(index,1); that.checkedStatus.splice(index,1);
@ -531,11 +600,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();//
}else if(that.type==30){
this.getUserList3();
} }
}); });
}, },
@ -605,70 +672,6 @@ export default {
}) })
}); });
}, },
//
getUserList() {
let that = this;
let userInfo = that.$TOOL.data.get("USER_INFO");
this.$API.system.user.list.req({ depts: that.deptID, page: 0 }).then((res) => {
that.userList = res;
let arr = res.filter(item=>{
return item.id==userInfo.id;
})
if(arr.length>0){
if(that.mode=="add"){
that.form.send_user = userInfo.id;
}
}else{
let obj = {};
obj.id = userInfo.id;
obj.name = userInfo.name;
that.userList.push(obj)
if(that.mode=="add"){
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;
if(that.mode=="add"){
that.$API.mtm.mgroup.item.req(that.form.recive_mgroup).then((res) => {
this.$API.system.user.list.req({ depts: res.belong_dept, page: 0 }).then((res) => {
that.userList2 = res;
});
})
}else{
this.mgroupOptions.forEach(item => {
if(item.id==that.form.recive_mgroup){
this.$API.system.user.list.req({ depts: item.belong_dept, 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;
});
},
addMaterial(){ addMaterial(){
let that = this; let that = this;
that.addShow = true; that.addShow = true;
@ -703,6 +706,9 @@ export default {
that.change_batch = true; that.change_batch = true;
} }
that.form.handoverb = data?data:[]; that.form.handoverb = data?data:[];
if (mode !== "show") {
that.prepareEditor();
}
if(data&&data!==''&&data.length>0){ if(data&&data!==''&&data.length>0){
data.forEach((item,index)=>{ data.forEach((item,index)=>{
item.wm = item.id; item.wm = item.id;
@ -759,7 +765,7 @@ 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);
} }
}) })
} }
@ -884,28 +890,33 @@ export default {
}, },
// //
setData(data) { setData(data) {
let that = this; Object.assign(this.form, data, { handoverb: data.handoverb || [] });
Object.assign(this.form, data); this.mtype = Number(data.mtype ?? this.mtype ?? 10);
this.$API.system.user.list.req({ depts: data.send_dept, page: 0 }).then((res) => { this.change_batch = Boolean(data.new_batch) || this.mtype === 30;
that.userList = res; this.checkedStatus = this.form.handoverb.map(item =>
(item.handoverbw || []).every(detail => detail.checked !== false)
);
this.form.handoverb.forEach(item => {
item.count_canhandover = item.count_available ?? item.count_canhandover ?? item.count;
}); });
this.$API.system.user.list.req({ depts: data.recive_dept, page: 0 }).then((res) => { if (data.recive_mgroup && !this.mgroupOptions.some(item => String(item.id) === String(data.recive_mgroup))) {
that.userList2 = res; this.mgroupOptions.push({
id: data.recive_mgroup,
name: data.recive_mgroup_name,
belong_dept: data.recive_dept,
}); });
setTimeout(() => {
let arr =that.userList2.filter((item) => {
return item.id == data.recive_user
})
if(arr.length>0){}else{
let obj = {};
obj.id = data.recive_user;
obj.name = data.recive_user_name;
that.userList2.push(obj);
} }
},500) return this;
if(data.new_batch!==''&&data.new_batch!==undefined&&data.new_batch!==null){ },
this.change_batch = true; async loadData(id) {
this.loading = true;
try {
const data = await this.$API.wpm.handover.item.req(id);
this.setData(data);
} finally {
this.loading = false;
} }
return this;
}, },
// //
setFilters(filters) { setFilters(filters) {
@ -957,7 +968,7 @@ export default {
that.mgroupOptions = res0; that.mgroupOptions = res0;
if(res0.length==1){ if(res0.length==1){
that.form.recive_mgroup = res0[0].id; that.form.recive_mgroup = res0[0].id;
that.getUserList2(); that.reciveMgroupChange(res0[0].id);
} }
}) })
let obj = {}; let obj = {};
@ -1154,4 +1165,26 @@ export default {
height: 50px; height: 50px;
line-height: 50px; line-height: 50px;
} }
.form-section-title {
margin: 4px 0 12px;
padding-left: 10px;
font-size: 15px;
font-weight: 600;
line-height: 20px;
border-left: 3px solid var(--el-color-primary);
}
.handover-summary {
margin-bottom: 20px;
}
.product-detail-list {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
padding: 8px 16px;
}
.product-detail-label {
margin-right: 4px;
color: var(--el-text-color-secondary);
}
</style> </style>

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;