| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <PageHeader content="生产计划追踪进度"> |
| | | <PageHeader v-if="applyNo" |
| | | content="生产计划追踪进度"> |
| | | </PageHeader> |
| | | <el-card style="height:82vh;overflow:auto;"> |
| | | <template #header> |
| | | <div class="card-header"> |
| | | <span>申请单编号 - {{ rowData.applyNo || '' }}</span> |
| | | <el-form :inline="true" |
| | | :model="searchForm" |
| | | class="search-form"> |
| | | <el-form-item label="申请单编号"> |
| | | <el-input v-model="searchForm.applyNo" |
| | | placeholder="请输入申请单编号" |
| | | style="width: 400px;"></el-input> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" |
| | | @click="handleSearch">搜索</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </template> |
| | | <!-- 基础信息 --> |
| | |
| | | <el-descriptions :column="3" |
| | | border> |
| | | <el-descriptions-item label="订单编号">{{ item.orderNo || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="订单状态"> |
| | | <!-- <el-descriptions-item label="订单状态"> |
| | | <el-tag :type="getStatusType(item.status)">{{ getStatusText(item.status) }}</el-tag> |
| | | </el-descriptions-item> |
| | | </el-descriptions-item> --> |
| | | <el-descriptions-item label="开始日期">{{ item.startTime || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="需求数量">{{ item.quantity || 0 }} <span class="unit">方</span></el-descriptions-item> |
| | | <el-descriptions-item label="完成数量">{{ item.completeQuantity || 0 }} <span class="unit">方</span></el-descriptions-item> |
| | | <el-descriptions-item label="完成进度"> |
| | | <el-progress :percentage="item.completionRate" |
| | | :color="customColors(item.completionRate)" |
| | | :status="item.completionRate === 100 ? 'success' : ''" |
| | | style="width: 120px;" /> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="需求数量">{{ item.quantity || 0 }} <span class="unit">方</span></el-descriptions-item> |
| | | <el-descriptions-item label="完成数量">{{ item.completeQuantity || 0 }} <span class="unit">方</span></el-descriptions-item> |
| | | <el-descriptions-item label="剩余数量">{{ item.remainingQuantity || 0 }} <span class="unit">方</span></el-descriptions-item> |
| | | </el-descriptions> |
| | | <el-table :data="trackProgressForm.progressDetails" |
| | | border |
| | |
| | | <el-link v-if="$index!=0" |
| | | @click="handleClickStep(row)" |
| | | type="primary">{{ row.step }}</el-link> |
| | | <span v-else |
| | | @click="handleClickStep(row)">{{ row.step }}</span> |
| | | <span v-else>{{ row.step }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="status" |
| | | <!-- <el-table-column prop="status" |
| | | label="状态" |
| | | align="center"> |
| | | <template #default="scope"> |
| | |
| | | {{ scope.row.status === 'completed' ? '已完成' : scope.row.status === 'processing' ? '进行中' : '待开始' }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table-column> --> |
| | | <el-table-column prop="quantity" |
| | | label="数量" |
| | | align="center" /> |
| | | <el-table-columnstep prop="startTime" |
| | | label="时间" |
| | | align="center" /> |
| | | <el-table-column prop="startTime" |
| | | label="时间" |
| | | align="center" /> |
| | | <el-table-column prop="startTime1" |
| | | label="岗位人员" |
| | | align="center" /> |
| | | </el-table> |
| | | </div> |
| | | </div> |
| | | <!-- <div class="progress-section"> |
| | | <h3 class="section-title">进度信息</h3> |
| | | <div class="progress-item"> |
| | | <div class="progress-label">完成进度:</div> |
| | | <div class="progress-content"> |
| | | <el-progress :percentage="trackProgressForm.completionRate" |
| | | :color="customColors" |
| | | :status="trackProgressForm.completionRate === 100 ? 'success' : ''" /> |
| | | </div> |
| | | </div> |
| | | <div class="progress-item"> |
| | | <div class="progress-label">进度详情:</div> |
| | | <div class="progress-content"> |
| | | <el-table :data="trackProgressForm.progressDetails" |
| | | border |
| | | style="width: auto; height: 300px"> |
| | | <el-table-column prop="step" |
| | | label="步骤(点击查看详情)" |
| | | align="center"> |
| | | <template #default="{ row, $index }"> |
| | | <el-link v-if="$index!=0" |
| | | @click="handleClickStep(row)" |
| | | type="primary">{{ row.step }}</el-link> |
| | | <span v-else |
| | | @click="handleClickStep(row)">{{ row.step }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="status" |
| | | label="状态" |
| | | align="center"> |
| | | <template #default="scope"> |
| | | <el-tag :type="scope.row.status === 'completed' ? 'success' : scope.row.status === 'processing' ? 'warning' : 'info'"> |
| | | {{ scope.row.status === 'completed' ? '已完成' : scope.row.status === 'processing' ? '进行中' : '待开始' }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="quantity" |
| | | label="数量" |
| | | align="center" /> |
| | | <el-table-column prop="startTime" |
| | | label="时间" |
| | | align="center" /> |
| | | </el-table> |
| | | </div> |
| | | </div> |
| | | </div> --> |
| | | </div> |
| | | </el-card> |
| | | <!-- 生产报工详情弹窗 --> |
| | | <el-dialog v-model="detailDialogVisible" |
| | | :title="'生产报工详情'" |
| | | width="1000px" |
| | | :close-on-click-modal="false" |
| | | custom-class="custom-dialog"> |
| | | <div class="detail-container"> |
| | | <!-- 基础信息 --> |
| | | <div class="detail-section"> |
| | | <h3 class="section-title">基础信息</h3> |
| | | <el-descriptions :column="3" |
| | | border> |
| | | <el-descriptions-item label="生产订单号">{{ detailData.npsNo || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="班组"><el-tag :type="detailData.schedule == '白班' ? 'primary' : 'warning'">{{ detailData.schedule || '-' }}</el-tag></el-descriptions-item> |
| | | <el-descriptions-item label="岗位人员">{{ detailData.postName || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="产品编码">{{ detailData.materialCode || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="产品名称">{{ detailData.productName || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="规格">{{ detailData.model || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="合格数量"><span class="num2">{{ detailData.qualifiedQuantity || 0 }}</span> <span class="unit">方</span></el-descriptions-item> |
| | | <el-descriptions-item label="不合格数量"><span class="num3">{{ detailData.unqualifiedQuantity || 0 }}</span> <span class="unit">方</span></el-descriptions-item> |
| | | <el-descriptions-item label="总数量"><span class="num1">{{ detailData.quantity || 0 }}</span> <span class="unit">方</span></el-descriptions-item> |
| | | <el-descriptions-item label="报工时间">{{ formatTime(detailData.reportingTime) }}</el-descriptions-item> |
| | | <el-descriptions-item label="创建时间">{{ formatTime(detailData.createTime) }}</el-descriptions-item> |
| | | <el-descriptions-item label="更新时间">{{ formatTime(detailData.updateTime) }}</el-descriptions-item> |
| | | </el-descriptions> |
| | | </div> |
| | | <!-- 工序信息 --> |
| | | <div class="detail-section" |
| | | v-if="detailData.productionProductRouteItemDtoList && detailData.productionProductRouteItemDtoList.length > 0"> |
| | | <h3 class="section-title">工序信息</h3> |
| | | <div v-for="(process) in detailData.productionProductRouteItemDtoList" |
| | | :key="process.id" |
| | | class="process-item"> |
| | | <div class="process-header"> |
| | | <h4 class="process-title">{{ process.processName || '-' }}</h4> |
| | | <div class="process-info"> |
| | | <span class="process-label">岗位人员:{{ process.postName || '-' }}</span> |
| | | <span class="process-label">工序ID:{{ process.processNo || '-' }}</span> |
| | | </div> |
| | | </div> |
| | | <!-- 工序基本信息 --> |
| | | <div class="process-details"> |
| | | <el-descriptions :column="2" |
| | | border> |
| | | <el-descriptions-item label="设备异常情况">{{ process.equipmentMalfunction || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="当班设备处置">{{ process.equipmentDisposal || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="工艺人员交待" |
| | | :span="2">{{ process.processExplained || '-' }}</el-descriptions-item> |
| | | </el-descriptions> |
| | | </div> |
| | | <!-- 工序参数 --> |
| | | <div v-if="process.productionProductRouteItemParamDtoList && process.productionProductRouteItemParamDtoList.length > 0"> |
| | | <!-- BOM信息 --> |
| | | <div class="param-section" |
| | | v-if="getBomList(process.productionProductRouteItemParamDtoList).length > 0"> |
| | | <h5 class="param-title">投入品信息</h5> |
| | | <el-table :data="getBomList(process.productionProductRouteItemParamDtoList)" |
| | | style="width: 100%" |
| | | size="small"> |
| | | <el-table-column prop="paramName" |
| | | label="产品名称" |
| | | min-width="120"></el-table-column> |
| | | <el-table-column prop="model" |
| | | label="规格型号" |
| | | min-width="120"></el-table-column> |
| | | <el-table-column prop="productValue" |
| | | label="投入量" |
| | | min-width="100"></el-table-column> |
| | | <el-table-column prop="unit" |
| | | label="单位" |
| | | width="80"></el-table-column> |
| | | </el-table> |
| | | </div> |
| | | <!-- 参数信息 --> |
| | | <div class="param-section" |
| | | v-if="getParamList(process.productionProductRouteItemParamDtoList).length > 0"> |
| | | <h5 class="param-title">生产记录</h5> |
| | | <el-card v-for="group in getParamGroups(process.productionProductRouteItemParamDtoList)" |
| | | :key="group.sourceSort" |
| | | class="detail-card" |
| | | style="margin-top: 10px;"> |
| | | <template #header> |
| | | <div class="card-header"> |
| | | <span v-if="Object.keys(getParamGroups(process.productionProductRouteItemParamDtoList)).length > 1">生产记录组 - {{ group.sourceSort }}</span> |
| | | <span v-else>生产记录</span> |
| | | </div> |
| | | </template> |
| | | <el-table :data="group.items" |
| | | style="width: 100%" |
| | | :row-class-name="rowClassName"> |
| | | <el-table-column prop="paramName" |
| | | label="指标" /> |
| | | <el-table-column prop="unit" |
| | | label="单位" |
| | | width="100"> |
| | | <template #default="scope"> |
| | | {{ scope.row.unit || "/" }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="standardText" |
| | | label="标准值" /> |
| | | <el-table-column prop="paramValue" |
| | | label="实际值" /> |
| | | <el-table-column prop="result" |
| | | label="结果" |
| | | width="100"> |
| | | <template #default="scope"> |
| | | <el-tag :type="scope.row.result === '合格' ? 'success' : 'danger'"> |
| | | {{ scope.row.result }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-card> |
| | | </div> |
| | | </div> |
| | | <!-- 上传文件 --> |
| | | <div class="file-section" |
| | | v-if="process.fileList && process.fileList.length > 0"> |
| | | <h5 class="file-title">上传文件</h5> |
| | | <div class="file-grid"> |
| | | <div v-for="file in process.fileList" |
| | | :key="file.id" |
| | | class="file-item"> |
| | | <el-image style="width: 100px; height: 100px" |
| | | v-if="file.fileUrl" |
| | | :src="baseUrl + file.fileUrl" |
| | | :zoom-rate="1.2" |
| | | :max-scale="7" |
| | | :alt="file.fileName" |
| | | :min-scale="0.2" |
| | | :preview-src-list="formatFileList(process.fileList)" |
| | | show-progress |
| | | :initial-index="4" |
| | | fit="cover" /> |
| | | <div class="file-info"> |
| | | <span class="file-name">{{ file.fileName || '-' }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button @click="detailDialogVisible = false">关闭</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | import { ref, reactive, onMounted } from "vue"; |
| | | import { ElMessage } from "element-plus"; |
| | | import { useRouter, useRoute } from "vue-router"; |
| | | import dayjs from "dayjs"; |
| | | |
| | | const router = useRouter(); |
| | | const route = useRoute(); |
| | |
| | | progressDetails: [], |
| | | remark: "", |
| | | }); |
| | | |
| | | // 搜索表单 |
| | | const searchForm = reactive({ |
| | | applyNo: "", |
| | | }); |
| | | |
| | | // 生产报工详情弹窗 |
| | | const detailDialogVisible = ref(false); |
| | | const detailData = ref({}); |
| | | const baseUrl = import.meta.env.VITE_APP_BASE_API; |
| | | |
| | | // 获取状态类型 |
| | | const getStatusType = status => { |
| | |
| | | router.push("/productionPlan/productionPlan"); |
| | | }; |
| | | |
| | | // 处理搜索 |
| | | const handleSearch = () => { |
| | | const applyNo = searchForm.applyNo.trim(); |
| | | if (!applyNo) { |
| | | ElMessage.warning("请输入申请单编号"); |
| | | return; |
| | | } |
| | | // 这里可以添加搜索逻辑,例如调用API获取数据 |
| | | // 目前使用模拟数据 |
| | | ElMessage.success(`搜索申请单编号: ${applyNo}`); |
| | | // 模拟搜索结果 |
| | | rowData.applyNo = applyNo; |
| | | rowData.productName = "搜索结果产品"; |
| | | rowData.model = "搜索结果规格"; |
| | | rowData.materialCode = "MAT-" + applyNo; |
| | | rowData.assignedQuantity = 100; |
| | | rowData.status = 1; |
| | | trackProgressForm.progressDetails = generateProgressDetails(1); |
| | | trackProgressForm.completionRate = calculateCompletionRate( |
| | | trackProgressForm.progressDetails |
| | | ); |
| | | rowData.orderList = generateOrderList(); |
| | | }; |
| | | |
| | | // 生成模拟订单数据 |
| | | const generateOrderList = () => { |
| | | return [ |
| | |
| | | status: 1, |
| | | quantity: 233.28, |
| | | completeQuantity: 14, |
| | | remainingQuantity: 149.28, |
| | | completionRate: 6, |
| | | startTime: "2026-03-25", |
| | | }, |
| | |
| | | status: 2, |
| | | quantity: 150.5, |
| | | completeQuantity: 100, |
| | | remainingQuantity: 50.5, |
| | | completionRate: 67, |
| | | startTime: "2026-03-20", |
| | | }, |
| | |
| | | status: 0, |
| | | quantity: 80.0, |
| | | completeQuantity: 0, |
| | | remainingQuantity: 80.0, |
| | | completionRate: 0, |
| | | startTime: "2026-03-30", |
| | | }, |
| | | ]; |
| | | }; |
| | | |
| | | // 处理点击步骤查看详情 |
| | | const handleClickStep = row => { |
| | | // 这里可以添加获取报工详情数据的逻辑 |
| | | // 目前使用模拟数据 |
| | | detailData.value = { |
| | | npsNo: "NPS-2026-001", |
| | | schedule: "白班", |
| | | postName: "张三", |
| | | materialCode: rowData.materialCode || "MAT-001", |
| | | productName: rowData.productName || "产品A", |
| | | model: rowData.model || "规格A", |
| | | qualifiedQuantity: 100, |
| | | unqualifiedQuantity: 5, |
| | | quantity: 105, |
| | | reportingTime: new Date(), |
| | | createTime: new Date(), |
| | | updateTime: new Date(), |
| | | productionProductRouteItemDtoList: [ |
| | | { |
| | | id: 1, |
| | | processName: "工序1", |
| | | postName: "张三", |
| | | processNo: "PROC-001", |
| | | equipmentMalfunction: "无异常", |
| | | equipmentDisposal: "正常运行", |
| | | processExplained: "按照标准工艺操作", |
| | | productionProductRouteItemParamDtoList: [ |
| | | { |
| | | id: 11, |
| | | paramName: "原材料A", |
| | | model: "型号A", |
| | | productValue: "100", |
| | | unit: "kg", |
| | | bomId: 101, |
| | | }, |
| | | { |
| | | id: 12, |
| | | paramName: "温度", |
| | | paramValue: "25", |
| | | unit: "°C", |
| | | sourceSort: 1, |
| | | valueMode: 2, |
| | | minValue: 20, |
| | | maxValue: 30, |
| | | }, |
| | | { |
| | | id: 13, |
| | | paramName: "压力", |
| | | paramValue: "1.5", |
| | | unit: "MPa", |
| | | sourceSort: 1, |
| | | valueMode: 2, |
| | | minValue: 1.0, |
| | | maxValue: 2.0, |
| | | }, |
| | | { |
| | | id: 14, |
| | | paramName: "转速", |
| | | paramValue: "1500", |
| | | unit: "rpm", |
| | | sourceSort: 2, |
| | | valueMode: 1, |
| | | standardValue: "1500", |
| | | }, |
| | | { |
| | | id: 15, |
| | | paramName: "电流", |
| | | paramValue: "12", |
| | | unit: "A", |
| | | sourceSort: 2, |
| | | valueMode: 2, |
| | | minValue: 10, |
| | | maxValue: 15, |
| | | }, |
| | | ], |
| | | fileList: [ |
| | | { |
| | | id: 21, |
| | | fileName: "生产记录1.jpg", |
| | | fileUrl: "/upload/files/20260301/12345.jpg", |
| | | fileSize: 1024000, |
| | | }, |
| | | { |
| | | id: 22, |
| | | fileName: "生产记录2.jpg", |
| | | fileUrl: "/upload/files/20260301/67890.jpg", |
| | | fileSize: 2048000, |
| | | }, |
| | | ], |
| | | }, |
| | | ], |
| | | }; |
| | | detailDialogVisible.value = true; |
| | | }; |
| | | |
| | | // 格式化时间 |
| | | const formatTime = time => { |
| | | return time ? dayjs(time).format("YYYY-MM-DD HH:mm:ss") : "-"; |
| | | }; |
| | | |
| | | // 格式化文件列表 |
| | | const formatFileList = fileList => { |
| | | return fileList.map(file => ({ |
| | | name: file.fileName, |
| | | url: baseUrl + file.fileUrl, |
| | | size: file.fileSize, |
| | | })); |
| | | }; |
| | | |
| | | // 获取BOM列表 |
| | | const getBomList = paramList => { |
| | | return paramList.filter(item => item.bomId); |
| | | }; |
| | | |
| | | // 获取参数列表 |
| | | const getParamList = paramList => { |
| | | return paramList.filter(item => !item.bomId); |
| | | }; |
| | | |
| | | // 按sourceSort分组参数 |
| | | const getParamGroups = paramList => { |
| | | const params = getParamList(paramList); |
| | | const groups = {}; |
| | | |
| | | params.forEach(param => { |
| | | const sort = param.sourceSort || 1; |
| | | if (!groups[sort]) { |
| | | groups[sort] = []; |
| | | } |
| | | // 计算结果 |
| | | let result = "合格"; |
| | | let standardText = ""; |
| | | if (param.valueMode === 1) { |
| | | // 单值比较 |
| | | if (param.standardValue !== null && param.standardValue !== undefined) { |
| | | standardText = param.standardValue; |
| | | if (param.paramValue !== param.standardValue) { |
| | | result = "不合格"; |
| | | } |
| | | } else { |
| | | standardText = "-"; |
| | | result = "合格"; |
| | | } |
| | | } else if (param.valueMode === 2) { |
| | | // 区间比较 |
| | | if (param.minValue !== null || param.maxValue !== null) { |
| | | standardText = |
| | | (param.minValue ? param.minValue : "-∞") + |
| | | "~" + |
| | | (param.maxValue ? param.maxValue : "+∞"); |
| | | if ( |
| | | param.paramValue < param.minValue || |
| | | param.paramValue > param.maxValue |
| | | ) { |
| | | result = "不合格"; |
| | | } |
| | | } else { |
| | | standardText = "-"; |
| | | result = "合格"; |
| | | } |
| | | } else { |
| | | // 默认情况 |
| | | standardText = "-"; |
| | | result = "合格"; |
| | | } |
| | | groups[sort].push({ |
| | | ...param, |
| | | standardText, |
| | | result, |
| | | }); |
| | | }); |
| | | |
| | | // 转换为数组格式 |
| | | return Object.entries(groups).map(([key, items]) => ({ |
| | | sourceSort: key, |
| | | items, |
| | | })); |
| | | }; |
| | | |
| | | // 为不合格的行添加样式 |
| | | const rowClassName = ({ row }) => { |
| | | return row.result === "不合格" ? "warning-row" : ""; |
| | | }; |
| | | |
| | | const applyNo = ref(null); |
| | | // 页面加载时获取数据 |
| | | onMounted(() => { |
| | | // 从路由参数中获取数据 |
| | | const data = route.query.row |
| | | ? JSON.parse(decodeURIComponent(route.query.row)) |
| | | applyNo.value = route.query.applyNo |
| | | ? decodeURIComponent(route.query.applyNo) |
| | | : null; |
| | | if (data) { |
| | | // 赋值给rowData |
| | | Object.assign(rowData, data); |
| | | // 赋值给表单数据 |
| | | trackProgressForm.materialCode = data.materialCode; |
| | | trackProgressForm.currentStatus = data.status; |
| | | trackProgressForm.progressDetails = generateProgressDetails(data.status); |
| | | trackProgressForm.completionRate = calculateCompletionRate( |
| | | trackProgressForm.progressDetails |
| | | ); |
| | | trackProgressForm.remark = ""; |
| | | } |
| | | searchForm.applyNo = applyNo.value; |
| | | |
| | | // 生成假数据 |
| | | rowData.applyNo = applyNo.value || "APPLY-2026-001"; |
| | | rowData.productName = "测试产品"; |
| | | rowData.model = "测试规格"; |
| | | rowData.materialCode = "MAT-001"; |
| | | rowData.assignedQuantity = 233; |
| | | rowData.status = 1; |
| | | // 赋值给表单数据 |
| | | trackProgressForm.materialCode = rowData.materialCode; |
| | | trackProgressForm.currentStatus = rowData.status; |
| | | trackProgressForm.progressDetails = generateProgressDetails(rowData.status); |
| | | trackProgressForm.completionRate = calculateCompletionRate( |
| | | trackProgressForm.progressDetails |
| | | ); |
| | | trackProgressForm.remark = ""; |
| | | |
| | | // 生成模拟订单数据 |
| | | rowData.orderList = generateOrderList(); |
| | | }); |
| | |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | padding: 0 10px; |
| | | } |
| | | |
| | | .search-form { |
| | | width: 100%; |
| | | } |
| | | |
| | | .search-form .el-form-item { |
| | | margin-right: 10px; |
| | | } |
| | | |
| | | .action-buttons { |
| | |
| | | box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.08); |
| | | flex: 1; |
| | | transition: all 0.3s ease; |
| | | width: 100%; |
| | | } |
| | | |
| | | .progress-section:hover { |
| | |
| | | border-radius: 12px; |
| | | padding: 2px 10px; |
| | | } |
| | | |
| | | /* 弹窗样式 */ |
| | | .detail-container { |
| | | max-height: 600px; |
| | | overflow-y: auto; |
| | | padding: 0 16px; |
| | | } |
| | | |
| | | .process-item { |
| | | margin-bottom: 24px; |
| | | padding: 20px; |
| | | background-color: #ffffff; |
| | | border-radius: 8px; |
| | | border: 1px solid #ebeef5; |
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); |
| | | } |
| | | |
| | | .process-header { |
| | | margin-bottom: 20px; |
| | | padding-bottom: 12px; |
| | | border-bottom: 1px solid #f0f2f5; |
| | | } |
| | | |
| | | .process-title { |
| | | font-size: 15px; |
| | | font-weight: 600; |
| | | margin-bottom: 12px; |
| | | color: #1a1a1a; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .process-title::before { |
| | | content: ""; |
| | | display: inline-block; |
| | | width: 4px; |
| | | height: 16px; |
| | | background-color: #409eff; |
| | | margin-right: 8px; |
| | | border-radius: 2px; |
| | | } |
| | | |
| | | .process-info { |
| | | display: flex; |
| | | gap: 20px; |
| | | font-size: 13px; |
| | | color: #606266; |
| | | } |
| | | |
| | | .process-label { |
| | | padding: 4px 12px; |
| | | background-color: #ecf5ff; |
| | | border-radius: 4px; |
| | | color: #409eff; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .process-details { |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .param-section { |
| | | margin-bottom: 20px; |
| | | background-color: #f9f9f9; |
| | | border-radius: 6px; |
| | | padding: 16px; |
| | | border: 1px solid #f0f2f5; |
| | | } |
| | | |
| | | .param-title { |
| | | font-size: 14px; |
| | | font-weight: 600; |
| | | margin-bottom: 14px; |
| | | color: #1a1a1a; |
| | | padding-bottom: 8px; |
| | | border-bottom: 1px solid #e8e8e8; |
| | | } |
| | | |
| | | .file-section { |
| | | margin-top: 20px; |
| | | background-color: #f9f9f9; |
| | | border-radius: 6px; |
| | | padding: 16px; |
| | | border: 1px solid #f0f2f5; |
| | | } |
| | | |
| | | .file-title { |
| | | font-size: 14px; |
| | | font-weight: 600; |
| | | margin-bottom: 14px; |
| | | color: #1a1a1a; |
| | | padding-bottom: 8px; |
| | | border-bottom: 1px solid #e8e8e8; |
| | | } |
| | | |
| | | .file-grid { |
| | | display: grid; |
| | | grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); |
| | | gap: 16px; |
| | | } |
| | | |
| | | .file-item { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | background-color: #ffffff; |
| | | border: 1px solid #e8e8e8; |
| | | border-radius: 6px; |
| | | padding: 10px; |
| | | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); |
| | | transition: all 0.3s ease; |
| | | } |
| | | |
| | | .file-item:hover { |
| | | box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); |
| | | border-color: #409eff; |
| | | transform: translateY(-2px); |
| | | } |
| | | |
| | | .file-info { |
| | | width: 100%; |
| | | text-align: center; |
| | | } |
| | | |
| | | .file-name { |
| | | font-size: 12px; |
| | | color: #606266; |
| | | word-break: break-all; |
| | | line-height: 1.4; |
| | | } |
| | | |
| | | .param-group { |
| | | margin-bottom: 16px; |
| | | padding: 14px; |
| | | background-color: #ffffff; |
| | | border-radius: 6px; |
| | | border: 1px solid #e8e8e8; |
| | | } |
| | | |
| | | .group-header { |
| | | margin-bottom: 12px; |
| | | padding-bottom: 8px; |
| | | border-bottom: 1px solid #f0f2f5; |
| | | } |
| | | |
| | | .num1 { |
| | | color: #1107cc; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .num2 { |
| | | color: #0fcf25; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .num3 { |
| | | color: #d31818; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .group-title { |
| | | font-size: 14px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | } |
| | | |
| | | .param-grid { |
| | | display: grid; |
| | | grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); |
| | | gap: 16px; |
| | | } |
| | | |
| | | .param-item { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 12px; |
| | | padding: 8px 0; |
| | | border-bottom: 1px solid #f5f7fa; |
| | | } |
| | | |
| | | .param-item:last-child { |
| | | border-bottom: none; |
| | | } |
| | | |
| | | .param-label { |
| | | font-size: 13px; |
| | | color: #606266; |
| | | min-width: 100px; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .param-value { |
| | | font-size: 13px; |
| | | color: #1a1a1a; |
| | | font-weight: 600; |
| | | flex: 1; |
| | | } |
| | | |
| | | .param-unit { |
| | | font-size: 12px; |
| | | color: #909399; |
| | | background-color: #f0f2f5; |
| | | padding: 2px 6px; |
| | | border-radius: 3px; |
| | | } |
| | | |
| | | .dialog-footer { |
| | | text-align: center; |
| | | padding: 20px; |
| | | border-top: 1px solid #ebeef5; |
| | | } |
| | | |
| | | .dialog-footer .el-button { |
| | | min-width: 100px; |
| | | padding: 8px 20px; |
| | | } |
| | | |
| | | /* 自定义对话框样式 */ |
| | | :deep(.custom-dialog) { |
| | | border-radius: 12px; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | :deep(.custom-dialog .el-dialog__header) { |
| | | background-color: #f5f7fa; |
| | | padding: 20px; |
| | | border-bottom: 1px solid #ebeef5; |
| | | } |
| | | |
| | | :deep(.custom-dialog .el-dialog__title) { |
| | | font-size: 18px; |
| | | font-weight: 600; |
| | | color: #1a1a1a; |
| | | } |
| | | |
| | | :deep(.custom-dialog .el-dialog__body) { |
| | | padding: 20px; |
| | | } |
| | | |
| | | /* 表格样式优化 */ |
| | | :deep(.el-table) { |
| | | border-radius: 6px; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | :deep(.el-table th) { |
| | | background-color: #f5f7fa; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | } |
| | | |
| | | :deep(.el-table tr:hover > td) { |
| | | background-color: #ecf5ff !important; |
| | | } |
| | | |
| | | /* 描述列表样式优化 */ |
| | | :deep(.el-descriptions) { |
| | | border-radius: 6px; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | :deep(.el-descriptions__label) { |
| | | font-weight: 500; |
| | | color: #606266; |
| | | } |
| | | |
| | | :deep(.el-descriptions__content) { |
| | | color: #1a1a1a; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | /* 不合格行样式 */ |
| | | :deep(.el-table .warning-row) { |
| | | background-color: #fef0f0 !important; |
| | | } |
| | | |
| | | .detail-card { |
| | | border-radius: 8px; |
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); |
| | | } |
| | | |
| | | .card-header { |
| | | font-weight: 600; |
| | | color: #303133; |
| | | } |
| | | </style> |