6 changed files with 1035 additions and 11 deletions
-
10src/api/schedule/todoCenter.js
-
85src/views/main-sidebar-hover.vue
-
43src/views/main-sidebar-sub-menu.vue
-
37src/views/main-sidebar.vue
-
21src/views/modules/sys/sceneExceptionRuleConfig.vue
-
850src/views/modules/todo/todoCenter.vue
@ -0,0 +1,10 @@ |
|||||
|
import { createAPI } from '@/utils/httpRequest.js' |
||||
|
|
||||
|
// 功能代办中心:查询统计
|
||||
|
export const getTodoCenterStats = data => createAPI('schedule/getTodoCenterStats', 'POST', data) |
||||
|
|
||||
|
// 功能代办中心:分页查询代办列表
|
||||
|
export const searchTodoCenterList = data => createAPI('schedule/searchTodoCenterList', 'POST', data) |
||||
|
|
||||
|
// 功能代办中心:查询创建分卷缓存详情
|
||||
|
export const getTodoCacheDetail = data => createAPI('schedule/shiftChange/getUnprocessedData', 'POST', data) |
||||
@ -0,0 +1,850 @@ |
|||||
|
<template> |
||||
|
<div class="mod-todo-center" v-loading="dataListLoading"> |
||||
|
<div class="todo-top-fixed"> |
||||
|
<div class="todo-filter-panel"> |
||||
|
<el-form :inline="true" :model="searchData" @keyup.enter.native="queryHandle"> |
||||
|
<el-form-item label="BU"> |
||||
|
<el-select v-model="searchData.buNo" clearable filterable placeholder="全部" style="width: 180px"> |
||||
|
<el-option |
||||
|
v-for="item in buList" |
||||
|
:key="item.buNo" |
||||
|
:label="(item.sitename || item.site || '') + '-' + (item.buDesc || item.buNo || '')" |
||||
|
:value="item.buNo"> |
||||
|
</el-option> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="是否强制"> |
||||
|
<el-select v-model="searchData.forceType" clearable placeholder="全部" style="width: 140px"> |
||||
|
<el-option |
||||
|
v-for="item in forceTypeOptions" |
||||
|
:key="item.value" |
||||
|
:label="item.label" |
||||
|
:value="item.value"> |
||||
|
</el-option> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="代办状态"> |
||||
|
<el-select v-model="searchData.todoStatus" clearable placeholder="全部" style="width: 140px"> |
||||
|
<el-option |
||||
|
v-for="item in todoStatusOptions" |
||||
|
:key="item.value" |
||||
|
:label="item.label" |
||||
|
:value="item.value"> |
||||
|
</el-option> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="责任部门"> |
||||
|
<el-select v-model="searchData.responsibilityDept" clearable filterable placeholder="全部" style="width: 160px"> |
||||
|
<el-option |
||||
|
v-for="item in roleList" |
||||
|
:key="item.roleId" |
||||
|
:label="item.roleName" |
||||
|
:value="String(item.roleId)"> |
||||
|
</el-option> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="关键字"> |
||||
|
<el-input |
||||
|
v-model="searchData.keyword" |
||||
|
clearable |
||||
|
placeholder="信息编码/派工单号/订单号" |
||||
|
style="width: 260px"> |
||||
|
</el-input> |
||||
|
</el-form-item> |
||||
|
<el-form-item label=" "> |
||||
|
<el-button type="primary" @click="queryHandle">查询</el-button> |
||||
|
<el-button @click="resetHandle">重置</el-button> |
||||
|
</el-form-item> |
||||
|
</el-form> |
||||
|
</div> |
||||
|
|
||||
|
<div class="todo-summary-row"> |
||||
|
<div class="summary-card blue"> |
||||
|
<div class="summary-icon"><i class="el-icon-document"></i></div> |
||||
|
<div class="summary-content"> |
||||
|
<div class="summary-value">{{ stats.pendingAuditCount }}</div> |
||||
|
<div class="summary-label">待审核</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="summary-card green"> |
||||
|
<div class="summary-icon"><i class="el-icon-success"></i></div> |
||||
|
<div class="summary-content"> |
||||
|
<div class="summary-value">{{ stats.pendingOperateCount }}</div> |
||||
|
<div class="summary-label">可报告</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="summary-card orange"> |
||||
|
<div class="summary-icon"><i class="el-icon-time"></i></div> |
||||
|
<div class="summary-content"> |
||||
|
<div class="summary-value">{{ stats.completedCount }}</div> |
||||
|
<div class="summary-label">已完成</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="todo-main-scroll"> |
||||
|
<div class="todo-card-grid" v-if="dataList.length > 0"> |
||||
|
<div class="todo-card" v-for="item in dataList" :key="item.infoCode"> |
||||
|
<div class="todo-card-head"> |
||||
|
<div class="risk-tag" :class="{ high: item.lockFlag === 'Y' }"> |
||||
|
{{ item.lockFlag === 'Y' ? '强制' : '提示' }} |
||||
|
</div> |
||||
|
<div class="todo-code">{{ item.infoCode || '-' }}</div> |
||||
|
<el-tag size="mini" :type="statusType(item)"> |
||||
|
{{ statusLabel(item) }} |
||||
|
</el-tag> |
||||
|
</div> |
||||
|
|
||||
|
<div class="todo-source">{{ item.messageSource || '-' }}</div> |
||||
|
|
||||
|
<div class="todo-main-title"> |
||||
|
{{ item.orderNo || '-' }} |
||||
|
</div> |
||||
|
|
||||
|
<div class="todo-detail-line"> |
||||
|
<span class="label">工序</span> |
||||
|
<span class="value">工序 1|创建分卷</span> |
||||
|
</div> |
||||
|
<div class="todo-detail-line"> |
||||
|
<span class="label">派工单号</span> |
||||
|
<span class="value">{{ item.seqNo || '-' }}</span> |
||||
|
</div> |
||||
|
<div class="todo-detail-line"> |
||||
|
<span class="label">责任部门</span> |
||||
|
<span class="value">{{ item.responsibilityDeptName || item.responsibilityDept || '-' }}</span> |
||||
|
</div> |
||||
|
|
||||
|
<div class="todo-step-row"> |
||||
|
<div class="step-item done">生成</div> |
||||
|
<div class="step-item" :class="{ done: item.auditFlag === 'Y' }">审核</div> |
||||
|
<div class="step-item" :class="{ done: item.operateFlag === 'Y' }">完成</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="todo-footer"> |
||||
|
<span class="todo-time">{{ formatDateTime(item.createdTime) }}</span> |
||||
|
<el-button |
||||
|
size="mini" |
||||
|
type="primary" |
||||
|
plain |
||||
|
@click="showDetail(item)"> |
||||
|
详情 |
||||
|
</el-button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div v-else class="todo-empty"> |
||||
|
暂无代办数据 |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="todo-bottom-fixed"> |
||||
|
<el-pagination |
||||
|
class="todo-pagination" |
||||
|
@size-change="sizeChangeHandle" |
||||
|
@current-change="currentChangeHandle" |
||||
|
:current-page="pageIndex" |
||||
|
:page-sizes="[15, 30, 60, 100]" |
||||
|
:page-size="pageSize" |
||||
|
:total="totalPage" |
||||
|
layout="total, sizes, prev, pager, next, jumper"> |
||||
|
</el-pagination> |
||||
|
</div> |
||||
|
|
||||
|
<el-dialog |
||||
|
:title="detailDialogTitle" |
||||
|
:close-on-click-modal="false" |
||||
|
:visible.sync="detailDialogVisible" |
||||
|
width="820px" |
||||
|
class="customer-dialog todo-cache-detail-dialog" |
||||
|
append-to-body> |
||||
|
<div v-loading="detailDialogLoading"> |
||||
|
<el-form :inline="true" label-position="top" style="height: auto;"> |
||||
|
<el-row style="margin-top: -10px;"> |
||||
|
<el-col :span="11"> |
||||
|
<el-form-item label="时间"> |
||||
|
<el-input :value="detailData.cacheTime" readonly style="width: 220px;"></el-input> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="6"> |
||||
|
<el-form-item label="固定载具"> |
||||
|
<el-input :value="detailData.fixture" readonly style="width: 120px;"></el-input> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="3"> |
||||
|
<el-form-item label="排数"> |
||||
|
<el-input-number :controls="false" :step="0" :value="detailData.rowCount" disabled style="width: 60px;"></el-input-number> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="3"> |
||||
|
<el-form-item label="分切卷数"> |
||||
|
<el-input-number :controls="false" :step="0" :value="detailData.rollCount" disabled style="width: 60px;"></el-input-number> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
|
||||
|
<div class="table-content-container"> |
||||
|
<el-table |
||||
|
:data="detailRowList" |
||||
|
border |
||||
|
style="width: 100%; margin-top: 10px;" |
||||
|
max-height="360"> |
||||
|
<el-table-column prop="rowNumber" label="NO." width="50" align="center"></el-table-column> |
||||
|
<el-table-column label="良品数" width="80" align="center"> |
||||
|
<template slot-scope="scope"> |
||||
|
<el-input-number |
||||
|
:controls="false" |
||||
|
:step="0" |
||||
|
:value="scope.row.goodQty" |
||||
|
disabled |
||||
|
style="width: 100%;" |
||||
|
class="readonly-qty-input good-qty-input"> |
||||
|
</el-input-number> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column label="面损" width="80" align="center"> |
||||
|
<template slot-scope="scope"> |
||||
|
<el-input-number |
||||
|
:controls="false" |
||||
|
:step="0" |
||||
|
:value="scope.row.surfaceLossQty" |
||||
|
disabled |
||||
|
style="width: 100%;" |
||||
|
class="readonly-qty-input"> |
||||
|
</el-input-number> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column label="性能不良" width="80" align="center"> |
||||
|
<template slot-scope="scope"> |
||||
|
<el-input-number |
||||
|
:controls="false" |
||||
|
:step="0" |
||||
|
:value="scope.row.poorPerformanceQty" |
||||
|
disabled |
||||
|
style="width: 100%;" |
||||
|
class="readonly-qty-input"> |
||||
|
</el-input-number> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column label="不良数" width="80" align="right"> |
||||
|
<template slot-scope="scope"> |
||||
|
<div class="readonly-number defect" style="text-align: right; padding-right: 10px;"> |
||||
|
{{ scope.row.defectQty }} |
||||
|
</div> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column label="良率" width="80" align="center"> |
||||
|
<template slot-scope="scope"> |
||||
|
<div class="readonly-number yield">{{ scope.row.yieldRate }}</div> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column label="总数" width="80" align="right"> |
||||
|
<template slot-scope="scope"> |
||||
|
<div class="readonly-number" style="text-align: right; padding-right: 10px;"> |
||||
|
{{ scope.row.totalQty }} |
||||
|
</div> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column label="Packing List" align="center" class-name="packing-list-column"> |
||||
|
<template slot-scope="scope"> |
||||
|
<div class="remark-wrapper"> |
||||
|
<el-input |
||||
|
type="textarea" |
||||
|
:value="scope.row.packingList" |
||||
|
resize="none" |
||||
|
:autosize="false" |
||||
|
readonly |
||||
|
class="remark-textarea"> |
||||
|
</el-input> |
||||
|
</div> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column label="备注" align="center" class-name="remark-column"> |
||||
|
<template slot-scope="scope"> |
||||
|
<div class="remark-wrapper"> |
||||
|
<el-input |
||||
|
type="textarea" |
||||
|
:value="scope.row.remark" |
||||
|
resize="none" |
||||
|
:autosize="false" |
||||
|
readonly |
||||
|
class="remark-textarea"> |
||||
|
</el-input> |
||||
|
</div> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
</el-form> |
||||
|
</div> |
||||
|
<span slot="footer" class="dialog-footer"> |
||||
|
<el-button type="primary" @click="detailDialogVisible = false">关闭</el-button> |
||||
|
</span> |
||||
|
</el-dialog> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { getSiteAndBuByUserName, getUserRoleList } from '@/api/qc/qc' |
||||
|
import { getTodoCenterStats, searchTodoCenterList, getTodoCacheDetail } from '@/api/schedule/todoCenter' |
||||
|
|
||||
|
export default { |
||||
|
data () { |
||||
|
return { |
||||
|
dataListLoading: false, |
||||
|
pageIndex: 1, |
||||
|
pageSize: 15, |
||||
|
totalPage: 0, |
||||
|
buList: [], |
||||
|
roleList: [], |
||||
|
searchData: { |
||||
|
site: this.$store.state.user.site, |
||||
|
buNo: '', |
||||
|
forceType: 'force', |
||||
|
todoStatus: 'pendingAudit', |
||||
|
responsibilityDept: '', |
||||
|
keyword: '' |
||||
|
}, |
||||
|
forceTypeOptions: [ |
||||
|
{ label: '强制', value: 'force' }, |
||||
|
{ label: '提示', value: 'hint' } |
||||
|
], |
||||
|
todoStatusOptions: [ |
||||
|
{ label: '待审核', value: 'pendingAudit' }, |
||||
|
{ label: '可报告', value: 'reportable' }, |
||||
|
{ label: '已完成', value: 'completed' } |
||||
|
], |
||||
|
stats: { |
||||
|
totalCount: 0, |
||||
|
pendingAuditCount: 0, |
||||
|
pendingOperateCount: 0, |
||||
|
pendingTotalCount: 0, |
||||
|
completedCount: 0, |
||||
|
lockPendingCount: 0 |
||||
|
}, |
||||
|
dataList: [], |
||||
|
detailDialogVisible: false, |
||||
|
detailDialogLoading: false, |
||||
|
detailDialogTitle: '创建分卷详情', |
||||
|
detailData: { |
||||
|
cacheTime: '', |
||||
|
fixture: '', |
||||
|
rowCount: 0, |
||||
|
rollCount: 0 |
||||
|
}, |
||||
|
detailRowList: [] |
||||
|
} |
||||
|
}, |
||||
|
created () { |
||||
|
this.loadBuList() |
||||
|
this.loadRoleList() |
||||
|
this.getTodoStats() |
||||
|
this.getDataList() |
||||
|
}, |
||||
|
methods: { |
||||
|
loadBuList () { |
||||
|
const params = { username: this.$store.state.user.name } |
||||
|
getSiteAndBuByUserName(params).then(({ data }) => { |
||||
|
if (data && data.code === 0) { |
||||
|
this.buList = data.rows || [] |
||||
|
} else { |
||||
|
this.buList = [] |
||||
|
} |
||||
|
}).catch(() => { |
||||
|
this.buList = [] |
||||
|
}) |
||||
|
}, |
||||
|
loadRoleList () { |
||||
|
getUserRoleList({}).then(({ data }) => { |
||||
|
if (data && data.code === 0) { |
||||
|
this.roleList = data.rows || [] |
||||
|
} else { |
||||
|
this.roleList = [] |
||||
|
} |
||||
|
}).catch(() => { |
||||
|
this.roleList = [] |
||||
|
}) |
||||
|
}, |
||||
|
queryHandle () { |
||||
|
this.pageIndex = 1 |
||||
|
this.getTodoStats() |
||||
|
this.getDataList() |
||||
|
}, |
||||
|
resetHandle () { |
||||
|
this.searchData.buNo = '' |
||||
|
this.searchData.forceType = 'force' |
||||
|
this.searchData.todoStatus = 'pendingAudit' |
||||
|
this.searchData.responsibilityDept = '' |
||||
|
this.searchData.keyword = '' |
||||
|
this.queryHandle() |
||||
|
}, |
||||
|
getTodoStats () { |
||||
|
const query = this.buildQuery() |
||||
|
getTodoCenterStats(query).then(({ data }) => { |
||||
|
if (data && data.code === 200 && data.resultMap) { |
||||
|
this.stats = Object.assign({}, this.stats, data.resultMap) |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
getDataList () { |
||||
|
this.dataListLoading = true |
||||
|
const query = this.buildQuery() |
||||
|
query.page = this.pageIndex |
||||
|
query.limit = this.pageSize |
||||
|
searchTodoCenterList(query).then(({ data }) => { |
||||
|
if (data && data.code === 200 && data.page) { |
||||
|
this.dataList = data.page.list || [] |
||||
|
this.totalPage = data.page.totalCount || 0 |
||||
|
} else { |
||||
|
this.dataList = [] |
||||
|
this.totalPage = 0 |
||||
|
} |
||||
|
}).finally(() => { |
||||
|
this.dataListLoading = false |
||||
|
}) |
||||
|
}, |
||||
|
buildQuery () { |
||||
|
const currentSite = this.searchData.site || this.$store.state.user.site || '' |
||||
|
return { |
||||
|
site: currentSite, |
||||
|
buNo: this.searchData.buNo, |
||||
|
forceType: this.searchData.forceType, |
||||
|
todoStatus: this.searchData.todoStatus, |
||||
|
responsibilityDept: this.searchData.responsibilityDept, |
||||
|
keyword: this.searchData.keyword |
||||
|
} |
||||
|
}, |
||||
|
sizeChangeHandle (val) { |
||||
|
this.pageSize = val |
||||
|
this.pageIndex = 1 |
||||
|
this.getDataList() |
||||
|
}, |
||||
|
currentChangeHandle (val) { |
||||
|
this.pageIndex = val |
||||
|
this.getDataList() |
||||
|
}, |
||||
|
statusLabel (row) { |
||||
|
if (!row) { |
||||
|
return '' |
||||
|
} |
||||
|
if (row.auditFlag === 'Y' && row.operateFlag === 'Y') { |
||||
|
return '已完成' |
||||
|
} |
||||
|
if (row.auditFlag === 'Y' && row.operateFlag === 'N') { |
||||
|
return '可报告' |
||||
|
} |
||||
|
if (row.auditFlag === 'N' && row.operateFlag === 'N') { |
||||
|
return '待审核' |
||||
|
} |
||||
|
return '处理中' |
||||
|
}, |
||||
|
statusType (row) { |
||||
|
if (!row) { |
||||
|
return 'info' |
||||
|
} |
||||
|
if (row.auditFlag === 'Y' && row.operateFlag === 'Y') { |
||||
|
return 'success' |
||||
|
} |
||||
|
if (row.auditFlag === 'Y' && row.operateFlag === 'N') { |
||||
|
return 'warning' |
||||
|
} |
||||
|
if (row.auditFlag === 'N' && row.operateFlag === 'N') { |
||||
|
return 'danger' |
||||
|
} |
||||
|
return 'info' |
||||
|
}, |
||||
|
formatDateTime (val) { |
||||
|
if (!val) { |
||||
|
return '-' |
||||
|
} |
||||
|
return String(val).replace('T', ' ').substring(0, 19) |
||||
|
}, |
||||
|
resetDetailData () { |
||||
|
this.detailData = { |
||||
|
cacheTime: '', |
||||
|
fixture: '', |
||||
|
rowCount: 0, |
||||
|
rollCount: 0 |
||||
|
} |
||||
|
this.detailRowList = [] |
||||
|
}, |
||||
|
toInt (value) { |
||||
|
const num = Number(value) |
||||
|
if (Number.isNaN(num)) { |
||||
|
return null |
||||
|
} |
||||
|
return parseInt(num, 10) |
||||
|
}, |
||||
|
toNum (value) { |
||||
|
const num = Number(value) |
||||
|
if (Number.isNaN(num)) { |
||||
|
return 0 |
||||
|
} |
||||
|
return num |
||||
|
}, |
||||
|
calcYieldRate (goodQty, defectQty) { |
||||
|
const totalQty = goodQty + defectQty |
||||
|
if (totalQty <= 0) { |
||||
|
return '0.00%' |
||||
|
} |
||||
|
return ((goodQty / totalQty) * 100).toFixed(2) + '%' |
||||
|
}, |
||||
|
mapCacheDetailRows (cacheList) { |
||||
|
return (cacheList || []).map(item => { |
||||
|
const goodQty = this.toNum(item.goodQty) |
||||
|
const defectQty = this.toNum(item.defectQty) |
||||
|
const totalQty = goodQty + defectQty |
||||
|
return { |
||||
|
rowNumber: this.toInt(item.rowBumber) || 0, |
||||
|
goodQty: goodQty, |
||||
|
surfaceLossQty: this.toNum(item.surfaceLossQty), |
||||
|
poorPerformanceQty: this.toNum(item.poorPerformanceQty), |
||||
|
defectQty: defectQty, |
||||
|
yieldRate: this.calcYieldRate(goodQty, defectQty), |
||||
|
totalQty: totalQty, |
||||
|
packingList: item.packingList || '', |
||||
|
remark: item.remark || '' |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
showDetail (row) { |
||||
|
if (!row) { |
||||
|
return |
||||
|
} |
||||
|
this.detailDialogTitle = `创建分卷缓存详情 - ${row.infoCode || ''}` |
||||
|
this.detailDialogVisible = true |
||||
|
this.detailDialogLoading = true |
||||
|
this.resetDetailData() |
||||
|
|
||||
|
const seqNo = this.toInt(row.seqNo) |
||||
|
if (seqNo === null) { |
||||
|
this.detailDialogLoading = false |
||||
|
this.$message.error('派工单号格式不正确,无法查询缓存数据') |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
const query = { |
||||
|
site: row.site || this.searchData.site || this.$store.state.user.site, |
||||
|
orderNo: row.orderNo, |
||||
|
seqNo: seqNo |
||||
|
} |
||||
|
getTodoCacheDetail(query).then(({ data }) => { |
||||
|
if (!(data && data.code === 0)) { |
||||
|
this.$message.error((data && data.msg) || '缓存数据查询失败') |
||||
|
return |
||||
|
} |
||||
|
const cacheList = data.data || [] |
||||
|
if (cacheList.length === 0) { |
||||
|
this.$message.warning('当前代办暂无缓存数据') |
||||
|
return |
||||
|
} |
||||
|
const first = cacheList[0] |
||||
|
this.detailData.cacheTime = this.formatDateTime(first.createdTime) |
||||
|
this.detailData.fixture = first.fixtureNo || '' |
||||
|
this.detailData.rowCount = this.toInt(first.rowCount) || cacheList.length |
||||
|
this.detailData.rollCount = this.toInt(first.rollCount) || 0 |
||||
|
this.detailRowList = this.mapCacheDetailRows(cacheList) |
||||
|
}).catch(() => { |
||||
|
this.$message.error('缓存数据查询失败') |
||||
|
}).finally(() => { |
||||
|
this.detailDialogLoading = false |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.mod-todo-center { |
||||
|
height: calc(100vh - 120px); |
||||
|
min-height: calc(100vh - 120px); |
||||
|
background: #f3f5f9; |
||||
|
padding: 10px; |
||||
|
box-sizing: border-box; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
|
||||
|
.todo-top-fixed { |
||||
|
flex-shrink: 0; |
||||
|
background: #f3f5f9; |
||||
|
z-index: 2; |
||||
|
} |
||||
|
|
||||
|
.todo-main-scroll { |
||||
|
flex: 1; |
||||
|
min-height: 0; |
||||
|
overflow-y: auto; |
||||
|
overflow-x: hidden; |
||||
|
padding-right: 2px; |
||||
|
} |
||||
|
|
||||
|
.todo-bottom-fixed { |
||||
|
flex-shrink: 0; |
||||
|
background: #f3f5f9; |
||||
|
padding-top: 10px; |
||||
|
} |
||||
|
|
||||
|
.todo-filter-panel { |
||||
|
background: #fff; |
||||
|
border: 1px solid #ebeef5; |
||||
|
border-radius: 6px; |
||||
|
padding: 12px 14px 2px; |
||||
|
margin-bottom: 10px; |
||||
|
} |
||||
|
|
||||
|
.panel-title { |
||||
|
font-size: 14px; |
||||
|
color: #606266; |
||||
|
margin-bottom: 8px; |
||||
|
font-weight: 600; |
||||
|
} |
||||
|
|
||||
|
.todo-summary-row { |
||||
|
display: flex; |
||||
|
gap: 10px; |
||||
|
margin-bottom: 10px; |
||||
|
} |
||||
|
|
||||
|
.summary-card { |
||||
|
flex: 1; |
||||
|
min-width: 0; |
||||
|
background: #fff; |
||||
|
border: 1px solid #ebeef5; |
||||
|
border-radius: 6px; |
||||
|
padding: 10px 12px; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.summary-icon { |
||||
|
width: 36px; |
||||
|
height: 36px; |
||||
|
border-radius: 8px; |
||||
|
text-align: center; |
||||
|
line-height: 36px; |
||||
|
font-size: 18px; |
||||
|
margin-right: 10px; |
||||
|
color: #fff; |
||||
|
} |
||||
|
|
||||
|
.summary-card.blue .summary-icon { |
||||
|
background: #3a8ee6; |
||||
|
} |
||||
|
|
||||
|
.summary-card.green .summary-icon { |
||||
|
background: #67c23a; |
||||
|
} |
||||
|
|
||||
|
.summary-card.orange .summary-icon { |
||||
|
background: #e6a23c; |
||||
|
} |
||||
|
|
||||
|
.summary-value { |
||||
|
font-size: 24px; |
||||
|
line-height: 24px; |
||||
|
font-weight: 700; |
||||
|
color: #303133; |
||||
|
} |
||||
|
|
||||
|
.summary-label { |
||||
|
margin-top: 4px; |
||||
|
font-size: 12px; |
||||
|
color: #909399; |
||||
|
} |
||||
|
|
||||
|
.todo-card-grid { |
||||
|
display: grid; |
||||
|
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); |
||||
|
gap: 10px; |
||||
|
} |
||||
|
|
||||
|
.todo-card { |
||||
|
background: #fff; |
||||
|
border: 1px solid #ebeef5; |
||||
|
border-radius: 6px; |
||||
|
padding: 10px 12px; |
||||
|
min-height: 248px; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
} |
||||
|
|
||||
|
.todo-card-head { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
gap: 6px; |
||||
|
} |
||||
|
|
||||
|
.risk-tag { |
||||
|
font-size: 12px; |
||||
|
color: #909399; |
||||
|
background: #f4f4f5; |
||||
|
border-radius: 10px; |
||||
|
padding: 2px 8px; |
||||
|
} |
||||
|
|
||||
|
.risk-tag.high { |
||||
|
color: #fff; |
||||
|
background: #f56c6c; |
||||
|
} |
||||
|
|
||||
|
.todo-code { |
||||
|
font-size: 13px; |
||||
|
color: #303133; |
||||
|
font-weight: 600; |
||||
|
flex: 1; |
||||
|
overflow: hidden; |
||||
|
text-overflow: ellipsis; |
||||
|
white-space: nowrap; |
||||
|
} |
||||
|
|
||||
|
.todo-source { |
||||
|
margin-top: 8px; |
||||
|
font-size: 12px; |
||||
|
color: #909399; |
||||
|
} |
||||
|
|
||||
|
.todo-main-title { |
||||
|
margin-top: 8px; |
||||
|
font-size: 16px; |
||||
|
color: #303133; |
||||
|
font-weight: 700; |
||||
|
} |
||||
|
|
||||
|
.todo-detail-line { |
||||
|
margin-top: 8px; |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
font-size: 12px; |
||||
|
} |
||||
|
|
||||
|
.todo-detail-line .label { |
||||
|
color: #909399; |
||||
|
} |
||||
|
|
||||
|
.todo-detail-line .value { |
||||
|
color: #303133; |
||||
|
max-width: 60%; |
||||
|
overflow: hidden; |
||||
|
text-overflow: ellipsis; |
||||
|
white-space: nowrap; |
||||
|
text-align: right; |
||||
|
} |
||||
|
|
||||
|
.todo-step-row { |
||||
|
margin-top: auto; |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
gap: 8px; |
||||
|
padding-top: 14px; |
||||
|
} |
||||
|
|
||||
|
.step-item { |
||||
|
flex: 1; |
||||
|
text-align: center; |
||||
|
font-size: 12px; |
||||
|
color: #c0c4cc; |
||||
|
border: 1px solid #ebeef5; |
||||
|
border-radius: 14px; |
||||
|
padding: 4px 0; |
||||
|
} |
||||
|
|
||||
|
.step-item.done { |
||||
|
color: #67c23a; |
||||
|
border-color: #b3e19d; |
||||
|
background: #f0f9eb; |
||||
|
} |
||||
|
|
||||
|
.todo-footer { |
||||
|
margin-top: 10px; |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.todo-time { |
||||
|
font-size: 12px; |
||||
|
color: #909399; |
||||
|
} |
||||
|
|
||||
|
.todo-empty { |
||||
|
margin-top: 20px; |
||||
|
text-align: center; |
||||
|
color: #909399; |
||||
|
min-height: 320px; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
} |
||||
|
|
||||
|
.todo-pagination { |
||||
|
margin-top: 0; |
||||
|
text-align: right; |
||||
|
} |
||||
|
|
||||
|
.todo-cache-detail-dialog /deep/ .el-dialog__body { |
||||
|
padding-top: 10px; |
||||
|
} |
||||
|
|
||||
|
.todo-cache-detail-dialog .table-content-container { |
||||
|
width: 100%; |
||||
|
} |
||||
|
|
||||
|
.todo-cache-detail-dialog .readonly-number { |
||||
|
width: 100%; |
||||
|
text-align: center; |
||||
|
color: #606266; |
||||
|
} |
||||
|
|
||||
|
.todo-cache-detail-dialog /deep/ .readonly-qty-input .el-input__inner { |
||||
|
text-align: center; |
||||
|
color: #606266; |
||||
|
padding: 0 6px; |
||||
|
} |
||||
|
|
||||
|
.todo-cache-detail-dialog /deep/ .readonly-qty-input.good-qty-input .el-input__inner { |
||||
|
color: #67c23a; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
|
||||
|
.todo-cache-detail-dialog .readonly-number.good { |
||||
|
color: #67c23a; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
|
||||
|
.todo-cache-detail-dialog .readonly-number.defect { |
||||
|
color: #f56c6c; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
|
||||
|
.todo-cache-detail-dialog .readonly-number.yield { |
||||
|
color: #409eff; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
|
||||
|
.todo-cache-detail-dialog /deep/ .el-table td.remark-column, |
||||
|
.todo-cache-detail-dialog /deep/ .el-table td.packing-list-column { |
||||
|
padding: 0 !important; |
||||
|
position: relative !important; |
||||
|
} |
||||
|
|
||||
|
.todo-cache-detail-dialog .remark-wrapper { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
|
||||
|
.todo-cache-detail-dialog .remark-textarea { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
|
||||
|
.todo-cache-detail-dialog /deep/ .remark-textarea .el-textarea__inner { |
||||
|
border: none !important; |
||||
|
resize: none !important; |
||||
|
border-radius: 0 !important; |
||||
|
min-height: 68px !important; |
||||
|
background: #fafafa !important; |
||||
|
} |
||||
|
</style> |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue