You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
309 lines
7.8 KiB
309 lines
7.8 KiB
<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-line-text" :title="buildTaskLineText(task)">{{ buildTaskLineText(task) }}</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: [],
|
|
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
|
|
const qcOperator = this.$store.state.user.name
|
|
const startDate = this.formatDate(new Date())
|
|
const site = this.$store.state.user.site
|
|
const qcDisplay = this.$store.state.user.userDisplay || this.$store.state.user.name
|
|
|
|
getScheduleView(qcOperator, startDate, site).then(({ data }) => {
|
|
if (data.code === 0 && data.list) {
|
|
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,
|
|
poNo: task.poNo,
|
|
supplierName: task.supplierName,
|
|
qcDisplay: qcDisplay,
|
|
inspectAddress: task.inspectAddress,
|
|
planStartDate: task.planStartDate,
|
|
planEndDate: task.planEndDate
|
|
})
|
|
}
|
|
currentDate.setDate(currentDate.getDate() + 1)
|
|
}
|
|
})
|
|
this.scheduleDays = days.map(day => ({
|
|
...day,
|
|
tasks: tasksByDate[day.date] || []
|
|
}))
|
|
} else {
|
|
this.scheduleDays = this.generateNextDays(10)
|
|
}
|
|
}).catch((error) => {
|
|
console.error('加载排程数据错误:', error)
|
|
this.scheduleDays = this.generateNextDays(10)
|
|
}).finally(() => {
|
|
this.loading = false
|
|
})
|
|
},
|
|
|
|
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
|
|
},
|
|
|
|
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}`
|
|
},
|
|
getSupplierDisplayName (supplierName) {
|
|
const value = supplierName || ''
|
|
return value.length > 30 ? value.substring(0, 30) : value
|
|
},
|
|
buildTaskLineText (task) {
|
|
const displayName = task.qcDisplay || this.$store.state.user.userDisplay || this.$store.state.user.name
|
|
const poNo = task.poNo || ''
|
|
const supplierName = this.getSupplierDisplayName(task.supplierName)
|
|
return [displayName, poNo, supplierName].filter(item => item).join(' | ')
|
|
},
|
|
|
|
// 点击任务卡片 - 只传递申请单号
|
|
handleTaskClick (task, date) {
|
|
console.log('点击任务:', task, '日期:', date)
|
|
// 构建查询参数,只传递申请单号
|
|
const query = {}
|
|
if (task.requestNo) {
|
|
query.requestNo = task.requestNo
|
|
}
|
|
// 不再传递 planStartDate, planEndDate, 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;
|
|
height: 470px;
|
|
width: 100%;
|
|
|
|
&: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;
|
|
flex-shrink: 0;
|
|
|
|
.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;
|
|
max-height: calc(100% - 55px);
|
|
|
|
&::-webkit-scrollbar {
|
|
width: 4px;
|
|
}
|
|
&::-webkit-scrollbar-thumb {
|
|
background: #dcdfe6;
|
|
border-radius: 2px;
|
|
&:hover {
|
|
background: #c0c4cc;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.task-item {
|
|
padding: 10px;
|
|
background: #f5f7fa;
|
|
border: 1px solid #dcdfe6;
|
|
border-radius: 3px;
|
|
cursor: pointer;
|
|
transition: all 0.3s;
|
|
flex-shrink: 0;
|
|
|
|
&:hover {
|
|
background: #ecf5ff;
|
|
border-color: #409eff;
|
|
box-shadow: 0 2px 8px rgba(64, 158, 255, 0.2);
|
|
transform: translateY(-2px);
|
|
}
|
|
}
|
|
|
|
.task-line-text {
|
|
font-size: 12px;
|
|
color: #303133;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
.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>
|