From 63bc8594046177d976d0436c709e928d71bbba0d Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期一, 30 三月 2026 10:15:58 +0800
Subject: [PATCH] 追踪进度
---
src/views/productionManagement/productionReporting/detailDialog.vue | 2
src/views/productionPlan/productionPlan/index.vue | 2
src/views/productionPlan/trackProgress/index.vue | 717 +++++++++++++++++++++++++++++++++++++++++++-
src/views/reportAnalysis/unitEnergyConsumption/index.vue | 212 +++++--------
4 files changed, 785 insertions(+), 148 deletions(-)
diff --git a/src/views/productionManagement/productionReporting/detailDialog.vue b/src/views/productionManagement/productionReporting/detailDialog.vue
index aec6b5c..4e519eb 100644
--- a/src/views/productionManagement/productionReporting/detailDialog.vue
+++ b/src/views/productionManagement/productionReporting/detailDialog.vue
@@ -28,7 +28,7 @@
<div class="detail-section"
v-if="detailData.productionProductRouteItemDtoList && detailData.productionProductRouteItemDtoList.length > 0">
<h3 class="section-title">宸ュ簭淇℃伅</h3>
- <div v-for="(process, index) in detailData.productionProductRouteItemDtoList"
+ <div v-for="(process) in detailData.productionProductRouteItemDtoList"
:key="process.id"
class="process-item">
<div class="process-header">
diff --git a/src/views/productionPlan/productionPlan/index.vue b/src/views/productionPlan/productionPlan/index.vue
index a294890..7fe0e90 100644
--- a/src/views/productionPlan/productionPlan/index.vue
+++ b/src/views/productionPlan/productionPlan/index.vue
@@ -672,7 +672,7 @@
router.push({
path: "/productionPlan/trackProgress",
query: {
- row: encodeURIComponent(JSON.stringify(row)),
+ applyNo: encodeURIComponent(row.applyNo),
},
});
};
diff --git a/src/views/productionPlan/trackProgress/index.vue b/src/views/productionPlan/trackProgress/index.vue
index b910bf5..80656de 100644
--- a/src/views/productionPlan/trackProgress/index.vue
+++ b/src/views/productionPlan/trackProgress/index.vue
@@ -1,11 +1,24 @@
<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>
<!-- 鍩虹淇℃伅 -->
@@ -57,8 +70,7 @@
<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"
@@ -127,6 +139,156 @@
</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>
@@ -134,6 +296,7 @@
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();
@@ -149,6 +312,16 @@
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 => {
@@ -261,6 +434,30 @@
router.push("/productionPlan/productionPlan");
};
+ // 澶勭悊鎼滅储
+ const handleSearch = () => {
+ const applyNo = searchForm.applyNo.trim();
+ if (!applyNo) {
+ ElMessage.warning("璇疯緭鍏ョ敵璇峰崟缂栧彿");
+ return;
+ }
+ // 杩欓噷鍙互娣诲姞鎼滅储閫昏緫锛屼緥濡傝皟鐢ˋPI鑾峰彇鏁版嵁
+ // 鐩墠浣跨敤妯℃嫙鏁版嵁
+ 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 [
@@ -291,24 +488,215 @@
];
};
+ // 澶勭悊鐐瑰嚮姝ラ鏌ョ湅璇︽儏
+ 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: "姝e父杩愯",
+ processExplained: "鎸夌収鏍囧噯宸ヨ壓鎿嶄綔",
+ productionProductRouteItemParamDtoList: [
+ {
+ id: 11,
+ paramName: "鍘熸潗鏂橝",
+ 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);
+ };
+
+ // 鎸塻ourceSort鍒嗙粍鍙傛暟
+ 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();
});
@@ -326,6 +714,14 @@
justify-content: space-between;
align-items: center;
padding: 0 10px;
+ }
+
+ .search-form {
+ width: 100%;
+ }
+
+ .search-form .el-form-item {
+ margin-right: 10px;
}
.action-buttons {
@@ -468,4 +864,289 @@
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>
\ No newline at end of file
diff --git a/src/views/reportAnalysis/unitEnergyConsumption/index.vue b/src/views/reportAnalysis/unitEnergyConsumption/index.vue
index 6aa4912..81d6679 100644
--- a/src/views/reportAnalysis/unitEnergyConsumption/index.vue
+++ b/src/views/reportAnalysis/unitEnergyConsumption/index.vue
@@ -89,53 +89,48 @@
<el-table :data="tableData"
v-loading="tableLoading"
border>
- <el-table-column prop="energyType"
- label="鑳借��"
- width="100"
- align="center">
+ <el-table-column prop="meterReadingDate"
+ label="鏃ユ湡"
+ align="center"
+ width="120" />
+ <el-table-column prop="type"
+ label="绫诲瀷"
+ align="center"
+ width="100">
<template #default="scope">
- <el-tag :type="getEnergyTypeType(scope.row.energyType)">
- {{ scope.row.energyType }}
+ <el-tag :type="scope.row.type === '鐢熶骇' ? 'primary' : 'success'">
+ {{ scope.row.type }}
</el-tag>
</template>
</el-table-column>
- <el-table-column prop="unit"
- label="鍗曚綅"
- width="120"
- align="center" />
- <el-table-column label="鏈堝害鏁版嵁"
- v-if="searchForm.timeDimension === 'month'">
- <el-table-column prop="monthlyUnitConsumption"
- label="鏈堝害绱鍗曡��"
- align="right">
- <template #default="scope">
- <span class="data-value">{{ scope.row.monthlyUnitConsumption }}</span>
- </template>
- </el-table-column>
- <el-table-column prop="monthlyConsumption"
- label="鏈堝害绱鐢ㄩ噺/鏈堝害绱浜ч噺"
- align="right">
- <template #default="scope">
- <span class="data-value">{{ scope.row.monthlyConsumption }}/{{ scope.row.monthlyProduction }}</span>
- </template>
- </el-table-column>
+ <el-table-column prop="energyTyep"
+ label="鑳借�楃被鍨�"
+ align="center"
+ width="100">
+ <template #default="scope">
+ <el-tag :type="getEnergyTypeType(scope.row.energyTyep)">
+ {{ scope.row.energyTyep }}
+ </el-tag>
+ </template>
</el-table-column>
- <el-table-column label="骞村害鏁版嵁"
- v-if="searchForm.timeDimension === 'year'">
- <el-table-column prop="annualUnitConsumption"
- label="骞村害绱鍗曡��"
- align="right">
- <template #default="scope">
- <span class="data-value">{{ scope.row.annualUnitConsumption }}</span>
- </template>
- </el-table-column>
- <el-table-column prop="annualConsumption"
- label="骞村害绱鐢ㄩ噺/骞村害绱浜ч噺"
- align="right">
- <template #default="scope">
- <span class="data-value">{{ scope.row.annualConsumption }}/{{ scope.row.annualProduction }}</span>
- </template>
- </el-table-column>
+ <el-table-column prop="consumption"
+ label="鐢ㄩ噺"
+ align="right"
+ width="120" />
+ <el-table-column prop="cost"
+ label="鎴愭湰"
+ align="right"
+ width="120">
+ <template #default="scope">
+ <span class="data-value">楼{{ scope.row.cost }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column prop="unitConsumption"
+ label="鍗曡��"
+ align="right">
+ <template #default="scope">
+ <span class="data-value">{{ scope.row.unitConsumption }}</span>
+ </template>
</el-table-column>
</el-table>
</div>
@@ -147,6 +142,7 @@
import { ElMessage } from "element-plus";
import { TrendCharts, List } from "@element-plus/icons-vue";
import * as echarts from "echarts";
+ import { energyConsumptionDetailStatistics } from "@/api/energyManagement/energyType";
// 鎼滅储琛ㄥ崟
const searchForm = reactive({
@@ -229,12 +225,12 @@
const energyTypes = ["姘�", "鐢�", "钂告苯"];
energyTypes.forEach(type => {
- const typeData = data.find(item => item.energyType === type);
- if (typeData && typeData[seriesDataKey]) {
+ const typeData = data.find(item => item.energyTyep === type);
+ if (typeData) {
series.push({
name: type,
type: "line",
- data: typeData[seriesDataKey].map(seriesDataMap),
+ data: typeData.cost,
smooth: true,
symbol: "circle",
symbolSize: 8,
@@ -302,12 +298,49 @@
const handleQuery = () => {
tableLoading.value = true;
- // 妯℃嫙鎺ュ彛璋冪敤
- setTimeout(() => {
- generateMockData();
- tableLoading.value = false;
- updateChart();
- }, 500);
+ const params = {
+ type: "",
+ state: searchForm.timeDimension === "year" ? "骞�" : "鏈�",
+ };
+
+ if (searchForm.energyType && searchForm.energyType !== "鍏ㄩ儴") {
+ params.type = searchForm.energyType;
+ }
+
+ if (searchForm.timeDimension === "year") {
+ params.startDate = searchForm.year + "-01-01";
+ params.endDate = searchForm.year + "-12-31";
+ params.days = 365;
+ } else if (searchForm.timeDimension === "month") {
+ const year = searchForm.year;
+ const month = searchForm.month;
+ const lastDay = new Date(year, month, 0).getDate();
+ params.startDate = `${year}-${String(month).padStart(2, "0")}-01`;
+ params.endDate = `${year}-${String(month).padStart(2, "0")}-${String(
+ lastDay
+ ).padStart(2, "0")}`;
+ params.days = lastDay;
+ }
+
+ energyConsumptionDetailStatistics(params)
+ .then(res => {
+ if (res.code === 200) {
+ const data = res.data;
+ tableData.value = data.energyCostDtos || [];
+ updateChart();
+ } else {
+ ElMessage.error(res.message || "鑾峰彇鏁版嵁澶辫触");
+ tableData.value = [];
+ }
+ })
+ .catch(err => {
+ console.error("鑾峰彇鏁版嵁寮傚父锛�", err);
+ ElMessage.error("绯荤粺寮傚父锛岃幏鍙栨暟鎹け璐�");
+ tableData.value = [];
+ })
+ .finally(() => {
+ tableLoading.value = false;
+ });
};
// 閲嶇疆
@@ -322,83 +355,6 @@
// 瀵煎嚭
const handleExport = () => {
ElMessage.success("鎶ヨ〃瀵煎嚭鎴愬姛");
- };
-
- // 鐢熸垚鍋囨暟鎹�
- const generateMockData = () => {
- const energyTypes = [
- {
- energyType: "姘�",
- unit: "鍚�/绔嬫柟绫�",
- monthlyUnitConsumption: (Math.random() * 0.5 + 0.8).toFixed(4),
- monthlyConsumption: Math.floor(Math.random() * 5000 + 10000),
- monthlyProduction: Math.floor(Math.random() * 10000 + 20000),
- annualUnitConsumption: (Math.random() * 0.3 + 0.9).toFixed(4),
- annualConsumption: Math.floor(Math.random() * 60000 + 120000),
- annualProduction: Math.floor(Math.random() * 120000 + 240000),
- monthlyData: generateMonthlyData(0.8, 1.3),
- dailyData: generateDailyData(0.7, 1.4),
- },
- {
- energyType: "鐢�",
- unit: "搴�/绔嬫柟绫�",
- monthlyUnitConsumption: (Math.random() * 2 + 5).toFixed(4),
- monthlyConsumption: Math.floor(Math.random() * 50000 + 100000),
- monthlyProduction: Math.floor(Math.random() * 10000 + 20000),
- annualUnitConsumption: (Math.random() * 1.5 + 5.5).toFixed(4),
- annualConsumption: Math.floor(Math.random() * 600000 + 1200000),
- annualProduction: Math.floor(Math.random() * 120000 + 240000),
- monthlyData: generateMonthlyData(5, 7),
- dailyData: generateDailyData(4.5, 7.5),
- },
- {
- energyType: "钂告苯",
- unit: "鍚�/绔嬫柟绫�",
- monthlyUnitConsumption: (Math.random() * 0.3 + 0.5).toFixed(4),
- monthlyConsumption: Math.floor(Math.random() * 3000 + 6000),
- monthlyProduction: Math.floor(Math.random() * 10000 + 20000),
- annualUnitConsumption: (Math.random() * 0.2 + 0.55).toFixed(4),
- annualConsumption: Math.floor(Math.random() * 36000 + 72000),
- annualProduction: Math.floor(Math.random() * 120000 + 240000),
- monthlyData: generateMonthlyData(0.5, 0.8),
- dailyData: generateDailyData(0.4, 0.9),
- },
- ];
-
- if (searchForm.energyType && searchForm.energyType !== "鍏ㄩ儴") {
- tableData.value = energyTypes.filter(
- item => item.energyType === searchForm.energyType
- );
- } else {
- tableData.value = energyTypes;
- }
- };
-
- // 鐢熸垚鏈堝害鏁版嵁
- const generateMonthlyData = (min, max) => {
- const data = [];
- for (let i = 1; i <= 12; i++) {
- data.push({
- month: i,
- unitConsumption: (Math.random() * (max - min) + min).toFixed(4),
- });
- }
- return data;
- };
-
- // 鐢熸垚姣忔棩鏁版嵁
- const generateDailyData = (min, max) => {
- const year = searchForm.year;
- const month = searchForm.month;
- const daysInMonth = new Date(year, month, 0).getDate();
- const data = [];
- for (let i = 1; i <= daysInMonth; i++) {
- data.push({
- day: i,
- unitConsumption: (Math.random() * (max - min) + min).toFixed(4),
- });
- }
- return data;
};
// 绐楀彛澶у皬鍙樺寲鏃堕噸鏂版覆鏌撳浘琛�
--
Gitblit v1.9.3