Browse Source
feat(inspection): 新增待办列表并优化排程界面
feat(inspection): 新增待办列表并优化排程界面
- 新增 myTodoList.vue 页面实现 QC 人员待办功能 - 在 inspectionScheduleView.vue 中添加无数据提示状态 - 重构排程表单的 QC 人员选择逻辑,区分显示名称和提交用户名 - 添加路由参数监听功能,支持从待办页面跳转到申请单列表 - 优化多个检验模块的搜索表单项布局和样式 - 在申请单列表中实现 Excel 导出功能 - 移除主表格的红色背景样式标记 - 添加定时刷新机制确保待办数据实时更新master
6 changed files with 516 additions and 96 deletions
-
96src/views/modules/inspection/com_inspectionScheduleView.vue
-
112src/views/modules/inspection/inspectionPendingList.vue
-
12src/views/modules/inspection/inspectionRequestAudit.vue
-
50src/views/modules/inspection/inspectionRequestList.vue
-
6src/views/modules/inspection/inspectionScheduleList.vue
-
336src/views/modules/inspection/myTodoList.vue
@ -0,0 +1,336 @@ |
|||
<template> |
|||
<div class="my-todo-container"> |
|||
<!-- 页面标题 --> |
|||
<div class="page-header"> |
|||
<h2 class="page-title">我的代办(QC人员)</h2> |
|||
<p class="page-desc">对于QC人员查看到自己的待验货的申请单</p> |
|||
</div> |
|||
|
|||
<!-- 日期卡片网格 --> |
|||
<div class="schedule-grid" v-loading="loading"> |
|||
<div |
|||
v-for="day in scheduleDays" |
|||
:key="day.date" |
|||
class="schedule-card"> |
|||
<div class="card-header"> |
|||
<span class="date-label">{{ day.dateLabel }}</span> |
|||
<span class="date-weekday">{{ day.weekday }}</span> |
|||
</div> |
|||
<div class="card-body"> |
|||
<div |
|||
v-for="task in day.tasks" |
|||
:key="task.requestNo" |
|||
class="task-item" |
|||
@click="handleTaskClick(task, day.date)"> |
|||
<div class="task-no">单号:{{ task.requestNo }}</div> |
|||
<div class="task-supplier" :title="task.supplierName">{{ task.supplierName }}</div> |
|||
<div v-if="task.inspectAddress" class="task-address" :title="task.inspectAddress"> |
|||
<i class="el-icon-location"></i> {{ task.inspectAddress }} |
|||
</div> |
|||
</div> |
|||
<div v-if="day.tasks.length === 0" class="empty-slot"> |
|||
<span class="empty-text">暂无排程</span> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import { getScheduleView } from '@/api/inspection/inspectionRequestHeader.js' |
|||
|
|||
export default { |
|||
name: 'MyTodoList', |
|||
|
|||
data () { |
|||
return { |
|||
scheduleDays: [], // 排程日期数组(未来10天) |
|||
loading: false, // 加载状态 |
|||
refreshTimer: null // 定时器 |
|||
} |
|||
}, |
|||
|
|||
mounted () { |
|||
this.loadScheduleData() |
|||
// 每分钟刷新一次 |
|||
this.refreshTimer = setInterval(() => { |
|||
this.loadScheduleData() |
|||
}, 60000) |
|||
}, |
|||
|
|||
beforeDestroy () { |
|||
// 清除定时器 |
|||
if (this.refreshTimer) { |
|||
clearInterval(this.refreshTimer) |
|||
this.refreshTimer = null |
|||
} |
|||
}, |
|||
|
|||
methods: { |
|||
// 加载排程数据 |
|||
loadScheduleData () { |
|||
this.loading = true |
|||
|
|||
// 使用当前登录用户的用户名作为QC人员查询 |
|||
const qcOperator = this.$store.state.user.name |
|||
|
|||
getScheduleView(qcOperator).then(({ data }) => { |
|||
if (data.code === 0 && data.list) { |
|||
// 生成未来10天的日期结构 |
|||
const days = this.generateNextDays(10) |
|||
|
|||
// 将后端返回的数据按日期分组 |
|||
const tasksByDate = {} |
|||
data.list.forEach(task => { |
|||
const dateStr = this.formatDate(new Date(task.planStartDate)) |
|||
if (!tasksByDate[dateStr]) { |
|||
tasksByDate[dateStr] = [] |
|||
} |
|||
tasksByDate[dateStr].push({ |
|||
requestNo: task.requestNo, |
|||
supplierName: task.supplierName, |
|||
inspectAddress: task.inspectAddress, |
|||
planStartDate: task.planStartDate, |
|||
planEndDate: task.planEndDate |
|||
}) |
|||
}) |
|||
|
|||
// 将任务分配到对应的日期卡片中 |
|||
this.scheduleDays = days.map(day => ({ |
|||
...day, |
|||
tasks: tasksByDate[day.date] || [] |
|||
})) |
|||
|
|||
console.log('加载排程数据成功:', this.scheduleDays) |
|||
} else { |
|||
// 即使失败也显示空白的日期卡片 |
|||
this.scheduleDays = this.generateNextDays(10) |
|||
} |
|||
}).catch((error) => { |
|||
console.error('加载排程数据错误:', error) |
|||
// 即使失败也显示空白的日期卡片 |
|||
this.scheduleDays = this.generateNextDays(10) |
|||
}).finally(() => { |
|||
this.loading = false |
|||
}) |
|||
}, |
|||
|
|||
// 生成未来N天的日期数组 |
|||
generateNextDays (days) { |
|||
const result = [] |
|||
const today = new Date() |
|||
const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'] |
|||
|
|||
for (let i = 0; i < days; i++) { |
|||
const date = new Date(today) |
|||
date.setDate(today.getDate() + i) |
|||
|
|||
const dateStr = this.formatDate(date) |
|||
const dateLabel = `${date.getMonth() + 1}/${date.getDate()}` |
|||
const weekday = weekdays[date.getDay()] |
|||
|
|||
result.push({ |
|||
date: dateStr, |
|||
dateLabel: dateLabel, |
|||
weekday: weekday, |
|||
tasks: [] |
|||
}) |
|||
} |
|||
|
|||
return result |
|||
}, |
|||
|
|||
// 格式化日期为 yyyy-MM-dd |
|||
formatDate (date) { |
|||
const year = date.getFullYear() |
|||
const month = String(date.getMonth() + 1).padStart(2, '0') |
|||
const day = String(date.getDate()).padStart(2, '0') |
|||
return `${year}-${month}-${day}` |
|||
}, |
|||
|
|||
// 点击任务卡片 |
|||
handleTaskClick (task, date) { |
|||
console.log('点击任务:', task, '日期:', date) |
|||
|
|||
// 跳转到待验货申请单页面,并传递任务信息 |
|||
const query = { |
|||
planStartDate: date, |
|||
planEndDate: date |
|||
} |
|||
|
|||
// 如果有申请单号,传递过去 |
|||
if (task.requestNo) { |
|||
query.requestNo = task.requestNo |
|||
} |
|||
|
|||
// 如果有供应商名称,传递过去 |
|||
if (task.supplierName) { |
|||
query.supplierName = task.supplierName |
|||
} |
|||
|
|||
this.$router.push({ |
|||
path: '/inspection-inspectionPendingList', |
|||
query: query |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped lang="scss"> |
|||
.my-todo-container { |
|||
padding: 20px; |
|||
background: #fff; |
|||
min-height: 100%; |
|||
} |
|||
|
|||
// 页面标题 |
|||
.page-header { |
|||
margin-bottom: 20px; |
|||
|
|||
.page-title { |
|||
font-size: 20px; |
|||
font-weight: bold; |
|||
color: #303133; |
|||
margin: 0 0 8px 0; |
|||
} |
|||
|
|||
.page-desc { |
|||
font-size: 14px; |
|||
color: #909399; |
|||
margin: 0; |
|||
} |
|||
} |
|||
|
|||
// 排程网格 |
|||
.schedule-grid { |
|||
display: grid; |
|||
grid-template-columns: repeat(5, 1fr); |
|||
grid-template-rows: repeat(2, 1fr); |
|||
gap: 15px; |
|||
min-height: 600px; |
|||
} |
|||
|
|||
// 排程卡片 |
|||
.schedule-card { |
|||
border: 2px solid #dcdfe6; |
|||
border-radius: 4px; |
|||
background: #fff; |
|||
display: flex; |
|||
flex-direction: column; |
|||
min-height: 180px; |
|||
transition: all 0.3s; |
|||
|
|||
&:hover { |
|||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1); |
|||
} |
|||
|
|||
.card-header { |
|||
padding: 10px 12px; |
|||
background: #f5f7fa; |
|||
border-bottom: 2px solid #dcdfe6; |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
|
|||
.date-label { |
|||
font-size: 18px; |
|||
font-weight: bold; |
|||
color: #303133; |
|||
} |
|||
|
|||
.date-weekday { |
|||
font-size: 13px; |
|||
color: #909399; |
|||
} |
|||
} |
|||
|
|||
.card-body { |
|||
flex: 1; |
|||
padding: 10px; |
|||
overflow-y: auto; |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 8px; |
|||
} |
|||
} |
|||
|
|||
// 任务项 |
|||
.task-item { |
|||
padding: 10px; |
|||
background: #f5f7fa; |
|||
border: 1px solid #dcdfe6; |
|||
border-radius: 3px; |
|||
cursor: pointer; |
|||
transition: all 0.3s; |
|||
|
|||
&:hover { |
|||
background: #ecf5ff; |
|||
border-color: #409eff; |
|||
box-shadow: 0 2px 8px rgba(64, 158, 255, 0.2); |
|||
transform: translateY(-2px); |
|||
} |
|||
|
|||
.task-no { |
|||
font-size: 13px; |
|||
font-weight: bold; |
|||
color: #409eff; |
|||
margin-bottom: 5px; |
|||
} |
|||
|
|||
.task-supplier { |
|||
font-size: 12px; |
|||
color: #606266; |
|||
overflow: hidden; |
|||
text-overflow: ellipsis; |
|||
white-space: nowrap; |
|||
margin-bottom: 4px; |
|||
} |
|||
|
|||
.task-address { |
|||
font-size: 11px; |
|||
color: #909399; |
|||
overflow: hidden; |
|||
text-overflow: ellipsis; |
|||
white-space: nowrap; |
|||
|
|||
i { |
|||
margin-right: 3px; |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 空白占位 |
|||
.empty-slot { |
|||
flex: 1; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
min-height: 80px; |
|||
|
|||
.empty-text { |
|||
color: #c0c4cc; |
|||
font-size: 13px; |
|||
} |
|||
} |
|||
|
|||
// 滚动条样式 |
|||
::-webkit-scrollbar { |
|||
width: 6px; |
|||
height: 6px; |
|||
} |
|||
|
|||
::-webkit-scrollbar-thumb { |
|||
background: #c0c4cc; |
|||
border-radius: 3px; |
|||
|
|||
&:hover { |
|||
background: #909399; |
|||
} |
|||
} |
|||
|
|||
::-webkit-scrollbar-track { |
|||
background: #f5f7fa; |
|||
} |
|||
</style> |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue