|
|
|
@ -1,13 +1,5 @@ |
|
|
|
<template> |
|
|
|
<div class="schedule-container"> |
|
|
|
<!-- 无数据提示 --> |
|
|
|
<div v-if="!hasSelectedData" class="empty-state"> |
|
|
|
<i class="el-icon-info" style="font-size: 48px; color: #c0c4cc;"></i> |
|
|
|
<p style="color: #909399; margin-top: 16px;">请先在主表中选择需要排程的申请单</p> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 有数据时显示正常内容 --> |
|
|
|
<template v-else> |
|
|
|
<!-- 左侧:QC人员清单 --> |
|
|
|
<div class="left-panel"> |
|
|
|
<div class="panel-title">QC人员清单</div> |
|
|
|
@ -23,15 +15,20 @@ |
|
|
|
class="qc-table"> |
|
|
|
<el-table-column prop="qcName" label="姓名" width="80" align="center" /> |
|
|
|
<el-table-column prop="region" label="负责区域" min-width="90" show-overflow-tooltip /> |
|
|
|
<el-table-column label="操作" width="80" align="center" fixed="right" v-if="currentStatusDb !== 'Scheduled'"> |
|
|
|
<el-table-column label="操作" width="80" align="center" fixed="right"> |
|
|
|
<template slot-scope="scope"> |
|
|
|
<el-link type="primary" style="cursor: pointer;" @click.stop="openScheduleDialog(null, scope.row)">排程</el-link> |
|
|
|
<!-- 只有当主表选中了数据且状态为已下达时才显示排程按钮 --> |
|
|
|
<el-link |
|
|
|
v-if="hasSelectedData && currentStatusDb === 'Audited'" |
|
|
|
type="primary" |
|
|
|
style="cursor: pointer;" |
|
|
|
@click.stop="openScheduleDialog(null, scope.row)">排程</el-link> |
|
|
|
</template> |
|
|
|
</el-table-column> |
|
|
|
</el-table> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 右侧:排程卡片 --> |
|
|
|
<!-- 右侧:排程卡片(始终显示) --> |
|
|
|
<div class="right-panel"> |
|
|
|
<div class="panel-title"> |
|
|
|
<span v-if="selectedQc">{{ selectedQc.qcName }} - 排程视图(未来10天)</span> |
|
|
|
@ -62,7 +59,6 @@ |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</template> |
|
|
|
|
|
|
|
<!-- 排程弹窗 --> |
|
|
|
<el-dialog |
|
|
|
@ -124,6 +120,7 @@ export default { |
|
|
|
} |
|
|
|
}, |
|
|
|
computed: { |
|
|
|
// 判断主表是否选中了数据 |
|
|
|
hasSelectedData() { |
|
|
|
return this.requestNos && this.requestNos.length > 0 |
|
|
|
} |
|
|
|
@ -132,41 +129,32 @@ export default { |
|
|
|
requestNos: { |
|
|
|
handler(newVal) { |
|
|
|
if (newVal && newVal.length > 0) { |
|
|
|
// 重置状态,重新加载 |
|
|
|
this.selectedQc = null |
|
|
|
this.scheduleDays = [] |
|
|
|
this.loadQcList() |
|
|
|
// 主表有选择数据时,加载排程数据 |
|
|
|
if (this.selectedQc) { |
|
|
|
this.loadScheduleData(this.selectedQc) |
|
|
|
} |
|
|
|
} else { |
|
|
|
this.selectedQc = null |
|
|
|
this.scheduleDays = [] |
|
|
|
this.qcList = [] |
|
|
|
// 主表无选择数据时,显示空卡片 |
|
|
|
this.scheduleDays = this.generateNextDays(10) |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
immediate: true |
|
|
|
} |
|
|
|
}, |
|
|
|
mounted() { |
|
|
|
console.log('[排程视图] 组件已挂载') |
|
|
|
// 组件挂载时自动加载QC列表和排程数据 |
|
|
|
this.loadQcList() |
|
|
|
}, |
|
|
|
methods: { |
|
|
|
// 强制刷新当前选中的QC排程视图(供父组件调用) |
|
|
|
forceRefresh() { |
|
|
|
console.log('[排程视图] 强制刷新,当前选中QC:', this.selectedQc) |
|
|
|
if (this.selectedQc) { |
|
|
|
this.loadScheduleData(this.selectedQc) |
|
|
|
} else if (this.qcList.length > 0) { |
|
|
|
// 如果没有选中QC但QC列表有数据,选中第一个并加载 |
|
|
|
this.selectedQc = this.qcList[0] |
|
|
|
this.loadScheduleData(this.selectedQc) |
|
|
|
this.$nextTick(() => { |
|
|
|
if (this.$refs.qcTable) this.$refs.qcTable.setCurrentRow(this.selectedQc) |
|
|
|
}) |
|
|
|
} else { |
|
|
|
// 如果QC列表为空,尝试重新加载QC列表 |
|
|
|
console.log('[排程视图] forceRefresh 被调用') |
|
|
|
// 直接重新加载QC列表和排程数据 |
|
|
|
this.loadQcList() |
|
|
|
} |
|
|
|
}, |
|
|
|
loadQcList() { |
|
|
|
console.log('[排程视图] 开始加载QC列表') |
|
|
|
|
|
|
|
const params = { page: 1, limit: 100 } |
|
|
|
getQcPersonList(params) |
|
|
|
.then(({ data }) => { |
|
|
|
@ -180,14 +168,26 @@ export default { |
|
|
|
console.log('[排程视图] QC列表加载成功:', this.qcList) |
|
|
|
|
|
|
|
if (this.qcList.length) { |
|
|
|
|
|
|
|
// 优先保持当前选中的QC,如果无效则选中第一个 |
|
|
|
if (!this.selectedQc || !this.qcList.some(q => q.userName === this.selectedQc.userName)) { |
|
|
|
if ( |
|
|
|
!this.selectedQc || |
|
|
|
!this.qcList.some(q => q.userName === this.selectedQc.userName) |
|
|
|
) { |
|
|
|
this.selectedQc = this.qcList[0] |
|
|
|
} |
|
|
|
// 加载排程数据 |
|
|
|
|
|
|
|
// 只有主表选择了数据时才加载排程数据,否则显示空卡片 |
|
|
|
if (this.hasSelectedData) { |
|
|
|
this.loadScheduleData(this.selectedQc) |
|
|
|
} else { |
|
|
|
this.scheduleDays = this.generateNextDays(10) |
|
|
|
} |
|
|
|
|
|
|
|
this.$nextTick(() => { |
|
|
|
if (this.$refs.qcTable) this.$refs.qcTable.setCurrentRow(this.selectedQc) |
|
|
|
if (this.$refs.qcTable) { |
|
|
|
this.$refs.qcTable.setCurrentRow(this.selectedQc) |
|
|
|
} |
|
|
|
}) |
|
|
|
} else { |
|
|
|
this.selectedQc = null |
|
|
|
@ -210,11 +210,68 @@ export default { |
|
|
|
handleQcSelect(row) { |
|
|
|
if (!row) return |
|
|
|
this.selectedQc = row |
|
|
|
// 只有主表选择了数据时才加载排程数据 |
|
|
|
if (this.hasSelectedData) { |
|
|
|
this.loadScheduleData(row) |
|
|
|
} else { |
|
|
|
this.scheduleDays = this.generateNextDays(10) |
|
|
|
} |
|
|
|
}, |
|
|
|
// 打开排程弹窗 |
|
|
|
openScheduleDialog(task, qcRow) { |
|
|
|
this.scheduleForm = { |
|
|
|
qcOperator: qcRow ? qcRow.userName : '', |
|
|
|
qcUserName: qcRow ? qcRow.qcName : '', |
|
|
|
planStartDate: '', |
|
|
|
planEndDate: '', |
|
|
|
remark: '' |
|
|
|
} |
|
|
|
this.scheduleDialogVisible = true |
|
|
|
}, |
|
|
|
// 其他方法保持不变(openScheduleDialog, submitSchedule, cancelSchedule, loadScheduleData, generateNextDays, formatDate, handleTaskClick) |
|
|
|
// 注意:loadScheduleData 中确保即使请求失败也生成空白卡片 |
|
|
|
|
|
|
|
// 关闭排程弹窗 |
|
|
|
cancelSchedule() { |
|
|
|
this.scheduleDialogVisible = false |
|
|
|
}, |
|
|
|
|
|
|
|
// 提交排程 |
|
|
|
submitSchedule() { |
|
|
|
this.$refs.scheduleForm.validate((valid) => { |
|
|
|
if (!valid) return |
|
|
|
if (!this.scheduleForm.planStartDate) { |
|
|
|
this.$message.warning('请选择计划验货日期') |
|
|
|
return |
|
|
|
} |
|
|
|
const params = { |
|
|
|
requestNos: this.requestNos, |
|
|
|
site: this.$store.state.user.site, |
|
|
|
qcOperator: this.scheduleForm.qcOperator, |
|
|
|
planStartDate: this.scheduleForm.planStartDate, |
|
|
|
planEndDate: this.scheduleForm.planEndDate || this.scheduleForm.planStartDate, |
|
|
|
remark: this.scheduleForm.remark |
|
|
|
} |
|
|
|
this.loading = true |
|
|
|
scheduleInspectionRequest(params).then(({ data }) => { |
|
|
|
if (data && data.code === 0) { |
|
|
|
this.$message.success('排程成功') |
|
|
|
this.scheduleDialogVisible = false |
|
|
|
// 通知父组件刷新主表数据(会触发整页刷新) |
|
|
|
this.$emit('schedule-success') |
|
|
|
} else { |
|
|
|
this.$message.error((data && data.msg) || '排程失败') |
|
|
|
} |
|
|
|
this.loading = false |
|
|
|
}).catch((error) => { |
|
|
|
console.error('排程失败:', error) |
|
|
|
this.$message.error('排程失败') |
|
|
|
this.loading = false |
|
|
|
}) |
|
|
|
}) |
|
|
|
}, |
|
|
|
|
|
|
|
loadScheduleData(qc) { |
|
|
|
console.log('======loadScheduleData======') |
|
|
|
console.log('qc=', qc) |
|
|
|
if (!qc) { |
|
|
|
console.warn('[排程视图] loadScheduleData 参数为空') |
|
|
|
this.scheduleDays = this.generateNextDays(10) |
|
|
|
@ -251,6 +308,15 @@ export default { |
|
|
|
...day, |
|
|
|
tasks: tasksByDate[day.date] || [] |
|
|
|
})) |
|
|
|
console.log('scheduleDays=', this.scheduleDays) |
|
|
|
|
|
|
|
console.log( |
|
|
|
'任务总数=', |
|
|
|
this.scheduleDays.reduce( |
|
|
|
(sum, item) => sum + item.tasks.length, |
|
|
|
0 |
|
|
|
) |
|
|
|
) |
|
|
|
console.log('[排程视图] 排程数据加载完成') |
|
|
|
} else { |
|
|
|
console.warn('[排程视图] 加载排程数据失败') |
|
|
|
@ -359,7 +425,7 @@ export default { |
|
|
|
grid-template-columns: repeat(5, 1fr); |
|
|
|
grid-template-rows: repeat(2, 1fr); |
|
|
|
gap: 10px; |
|
|
|
overflow: hidden; |
|
|
|
overflow-y: auto; |
|
|
|
} |
|
|
|
|
|
|
|
.schedule-card { |
|
|
|
|