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.
856 lines
23 KiB
856 lines
23 KiB
<template>
|
|
<div class="report-container">
|
|
<div class="page-header">
|
|
<div class="header-left">
|
|
<h2 class="page-title">
|
|
<i class="el-icon-s-order"></i> 生产报工
|
|
</h2>
|
|
<p class="page-subtitle">家用电梯 / 线缆COP / 改造项目节点报工管理</p>
|
|
</div>
|
|
<div class="header-right">
|
|
<div class="stat-cards">
|
|
<div class="stat-card stat-total">
|
|
<div class="stat-icon"><i class="el-icon-document"></i></div>
|
|
<div class="stat-content">
|
|
<div class="stat-value">{{ totalOrders }}</div>
|
|
<div class="stat-label">订单总数</div>
|
|
</div>
|
|
</div>
|
|
<div class="stat-card stat-pending">
|
|
<div class="stat-icon"><i class="el-icon-time"></i></div>
|
|
<div class="stat-content">
|
|
<div class="stat-value">{{ pendingNodeCount }}</div>
|
|
<div class="stat-label">待报工节点</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="search-section">
|
|
<el-collapse class="no-arrow" v-model="searchExpanded">
|
|
<el-collapse-item name="1">
|
|
<template slot="title">
|
|
<i class="el-icon-search"></i>
|
|
<span class="search-title">筛选条件</span>
|
|
</template>
|
|
<el-form :inline="true" label-position="top" class="search-form">
|
|
<el-form-item label="项目号">
|
|
<el-input v-model="searchData.projectNo" placeholder="支持模糊查询" clearable style="width: 150px"></el-input>
|
|
</el-form-item>
|
|
<el-form-item label="订单类型">
|
|
<el-select v-model="searchData.orderType" placeholder="请选择" clearable style="width: 150px">
|
|
<el-option label="全部" value=""></el-option>
|
|
<el-option label="家用电梯" value="HOME_LIFT"></el-option>
|
|
<el-option label="线缆COP" value="CABLE_COP"></el-option>
|
|
<el-option label="改造项目" value="RENOVATION"></el-option>
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item label="状态">
|
|
<el-select v-model="searchData.status" placeholder="请选择" clearable style="width: 120px">
|
|
<el-option label="全部" value=""></el-option>
|
|
<el-option label="已排产" value="已排产"></el-option>
|
|
<el-option label="进行中" value="进行中"></el-option>
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item label="计划日期">
|
|
<el-date-picker
|
|
v-model="searchData.planStartDate"
|
|
type="date"
|
|
value-format="yyyy-MM-dd"
|
|
placeholder="开始日期"
|
|
style="width: 140px">
|
|
</el-date-picker>
|
|
</el-form-item>
|
|
<el-form-item label="至">
|
|
<el-date-picker
|
|
v-model="searchData.planEndDate"
|
|
type="date"
|
|
value-format="yyyy-MM-dd"
|
|
placeholder="结束日期"
|
|
style="width: 140px">
|
|
</el-date-picker>
|
|
</el-form-item>
|
|
<el-form-item label=" " class="search-btn-group">
|
|
<el-button @click="getDataList('Y')" type="primary" icon="el-icon-search">查询</el-button>
|
|
<el-button @click="resetQuery()" type="default" icon="el-icon-refresh-left">重置</el-button>
|
|
</el-form-item>
|
|
</el-form>
|
|
</el-collapse-item>
|
|
</el-collapse>
|
|
</div>
|
|
|
|
<div class="cards-container">
|
|
<div class="cards-grid">
|
|
<div
|
|
v-for="item in dataList"
|
|
:key="item.orderNo"
|
|
class="report-card"
|
|
:class="getCardClass(item)">
|
|
<div class="card-header">
|
|
<div class="card-title-area">
|
|
<el-tag :type="getTypeTag(item.orderType)" effect="dark" class="type-tag">{{ item.orderTypeName }}</el-tag>
|
|
<span class="project-no">{{ item.projectNo }}</span>
|
|
</div>
|
|
<el-tag :type="getStatusType(item.status)" size="small">{{ item.status }}</el-tag>
|
|
</div>
|
|
|
|
<div class="card-body">
|
|
<h3 class="item-title">
|
|
<i class="el-icon-document"></i>
|
|
{{ item.productName }}
|
|
</h3>
|
|
|
|
<div class="card-details">
|
|
<div class="detail-row">
|
|
<span class="detail-label"><i class="el-icon-goods"></i> 型号</span>
|
|
<span class="detail-value">{{ item.modelNo }}</span>
|
|
</div>
|
|
<div class="detail-row">
|
|
<span class="detail-label"><i class="el-icon-date"></i> 计划完工</span>
|
|
<span class="detail-value">{{ item.planDate }}</span>
|
|
</div>
|
|
<div class="detail-row">
|
|
<span class="detail-label"><i class="el-icon-user"></i> 责任人</span>
|
|
<span class="detail-value">{{ item.owner }}</span>
|
|
</div>
|
|
<div class="detail-row">
|
|
<span class="detail-label"><i class="el-icon-finished"></i> 节点进度</span>
|
|
<span class="detail-value">{{ item.nodeDoneCount }}/{{ item.nodeTotalCount }}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="node-section">
|
|
<div class="node-title">
|
|
<i class="el-icon-position"></i> 节点报工
|
|
</div>
|
|
<div v-for="node in item.visiblePendingNodeList" :key="node.nodeCode" class="node-row">
|
|
<span class="node-name">{{ node.nodeName }}</span>
|
|
<div class="node-right">
|
|
<!-- <el-tag :type="getNodeStatusType(node.status)" size="mini">{{ node.status }}</el-tag>-->
|
|
<el-button
|
|
size="mini"
|
|
type="primary"
|
|
plain
|
|
:disabled="node.status === '已完成' || !canReportNode(item, node)"
|
|
@click="directReportNode(item, node)">
|
|
报工
|
|
</el-button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- <div class="card-footer">
|
|
<div class="current-step"><i class="el-icon-caret-right"></i> 当前工序:{{ item.currentNode }}</div>
|
|
<el-button type="text" @click="openHistoryDialog(item)">报工记录</el-button>
|
|
</div>-->
|
|
</div>
|
|
</div>
|
|
|
|
<div v-if="dataList.length === 0" class="empty-state">
|
|
<i class="el-icon-document-checked empty-icon"></i>
|
|
<p class="empty-text">暂无报工任务</p>
|
|
<p class="empty-subtext">请调整筛选条件后重试</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="pagination-wrapper" v-if="totalPage > 0">
|
|
<el-pagination
|
|
@size-change="sizeChangeHandle"
|
|
@current-change="currentChangeHandle"
|
|
:current-page="pageIndex"
|
|
:page-sizes="[8, 12, 24]"
|
|
:page-size="pageSize"
|
|
:total="totalPage"
|
|
layout="total, sizes, prev, pager, next, jumper"
|
|
background>
|
|
</el-pagination>
|
|
</div>
|
|
|
|
<el-dialog
|
|
title="节点报工"
|
|
:visible.sync="reportDialogVisible"
|
|
width="520px"
|
|
:close-on-click-modal="false"
|
|
v-drag>
|
|
<el-form :model="reportData" label-position="top">
|
|
<el-row :gutter="12">
|
|
<el-col :span="12">
|
|
<el-form-item label="项目号">
|
|
<el-input v-model="reportData.projectNo" disabled></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="12">
|
|
<el-form-item label="报工节点">
|
|
<el-input v-model="reportData.nodeName" disabled></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
<el-row :gutter="12">
|
|
<el-col :span="12">
|
|
<el-form-item label="报工数量" required>
|
|
<el-input v-model="reportData.reportQty" style="width: 100%"></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="12">
|
|
<el-form-item label="报工人员">
|
|
<el-input v-model="reportData.reportBy" disabled></el-input>
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
<el-form-item label="报工备注">
|
|
<el-input v-model="reportData.remark" type="textarea" :rows="3" placeholder="请输入报工说明"></el-input>
|
|
</el-form-item>
|
|
</el-form>
|
|
<div slot="footer" class="dialog-footer">
|
|
<el-button @click="reportDialogVisible = false">取消</el-button>
|
|
<el-button type="primary" :loading="reportLoading" @click="submitNodeReport">
|
|
{{ reportLoading ? '提交中...' : '确认报工' }}
|
|
</el-button>
|
|
</div>
|
|
</el-dialog>
|
|
|
|
<el-dialog
|
|
:title="`报工记录 - ${historyOrder.projectNo || ''}`"
|
|
:visible.sync="historyDialogVisible"
|
|
width="760px"
|
|
:close-on-click-modal="false"
|
|
v-drag>
|
|
<el-table
|
|
class="history-table"
|
|
:data="historyOrder.visibleReportHistory || []"
|
|
border
|
|
stripe
|
|
max-height="420px"
|
|
style="width: 100%">
|
|
<el-table-column type="index" label="序号" width="60" align="center"></el-table-column>
|
|
<el-table-column prop="nodeName" label="报工节点" min-width="140" align="left" header-align="center"></el-table-column>
|
|
<el-table-column prop="reportQty" label="数量" width="90" align="center" header-align="center"></el-table-column>
|
|
<el-table-column prop="reportBy" label="报工人" width="110" align="center" header-align="center"></el-table-column>
|
|
<el-table-column prop="reportTime" label="报工时间" width="170" align="center" header-align="center"></el-table-column>
|
|
<el-table-column prop="remark" label="备注" min-width="180" show-overflow-tooltip align="left" header-align="center"></el-table-column>
|
|
</el-table>
|
|
<div v-if="(historyOrder.visibleReportHistory || []).length === 0" class="empty-attachment">
|
|
<i class="el-icon-folder-opened"></i>
|
|
<p>暂无报工记录</p>
|
|
</div>
|
|
<div slot="footer" class="dialog-footer">
|
|
<el-button type="primary" @click="historyDialogVisible = false">关闭</el-button>
|
|
</div>
|
|
</el-dialog>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import { getWorkReportOrderList, reportCableCopTaskNode, reportHomeLiftOrderNode, reportRenovationOrderNode } from '@/api/longchuang/productionPlan'
|
|
|
|
export default {
|
|
name: 'ProductionWorkReport',
|
|
data() {
|
|
return {
|
|
searchExpanded: ['0'],
|
|
searchData: {
|
|
projectNo: '',
|
|
orderType: '',
|
|
status: '',
|
|
planStartDate: '',
|
|
planEndDate: '',
|
|
page: 1,
|
|
limit: 8
|
|
},
|
|
dataList: [],
|
|
pageIndex: 1,
|
|
pageSize: 8,
|
|
totalPage: 0,
|
|
reportDialogVisible: false,
|
|
historyDialogVisible: false,
|
|
historyOrder: {},
|
|
reportLoading: false,
|
|
reportData: {
|
|
orderNo: '',
|
|
orderType: '',
|
|
nodeCode: '',
|
|
projectNo: '',
|
|
nodeName: '',
|
|
reportQty: 1,
|
|
reportBy: '',
|
|
remark: ''
|
|
}
|
|
}
|
|
},
|
|
computed: {
|
|
totalOrders() {
|
|
return this.totalPage || 0
|
|
},
|
|
pendingNodeCount() {
|
|
return this.dataList.reduce((sum, item) => sum + (item.visibleNodeList || []).filter(node => node.status !== '已完成').length, 0)
|
|
}
|
|
},
|
|
activated() {
|
|
this.getDataList('Y')
|
|
},
|
|
methods: {
|
|
getDataList(flag) {
|
|
if (flag === 'Y') {
|
|
this.pageIndex = 1
|
|
}
|
|
this.searchData.page = this.pageIndex
|
|
this.searchData.limit = this.pageSize
|
|
getWorkReportOrderList(this.searchData).then(({ data }) => {
|
|
if (data && data.code === 0) {
|
|
const page = data.page || {}
|
|
const list = page.list || []
|
|
this.dataList = list.map(this.normalizeOrderRow)
|
|
this.totalPage = page.totalCount || 0
|
|
} else {
|
|
this.dataList = []
|
|
this.totalPage = 0
|
|
this.$message.error((data && data.msg) || '查询失败')
|
|
}
|
|
}).catch(() => {
|
|
this.dataList = []
|
|
this.totalPage = 0
|
|
this.$message.error('查询失败')
|
|
})
|
|
},
|
|
normalizeOrderRow(row) {
|
|
const nodeList = row.nodeList || []
|
|
const fallbackNodeDoneCount = nodeList.filter(item => item.status === '已完成').length
|
|
const fallbackCurrentNodeObj = nodeList.find(item => item.status !== '已完成') || {}
|
|
const nodeDoneCount = typeof row.nodeDoneCount === 'number' ? row.nodeDoneCount : fallbackNodeDoneCount
|
|
const nodeTotalCount = typeof row.nodeTotalCount === 'number' ? row.nodeTotalCount : nodeList.length
|
|
const currentNode = row.currentNode || fallbackCurrentNodeObj.nodeName || '全部完成'
|
|
return {
|
|
...row,
|
|
nodeReportMode: row.nodeReportMode || 'PARALLEL',
|
|
currentNodeCode: row.currentNodeCode || fallbackCurrentNodeObj.nodeCode || '',
|
|
orderTypeName: this.getOrderTypeName(row.orderType),
|
|
productName: row.taskNo || row.projectNo || '-',
|
|
planDate: row.planFinishDate || row.planDeliveryDate || '-',
|
|
owner: this.$store.state.user.userDisplay || this.$store.state.user.name || '-',
|
|
nodeDoneCount: nodeDoneCount,
|
|
nodeTotalCount: nodeTotalCount,
|
|
currentNode: currentNode,
|
|
visibleNodeList: nodeList,
|
|
visiblePendingNodeList: nodeList.filter(item => item.status !== '已完成')
|
|
}
|
|
},
|
|
getOrderTypeName(orderType) {
|
|
const map = {
|
|
HOME_LIFT: '家用电梯',
|
|
CABLE_COP: '线缆COP',
|
|
RENOVATION: 'VL2.5升级'
|
|
}
|
|
return map[orderType] || orderType || '-'
|
|
},
|
|
resetQuery() {
|
|
this.searchData = {
|
|
projectNo: '',
|
|
orderType: '',
|
|
status: '',
|
|
planStartDate: '',
|
|
planEndDate: '',
|
|
page: 1,
|
|
limit: this.pageSize
|
|
}
|
|
this.getDataList('Y')
|
|
},
|
|
getTypeTag(type) {
|
|
const tagMap = {
|
|
HOME_LIFT: 'primary',
|
|
CABLE_COP: 'warning',
|
|
RENOVATION: 'success'
|
|
}
|
|
return tagMap[type] || 'info'
|
|
},
|
|
getStatusType(status) {
|
|
const statusMap = {
|
|
已排产: 'info',
|
|
进行中: 'warning',
|
|
已完成: 'success'
|
|
}
|
|
return statusMap[status] || 'info'
|
|
},
|
|
getNodeStatusType(status) {
|
|
const statusMap = {
|
|
未开始: 'info',
|
|
进行中: 'warning',
|
|
已完成: 'success'
|
|
}
|
|
return statusMap[status] || 'info'
|
|
},
|
|
getCardClass(item) {
|
|
if (item.status === '已完成') {
|
|
return 'card-done'
|
|
}
|
|
if (item.status === '进行中') {
|
|
return 'card-progress'
|
|
}
|
|
return 'card-plan'
|
|
},
|
|
canReportNode(order, node) {
|
|
if (!order || !node) {
|
|
return false
|
|
}
|
|
if ((order.nodeReportMode || 'PARALLEL') !== 'SEQUENTIAL') {
|
|
return true
|
|
}
|
|
return !!order.currentNodeCode && order.currentNodeCode === node.nodeCode
|
|
},
|
|
directReportNode(order, node) {
|
|
this.reportData = {
|
|
orderNo: order.orderNo,
|
|
orderType: order.orderType,
|
|
nodeCode: node.nodeCode,
|
|
projectNo: order.projectNo,
|
|
nodeName: node.nodeName,
|
|
reportQty: 1,
|
|
reportBy: this.$store.state.user.userDisplay || this.$store.state.user.name || '当前用户',
|
|
remark: ''
|
|
}
|
|
this.submitNodeReport()
|
|
},
|
|
openReportDialog(order, node) {
|
|
this.reportData = {
|
|
orderNo: order.orderNo,
|
|
orderType: order.orderType,
|
|
nodeCode: node.nodeCode,
|
|
projectNo: order.projectNo,
|
|
nodeName: node.nodeName,
|
|
reportQty: 1,
|
|
reportBy: this.$store.state.user.userDisplay || this.$store.state.user.name || '当前用户',
|
|
remark: ''
|
|
}
|
|
this.reportDialogVisible = true
|
|
},
|
|
submitNodeReport() {
|
|
if (!this.reportData.nodeCode) {
|
|
this.$message.warning('请选择报工节点')
|
|
return
|
|
}
|
|
const apiMap = {
|
|
HOME_LIFT: reportHomeLiftOrderNode,
|
|
CABLE_COP: reportCableCopTaskNode,
|
|
RENOVATION: reportRenovationOrderNode
|
|
}
|
|
const apiFn = apiMap[this.reportData.orderType]
|
|
if (!apiFn) {
|
|
this.$message.error('订单类型不支持报工')
|
|
return
|
|
}
|
|
this.reportLoading = true
|
|
apiFn({
|
|
orderNo: this.reportData.orderNo,
|
|
nodeCode: this.reportData.nodeCode,
|
|
reportQty: this.reportData.reportQty,
|
|
remark: this.reportData.remark
|
|
}).then(({ data }) => {
|
|
this.reportLoading = false
|
|
if (data && data.code === 0) {
|
|
this.$message.success(data.msg || '报工成功')
|
|
this.reportDialogVisible = false
|
|
this.getDataList()
|
|
} else {
|
|
this.$message.error((data && data.msg) || '报工失败')
|
|
}
|
|
}).catch(() => {
|
|
this.reportLoading = false
|
|
this.$message.error('报工失败')
|
|
})
|
|
},
|
|
openHistoryDialog(item) {
|
|
this.historyOrder = item
|
|
this.historyDialogVisible = true
|
|
},
|
|
sizeChangeHandle(val) {
|
|
this.pageSize = val
|
|
this.pageIndex = 1
|
|
this.getDataList()
|
|
},
|
|
currentChangeHandle(val) {
|
|
this.pageIndex = val
|
|
this.getDataList()
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.report-container {
|
|
padding: 15px;
|
|
background: #f5f7fa;
|
|
min-height: calc(100vh - 80px);
|
|
}
|
|
|
|
.page-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 8px;
|
|
padding: 5px 20px;
|
|
background: #FFFFFF;
|
|
border-radius: 4px;
|
|
border: 1px solid #EBEEF5;
|
|
}
|
|
|
|
.page-title {
|
|
margin: 0;
|
|
font-size: 20px;
|
|
font-weight: 600;
|
|
color: #303133;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
}
|
|
|
|
.page-title i {
|
|
font-size: 22px;
|
|
color: #409EFF;
|
|
}
|
|
|
|
.page-subtitle {
|
|
margin: 6px 0 0 0;
|
|
font-size: 13px;
|
|
color: #909399;
|
|
}
|
|
|
|
.stat-cards {
|
|
display: flex;
|
|
gap: 12px;
|
|
}
|
|
|
|
.stat-card {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
padding: 12px 20px;
|
|
background: #FFFFFF;
|
|
border-radius: 4px;
|
|
border: 1px solid #EBEEF5;
|
|
min-width: 140px;
|
|
}
|
|
|
|
.stat-icon {
|
|
width: 40px;
|
|
height: 40px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border-radius: 4px;
|
|
font-size: 20px;
|
|
color: white;
|
|
}
|
|
|
|
.stat-total .stat-icon {
|
|
background: #409EFF;
|
|
}
|
|
|
|
.stat-pending .stat-icon {
|
|
background: #E6A23C;
|
|
}
|
|
|
|
.stat-done .stat-icon {
|
|
background: #67C23A;
|
|
}
|
|
|
|
.stat-value {
|
|
font-size: 24px;
|
|
font-weight: 600;
|
|
color: #303133;
|
|
line-height: 1;
|
|
}
|
|
|
|
.stat-label {
|
|
font-size: 12px;
|
|
color: #909399;
|
|
margin-top: 4px;
|
|
}
|
|
|
|
.search-section {
|
|
margin-bottom: 8px;
|
|
background: #FFFFFF;
|
|
border-radius: 4px;
|
|
border: 1px solid #EBEEF5;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.search-title {
|
|
margin-left: 8px;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.search-section >>> .el-collapse-item__header {
|
|
padding: 0 15px;
|
|
height: 35px;
|
|
line-height: 35px;
|
|
background: white;
|
|
border-bottom: 1px solid #ebeef5;
|
|
font-size: 13px;
|
|
color: #303133;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.search-section >>> .el-collapse-item__content {
|
|
padding: 15px;
|
|
background: #FFFFFF;
|
|
}
|
|
|
|
.search-form >>> .el-form-item {
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.cards-container {
|
|
min-height: 360px;
|
|
}
|
|
|
|
.cards-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fill, minmax(390px, 1fr));
|
|
gap: 15px;
|
|
}
|
|
|
|
.report-card {
|
|
background: white;
|
|
border-radius: 4px;
|
|
padding: 8px 16px;
|
|
border: 1px solid #EBEEF5;
|
|
transition: all 0.3s ease;
|
|
position: relative;
|
|
}
|
|
|
|
.report-card::before {
|
|
content: '';
|
|
position: absolute;
|
|
left: 0;
|
|
top: 0;
|
|
width: 2px;
|
|
height: 100%;
|
|
}
|
|
|
|
.report-card.card-plan::before {
|
|
background: #909399;
|
|
}
|
|
|
|
.report-card.card-progress::before {
|
|
background: #E6A23C;
|
|
}
|
|
|
|
.report-card.card-done::before {
|
|
background: #67C23A;
|
|
}
|
|
|
|
.report-card:hover {
|
|
border-color: #409EFF;
|
|
box-shadow: 0 4px 12px rgba(64, 158, 255, 0.12);
|
|
}
|
|
|
|
.card-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 4px;
|
|
padding-bottom: 6px;
|
|
border-bottom: 1px solid #EBEEF5;
|
|
}
|
|
|
|
.card-title-area {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
}
|
|
|
|
.type-tag {
|
|
font-size: 12px;
|
|
}
|
|
|
|
.project-no {
|
|
font-size: 13px;
|
|
color: #606266;
|
|
font-family: 'Courier New', monospace;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.item-title {
|
|
font-size: 15px;
|
|
font-weight: 600;
|
|
color: #303133;
|
|
margin: 0 0 6px 0;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
}
|
|
|
|
.item-title i {
|
|
color: #409EFF;
|
|
}
|
|
|
|
.card-details {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 4px;
|
|
}
|
|
|
|
.detail-row {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
font-size: 13px;
|
|
padding: 6px 10px;
|
|
background: #F5F7FA;
|
|
border-radius: 3px;
|
|
}
|
|
|
|
.detail-label {
|
|
color: #909399;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 5px;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.detail-label i {
|
|
color: #409EFF;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.detail-value {
|
|
color: #606266;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.node-section {
|
|
margin-top: 4px;
|
|
border-top: 1px dashed #EBEEF5;
|
|
padding-top: 10px;
|
|
}
|
|
|
|
.node-title {
|
|
font-size: 12px;
|
|
color: #909399;
|
|
margin-bottom: 2px;
|
|
}
|
|
|
|
.node-row {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 4px 8px;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.node-row:hover {
|
|
background: #F5F7FA;
|
|
}
|
|
|
|
.node-name {
|
|
color: #303133;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.node-right {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
}
|
|
|
|
.card-footer {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding-top: 10px;
|
|
margin-top: 8px;
|
|
border-top: 1px solid #EBEEF5;
|
|
}
|
|
|
|
.current-step {
|
|
font-size: 12px;
|
|
color: #909399;
|
|
}
|
|
|
|
.pagination-wrapper {
|
|
display: flex;
|
|
justify-content: center;
|
|
padding: 15px;
|
|
margin-top: 15px;
|
|
background: #FFFFFF;
|
|
border-radius: 4px;
|
|
border: 1px solid #EBEEF5;
|
|
}
|
|
|
|
.empty-state {
|
|
text-align: center;
|
|
padding: 80px 20px;
|
|
background: white;
|
|
border-radius: 4px;
|
|
border: 1px solid #EBEEF5;
|
|
}
|
|
|
|
.empty-icon {
|
|
font-size: 64px;
|
|
color: #c0c4cc;
|
|
margin-bottom: 12px;
|
|
}
|
|
|
|
.empty-text {
|
|
font-size: 15px;
|
|
color: #606266;
|
|
margin: 0 0 6px 0;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.empty-subtext {
|
|
font-size: 13px;
|
|
color: #909399;
|
|
margin: 0;
|
|
}
|
|
|
|
.empty-attachment {
|
|
text-align: center;
|
|
padding: 40px 20px;
|
|
color: #909399;
|
|
}
|
|
|
|
.empty-attachment i {
|
|
font-size: 42px;
|
|
}
|
|
|
|
.history-table >>> .el-table__header-wrapper th,
|
|
.history-table >>> .el-table__header-wrapper .el-table__cell {
|
|
background-color: #F5F7FA !important;
|
|
color: #606266 !important;
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
/deep/ .no-arrow .el-collapse-item__header .el-collapse-item__arrow {
|
|
display: none !important;
|
|
}
|
|
|
|
@media screen and (max-width: 1200px) {
|
|
.page-header {
|
|
flex-direction: column;
|
|
align-items: flex-start;
|
|
gap: 12px;
|
|
}
|
|
|
|
.cards-grid {
|
|
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
|
|
}
|
|
}
|
|
|
|
@media screen and (max-width: 768px) {
|
|
.stat-cards {
|
|
flex-direction: column;
|
|
width: 100%;
|
|
}
|
|
|
|
.stat-card {
|
|
width: 100%;
|
|
}
|
|
|
|
.cards-grid {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
}
|
|
</style>
|