|
|
|
@ -2,7 +2,15 @@ |
|
|
|
<div class="schedule-container"> |
|
|
|
<!-- 左侧:QC人员清单 --> |
|
|
|
<div class="left-panel"> |
|
|
|
<div class="panel-title">QC人员清单</div> |
|
|
|
<div class="panel-title"> |
|
|
|
<span>QC人员清单</span> |
|
|
|
<el-button |
|
|
|
type="text" |
|
|
|
size="mini" |
|
|
|
icon="el-icon-view" |
|
|
|
style="float: right; margin-top: -2px;" |
|
|
|
@click="showAllQcSchedule">查看全部</el-button> |
|
|
|
</div> |
|
|
|
<el-table |
|
|
|
:data="qcList" |
|
|
|
border |
|
|
|
@ -88,6 +96,47 @@ |
|
|
|
<el-button size="small" @click="cancelSchedule">关闭</el-button> |
|
|
|
</div> |
|
|
|
</el-dialog> |
|
|
|
|
|
|
|
<!-- 所有QC排程查看弹窗 --> |
|
|
|
<el-dialog |
|
|
|
title="所有QC排程情况" |
|
|
|
:visible.sync="allQcScheduleDialogVisible" |
|
|
|
width="80%" |
|
|
|
:close-on-click-modal="false" |
|
|
|
append-to-body |
|
|
|
top="5vh"> |
|
|
|
<div class="all-qc-schedule-container" v-loading="allQcLoading"> |
|
|
|
<div class="schedule-days-grid"> |
|
|
|
<div v-for="day in allScheduleDays" :key="day.date" class="schedule-day-card"> |
|
|
|
<div class="day-header"> |
|
|
|
<span class="date-label">{{ day.dateLabel }}</span> |
|
|
|
<span class="date-weekday">{{ day.weekday }}</span> |
|
|
|
</div> |
|
|
|
<div class="day-body"> |
|
|
|
<div |
|
|
|
v-for="qcTask in day.qcTasks" |
|
|
|
:key="qcTask.userName" |
|
|
|
class="qc-task-item" |
|
|
|
@click="handleQcTaskClick(qcTask)"> |
|
|
|
<div class="qc-name-tag">{{ qcTask.qcName }}</div> |
|
|
|
<div class="task-list"> |
|
|
|
<div v-for="task in qcTask.tasks" :key="task.requestNo" class="mini-task"> |
|
|
|
<span class="task-no-text">{{ task.requestNo }}</span> |
|
|
|
<span class="task-supplier-text" :title="task.supplierName">{{ task.supplierName }}</span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div v-if="day.qcTasks.length === 0" class="empty-day"> |
|
|
|
<span class="empty-text">暂无排程</span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div slot="footer" class="dialog-footer"> |
|
|
|
<el-button size="small" @click="allQcScheduleDialogVisible = false">关闭</el-button> |
|
|
|
</div> |
|
|
|
</el-dialog> |
|
|
|
</div> |
|
|
|
</template> |
|
|
|
|
|
|
|
@ -109,6 +158,10 @@ export default { |
|
|
|
loading: false, |
|
|
|
qcTableHeight: 500, |
|
|
|
scheduleDialogVisible: false, |
|
|
|
allQcScheduleDialogVisible: false, |
|
|
|
allQcLoading: false, |
|
|
|
allQcScheduleData: {}, // 存储所有QC的排程数据 { userName: [days] } |
|
|
|
allScheduleDays: [], // 按日期组织的排程数据 [{ date, dateLabel, weekday, qcTasks: [...] }] |
|
|
|
scheduleForm: { |
|
|
|
qcOperator: '', |
|
|
|
qcUserName: '', |
|
|
|
@ -380,6 +433,98 @@ export default { |
|
|
|
handleTaskClick(task) { |
|
|
|
console.log('点击任务:', task) |
|
|
|
this.$emit('task-click', task) |
|
|
|
}, |
|
|
|
// 显示所有QC排程弹窗 |
|
|
|
showAllQcSchedule() { |
|
|
|
this.allQcScheduleDialogVisible = true |
|
|
|
this.loadAllQcSchedule() |
|
|
|
}, |
|
|
|
// 加载所有QC的排程数据 |
|
|
|
loadAllQcSchedule() { |
|
|
|
if (!this.qcList || this.qcList.length === 0) { |
|
|
|
this.$message.warning('暂无QC人员数据') |
|
|
|
return |
|
|
|
} |
|
|
|
this.allQcLoading = true |
|
|
|
const promises = this.qcList.map(qc => { |
|
|
|
return getScheduleView(qc.userName).then(({ data }) => { |
|
|
|
if (data.code === 0) { |
|
|
|
const days = this.generateNextDays(10) |
|
|
|
const tasksByDate = {} |
|
|
|
;(data.list || []).forEach(task => { |
|
|
|
const startDate = new Date(task.planStartDate) |
|
|
|
const endDate = new Date(task.planEndDate || task.planStartDate) |
|
|
|
let currentDate = new Date(startDate) |
|
|
|
while (currentDate <= endDate) { |
|
|
|
const dateStr = this.formatDate(currentDate) |
|
|
|
if (!tasksByDate[dateStr]) tasksByDate[dateStr] = [] |
|
|
|
const exists = tasksByDate[dateStr].some(t => t.requestNo === task.requestNo) |
|
|
|
if (!exists) { |
|
|
|
tasksByDate[dateStr].push({ |
|
|
|
requestNo: task.requestNo, |
|
|
|
supplierName: task.supplierName, |
|
|
|
inspectAddress: task.inspectAddress, |
|
|
|
planStartDate: task.planStartDate, |
|
|
|
planEndDate: task.planEndDate |
|
|
|
}) |
|
|
|
} |
|
|
|
currentDate.setDate(currentDate.getDate() + 1) |
|
|
|
} |
|
|
|
}) |
|
|
|
const scheduleDays = days.map(day => ({ |
|
|
|
...day, |
|
|
|
tasks: tasksByDate[day.date] || [] |
|
|
|
})) |
|
|
|
return { userName: qc.userName, qcName: qc.qcName, scheduleDays } |
|
|
|
} else { |
|
|
|
return { userName: qc.userName, qcName: qc.qcName, scheduleDays: this.generateNextDays(10) } |
|
|
|
} |
|
|
|
}).catch(() => { |
|
|
|
return { userName: qc.userName, qcName: qc.qcName, scheduleDays: this.generateNextDays(10) } |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
Promise.all(promises).then(results => { |
|
|
|
// 按日期重新组织数据 |
|
|
|
const daysMap = {} |
|
|
|
const baseDays = this.generateNextDays(10) |
|
|
|
|
|
|
|
// 初始化每一天的数据结构 |
|
|
|
baseDays.forEach(day => { |
|
|
|
daysMap[day.date] = { |
|
|
|
date: day.date, |
|
|
|
dateLabel: day.dateLabel, |
|
|
|
weekday: day.weekday, |
|
|
|
qcTasks: [] |
|
|
|
} |
|
|
|
}) |
|
|
|
|
|
|
|
// 将每个QC的任务分配到对应的日期 |
|
|
|
results.forEach(result => { |
|
|
|
result.scheduleDays.forEach(day => { |
|
|
|
if (day.tasks && day.tasks.length > 0) { |
|
|
|
if (daysMap[day.date]) { |
|
|
|
daysMap[day.date].qcTasks.push({ |
|
|
|
userName: result.userName, |
|
|
|
qcName: result.qcName, |
|
|
|
tasks: day.tasks |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
// 转换为数组并按日期排序 |
|
|
|
this.allScheduleDays = Object.values(daysMap).sort((a, b) => a.date.localeCompare(b.date)) |
|
|
|
this.allQcLoading = false |
|
|
|
}).catch(() => { |
|
|
|
this.allQcLoading = false |
|
|
|
}) |
|
|
|
}, |
|
|
|
// 点击QC任务项 |
|
|
|
handleQcTaskClick(qcTask) { |
|
|
|
console.log('点击QC任务:', qcTask) |
|
|
|
// 可以在这里添加查看详情等逻辑 |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -586,4 +731,152 @@ export default { |
|
|
|
font-size: 12px; |
|
|
|
border-radius: 3px; |
|
|
|
} |
|
|
|
|
|
|
|
/* 所有QC排程弹窗样式 */ |
|
|
|
.all-qc-schedule-container { |
|
|
|
max-height: 75vh; |
|
|
|
overflow-y: auto; |
|
|
|
padding: 10px; |
|
|
|
|
|
|
|
&::-webkit-scrollbar { |
|
|
|
width: 6px; |
|
|
|
} |
|
|
|
|
|
|
|
&::-webkit-scrollbar-thumb { |
|
|
|
background: #dcdfe6; |
|
|
|
border-radius: 3px; |
|
|
|
|
|
|
|
&:hover { |
|
|
|
background: #c0c4cc; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
.schedule-days-grid { |
|
|
|
display: grid; |
|
|
|
grid-template-columns: repeat(5, 1fr); |
|
|
|
gap: 12px; |
|
|
|
} |
|
|
|
|
|
|
|
.schedule-day-card { |
|
|
|
border: 2px solid #dcdfe6; |
|
|
|
border-radius: 4px; |
|
|
|
background: #fff; |
|
|
|
display: flex; |
|
|
|
flex-direction: column; |
|
|
|
height: 280px; |
|
|
|
width: 100%; |
|
|
|
|
|
|
|
.day-header { |
|
|
|
padding: 8px 10px; |
|
|
|
background: #f5f7fa; |
|
|
|
border-bottom: 2px solid #dcdfe6; |
|
|
|
display: flex; |
|
|
|
justify-content: space-between; |
|
|
|
align-items: center; |
|
|
|
height: 38px; |
|
|
|
flex-shrink: 0; |
|
|
|
|
|
|
|
.date-label { |
|
|
|
font-size: 14px; |
|
|
|
font-weight: bold; |
|
|
|
color: #303133; |
|
|
|
} |
|
|
|
|
|
|
|
.date-weekday { |
|
|
|
font-size: 11px; |
|
|
|
color: #909399; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
.day-body { |
|
|
|
padding: 8px; |
|
|
|
display: flex; |
|
|
|
flex-direction: column; |
|
|
|
gap: 6px; |
|
|
|
height: calc(100% - 38px); |
|
|
|
overflow-y: auto; |
|
|
|
|
|
|
|
&::-webkit-scrollbar { |
|
|
|
width: 4px; |
|
|
|
} |
|
|
|
|
|
|
|
&::-webkit-scrollbar-thumb { |
|
|
|
background: #dcdfe6; |
|
|
|
border-radius: 2px; |
|
|
|
|
|
|
|
&:hover { |
|
|
|
background: #c0c4cc; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
.qc-task-item { |
|
|
|
padding: 6px 8px; |
|
|
|
background: #f5f7fa; |
|
|
|
border: 1px solid #e4e7ed; |
|
|
|
border-radius: 3px; |
|
|
|
cursor: pointer; |
|
|
|
transition: all 0.3s; |
|
|
|
|
|
|
|
&:hover { |
|
|
|
background: #ecf5ff; |
|
|
|
border-color: #409eff; |
|
|
|
box-shadow: 0 2px 6px rgba(64, 158, 255, 0.12); |
|
|
|
} |
|
|
|
|
|
|
|
.qc-name-tag { |
|
|
|
font-size: 12px; |
|
|
|
font-weight: bold; |
|
|
|
color: #409eff; |
|
|
|
margin-bottom: 4px; |
|
|
|
padding-bottom: 3px; |
|
|
|
border-bottom: 1px dashed #dcdfe6; |
|
|
|
} |
|
|
|
|
|
|
|
.task-list { |
|
|
|
display: flex; |
|
|
|
flex-direction: column; |
|
|
|
gap: 3px; |
|
|
|
} |
|
|
|
|
|
|
|
.mini-task { |
|
|
|
padding: 3px 5px; |
|
|
|
background: #fff; |
|
|
|
border-radius: 2px; |
|
|
|
font-size: 10px; |
|
|
|
color: #606266; |
|
|
|
display: flex; |
|
|
|
justify-content: space-between; |
|
|
|
align-items: center; |
|
|
|
gap: 4px; |
|
|
|
|
|
|
|
.task-no-text { |
|
|
|
font-weight: 500; |
|
|
|
color: #303133; |
|
|
|
flex-shrink: 0; |
|
|
|
} |
|
|
|
|
|
|
|
.task-supplier-text { |
|
|
|
color: #909399; |
|
|
|
overflow: hidden; |
|
|
|
text-overflow: ellipsis; |
|
|
|
white-space: nowrap; |
|
|
|
flex: 1; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
.empty-day { |
|
|
|
flex: 1; |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
justify-content: center; |
|
|
|
|
|
|
|
.empty-text { |
|
|
|
color: #c0c4cc; |
|
|
|
font-size: 13px; |
|
|
|
} |
|
|
|
} |
|
|
|
</style> |