refactor(wms/flow): 调整客诉流程为串行模式并替换质量部为技术部
1. 将原并行的质量部+生产部流程改为技术部→生产部→陈总→吴部长的串行流程 2. 替换所有质量部相关描述为技术部,更新部门映射配置 3. 重构流程状态推进逻辑,新增getNextDept方法简化流程推进 4. 新增表单本地暂存功能,优化列表项UI布局 5. 更新流程步骤展示、状态文案和标签颜色配置
This commit is contained in:
@@ -66,7 +66,7 @@ export default {
|
||||
}
|
||||
},
|
||||
getDeptName(deptId) {
|
||||
const map = { 1: '生产部', 2: '质量部', 3: '销售部(吴部长)', 4: '陈总审批' };
|
||||
const map = { 1: '生产部', 2: '技术部', 3: '销售部(吴部长)', 4: '陈总审批' };
|
||||
return map[deptId] || '部门' + deptId;
|
||||
},
|
||||
parseTime(time, option) {
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<!-- 质量部 deptId=2 -->
|
||||
<!-- 技术部 deptId=2 -->
|
||||
<template v-else-if="deptId === 2">
|
||||
<el-form-item label="产生原因" prop="cause">
|
||||
<el-input v-model="formData.cause" type="textarea" :rows="3" placeholder="请描述产生原因" @input="emitJson" />
|
||||
@@ -72,7 +72,7 @@
|
||||
<template v-else-if="deptId === 4">
|
||||
<el-form-item label="审阅意见" prop="reviewOpinion">
|
||||
<el-input v-model="formData.reviewOpinion" type="textarea" :rows="4"
|
||||
placeholder="请审阅质量部、生产部意见后填写审批意见" @input="emitJson" />
|
||||
placeholder="请审阅技术部、生产部意见后填写审批意见" @input="emitJson" />
|
||||
</el-form-item>
|
||||
<el-form-item label="审批结论" prop="approvalResult">
|
||||
<el-radio-group v-model="formData.approvalResult" @change="emitJson">
|
||||
@@ -91,8 +91,8 @@
|
||||
<el-form-item label="处理意见" prop="handlingOpinion">
|
||||
<el-input v-model="formData.handlingOpinion" type="textarea" :rows="4" placeholder="请输入处理意见" @input="emitJson" />
|
||||
</el-form-item>
|
||||
<el-form-item label="领导意见" prop="leaderOpinion">
|
||||
<el-input v-model="formData.leaderOpinion" type="textarea" :rows="3" placeholder="请输入领导意见" @input="emitJson" />
|
||||
<el-form-item label="处理方案" prop="leaderOpinion">
|
||||
<el-input v-model="formData.leaderOpinion" type="textarea" :rows="3" placeholder="请输入处理方案" @input="emitJson" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 质量部 deptId=2 -->
|
||||
<!-- 技术部 deptId=2 -->
|
||||
<template v-else-if="deptId === 2">
|
||||
<div class="preview-row" v-if="parsedData.cause">
|
||||
<span class="preview-label">产生原因</span>
|
||||
|
||||
@@ -51,7 +51,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
getDeptName(deptId) {
|
||||
const map = { 1: '生产部', 2: '质量部', 3: '销售部' };
|
||||
const map = { 1: '生产部', 2: '技术部', 3: '销售部' };
|
||||
return map[deptId] || '部门' + deptId;
|
||||
},
|
||||
parseTime(time, option) {
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
<span>流程总览 <span class="en-sub">· Process Overview</span></span>
|
||||
</div>
|
||||
<el-steps :active="activeStep" align-center class="flow-steps">
|
||||
<el-step title="质量部·生产部" icon="el-icon-s-operation" />
|
||||
<el-step title="技术部处理" icon="el-icon-s-operation" />
|
||||
<el-step title="生产部处理" icon="el-icon-s-operation" />
|
||||
<el-step title="陈总审批" icon="el-icon-s-check" />
|
||||
<el-step title="吴部长处理" icon="el-icon-s-custom" />
|
||||
<el-step title="已办结" icon="el-icon-circle-check" />
|
||||
@@ -33,29 +34,31 @@ export default {
|
||||
computed: {
|
||||
/**
|
||||
* el-steps active 从 0 开始。
|
||||
* 1=技术部·生产部→0, 2=陈总审批→1, 3=吴部长处理→2, 4=已办结→3
|
||||
* 1=技术部处理→0, 2=生产部处理→1, 3=陈总审批→2, 4=吴部长处理→3, 5=已办结→4
|
||||
*/
|
||||
activeStep() {
|
||||
if (this.flowStatus == null) return -1;
|
||||
const v = Number(this.flowStatus);
|
||||
if (v >= 4) return 3;
|
||||
if (v >= 5) return 4;
|
||||
return v - 1;
|
||||
},
|
||||
flowStatusText() {
|
||||
const map = {
|
||||
1: '质量部·生产部处理中',
|
||||
2: '待陈总审批',
|
||||
3: '待吴部长处理',
|
||||
4: '已办结'
|
||||
1: '技术部处理中',
|
||||
2: '生产部处理中',
|
||||
3: '待陈总审批',
|
||||
4: '待吴部长处理',
|
||||
5: '已办结'
|
||||
};
|
||||
return map[this.flowStatus] || '未知';
|
||||
},
|
||||
tagType() {
|
||||
const map = {
|
||||
1: 'warning',
|
||||
2: 'primary',
|
||||
3: 'warning',
|
||||
4: 'success'
|
||||
2: 'warning',
|
||||
3: 'primary',
|
||||
4: 'warning',
|
||||
5: 'success'
|
||||
};
|
||||
return map[this.flowStatus] || '';
|
||||
}
|
||||
|
||||
@@ -57,10 +57,11 @@ export default {
|
||||
computed: {
|
||||
flowStatusText() {
|
||||
const map = {
|
||||
1: '待审核',
|
||||
2: '意见填写中',
|
||||
3: '待汇总方案',
|
||||
4: '全部办结'
|
||||
1: '技术部处理中',
|
||||
2: '生产部处理中',
|
||||
3: '待陈总审批',
|
||||
4: '待吴部长处理',
|
||||
5: '已办结'
|
||||
};
|
||||
return map[this.flowStatus] || '未知';
|
||||
},
|
||||
@@ -68,8 +69,9 @@ export default {
|
||||
const map = {
|
||||
1: 'info',
|
||||
2: 'warning',
|
||||
3: '',
|
||||
4: 'success'
|
||||
3: 'warning',
|
||||
4: '',
|
||||
5: 'success'
|
||||
};
|
||||
return map[this.flowStatus] || '';
|
||||
}
|
||||
|
||||
@@ -12,10 +12,11 @@
|
||||
</div>
|
||||
<el-select v-model="queryParams.flowStatus" placeholder="全部阶段" clearable size="mini" @change="handleQuery"
|
||||
class="header-filter">
|
||||
<el-option label="质量部·生产部处理" :value="1" />
|
||||
<el-option label="待陈总审批" :value="2" />
|
||||
<el-option label="待吴部长处理" :value="3" />
|
||||
<el-option label="已办结" :value="4" />
|
||||
<el-option label="技术部处理中" :value="1" />
|
||||
<el-option label="生产部处理中" :value="2" />
|
||||
<el-option label="待陈总审批" :value="3" />
|
||||
<el-option label="待吴部长处理" :value="4" />
|
||||
<el-option label="已办结" :value="5" />
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
@@ -30,21 +31,22 @@
|
||||
<div v-loading="loading" class="list-body">
|
||||
<div v-for="item in dataList" :key="item.acceptId" class="list-item"
|
||||
:class="{ active: currentRow && currentRow.acceptId === item.acceptId }" @click="handleRowClick(item)">
|
||||
<div class="item-main">
|
||||
<div class="item-row-top">
|
||||
<span class="item-title">{{ item.complaintNo }}</span>
|
||||
<el-tag v-if="item.flowStatus === 1" type="warning" size="mini">技术部处理中</el-tag>
|
||||
<el-tag v-else-if="item.flowStatus === 2" type="warning" size="mini">生产部处理中</el-tag>
|
||||
<el-tag v-else-if="item.flowStatus === 3" type="primary" size="mini">待陈总审批</el-tag>
|
||||
<el-tag v-else-if="item.flowStatus === 4" type="warning" size="mini">待吴部长处理</el-tag>
|
||||
<el-tag v-else-if="item.flowStatus === 5" type="success" size="mini">已办结</el-tag>
|
||||
</div>
|
||||
<div class="item-row-bottom">
|
||||
<span class="item-sub">{{ parseTime(item.complaintDate, '{y}-{m}-{d}') }}</span>
|
||||
</div>
|
||||
<div class="item-meta">
|
||||
<el-tag v-if="item.flowStatus === 1" type="warning" size="mini">质量部·生产部处理中</el-tag>
|
||||
<el-tag v-else-if="item.flowStatus === 2" type="primary" size="mini">待陈总审批</el-tag>
|
||||
<el-tag v-else-if="item.flowStatus === 3" type="warning" size="mini">待吴部长处理</el-tag>
|
||||
<el-tag v-else-if="item.flowStatus === 4" type="success" size="mini">已办结</el-tag>
|
||||
</div>
|
||||
<div class="item-actions">
|
||||
<el-button size="mini" type="text" icon="el-icon-download"
|
||||
@click.stop="handleExportPdf(item)" title="导出PDF"></el-button>
|
||||
<el-button size="mini" type="text" icon="el-icon-edit" @click.stop="handleUpdate(item)"></el-button>
|
||||
<el-button size="mini" type="text" icon="el-icon-delete" @click.stop="handleDelete(item)"></el-button>
|
||||
<div class="item-actions">
|
||||
<el-button size="mini" type="text" icon="el-icon-download"
|
||||
@click.stop="handleExportPdf(item)" title="导出PDF"></el-button>
|
||||
<el-button size="mini" type="text" icon="el-icon-edit" @click.stop="handleUpdate(item)"></el-button>
|
||||
<el-button size="mini" type="text" icon="el-icon-delete" @click.stop="handleDelete(item)"></el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="dataList.length === 0 && !loading" class="list-empty">
|
||||
@@ -108,7 +110,7 @@
|
||||
<DepartmentOpinionSection :taskList="taskList" @refresh="refreshTaskList" />
|
||||
|
||||
<div class="section-gap" />
|
||||
<HandlingSchemeSection :content="currentRow.planContent" :editable="currentRow.flowStatus === 3" @save="handleSavePlan" />
|
||||
<HandlingSchemeSection :content="currentRow.planContent" :editable="currentRow.flowStatus === 4" @save="handleSavePlan" />
|
||||
|
||||
<div class="section-gap" />
|
||||
<template v-if="false">
|
||||
@@ -170,8 +172,9 @@
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
<el-button v-if="form.acceptId" :loading="draftLoading" @click="saveDraft">暂 存</el-button>
|
||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
@@ -222,6 +225,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
buttonLoading: false,
|
||||
draftLoading: false,
|
||||
pdfLoading: false,
|
||||
loading: true,
|
||||
detailLoading: false,
|
||||
@@ -248,7 +252,7 @@ export default {
|
||||
selectedDeptIds: [],
|
||||
deptOptions: [
|
||||
{ deptId: 1, deptName: '生产部' },
|
||||
{ deptId: 2, deptName: '质量部' },
|
||||
{ deptId: 2, deptName: '技术部' },
|
||||
{ deptId: 3, deptName: '销售部' }
|
||||
],
|
||||
rules: {
|
||||
@@ -306,7 +310,7 @@ export default {
|
||||
}).finally(() => { this.coilLoading = false; });
|
||||
},
|
||||
getDeptName(deptId) {
|
||||
const map = { 1: '生产部', 2: '质量部', 3: '销售部' };
|
||||
const map = { 1: '生产部', 2: '技术部', 3: '销售部' };
|
||||
return map[deptId] || '部门' + deptId;
|
||||
},
|
||||
handleAdd() {
|
||||
@@ -332,6 +336,19 @@ export default {
|
||||
handleUpdate(row) {
|
||||
this.reset();
|
||||
const acceptId = row.acceptId;
|
||||
// 检查是否有本地暂存
|
||||
const draftKey = 'draft_' + acceptId;
|
||||
const cached = localStorage.getItem(draftKey);
|
||||
if (cached) {
|
||||
try {
|
||||
const draft = JSON.parse(cached);
|
||||
this.form = draft.form;
|
||||
this.formCoilList = draft.formCoilList || [];
|
||||
this.open = true;
|
||||
this.title = "修改售后单(已恢复未保存内容)";
|
||||
return;
|
||||
} catch (e) { /* ignore */ }
|
||||
}
|
||||
getComplaintAccept(acceptId).then(response => {
|
||||
this.form = response.data;
|
||||
listAcceptCoilRel({ acceptId, pageNum: 1, pageSize: 999 }).then(r => {
|
||||
@@ -370,6 +387,21 @@ export default {
|
||||
this.open = false;
|
||||
this.reset();
|
||||
},
|
||||
saveDraft() {
|
||||
this.draftLoading = true;
|
||||
const draftKey = 'draft_' + this.form.acceptId;
|
||||
localStorage.setItem(draftKey, JSON.stringify({
|
||||
form: this.form,
|
||||
formCoilList: this.formCoilList
|
||||
}));
|
||||
this.$modal.msgSuccess("已暂存");
|
||||
this.draftLoading = false;
|
||||
this.open = false;
|
||||
},
|
||||
clearDraft(acceptId) {
|
||||
const draftKey = 'draft_' + acceptId;
|
||||
localStorage.removeItem(draftKey);
|
||||
},
|
||||
submitForm() {
|
||||
this.$refs["form"].validate(valid => {
|
||||
if (valid) {
|
||||
@@ -377,6 +409,7 @@ export default {
|
||||
const formData = { ...this.form, coilIds: this.formCoilList.map(c => c.coilId) };
|
||||
if (this.form.acceptId != null) {
|
||||
updateComplaintAccept(formData).then(() => {
|
||||
this.clearDraft(this.form.acceptId);
|
||||
this.$modal.msgSuccess("修改成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
@@ -610,8 +643,8 @@ export default {
|
||||
|
||||
.list-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10px 12px;
|
||||
flex-direction: column;
|
||||
padding: 8px 12px;
|
||||
margin-bottom: 2px;
|
||||
cursor: pointer;
|
||||
border-radius: 6px;
|
||||
@@ -631,15 +664,23 @@ export default {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.item-main {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
.item-row-top {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.item-row-bottom {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.item-title {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: #303133;
|
||||
@@ -654,8 +695,7 @@ export default {
|
||||
}
|
||||
|
||||
.item-meta {
|
||||
flex-shrink: 0;
|
||||
margin: 0 8px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.item-actions {
|
||||
|
||||
@@ -25,19 +25,19 @@
|
||||
<div v-loading="loading" class="list-body">
|
||||
<div v-for="item in taskList" :key="item.taskId" class="list-item"
|
||||
:class="{ active: currentTask && currentTask.taskId === item.taskId }" @click="handleRowClick(item)">
|
||||
<div class="item-main">
|
||||
<div class="item-row-top">
|
||||
<span class="item-title">{{ (item.acceptInfo || {}).complaintNo || '' }}</span>
|
||||
<span class="item-sub">{{ parseTime((item.acceptInfo || {}).complaintDate, '{y}-{m}-{d}') }}</span>
|
||||
</div>
|
||||
<div class="item-meta">
|
||||
<el-tag v-if="item.rejectMark === 1" type="danger" size="mini">已驳回</el-tag>
|
||||
<el-tag v-else-if="item.rejectMark === 2" type="info" size="mini">已隐藏</el-tag>
|
||||
<el-tag v-else-if="item.taskStatus === 0" type="warning" size="mini">待填写</el-tag>
|
||||
<el-tag v-else-if="item.taskStatus === 1" type="success" size="mini">已完成</el-tag>
|
||||
</div>
|
||||
<div class="item-actions">
|
||||
<el-button v-if="canEdit(item)" size="mini" type="text" icon="el-icon-edit" @click.stop="handleRowClick(item)"></el-button>
|
||||
<el-button v-else size="mini" type="text" icon="el-icon-view" @click.stop="handleRowClick(item)"></el-button>
|
||||
<div class="item-row-bottom">
|
||||
<span class="item-sub">{{ parseTime((item.acceptInfo || {}).complaintDate, '{y}-{m}-{d}') }}</span>
|
||||
<div class="item-actions">
|
||||
<el-button v-if="canEdit(item)" size="mini" type="text" icon="el-icon-edit" @click.stop="handleRowClick(item)"></el-button>
|
||||
<el-button v-else size="mini" type="text" icon="el-icon-view" @click.stop="handleRowClick(item)"></el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="taskList.length === 0 && !loading" class="list-empty">
|
||||
@@ -116,6 +116,7 @@
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="form-actions">
|
||||
<el-button :loading="draftLoading" @click="saveDraft">暂 存</el-button>
|
||||
<el-button :loading="submitLoading" type="primary" @click="submitOpinion">提 交</el-button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -151,6 +152,7 @@ export default {
|
||||
detailLoading: false,
|
||||
coilLoading: false,
|
||||
submitLoading: false,
|
||||
draftLoading: false,
|
||||
total: 0,
|
||||
|
||||
queryParams: {
|
||||
@@ -211,6 +213,17 @@ export default {
|
||||
this.dialogCoilList = r.rows || [];
|
||||
}).finally(() => { this.coilLoading = false; this.detailLoading = false; });
|
||||
|
||||
// 检查本地暂存
|
||||
const draftKey = 'draft_opinion_' + row.taskId;
|
||||
const cached = localStorage.getItem(draftKey);
|
||||
if (cached) {
|
||||
try {
|
||||
const draft = JSON.parse(cached);
|
||||
this.opinionForm = { deptOpinion: draft.deptOpinion || '', fillFile: draft.fillFile || '' };
|
||||
return;
|
||||
} catch (e) { /* ignore */ }
|
||||
}
|
||||
|
||||
getComplaintTask(row.taskId).then(response => {
|
||||
const task = response.data || {};
|
||||
this.opinionForm = {
|
||||
@@ -236,13 +249,19 @@ export default {
|
||||
}).finally(() => { this.coilLoading = false; });
|
||||
},
|
||||
getDeptLabel() {
|
||||
const map = { 1: '生产部', 2: '质量部', 3: '销售部(吴部长)', 4: '陈总审批' };
|
||||
const map = { 1: '生产部', 2: '技术部', 3: '销售部(吴部长)', 4: '陈总审批' };
|
||||
return map[this.queryParams.deptId] || '';
|
||||
},
|
||||
canEdit(row) {
|
||||
const status = (row.acceptInfo || {}).flowStatus;
|
||||
// 只要节点task状态为待处理(0)就可编辑
|
||||
return status >= 1 && status <= 3;
|
||||
const deptId = row.deptId;
|
||||
// 技术部(deptId=2) 仅在 flowStatus=1 时可编辑
|
||||
// 生产部(deptId=1) 仅在 flowStatus=2 时可编辑
|
||||
// 吴部长(deptId=3) 仅在 flowStatus=4 时可编辑
|
||||
if (deptId === 2 && status === 1) return true;
|
||||
if (deptId === 1 && status === 2) return true;
|
||||
if (deptId === 3 && status === 4) return true;
|
||||
return false;
|
||||
},
|
||||
loadAllTasks() {
|
||||
if (!this.currentTask.acceptId) return;
|
||||
@@ -252,7 +271,7 @@ export default {
|
||||
pageSize: 999
|
||||
}).then(r => {
|
||||
const tasks = r.rows || [];
|
||||
// 按 deptId 排序: 质量部(2)→生产部(1)→陈总(4)
|
||||
// 按 deptId 排序: 技术部(2)→生产部(1)→陈总(4)
|
||||
const order = { 2: 1, 1: 2, 4: 3 };
|
||||
tasks.sort((a, b) => (order[a.deptId] || 99) - (order[b.deptId] || 99));
|
||||
this.allTaskList = tasks;
|
||||
@@ -285,11 +304,29 @@ export default {
|
||||
taskStatus: 1,
|
||||
fillTime: this.parseTime(new Date(), '{y}-{m}-{d} {h}:{i}:{s}')
|
||||
}).then(() => {
|
||||
this.clearDraft(this.currentTask.taskId);
|
||||
this.$modal.msgSuccess("已提交,流程已流转至下一节点");
|
||||
this.getList();
|
||||
this.currentTask = {};
|
||||
}).finally(() => { this.submitLoading = false; });
|
||||
}
|
||||
},
|
||||
saveDraft() {
|
||||
if (!this.currentTask.taskId) {
|
||||
this.$modal.msgWarning("请先在左侧选择一条任务");
|
||||
return;
|
||||
}
|
||||
this.draftLoading = true;
|
||||
const draftKey = 'draft_opinion_' + this.currentTask.taskId;
|
||||
localStorage.setItem(draftKey, JSON.stringify({
|
||||
deptOpinion: this.opinionForm.deptOpinion,
|
||||
fillFile: this.opinionForm.fillFile
|
||||
}));
|
||||
this.$modal.msgSuccess("已暂存");
|
||||
this.draftLoading = false;
|
||||
},
|
||||
clearDraft(taskId) {
|
||||
localStorage.removeItem('draft_opinion_' + taskId);
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -350,8 +387,8 @@ export default {
|
||||
|
||||
.list-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10px 12px;
|
||||
flex-direction: column;
|
||||
padding: 8px 12px;
|
||||
margin-bottom: 2px;
|
||||
cursor: pointer;
|
||||
border-radius: 6px;
|
||||
@@ -371,15 +408,23 @@ export default {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.item-main {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
.item-row-top {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 3px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.item-row-bottom {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.item-title {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: #303133;
|
||||
@@ -393,9 +438,12 @@ export default {
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.item-main {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.item-meta {
|
||||
flex-shrink: 0;
|
||||
margin: 0 8px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.item-actions {
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
</div>
|
||||
<el-select v-model="queryParams.flowStatus" placeholder="全部阶段" clearable size="mini" @change="handleQuery"
|
||||
class="header-filter">
|
||||
<el-option label="待审批" :value="2" />
|
||||
<el-option label="已办结" :value="4" />
|
||||
<el-option label="待审批" :value="3" />
|
||||
<el-option label="已办结" :value="5" />
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
@@ -25,13 +25,13 @@
|
||||
<div v-loading="loading" class="list-body">
|
||||
<div v-for="item in dataList" :key="item.acceptId" class="list-item"
|
||||
:class="{ active: currentRow && currentRow.acceptId === item.acceptId }" @click="handleRowClick(item)">
|
||||
<div class="item-main">
|
||||
<div class="item-row-top">
|
||||
<span class="item-title">{{ item.complaintNo }}</span>
|
||||
<span class="item-sub">{{ parseTime(item.complaintDate, '{y}-{m}-{d}') }}</span>
|
||||
<el-tag v-if="item.flowStatus === 3" type="primary" size="mini">待陈总审批</el-tag>
|
||||
<el-tag v-else-if="item.flowStatus === 5" type="success" size="mini">已办结</el-tag>
|
||||
</div>
|
||||
<div class="item-meta">
|
||||
<el-tag v-if="item.flowStatus === 2" type="primary" size="mini">待陈总审批</el-tag>
|
||||
<el-tag v-else-if="item.flowStatus === 4" type="success" size="mini">已办结</el-tag>
|
||||
<div class="item-row-bottom">
|
||||
<span class="item-sub">{{ parseTime(item.complaintDate, '{y}-{m}-{d}') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="dataList.length === 0 && !loading" class="list-empty">
|
||||
@@ -57,7 +57,7 @@
|
||||
<HeaderControlSection :complaintNo="currentRow.complaintNo" :flowStatus="currentRow.flowStatus"
|
||||
:meta="currentRow">
|
||||
<template #actions>
|
||||
<el-button v-if="currentRow.flowStatus === 4" size="mini" type="primary" plain
|
||||
<el-button v-if="currentRow.flowStatus === 5" size="mini" type="primary" plain
|
||||
icon="el-icon-download" @click="handleExportPdf">导出</el-button>
|
||||
<el-button size="mini" type="text" icon="el-icon-refresh" @click="handleRefreshDetail"
|
||||
title="刷新详情">刷新</el-button>
|
||||
@@ -83,14 +83,15 @@
|
||||
<div class="section-gap" />
|
||||
<DepartmentOpinionSection :taskList="taskList" @refresh="refreshTaskList" />
|
||||
|
||||
<div v-if="currentRow.flowStatus === 2" class="section-gap" />
|
||||
<div v-if="currentRow.flowStatus === 2" class="approval-section">
|
||||
<div v-if="currentRow.flowStatus === 3" class="section-gap" />
|
||||
<div v-if="currentRow.flowStatus === 3" class="approval-section">
|
||||
<div class="section-title">
|
||||
<span>审批意见 <span class="en-sub">· Approval Opinion</span></span>
|
||||
</div>
|
||||
<el-input v-model="approvalOpinion" type="textarea" :rows="4"
|
||||
placeholder="请填写审批意见(审阅质量部、生产部意见后)" />
|
||||
placeholder="请填写审批意见(审阅技术部、生产部意见后)" />
|
||||
<div class="form-actions">
|
||||
<el-button :loading="draftLoading" @click="saveDraft">暂 存</el-button>
|
||||
<el-button type="primary" plain icon="el-icon-circle-check" :loading="completeLoading"
|
||||
@click="handleComplete">提交审批</el-button>
|
||||
</div>
|
||||
@@ -132,6 +133,7 @@ export default {
|
||||
detailLoading: false,
|
||||
coilLoading: false,
|
||||
completeLoading: false,
|
||||
draftLoading: false,
|
||||
total: 0,
|
||||
dataList: [],
|
||||
currentRow: null,
|
||||
@@ -139,7 +141,7 @@ export default {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
complaintNo: undefined,
|
||||
flowStatus: 2
|
||||
flowStatus: 3
|
||||
},
|
||||
coilList: [],
|
||||
taskList: [],
|
||||
@@ -168,6 +170,16 @@ export default {
|
||||
},
|
||||
loadDetail(acceptId) {
|
||||
this.detailLoading = true;
|
||||
// 检查本地暂存
|
||||
const draftKey = 'draft_summary_' + acceptId;
|
||||
const cached = localStorage.getItem(draftKey);
|
||||
if (cached) {
|
||||
try {
|
||||
this.approvalOpinion = cached;
|
||||
} catch (e) { /* ignore */ }
|
||||
} else {
|
||||
this.approvalOpinion = '';
|
||||
}
|
||||
getComplaintAccept(acceptId).then(response => {
|
||||
this.currentRow = response.data;
|
||||
this.loadRelData(acceptId);
|
||||
@@ -223,6 +235,7 @@ export default {
|
||||
throw new Error('no chen task');
|
||||
}
|
||||
}).then(() => {
|
||||
this.clearDraft(this.currentRow.acceptId);
|
||||
this.$modal.msgSuccess("审批已提交,已流转至吴部长处理");
|
||||
this.completeLoading = false;
|
||||
this.approvalOpinion = '';
|
||||
@@ -230,6 +243,23 @@ export default {
|
||||
this.getList();
|
||||
}).catch(() => { this.completeLoading = false; });
|
||||
},
|
||||
saveDraft() {
|
||||
if (!this.currentRow || !this.currentRow.acceptId) {
|
||||
this.$modal.msgWarning("请先在左侧选择一条售后单");
|
||||
return;
|
||||
}
|
||||
if (!this.approvalOpinion) {
|
||||
this.$modal.msgWarning("请先填写审批意见再暂存");
|
||||
return;
|
||||
}
|
||||
this.draftLoading = true;
|
||||
localStorage.setItem('draft_summary_' + this.currentRow.acceptId, this.approvalOpinion);
|
||||
this.$modal.msgSuccess("已暂存");
|
||||
this.draftLoading = false;
|
||||
},
|
||||
clearDraft(acceptId) {
|
||||
localStorage.removeItem('draft_summary_' + acceptId);
|
||||
},
|
||||
handleExportPdf() {
|
||||
this.$refs.exportPdfDialog.open(this.currentRow.acceptId);
|
||||
}
|
||||
@@ -292,8 +322,8 @@ export default {
|
||||
|
||||
.list-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10px 12px;
|
||||
flex-direction: column;
|
||||
padding: 8px 12px;
|
||||
margin-bottom: 2px;
|
||||
cursor: pointer;
|
||||
border-radius: 6px;
|
||||
@@ -313,15 +343,23 @@ export default {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.item-main {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
.item-row-top {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 3px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.item-row-bottom {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.item-title {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: #303133;
|
||||
@@ -335,9 +373,12 @@ export default {
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.item-main {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.item-meta {
|
||||
flex-shrink: 0;
|
||||
margin: 0 8px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.list-empty {
|
||||
|
||||
@@ -25,19 +25,19 @@
|
||||
<div v-loading="loading" class="list-body">
|
||||
<div v-for="item in dataList" :key="item.relId" class="list-item"
|
||||
:class="{ active: currentRel && currentRel.relId === item.relId }" @click="handleRowClick(item)">
|
||||
<div class="item-main">
|
||||
<div class="item-row-top">
|
||||
<span class="item-title">{{ (item.acceptInfo || {}).complaintNo || '' }}</span>
|
||||
<span class="item-sub">{{ getDeptName(item.deptId) }} · {{ parseTime((item.acceptInfo || {}).complaintDate, '{y}-{m}-{d}') }}</span>
|
||||
</div>
|
||||
<div class="item-meta">
|
||||
<el-tag v-if="item.rejectMark === 1" type="danger" size="mini">已驳回</el-tag>
|
||||
<el-tag v-else-if="item.rejectMark === 2" type="info" size="mini">已隐藏</el-tag>
|
||||
<el-tag v-else-if="item.executeStatus === 0" type="warning" size="mini">待执行</el-tag>
|
||||
<el-tag v-else-if="item.executeStatus === 1" type="success" size="mini">已反馈</el-tag>
|
||||
</div>
|
||||
<div class="item-actions">
|
||||
<el-button v-if="item.executeStatus === 0" size="mini" type="text" icon="el-icon-edit" @click.stop="handleRowClick(item)"></el-button>
|
||||
<el-button v-else size="mini" type="text" icon="el-icon-view" @click.stop="handleRowClick(item)"></el-button>
|
||||
<div class="item-row-bottom">
|
||||
<span class="item-sub">{{ getDeptName(item.deptId) }} · {{ parseTime((item.acceptInfo || {}).complaintDate, '{y}-{m}-{d}') }}</span>
|
||||
<div class="item-actions">
|
||||
<el-button v-if="item.executeStatus === 0" size="mini" type="text" icon="el-icon-edit" @click.stop="handleRowClick(item)"></el-button>
|
||||
<el-button v-else size="mini" type="text" icon="el-icon-view" @click.stop="handleRowClick(item)"></el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="dataList.length === 0 && !loading" class="list-empty">
|
||||
@@ -183,11 +183,11 @@ export default {
|
||||
}).finally(() => { this.loading = false; });
|
||||
},
|
||||
getDeptName(deptId) {
|
||||
const map = { 1: '生产部', 2: '质量部', 3: '销售部' };
|
||||
const map = { 1: '生产部', 2: '技术部', 3: '销售部' };
|
||||
return map[deptId] || '部门' + deptId;
|
||||
},
|
||||
getDeptLabel() {
|
||||
const map = { 1: '生产部', 2: '质量部', 3: '销售部' };
|
||||
const map = { 1: '生产部', 2: '技术部', 3: '销售部' };
|
||||
return map[this.currentRel.deptId] || '';
|
||||
},
|
||||
handleQuery() {
|
||||
@@ -326,8 +326,8 @@ export default {
|
||||
|
||||
.list-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10px 12px;
|
||||
flex-direction: column;
|
||||
padding: 8px 12px;
|
||||
margin-bottom: 2px;
|
||||
cursor: pointer;
|
||||
border-radius: 6px;
|
||||
@@ -347,15 +347,23 @@ export default {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.item-main {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
.item-row-top {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 3px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.item-row-bottom {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.item-title {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: #303133;
|
||||
@@ -369,9 +377,12 @@ export default {
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.item-main {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.item-meta {
|
||||
flex-shrink: 0;
|
||||
margin: 0 8px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.item-actions {
|
||||
|
||||
Reference in New Issue
Block a user