Browse Source
feat(inspection): 添加检验排程概览页面
feat(inspection): 添加检验排程概览页面
- 新增 inspectionScheduleOverview.vue 页面,包含 QC 排程情况和验货进度列表两个标签页 - 实现所有 QC 人员排程可视化展示功能,支持按日期查询排程任务 - 添加验货进度列表功能,支持多条件筛选和分页查询 - 集成日历视图展示 QC 检验任务分布情况 - 实现任务卡片显示 QC 名称、供应商信息和城市简称 - 添加申请变更中任务的特殊样式标识 feat(part): 优化产品信息管理功能 - 在新增产品时实现 SKU 联想自动补全功能 - 添加基准料号失焦时查询已维护 SKU 的逻辑 - 集成供应商产品价格表校验机制 - 实现新品审核流程的自动处理功能 - 添加 SKU 自动建议列表和前缀匹配搜索 feat(supplier): 增强价格表报告权限控制 - 添加特殊权限 SRM0003 控制价格表导出功能 - 实现导出权限动态校验和界面按钮显示控制 - 集成权限验证 API 接口调用 feat(supplier): 扩展供应商零件价格管理 - 添加删除供应商零件阶梯价功能 - 实现供应商零件按 Item 和 SKU 校验存在性接口 - 集成新品审核流程启动功能master
6 changed files with 951 additions and 31 deletions
-
2src/api/part/partInfo.js
-
2src/api/supplier/supplierPartMoqPrice.js
-
732src/views/modules/inspection/inspectionScheduleOverview.vue
-
184src/views/modules/srmPart/partInfoList.vue
-
23src/views/modules/supplier/priceSheetReport.vue
-
39src/views/modules/supplier/supplierPartMoqPrice.vue
@ -0,0 +1,732 @@ |
|||
<template> |
|||
<div class="customer-css inspection-schedule-overview" ref="pageRoot"> |
|||
<el-tabs v-model="activeTab" type="border-card" class="customer-tab" @tab-click="handleTabClick"> |
|||
<!-- 页签一:所有QC人员排程情况 --> |
|||
<el-tab-pane label="QC排程情况" name="schedule"> |
|||
<el-form :inline="true" size="small" class="all-qc-query-form"> |
|||
<el-form-item label="起始日期"> |
|||
<el-date-picker |
|||
v-model="allQcQuery.startDate" |
|||
type="date" |
|||
value-format="yyyy-MM-dd" |
|||
placeholder="请选择起始日期" |
|||
style="width: 150px;" /> |
|||
</el-form-item> |
|||
<el-form-item label=" "> |
|||
<el-button type="primary" size="small" @click="queryAllQcSchedule">查询</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
<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"> |
|||
<div class="task-list"> |
|||
<div |
|||
v-for="task in qcTask.tasks" |
|||
:key="task.requestNo" |
|||
:class="['mini-task', { 'mini-task--change-applying': isChangeApplyingTask(task) }]"> |
|||
<span class="task-line-text" :title="buildTaskLineText(task, qcTask.qcName)">{{ buildTaskLineText(task, qcTask.qcName) }}</span> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div v-if="day.qcTasks.length === 0" class="empty-day"> |
|||
<span class="empty-text">暂无排程</span> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</el-tab-pane> |
|||
|
|||
<!-- 页签二:已排程/验货中/申请变更中 列表 --> |
|||
<el-tab-pane label="验货进度列表" name="progress"> |
|||
<el-form :inline="true" label-position="top" class="search-form-inline"> |
|||
<div class="search-row"> |
|||
<el-form-item class="search-item"> |
|||
<span style="cursor: pointer" slot="label" @click="getBaseList(520)"><a href="#">供应商编码</a></span> |
|||
<el-input v-model="searchData.supplierNo" style="width: 120px" @keyup.enter.native="getMainData"/> |
|||
</el-form-item> |
|||
<el-form-item label="供应商名称" class="search-item"> |
|||
<el-input v-model="searchData.supplierName" style="width: 220px" @keyup.enter.native="getMainData"/> |
|||
</el-form-item> |
|||
<el-form-item class="search-item"> |
|||
<span style="cursor: pointer" slot="label" @click="getBaseList(2016, 'qcOperator')"><a href="#">QC人员</a></span> |
|||
<el-input v-model="searchData.qcOperator" clearable style="width: 120px" @keyup.enter.native="getMainData"/> |
|||
</el-form-item> |
|||
<el-form-item class="search-item"> |
|||
<span style="cursor: pointer" slot="label" @click="getBaseList(2016, 'createBy')"><a href="#">申请人员</a></span> |
|||
<el-input v-model="searchData.createBy" clearable style="width: 120px" @keyup.enter.native="getMainData"/> |
|||
</el-form-item> |
|||
<el-form-item label="申请单号" class="search-item"> |
|||
<el-input v-model="searchData.requestNo" style="width: 120px" @keyup.enter.native="getMainData"/> |
|||
</el-form-item> |
|||
</div> |
|||
<div class="search-row"> |
|||
<el-form-item label="状态" class="search-item"> |
|||
<el-select v-model="searchData.statusFilter" clearable placeholder="全部" style="width: 140px"> |
|||
<el-option label="已排程" value="Scheduled" /> |
|||
<el-option label="验货中" value="Inspecting" /> |
|||
<el-option label="申请变更中" value="ChangeApplying" /> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="建议验货日期" class="search-item"> |
|||
<div class="date-range"> |
|||
<el-date-picker v-model="searchData.needInspectDateStart" type="date" value-format="yyyy-MM-dd" placeholder="开始" style="width: 150px"/> |
|||
<span class="split">-</span> |
|||
<el-date-picker v-model="searchData.needInspectDateEnd" type="date" value-format="yyyy-MM-dd" placeholder="结束" style="width: 150px"/> |
|||
</div> |
|||
</el-form-item> |
|||
<el-form-item label="计划验货日期" class="search-item"> |
|||
<div class="date-range"> |
|||
<el-date-picker v-model="searchData.planStartDate" type="date" value-format="yyyy-MM-dd" placeholder="开始" style="width: 150px"/> |
|||
<span class="split">-</span> |
|||
<el-date-picker v-model="searchData.planEndDate" type="date" value-format="yyyy-MM-dd" placeholder="结束" style="width: 150px"/> |
|||
</div> |
|||
</el-form-item> |
|||
<el-form-item label=" " class="search-item search-btn-item"> |
|||
<el-button type="primary" @click="getMainData">查询</el-button> |
|||
<el-button @click="resetSearch">重置</el-button> |
|||
</el-form-item> |
|||
</div> |
|||
</el-form> |
|||
|
|||
<el-table |
|||
:height="tableHeight" |
|||
:data="mainDataList" |
|||
border |
|||
ref="mainTable" |
|||
highlight-current-row |
|||
v-loading="dataListLoading" |
|||
style="margin-top: 0px; width: 100%;"> |
|||
<el-table-column |
|||
v-for="(item,index) in columnArray1" :key="index" |
|||
:sortable="item.columnSortable" |
|||
:prop="item.columnProp" |
|||
:header-align="item.headerAlign" |
|||
:show-overflow-tooltip="item.showOverflowTooltip" |
|||
:align="item.align" |
|||
:fixed="item.fixed === '' ? false : item.fixed" |
|||
:min-width="item.columnWidth" |
|||
:label="item.columnLabel"> |
|||
<template slot-scope="scope"> |
|||
<span v-if="!item.columnHidden">{{ scope.row[item.columnProp] }}</span> |
|||
</template> |
|||
</el-table-column> |
|||
</el-table> |
|||
|
|||
<el-pagination style="margin-top: 0px" |
|||
@size-change="sizeChangeHandle" |
|||
@current-change="currentChangeHandle" |
|||
:current-page="pageIndex" |
|||
:page-sizes="[20, 50, 100, 200, 500]" |
|||
:page-size="pageSize" |
|||
:total="totalPage" |
|||
layout="total, sizes, prev, pager, next, jumper"> |
|||
</el-pagination> |
|||
</el-tab-pane> |
|||
</el-tabs> |
|||
|
|||
<Chooselist ref="baseList" @getBaseData="getBaseData"></Chooselist> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import { |
|||
getQcPersonList, |
|||
getScheduleView, |
|||
searchInspectionRequestHeaderList |
|||
} from '@/api/inspection/inspectionRequestHeader.js' |
|||
import Chooselist from '@/views/modules/common/Chooselist_eam' |
|||
|
|||
// 页签二固定查询的状态分组:已排程、验货中、申请变更中 |
|||
const PROGRESS_GROUP = 'PROGRESS_GROUP' |
|||
|
|||
// 构建页签二表格列配置(模块级函数,避免依赖组件初始化顺序) |
|||
const buildColumn = (prop, label, width, align) => ({ |
|||
columnProp: prop, |
|||
columnLabel: label, |
|||
columnWidth: width, |
|||
headerAlign: 'center', |
|||
align: align || 'left', |
|||
showOverflowTooltip: true, |
|||
columnSortable: false, |
|||
columnHidden: false, |
|||
columnImage: false, |
|||
fixed: false |
|||
}) |
|||
|
|||
export default { |
|||
name: 'InspectionScheduleOverview', |
|||
components: { |
|||
Chooselist |
|||
}, |
|||
data () { |
|||
return { |
|||
activeTab: 'schedule', |
|||
functionId: (this.$route && this.$route.meta) ? this.$route.meta.menuId : '', |
|||
|
|||
// ===== 页签一:所有QC排程 ===== |
|||
qcList: [], |
|||
qcLoaded: false, |
|||
allQcLoading: false, |
|||
allQcScheduleLoaded: false, |
|||
allScheduleDays: [], |
|||
allQcQuery: { |
|||
startDate: '' |
|||
}, |
|||
|
|||
// ===== 页签二:验货进度列表 ===== |
|||
tableHeight: 400, |
|||
tagNo: '', |
|||
searchType: '', |
|||
dataListLoading: false, |
|||
mainDataList: [], |
|||
progressLoaded: false, |
|||
pageIndex: 1, |
|||
pageSize: 50, |
|||
totalPage: 0, |
|||
searchData: { |
|||
site: this.$store.state.user.site, |
|||
requestNo: '', |
|||
supplierNo: '', |
|||
supplierName: '', |
|||
status: PROGRESS_GROUP, |
|||
statusFilter: '', |
|||
qcOperator: '', |
|||
createBy: '', |
|||
needInspectDateStart: '', |
|||
needInspectDateEnd: '', |
|||
planStartDate: '', |
|||
planEndDate: '', |
|||
planStartDateStr: '', |
|||
planEndDateStr: '', |
|||
page: 1, |
|||
limit: 50 |
|||
}, |
|||
columnArray1: [ |
|||
buildColumn('qcOperator', 'QC人员', '100', 'left'), |
|||
buildColumn('status', '状态', '100', 'center'), |
|||
buildColumn('requestNo', '申请单号', '120', 'left'), |
|||
buildColumn('requestDate', '申请日期', '120', 'center'), |
|||
buildColumn('supplierNo', '供应商编码', '120', 'left'), |
|||
buildColumn('supplierName', '供应商名称', '150', 'left'), |
|||
buildColumn('createBy', '申请人员', '100', 'left'), |
|||
buildColumn('needInspectDate', '建议验货日期', '120', 'center'), |
|||
buildColumn('planStartDate', '计划验货日期', '120', 'center'), |
|||
buildColumn('inspectAddress', '验货地址', '200', 'left'), |
|||
buildColumn('inspectCityShort', '城市简称', '120', 'left'), |
|||
buildColumn('inspectContract', '联系人', '150', 'left'), |
|||
buildColumn('remark', '备注', '150', 'left') |
|||
] |
|||
} |
|||
}, |
|||
mounted () { |
|||
this.allQcQuery.startDate = this.getTodayDateString() |
|||
this.$nextTick(() => { |
|||
this.updateTableHeight() |
|||
// 默认加载页签一 |
|||
this.loadQcList().then(() => { |
|||
this.loadAllQcSchedule() |
|||
this.allQcScheduleLoaded = true |
|||
}) |
|||
}) |
|||
window.addEventListener('resize', this.updateTableHeight) |
|||
}, |
|||
beforeDestroy () { |
|||
window.removeEventListener('resize', this.updateTableHeight) |
|||
}, |
|||
methods: { |
|||
updateTableHeight () { |
|||
// 页签二仅有主表,预留页签头、查询区与分页高度 |
|||
this.tableHeight = Math.max(280, window.innerHeight - 320) |
|||
}, |
|||
handleTabClick (tab) { |
|||
if (tab.name === 'progress') { |
|||
this.$nextTick(this.updateTableHeight) |
|||
if (!this.progressLoaded) { |
|||
this.getMainData() |
|||
this.progressLoaded = true |
|||
} |
|||
} else if (tab.name === 'schedule') { |
|||
if (!this.allQcScheduleLoaded) { |
|||
this.loadQcList().then(() => { |
|||
this.loadAllQcSchedule() |
|||
this.allQcScheduleLoaded = true |
|||
}) |
|||
} |
|||
} |
|||
}, |
|||
|
|||
// ==================== 页签一:所有QC排程 ==================== |
|||
loadQcList () { |
|||
const params = { |
|||
page: 1, |
|||
limit: 100, |
|||
site: this.$store.state.user.site |
|||
} |
|||
return getQcPersonList(params).then(({ data }) => { |
|||
if (data.code === 0 && data.page && data.page.list) { |
|||
this.qcList = data.page.list.map(item => ({ |
|||
id: item.id || item.userId, |
|||
qcName: item.userDisplay || item.userName, |
|||
userName: item.userName, |
|||
region: '' |
|||
})) |
|||
this.qcLoaded = true |
|||
} else { |
|||
this.qcList = [] |
|||
} |
|||
}).catch(() => { |
|||
this.qcList = [] |
|||
}) |
|||
}, |
|||
queryAllQcSchedule () { |
|||
if (!this.allQcQuery.startDate) { |
|||
this.allQcQuery.startDate = this.getTodayDateString() |
|||
} |
|||
this.loadAllQcSchedule() |
|||
}, |
|||
loadAllQcSchedule () { |
|||
if (!this.qcList || this.qcList.length === 0) { |
|||
this.allScheduleDays = this.generateNextDays(10, this.allQcQuery.startDate) |
|||
this.$message.warning('暂无QC人员数据') |
|||
return |
|||
} |
|||
const startDate = this.allQcQuery.startDate || this.getTodayDateString() |
|||
this.allQcQuery.startDate = startDate |
|||
this.allQcLoading = true |
|||
const promises = this.qcList.map(qc => { |
|||
return getScheduleView(qc.userName, startDate, this.$store.state.user.site).then(({ data }) => { |
|||
if (data.code === 0) { |
|||
const days = this.generateNextDays(10, startDate) |
|||
const tasksByDate = {} |
|||
;(data.list || []).forEach(task => { |
|||
const taskStartDate = new Date(task.planStartDate) |
|||
const taskEndDate = new Date(task.planEndDate || task.planStartDate) |
|||
let currentDate = new Date(taskStartDate) |
|||
while (currentDate <= taskEndDate) { |
|||
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, |
|||
supplierShortOffice: task.supplierShortOffice || '', |
|||
inspectAddress: task.inspectAddress, |
|||
inspectCityShort: task.inspectCityShort || '', |
|||
planStartDate: task.planStartDate, |
|||
planEndDate: task.planEndDate, |
|||
statusDb: task.statusDb || '' |
|||
}) |
|||
} |
|||
currentDate = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate() + 1) |
|||
} |
|||
}) |
|||
const scheduleDays = days.map(day => ({ |
|||
...day, |
|||
tasks: tasksByDate[day.date] || [] |
|||
})) |
|||
return { userName: qc.userName, qcName: qc.qcName, scheduleDays } |
|||
} |
|||
return { userName: qc.userName, qcName: qc.qcName, scheduleDays: this.generateNextDays(10, startDate) } |
|||
}).catch(() => { |
|||
return { userName: qc.userName, qcName: qc.qcName, scheduleDays: this.generateNextDays(10, startDate) } |
|||
}) |
|||
}) |
|||
|
|||
Promise.all(promises).then(results => { |
|||
const daysMap = {} |
|||
const baseDays = this.generateNextDays(10, startDate) |
|||
baseDays.forEach(day => { |
|||
daysMap[day.date] = { |
|||
date: day.date, |
|||
dateLabel: day.dateLabel, |
|||
weekday: day.weekday, |
|||
qcTasks: [] |
|||
} |
|||
}) |
|||
results.forEach(result => { |
|||
result.scheduleDays.forEach(day => { |
|||
if (day.tasks && day.tasks.length > 0 && 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 |
|||
}) |
|||
}, |
|||
generateNextDays (days, startDate) { |
|||
const result = [] |
|||
const baseDate = this.parseDateString(startDate) || new Date() |
|||
const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'] |
|||
for (let i = 0; i < days; i++) { |
|||
const date = new Date(baseDate) |
|||
date.setDate(baseDate.getDate() + i) |
|||
result.push({ |
|||
date: this.formatDate(date), |
|||
dateLabel: `${date.getMonth() + 1}/${date.getDate()}`, |
|||
weekday: weekdays[date.getDay()], |
|||
tasks: [] |
|||
}) |
|||
} |
|||
return result |
|||
}, |
|||
getTodayDateString () { |
|||
return this.formatDate(new Date()) |
|||
}, |
|||
parseDateString (dateStr) { |
|||
if (!dateStr) { |
|||
return null |
|||
} |
|||
const parts = String(dateStr).split('-') |
|||
if (parts.length !== 3) { |
|||
return null |
|||
} |
|||
const year = Number(parts[0]) |
|||
const month = Number(parts[1]) - 1 |
|||
const day = Number(parts[2]) |
|||
const parsedDate = new Date(year, month, day) |
|||
if (Number.isNaN(parsedDate.getTime())) { |
|||
return null |
|||
} |
|||
return parsedDate |
|||
}, |
|||
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}` |
|||
}, |
|||
getShortOfficeDisplayName (shortOffice, supplierName) { |
|||
const value = shortOffice || supplierName || '' |
|||
return value.length > 30 ? value.substring(0, 30) : value |
|||
}, |
|||
buildTaskLineText (task, qcDisplayName) { |
|||
const displayName = qcDisplayName || task.qcDisplay || '' |
|||
const supplierShortOffice = this.getShortOfficeDisplayName(task.supplierShortOffice, task.supplierName) |
|||
const inspectCityShort = task.inspectCityShort || '' |
|||
return [displayName, supplierShortOffice, inspectCityShort].filter(item => item).join(' | ') |
|||
}, |
|||
isChangeApplyingTask (task) { |
|||
return !!(task && task.statusDb === 'ChangeApplying') |
|||
}, |
|||
|
|||
// ==================== 页签二:验货进度列表 ==================== |
|||
resolveUserCode (val, tagNo) { |
|||
if (!val) return '' |
|||
if (tagNo === 2016) { |
|||
return val.username || '' |
|||
} |
|||
if (tagNo === 528 || tagNo === 529 || tagNo === 530) { |
|||
return val.UserName || '' |
|||
} |
|||
return '' |
|||
}, |
|||
getBaseList (val, type) { |
|||
this.tagNo = val |
|||
this.searchType = type || '' |
|||
this.$nextTick(() => { |
|||
let strVal = '' |
|||
let conSql = '' |
|||
if (val === 520) { |
|||
strVal = this.searchData.supplierNo || '' |
|||
conSql = " and site = '" + this.$store.state.user.site + "'" |
|||
} |
|||
if (val === 2016) { |
|||
strVal = type === 'createBy' |
|||
? (this.searchData.createBy || '') |
|||
: (type === 'qcOperator' ? (this.searchData.qcOperator || '') : '') |
|||
conSql = " and username <> '' " |
|||
} |
|||
this.$refs.baseList.init(val, strVal, conSql) |
|||
}) |
|||
}, |
|||
getBaseData (val) { |
|||
if (this.tagNo === 520) { |
|||
this.searchData.supplierNo = val.supplier_no || '' |
|||
} |
|||
if (this.tagNo === 2016) { |
|||
const userCode = this.resolveUserCode(val, 2016) |
|||
if (this.searchType === 'createBy') { |
|||
this.searchData.createBy = userCode |
|||
} else if (this.searchType === 'qcOperator') { |
|||
this.searchData.qcOperator = userCode |
|||
} |
|||
} |
|||
}, |
|||
getMainData () { |
|||
this.searchData.limit = this.pageSize |
|||
this.searchData.page = this.pageIndex |
|||
this.searchData.planStartDateStr = this.searchData.planStartDate || '' |
|||
this.searchData.planEndDateStr = this.searchData.planEndDate || '' |
|||
// 选中具体状态时按该状态精确查询,未选时按已排程/验货中/申请变更中分组查询 |
|||
this.searchData.status = this.searchData.statusFilter || PROGRESS_GROUP |
|||
|
|||
this.dataListLoading = true |
|||
searchInspectionRequestHeaderList(this.searchData).then(({ data }) => { |
|||
if (data.code === 0) { |
|||
this.mainDataList = data.page.list |
|||
this.pageIndex = data.page.currPage |
|||
this.pageSize = data.page.pageSize |
|||
this.totalPage = data.page.totalCount |
|||
} else { |
|||
this.mainDataList = [] |
|||
this.totalPage = 0 |
|||
this.$message.error((data && data.msg) || '查询失败') |
|||
} |
|||
this.dataListLoading = false |
|||
}).catch(() => { |
|||
this.mainDataList = [] |
|||
this.totalPage = 0 |
|||
this.dataListLoading = false |
|||
}) |
|||
}, |
|||
resetSearch () { |
|||
this.searchData = { |
|||
site: this.$store.state.user.site, |
|||
requestNo: '', |
|||
supplierNo: '', |
|||
supplierName: '', |
|||
status: PROGRESS_GROUP, |
|||
statusFilter: '', |
|||
qcOperator: '', |
|||
createBy: '', |
|||
needInspectDateStart: '', |
|||
needInspectDateEnd: '', |
|||
planStartDate: '', |
|||
planEndDate: '', |
|||
planStartDateStr: '', |
|||
planEndDateStr: '', |
|||
page: 1, |
|||
limit: 50 |
|||
} |
|||
this.pageIndex = 1 |
|||
this.getMainData() |
|||
}, |
|||
sizeChangeHandle (val) { |
|||
this.pageSize = val |
|||
this.pageIndex = 1 |
|||
this.getMainData() |
|||
}, |
|||
currentChangeHandle (val) { |
|||
this.pageIndex = val |
|||
this.getMainData() |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped lang="scss"> |
|||
.inspection-schedule-overview { |
|||
padding: 0; |
|||
} |
|||
|
|||
/* ===== 页签一:所有QC排程 ===== */ |
|||
.all-qc-query-form { |
|||
padding: 0 4px; |
|||
margin-bottom: 6px; |
|||
} |
|||
|
|||
.all-qc-schedule-container { |
|||
height: calc(100vh - 230px); |
|||
min-height: 320px; |
|||
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: 340px; |
|||
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; |
|||
transition: all 0.3s; |
|||
|
|||
&:hover { |
|||
background: #ecf5ff; |
|||
border-color: #409eff; |
|||
box-shadow: 0 2px 6px rgba(64, 158, 255, 0.12); |
|||
} |
|||
|
|||
.task-list { |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 3px; |
|||
} |
|||
|
|||
.mini-task { |
|||
padding: 3px 5px; |
|||
background: #fff; |
|||
border-radius: 2px; |
|||
border: 1px solid transparent; |
|||
} |
|||
|
|||
.mini-task--change-applying { |
|||
border-color: #f56c6c; |
|||
box-shadow: 0 0 6px rgba(245, 108, 108, 0.35); |
|||
background: linear-gradient(135deg, #fff5f5 0%, #ffffff 100%); |
|||
} |
|||
} |
|||
|
|||
.task-line-text { |
|||
font-size: 12px; |
|||
color: #303133; |
|||
white-space: nowrap; |
|||
overflow: hidden; |
|||
text-overflow: ellipsis; |
|||
display: block; |
|||
} |
|||
|
|||
.empty-day { |
|||
flex: 1; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
|
|||
.empty-text { |
|||
color: #c0c4cc; |
|||
font-size: 13px; |
|||
} |
|||
} |
|||
|
|||
/* ===== 页签二:验货进度列表 ===== */ |
|||
.search-form-inline { |
|||
background: #fff; |
|||
padding: 0; |
|||
margin-bottom: 0; |
|||
} |
|||
|
|||
.search-row { |
|||
display: flex; |
|||
align-items: flex-end; |
|||
flex-wrap: wrap; |
|||
gap: 0; |
|||
margin-bottom: 0; |
|||
} |
|||
|
|||
.search-item { |
|||
flex: none; |
|||
margin-bottom: 0; |
|||
margin-right: 12px; |
|||
} |
|||
|
|||
.search-item /deep/ .el-form-item__label { |
|||
padding-bottom: 5px; |
|||
line-height: 1; |
|||
height: auto; |
|||
} |
|||
|
|||
.search-btn-item { |
|||
flex: none; |
|||
margin-bottom: 0; |
|||
margin-right: 0; |
|||
} |
|||
|
|||
.search-item /deep/ .el-form-item__content { |
|||
line-height: normal; |
|||
} |
|||
|
|||
.date-range { |
|||
display: flex; |
|||
align-items: center; |
|||
} |
|||
|
|||
.split { |
|||
padding: 0 6px; |
|||
color: #606266; |
|||
font-size: 13px; |
|||
} |
|||
|
|||
/deep/ .customer-tab .el-tabs__content { |
|||
padding: 5px !important; |
|||
} |
|||
</style> |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue