From 2f63f26c3240f9d8f9e8696df7037d2ac5c744a6 Mon Sep 17 00:00:00 2001
From: zxl <763096477@qq.com>
Date: 星期三, 25 三月 2026 09:16:30 +0800
Subject: [PATCH] 新增标签页面以及跳转路径和大屏内容调整
---
src/views/analysisScreen/alarmBigdata.vue | 19
src/views/dataAnalysis/components/DataReGasStation.vue | 24 +
src/views/dataAnalysis/components/DataReMechanism.vue | 18 +
src/views/dataAnalysis/components/DepartLabel.vue | 500 +++++++++++++++++++++++++++++++
src/views/user/Login.vue | 2
src/views/dataAnalysis/ActivityList.vue | 5
src/views/analysisScreen/operationBigdata.vue | 30 +
src/config/router.config.js | 2
src/views/dataAnalysis/components/DepartLabelModal.vue | 132 ++++++++
src/views/dataAnalysis/components/ActiveCom.vue | 82 +++++
src/views/dataAnalysis/components/DataReLineChart.vue | 124 ++++---
11 files changed, 860 insertions(+), 78 deletions(-)
diff --git a/src/config/router.config.js b/src/config/router.config.js
index 4386460..0799e74 100644
--- a/src/config/router.config.js
+++ b/src/config/router.config.js
@@ -17,7 +17,7 @@
meta: {
title: '棣栭〉'
},
- redirect: '/dashboard/analysis',
+ redirect: '/analysisScreen/operationBigdata',
children: []
},
{
diff --git a/src/views/analysisScreen/alarmBigdata.vue b/src/views/analysisScreen/alarmBigdata.vue
index 21a2080..18bbc03 100644
--- a/src/views/analysisScreen/alarmBigdata.vue
+++ b/src/views/analysisScreen/alarmBigdata.vue
@@ -1,7 +1,8 @@
<template>
<div>
<div class="content">
- <div class="header_ct">{{ localInfo.taskViewName }}</div>
+ <div class="header_ct"><span class="blue-text">{{ localInfo.operationViewName }}</span>
+ 鍙鍖栧ぇ灞�</div>
<div class="tab_page">
<div class="operation" @click="goOperation">杩愯惀鏁版嵁鍒嗘瀽</div>
<div class="alarm">鍛婅鏁版嵁鍒嗘瀽</div>
@@ -17,7 +18,7 @@
</div>
<div class="info_ct">
<div class="left_ct">
- <div class="block alarm_overview">
+ <div class="block alarm_overview" @click="goToAlarmQuery">
<div class="block_title">
<div>
<span class="blue_text">鍛婅</span>
@@ -133,7 +134,7 @@
</div> -->
</div>
</div>
- <div class="block latest_alarm">
+ <div class="block latest_alarm" @click="goToAlarmQuery">
<div class="block_title">
<div>
<span class="blue_text">鏈�鏂�</span>
@@ -157,7 +158,7 @@
</div>
</div>
<div class="right_ct">
- <div class="block terminal_statis">
+ <div class="block terminal_statis" @click="goToTerminal">
<div class="block_title">
<div>
<span class="blue_text">缁堢</span>
@@ -366,8 +367,13 @@
this.getAlarmRankingData()
},
goOperation() {
- // this.$router.replace("operationBigdata")
window.location.href = window.location.origin + '/analysisScreen/operationBigdata'
+ },
+ goToAlarmQuery() {
+ window.location.href = window.location.origin + '/event/oilout'
+ },
+ goToTerminal() {
+ window.location.href = window.location.origin + '/device/camera'
},
//鑾峰彇鍛婅姒傚喌鏁版嵁
getOverviewData() {
@@ -1039,6 +1045,9 @@
text-align: center;
font-size: 40px;
color: #fff;
+ .blue-text {
+ color: #5a81f9;
+ }
}
.tab_page {
display: flex;
diff --git a/src/views/analysisScreen/operationBigdata.vue b/src/views/analysisScreen/operationBigdata.vue
index ae0980e..ab63b7b 100644
--- a/src/views/analysisScreen/operationBigdata.vue
+++ b/src/views/analysisScreen/operationBigdata.vue
@@ -27,21 +27,21 @@
</div>
<img class="title_line" src="@/assets/img/bigdata/daoh.png" alt="" />
<div class="icon_ct">
- <div class="icon_fa">
+ <div class="icon_fa" @click="goToDataAnalysis">
<div class="icon_img_fa">
<img src="@/assets/img/bigdata/cheliuliang.png" alt="" />
</div>
<div class="icon_name">杞︽祦閲�</div>
<div class="icon_num">{{ overviewData.trafficFlow }}</div>
</div>
- <div class="icon_fa">
+ <div class="icon_fa" @click="goToDataAnalysis">
<div class="icon_img_fa">
<img src="@/assets/img/bigdata/jinzhanshu.png" alt="" />
</div>
<div class="icon_name">杩涚珯鏁�</div>
<div class="icon_num">{{ overviewData.inboundCount }}</div>
</div>
- <div class="icon_fa">
+ <div class="icon_fa" @click="goToDataAnalysis('oilCount')">
<div class="icon_img_fa">
<img src="@/assets/img/bigdata/jiayoushuliang.png" alt="" />
</div>
@@ -65,7 +65,7 @@
<div class="pie_self" id="refuelingRateChart"></div>
</div>
</div>
- <div class="block customer_statis">
+ <div class="block customer_statis" @click="goToCarInfo">
<div class="block_title">
<div>
<span class="blue_text">瀹㈡埛</span>
@@ -103,7 +103,7 @@
</div>
</div>
</div>
- <div class="block traffic_statis">
+ <div class="block traffic_statis" @click="goToDataAnalysis">
<div class="block_title">
<div>
<span class="blue_text">杞︽祦閲�</span>
@@ -126,7 +126,7 @@
<!-- <img class="person_img" src="@/assets/img/bigdata/person.png" alt="" />
<img class="car_img" src="@/assets/img/bigdata/car.png" alt="" /> -->
</div>
- <div class="block refueling_statis">
+ <div class="block refueling_statis" @click="goToDataAnalysis">
<div class="block_title">
<div>
<span class="blue_text">鍔犳补</span>
@@ -164,7 +164,7 @@
</div>
</div>
</div>
- <div class="block vehicle_type_distribution">
+ <div class="block vehicle_type_distribution" @click="goToCarInfo">
<div class="block_title">
<div>
<span class="blue_text">杞﹀瀷</span>
@@ -184,7 +184,7 @@
</div>
</div>
</div>
- <div class="block monthly_sales_statis">
+ <div class="block monthly_sales_statis" @click="goToSales">
<div class="block_title">
<div>
<span class="blue_text">鏈堝害閿�鍞�</span>
@@ -281,6 +281,20 @@
goAlarmPage() {
window.location.href = window.location.origin + '/analysisScreen/alarmBigdata'
},
+ goToDataAnalysis(target) {
+ const scrollTarget = target === 'oilCount' ? 'oil-count-card' : 'traffic-flow-card'
+ localStorage.setItem('scrollToTarget', scrollTarget)
+ if (target === 'oilCount') {
+ localStorage.setItem('trendAnalysisType', '1')
+ }
+ window.location.href = window.location.origin + '/data/DataReport'
+ },
+ goToCarInfo() {
+ window.location.href = window.location.origin + '/data/carInfo'
+ },
+ goToSales() {
+ window.location.href = window.location.origin + '/data/sales'
+ },
//鑾峰彇杩愯惀姒傚喌鏁版嵁
getOverviewData() {
getAction('/jyz/operationData/overview', {}).then((res) => {
diff --git a/src/views/dataAnalysis/ActivityList.vue b/src/views/dataAnalysis/ActivityList.vue
index d5700a7..d6fd9c5 100644
--- a/src/views/dataAnalysis/ActivityList.vue
+++ b/src/views/dataAnalysis/ActivityList.vue
@@ -7,6 +7,9 @@
<a-tab-pane key="2" tab="娲诲姩閰嶇疆" force-render>
<ActiveCom></ActiveCom>
</a-tab-pane>
+ <a-tab-pane key="3" tab="鏈烘瀯鏍囩" force-render>
+ <DepartLabel></DepartLabel>
+ </a-tab-pane>
</a-tabs>
</div>
</template>
@@ -14,6 +17,7 @@
<script>
import ActiveCom from './components/ActiveCom'
import CustTypeConfig from './components/CustTypeConfig'
+import DepartLabel from './components/DepartLabel'
export default {
name: 'ActivityList',
@@ -22,6 +26,7 @@
components: {
ActiveCom,
CustTypeConfig,
+ DepartLabel,
},
data() {
diff --git a/src/views/dataAnalysis/components/ActiveCom.vue b/src/views/dataAnalysis/components/ActiveCom.vue
index aba9465..81c9cbd 100644
--- a/src/views/dataAnalysis/components/ActiveCom.vue
+++ b/src/views/dataAnalysis/components/ActiveCom.vue
@@ -27,6 +27,8 @@
<a v-if="new Date().getTime() < Date.parse(record.startTime)" @click="handleEdit(record)">缂栬緫</a>
<a v-else disabled>缂栬緫</a>
<a-divider type="vertical" />
+ <a @click="viewVehicleFrequency(record)">鏌ョ湅杞﹁締鍔犳补棰戞</a>
+ <a-divider type="vertical" />
<a-popconfirm title="纭畾鍒犻櫎鍚�?" @confirm="() => handleDelete(record.id)">
<a>鍒犻櫎</a>
</a-popconfirm>
@@ -43,6 +45,7 @@
<script>
import ActivityModal from './ActivityModal'
import { JeecgListMixin } from '@tievd/cube-block/lib/mixins/JeecgListMixin'
+import { getAction } from '@tievd/cube-block/lib/api/manage'
export default {
name: 'ActivityList',
@@ -113,11 +116,88 @@
delete: '/jyz/activity/delete',
deleteBatch: '/jyz/activity/deleteBatch',
exportXlsUrl: '/jyz/activity/exportXls',
+ getVehicleFrequency: '/jyz/activity/getVehicleFrequency',
},
}
},
- methods: {},
+ methods: {
+ viewVehicleFrequency(record) {
+ console.log('鏌ョ湅杞﹁締鍔犳补棰戞', record)
+ getAction(this.url.getVehicleFrequency, { actId: record.id }).then((res) => {
+ if (res.code === 200) {
+ const result = res.result
+ const activity = result.activity || {}
+ const beforeData = result.beforeActivity || {}
+ const duringData = result.duringActivity || {}
+ const afterData = result.afterActivity || {}
+
+ const formatNumber = (num) => num ? Number(num).toFixed(2) : '0.00'
+
+ const content = `
+ <div style="padding: 10px;">
+ <h3 style="text-align: center; margin-bottom: 15px;">${activity.name || '娲诲姩'}</h3>
+ <p style="text-align: center; color: #666; margin-bottom: 20px;">
+ 娲诲姩鏃堕棿锛�${activity.startTime} ~ ${activity.endTime}
+ </p>
+
+ <table style="width: 100%; border-collapse: collapse; margin-bottom: 20px;">
+ <thead>
+ <tr style="background-color: #f5f5f5;">
+ <th style="border: 1px solid #ddd; padding: 8px; text-align: center;">缁熻椤�</th>
+ <th style="border: 1px solid #ddd; padding: 8px; text-align: center;">娲诲姩鍓�</th>
+ <th style="border: 1px solid #ddd; padding: 8px; text-align: center;">娲诲姩涓�</th>
+ <th style="border: 1px solid #ddd; padding: 8px; text-align: center;">娲诲姩鍚�</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td style="border: 1px solid #ddd; padding: 8px; text-align: center; font-weight: bold;">鍔犳补杞﹁締鏁�</td>
+ <td style="border: 1px solid #ddd; padding: 8px; text-align: center;">${beforeData.totalVehicles || 0} 杈�</td>
+ <td style="border: 1px solid #ddd; padding: 8px; text-align: center; color: #1890ff;">${duringData.totalVehicles || 0} 杈�</td>
+ <td style="border: 1px solid #ddd; padding: 8px; text-align: center;">${afterData.totalVehicles || 0} 杈�</td>
+ </tr>
+ <tr>
+ <td style="border: 1px solid #ddd; padding: 8px; text-align: center; font-weight: bold;">鍔犳补璁板綍鏁�</td>
+ <td style="border: 1px solid #ddd; padding: 8px; text-align: center;">${beforeData.totalOilRecords || 0} 绗�</td>
+ <td style="border: 1px solid #ddd; padding: 8px; text-align: center; color: #1890ff;">${duringData.totalOilRecords || 0} 绗�</td>
+ <td style="border: 1px solid #ddd; padding: 8px; text-align: center;">${afterData.totalOilRecords || 0} 绗�</td>
+ </tr>
+ <tr>
+ <td style="border: 1px solid #ddd; padding: 8px; text-align: center; font-weight: bold;">骞冲潎鍔犳补閲�</td>
+ <td style="border: 1px solid #ddd; padding: 8px; text-align: center;">${formatNumber(beforeData.avgOilVolume)} 鍗�</td>
+ <td style="border: 1px solid #ddd; padding: 8px; text-align: center; color: #1890ff;">${formatNumber(duringData.avgOilVolume)} 鍗�</td>
+ <td style="border: 1px solid #ddd; padding: 8px; text-align: center;">${formatNumber(afterData.avgOilVolume)} 鍗�</td>
+ </tr>
+ <tr>
+ <td style="border: 1px solid #ddd; padding: 8px; text-align: center; font-weight: bold;">鎬诲姞娌归噺</td>
+ <td style="border: 1px solid #ddd; padding: 8px; text-align: center;">${beforeData.totalOilVolume || 0} 鍗�</td>
+ <td style="border: 1px solid #ddd; padding: 8px; text-align: center; color: #1890ff;">${duringData.totalOilVolume || 0} 鍗�</td>
+ <td style="border: 1px solid #ddd; padding: 8px; text-align: center;">${afterData.totalOilVolume || 0} 鍗�</td>
+ </tr>
+ </tbody>
+ </table>
+
+ <p style="text-align: center; color: #999; font-size: 12px; margin-top: 10px;">
+ 娉細娲诲姩鏈熼棿鏁版嵁浠ヨ摑鑹查珮浜樉绀�
+ </p>
+ </div>
+ `
+ this.$info({
+ title: '娲诲姩鍔犳补棰戞瀵规瘮缁熻',
+ content: this.$createElement('div', { domProps: { innerHTML: content } }),
+ width: 700,
+ okText: '纭畾',
+ })
+ } else {
+ this.$message.error(res.message || '鏌ヨ澶辫触')
+ }
+ }).catch((err) => {
+ console.error(err)
+ this.$message.error('鏌ヨ澶辫触')
+ })
+ },
+ },
created() {},
}
diff --git a/src/views/dataAnalysis/components/DataReGasStation.vue b/src/views/dataAnalysis/components/DataReGasStation.vue
index 6c4dca0..bb3ed28 100644
--- a/src/views/dataAnalysis/components/DataReGasStation.vue
+++ b/src/views/dataAnalysis/components/DataReGasStation.vue
@@ -64,7 +64,7 @@
<a-range-picker style="width: 300px; margin: 0 12px" v-if="isContrast" @change="contrastTimeChange" />
</div>
<div class="fueling-overview-block">
- <div class="fueling-overview-item">
+ <div class="fueling-overview-item" id="traffic-flow-card">
<div class="fueling-overview-name">杞︽祦閲�</div>
<div class="fueling-overview-num">
<span style="margin-right: 24px">{{ statisTotalObj.carCount }}</span>
@@ -78,7 +78,7 @@
<span style="color: #16b777" v-if="isContrast">{{ contrastObj.appearCount }}</span>
</div>
</div>
- <div class="fueling-overview-item">
+ <div class="fueling-overview-item" id="oil-count-card">
<div class="fueling-overview-name">鍔犳补鏁�</div>
<div class="fueling-overview-num">
<span style="margin-right: 24px">{{ statisTotalObj.oilCount }}</span>
@@ -405,6 +405,26 @@
created() {
this.initData()
},
+ mounted() {
+ this.$nextTick(() => {
+ setTimeout(() => {
+ const scrollTarget = localStorage.getItem('scrollToTarget')
+ if (scrollTarget) {
+ const element = document.getElementById(scrollTarget)
+ if (element) {
+ element.scrollIntoView({ behavior: 'smooth', block: 'center' })
+ localStorage.removeItem('scrollToTarget')
+ }
+ }
+ const trendType = localStorage.getItem('trendAnalysisType')
+ if (trendType) {
+ this.trendAnalysisType = parseInt(trendType)
+ localStorage.removeItem('trendAnalysisType')
+ this.getTrendAnalysis()
+ }
+ }, 500)
+ })
+ },
}
</script>
<style scoped lang="less">
diff --git a/src/views/dataAnalysis/components/DataReLineChart.vue b/src/views/dataAnalysis/components/DataReLineChart.vue
index 764b5d8..782f712 100644
--- a/src/views/dataAnalysis/components/DataReLineChart.vue
+++ b/src/views/dataAnalysis/components/DataReLineChart.vue
@@ -54,15 +54,23 @@
shadowBlur: 10,
formatter: (params) => {
let strName1 = params[0].name
- let value1 = params[0].value
- let value2 = params[1] ? params[1].value : '鏈紑鍚�'
+ let value1 = params[0] ? params[0].value : 0
+ let value2 = params[1] ? params[1].value : 0
+ let value3 = params[2] ? params[2].value : 0
+ let value4 = params[3] ? params[3].value : 0
return `<div style="color:#fff;font-size:16px;">${strName1}</div>
<div><span style="color:#fff;display: inline-block;width: 86px;">${
this.chartData.barName
}</span><span style="color:#5DB6FB">${value1}
</span></div><div><span style="color:#fff;display: inline-block;width: 86px;">${
this.chartData.lineName
- }</span><span style="color:#5DB6FB">${value2}${this.showpercent ? '%' : ''}`
+ }</span><span style="color:#5DB6FB">${value2}
+ </span></div><div><span style="color:#fff;display: inline-block;width: 86px;">${
+ this.chartData.barName2
+ }</span><span style="color:#FF6B6B">${value3}
+ </span></div><div><span style="color:#fff;display: inline-block;width: 86px;">${
+ this.chartData.lineName2
+ }</span><span style="color:#FFD93D">${value4}</span>`
},
textStyle: {
rich: {
@@ -119,32 +127,6 @@
show: false,
},
},
- {
- type: 'value',
- nameTextStyle: {
- color: 'rgba(185, 185, 185, 1)',
- },
- position: 'right',
- axisLine: {
- show: false,
- },
- splitLine: {
- show: false,
- },
- axisTick: {
- show: false,
- },
- axisLabel: {
- show: true,
- formatter: '{value} %', //鍙充晶Y杞存枃瀛楁樉绀�
- formatter: (value, index) => {
- return value + (this.showpercent ? '%' : '')
- },
- textStyle: {
- color: 'rgba(185, 185, 185, 1)',
- },
- },
- },
],
series: [
@@ -171,40 +153,66 @@
{
name: this.chartData.lineName,
- type: 'line',
- // smooth: true,
- yAxisIndex: 1, //浣跨敤鐨� y 杞寸殑 index锛屽湪鍗曚釜鍥捐〃瀹炰緥涓瓨鍦ㄥ涓� y杞寸殑鏃跺�欐湁鐢�
-
- symbol: 'emptycircle', //鏍囪鐨勫浘褰负瀹炲績鍦�
- symbolSize: 0, //鏍囪鐨勫ぇ灏�
- areaStyle: {
+ type: 'bar',
+ barWidth: '12px',
+ itemStyle: {
normal: {
- color: {
- type: 'linear',
- x: 0,
- y: 0,
- x2: 0,
- y2: 1,
- colorStops: [
- {
- offset: 0,
- color: 'rgba(87, 147, 67, .5)', // 0% 澶勭殑棰滆壊
- },
- {
- offset: 1,
- color: 'rgba(87, 147, 67, 0.1)', // 100% 澶勭殑棰滆壊
- },
- ],
- global: false, // 缂虹渷涓� false
- },
+ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+ {
+ offset: 0,
+ color: '#16B777',
+ },
+ {
+ offset: 1,
+ color: '#0D6E4A',
+ },
+ ]),
},
},
- itemStyle: {
- color: 'rgba(65, 197, 95, 1)',
- },
-
data: this.chartData.lineData,
},
+
+ {
+ name: this.chartData.barName2,
+ type: 'bar',
+ barWidth: '12px',
+ itemStyle: {
+ normal: {
+ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+ {
+ offset: 0,
+ color: '#FF6B6B',
+ },
+ {
+ offset: 1,
+ color: '#8B0000',
+ },
+ ]),
+ },
+ },
+ data: this.chartData.barData2,
+ },
+
+ {
+ name: this.chartData.lineName2,
+ type: 'bar',
+ barWidth: '12px',
+ itemStyle: {
+ normal: {
+ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+ {
+ offset: 0,
+ color: '#FFD93D',
+ },
+ {
+ offset: 1,
+ color: '#B8860B',
+ },
+ ]),
+ },
+ },
+ data: this.chartData.lineData2,
+ },
],
}
option && this.chartEntity.setOption(option, true)
diff --git a/src/views/dataAnalysis/components/DataReMechanism.vue b/src/views/dataAnalysis/components/DataReMechanism.vue
index 5699ab4..bd9fe1e 100644
--- a/src/views/dataAnalysis/components/DataReMechanism.vue
+++ b/src/views/dataAnalysis/components/DataReMechanism.vue
@@ -28,7 +28,7 @@
<a-range-picker style="width: 300px; margin: 0 12px" v-if="isContrast" @change="contrastTimeChange" />
</div>
<div class="fueling-overview-block">
- <div class="fueling-overview-item">
+ <div class="fueling-overview-item" id="traffic-flow-card">
<div class="fueling-overview-name">杞︽祦閲�</div>
<div class="fueling-overview-num">
<span style="margin-right: 24px">{{ statisTotalObj.carCount }}</span>
@@ -42,7 +42,7 @@
<span style="color: #16b777" v-if="isContrast">{{ contrastObj.appearCount }}</span>
</div>
</div>
- <div class="fueling-overview-item">
+ <div class="fueling-overview-item" id="oil-count-card">
<div class="fueling-overview-name">鍔犳补鏁�</div>
<div class="fueling-overview-num">
<span style="margin-right: 24px">{{ statisTotalObj.oilCount }}</span>
@@ -352,6 +352,20 @@
created() {
this.initData()
},
+ mounted() {
+ this.$nextTick(() => {
+ setTimeout(() => {
+ const scrollTarget = localStorage.getItem('scrollToTarget')
+ if (scrollTarget) {
+ const element = document.getElementById(scrollTarget)
+ if (element) {
+ element.scrollIntoView({ behavior: 'smooth', block: 'center' })
+ localStorage.removeItem('scrollToTarget')
+ }
+ }
+ }, 500)
+ })
+ },
}
</script>
<style scoped lang="less">
diff --git a/src/views/dataAnalysis/components/DepartLabel.vue b/src/views/dataAnalysis/components/DepartLabel.vue
new file mode 100644
index 0000000..eef25ac
--- /dev/null
+++ b/src/views/dataAnalysis/components/DepartLabel.vue
@@ -0,0 +1,500 @@
+<template>
+ <div class="depart-label-container">
+ <div class="table-page-search-wrapper">
+ <a-form layout="inline">
+ <a-row :gutter="24">
+ <a-col :md="6" :sm="12">
+ <a-form-item label="鏍囩鍚嶇О">
+ <a-select v-model="queryParam.labelName" placeholder="璇烽�夋嫨鏍囩" allowClear @change="searchQuery">
+ <a-select-option value="">鍏ㄩ儴</a-select-option>
+ <a-select-option v-for="label in labelList" :key="label" :value="label">
+ {{ label }}
+ </a-select-option>
+ </a-select>
+ </a-form-item>
+ </a-col>
+ <a-col :md="6" :sm="12">
+ <a-button type="primary" @click="searchQuery" icon="search">鏌ヨ</a-button>
+ <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">閲嶇疆</a-button>
+ </a-col>
+ </a-row>
+ </a-form>
+ </div>
+
+ <div class="table-operator">
+ <div class="data-overview-ct">
+ <div class="block-title" style="display: flex; align-items: center">
+ <div style="margin-right: 12px">鏁版嵁瀵规瘮</div>
+ <a-switch v-model="isContrast" />
+ <a-range-picker
+ style="width: 300px; margin: 0 12px"
+ v-if="isContrast"
+ v-model="contrastTimeRange"
+ @change="contrastTimeChange"
+ :placeholder="['寮�濮嬫椂闂�', '缁撴潫鏃堕棿']"
+ />
+ </div>
+ </div>
+ </div>
+
+ <div class="chart-container" v-if="isContrast && lineChartData.xData && lineChartData.xData.length > 0">
+ <div class="chart-block">
+ <div class="block-title">鏁版嵁瀵规瘮鏌辩姸鍥�</div>
+ <DataReLineChart
+ ref="lineChart"
+ :chartData="lineChartData"
+ :showpercent="true"
+ :domId="'departLabelLineChart'"
+ ></DataReLineChart>
+ </div>
+ </div>
+
+ <a-table
+ :columns="columns"
+ :data-source="dataSource"
+ :pagination="pagination"
+ :loading="loading"
+ @change="handleTableChange"
+ :scroll="{ y: 350 }"
+ >
+ <span slot="action" slot-scope="text, record">
+ <a @click="handleAdd(record)" style="margin-right: 8px">娣诲姞鏍囩</a>
+ <a-dropdown>
+ <a-menu slot="overlay">
+ <a-menu-item v-for="label in getLabels(record)" :key="label" @click="() => handleMenuClick(record, label)">
+ 鍒犻櫎{{ label }}
+ </a-menu-item>
+ </a-menu>
+ <a slot="default">鍒犻櫎鏍囩</a>
+ </a-dropdown>
+ </span>
+ </a-table>
+
+ <DepartLabelModal
+ ref="modalForm"
+ @ok="modalFormOk"
+ :parentCode="queryParam.parentCode"
+ :parentId="queryParam.parentId"
+ ></DepartLabelModal>
+ </div>
+</template>
+
+<script>
+import { getAction, deleteAction, putAction, postAction } from '@tievd/cube-block/lib/api/manage'
+import DepartLabelModal from './DepartLabelModal'
+import DataReLineChart from './DataReLineChart'
+
+export default {
+ name: 'DepartLabel',
+ components: {
+ DepartLabelModal,
+ DataReLineChart
+ },
+ data() {
+ return {
+ queryParam: {
+ labelName: '',
+ parentCode: JSON.parse(localStorage.getItem("userDepartInfo")).orgCode,
+ parentId: JSON.parse(localStorage.getItem("userDepartInfo")).id
+ },
+ labelList: [],
+ dataSource: [],
+ loading: false,
+ isContrast: false,
+ statisTotalObj: {},
+ contrastObj: {},
+ contrastStartTime: '',
+ contrastEndTime: '',
+ contrastTimeRange: [],
+ lineChartData: {},
+ currentOrgData: [],
+ contrastOrgData: [],
+ pagination: {
+ current: 1,
+ pageSize: 10,
+ total: 0,
+ showSizeChanger: true,
+ showTotal: (total) => `鍏� ${total} 鏉
+ },
+ columns: [
+ {
+ title: '搴忓彿',
+ dataIndex: '',
+ key: 'rowIndex',
+ width: 60,
+ align: 'center',
+ customRender: function (text, record, index) {
+ return index + 1
+ }
+ },
+ {
+ title: '绔欑偣鍚嶇О',
+ align: 'center',
+ dataIndex: 'depart_name'
+ },
+ {
+ title: '绔欑偣缂栫爜',
+ align: 'center',
+ dataIndex: 'org_code'
+ },
+ {
+ title: '鏍囩鍚嶇О',
+ align: 'center',
+ dataIndex: 'label_name'
+ },
+ {
+ title: '鍒涘缓鏃堕棿',
+ align: 'center',
+ dataIndex: 'create_time',
+ customRender: function (text) {
+ if (!text) return ''
+ return text.replace('T', ' ')
+ }
+ },
+ {
+ title: '鎿嶄綔',
+ dataIndex: 'action',
+ align: 'center',
+ scopedSlots: { customRender: 'action' }
+ }
+ ],
+ url: {
+ list: '/jyz/departLabel/list',
+ listLabels: '/jyz/departLabel/listLabels',
+ listDeparts: '/jyz/custom/sys/depart/tables',
+ delete: '/jyz/departLabel/delete',
+ update: '/jyz/departLabel/update',
+ queryOrgOilCount: '/jyz/departLabel/queryOrgOilCount'
+ }
+ }
+ },
+ watch: {
+ isContrast(newVal) {
+ if (newVal) {
+ this.setDefaultMonthTime()
+ }
+ }
+ },
+ created() {
+ this.loadLabelList()
+ this.loadData()
+ },
+ methods: {
+ loadLabelList() {
+ const params = {
+ parentCode: this.queryParam.parentCode,
+ parentId: this.queryParam.parentId
+ }
+ getAction(this.url.listLabels, params).then((res) => {
+ if (res.success) {
+ this.labelList = res.result
+ console.log('鏍囩鍒楄〃:', this.labelList)
+ } else {
+ console.error('鍔犺浇鏍囩鍒楄〃澶辫触:', res.message)
+ }
+ })
+ },
+ loadData() {
+ this.loading = true
+ const params = {
+ pageNo: this.pagination.current,
+ pageSize: this.pagination.pageSize,
+ labelName: this.queryParam.labelName,
+ parentCode: this.queryParam.parentCode,
+ parentId: this.queryParam.parentId
+ }
+
+ getAction(this.url.list, params).then((res) => {
+ if (res.success) {
+ this.dataSource = res.result.records || []
+ this.pagination.total = Number(res.result.total) || 0
+ this.getOrgData()
+ } else {
+ this.$message.error(res.message || '鏌ヨ澶辫触')
+ }
+ }).catch(() => {
+ this.$message.error('鏌ヨ澶辫触')
+ }).finally(() => {
+ this.loading = false
+ })
+ },
+ updateChartData() {
+ if (this.dataSource.length === 0) {
+ this.lineChartData = {}
+ return
+ }
+
+ console.log('updateChartData - dataSource:', this.dataSource)
+ console.log('updateChartData - currentOrgData:', this.currentOrgData)
+ console.log('updateChartData - contrastOrgData:', this.contrastOrgData)
+
+ const xData = this.dataSource.map(item => item.depart_name)
+
+ const currentCarData = this.dataSource.map(item => {
+ const orgData = this.currentOrgData.find(d => d.org_code === item.org_code)
+ console.log(`Matching ${item.org_code}:`, orgData)
+ return orgData ? (orgData.carCount || 0) : 0
+ })
+
+ const currentOilData = this.dataSource.map(item => {
+ const orgData = this.currentOrgData.find(d => d.org_code === item.org_code)
+ return orgData ? (orgData.oilCount || 0) : 0
+ })
+
+ const currentStationData = this.dataSource.map(item => {
+ const orgData = this.currentOrgData.find(d => d.org_code === item.org_code)
+ return orgData ? (orgData.stationCount || 0) : 0
+ })
+
+ const currentVolumeData = this.dataSource.map(item => {
+ const orgData = this.currentOrgData.find(d => d.org_code === item.org_code)
+ return orgData ? (orgData.oilVolume || 0) : 0
+ })
+
+ console.log('Final data - xData:', xData)
+ console.log('Final data - currentCarData:', currentCarData)
+ console.log('Final data - currentOilData:', currentOilData)
+ console.log('Final data - currentStationData:', currentStationData)
+ console.log('Final data - currentVolumeData:', currentVolumeData)
+
+ this.lineChartData = {
+ xData: xData,
+ barData: currentCarData,
+ lineData: currentOilData,
+ barName: '杞︽祦閲�',
+ lineName: '鍔犳补鏁�',
+ barData2: currentStationData,
+ lineData2: currentVolumeData,
+ barName2: '杩涚珯鏁�',
+ lineName2: '娌瑰搧閿�閲�'
+ }
+
+ this.$nextTick(() => {
+ if (this.$refs.lineChart && this.$refs.lineChart.setChart) {
+ this.$refs.lineChart.setChart()
+ }
+ })
+ },
+ contrastTimeChange(e, t) {
+ this.contrastStartTime = t[0]
+ this.contrastEndTime = t[1]
+ this.getContrastData()
+ },
+ setDefaultMonthTime() {
+ const now = new Date()
+ const year = now.getFullYear()
+ const month = now.getMonth() + 1
+ const day = now.getDate()
+
+ const startTime = `${year}-${String(month).padStart(2, '0')}-01 00:00:00`
+ const endTime = `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')} 23:59:59`
+
+ this.contrastStartTime = startTime
+ this.contrastEndTime = endTime
+
+ this.getContrastData()
+ },
+ getOrgData() {
+ postAction(this.url.queryOrgOilCount, {
+ orgCode: this.queryParam.parentCode
+ }).then((res) => {
+ if (res.success) {
+ console.log('getOrgData result:', res.result)
+ this.currentOrgData = res.result || []
+ this.updateChartData()
+ }
+ })
+ },
+ getContrastData() {
+ postAction(this.url.queryOrgOilCount, {
+ orgCode: this.queryParam.parentCode,
+ startTime: this.contrastStartTime,
+ endTime: this.contrastEndTime
+ }).then((res) => {
+ if (res.success) {
+ console.log('getContrastData result:', res.result)
+ this.contrastOrgData = res.result || []
+ this.updateChartData()
+ }
+ })
+ },
+ searchQuery() {
+ this.pagination.current = 1
+ this.loadData()
+ },
+ searchReset() {
+ this.queryParam.labelName = ''
+ this.pagination.current = 1
+ this.loadData()
+ },
+ handleTableChange(pagination) {
+ this.pagination = pagination
+ this.loadData()
+ },
+ handleAdd(record) {
+ this.$refs.modalForm.add(record)
+ },
+ handleDelete(record) {
+ this.$confirm({
+ title: '纭鍒犻櫎',
+ content: '纭畾瑕佸垹闄よ鏍囩鍚楋紵',
+ onOk: () => {
+ deleteAction(this.url.delete, {
+ departId: record.depart_id,
+ labelName: record.label_name
+ }).then((res) => {
+ if (res.success) {
+ this.$message.success('鍒犻櫎鎴愬姛')
+ this.loadData()
+ this.loadLabelList()
+ } else {
+ this.$message.error(res.message || '鍒犻櫎澶辫触')
+ }
+ })
+ }
+ })
+ },
+ modalFormOk() {
+ this.loadData()
+ this.loadLabelList()
+ },
+ getLabels(record) {
+ if (!record.label_name) return []
+ return record.label_name.split(',').map(label => label.trim()).filter(label => label)
+ },
+ handleMenuClick(record, label) {
+ this.$confirm({
+ title: '纭鍒犻櫎',
+ content: `纭畾瑕佸垹闄�"${label}"鏍囩鍚楋紵`,
+ onOk: () => {
+ deleteAction(this.url.delete, {
+ departId: record.depart_id,
+ labelName: label
+ }).then((res) => {
+ if (res.success) {
+ this.$message.success('鍒犻櫎鎴愬姛')
+ this.loadData()
+ this.loadLabelList()
+ } else {
+ this.$message.error(res.message || '鍒犻櫎澶辫触')
+ }
+ })
+ }
+ })
+ }
+ }
+}
+</script>
+
+<style scoped lang="less">
+.depart-label-container {
+ padding: 24px;
+ background: linear-gradient(135deg, #1a1f2e 0%, #0f1219 100%);
+ min-height: 100vh;
+}
+
+.table-page-search-wrapper {
+ margin-bottom: 24px;
+ padding: 20px;
+ background: rgba(255, 255, 255, 0.05);
+ border-radius: 12px;
+ border: 1px solid rgba(255, 255, 255, 0.1);
+ backdrop-filter: blur(10px);
+}
+
+.table-operator {
+ margin-bottom: 24px;
+ padding: 20px;
+ background: rgba(255, 255, 255, 0.05);
+ border-radius: 12px;
+ border: 1px solid rgba(255, 255, 255, 0.1);
+ backdrop-filter: blur(10px);
+}
+
+.data-overview-ct {
+ .block-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #fff;
+ display: flex;
+ align-items: center;
+ }
+}
+
+.chart-container {
+ margin: 24px 0;
+ padding: 24px;
+ background: rgba(255, 255, 255, 0.05);
+ border-radius: 12px;
+ border: 1px solid rgba(255, 255, 255, 0.1);
+ backdrop-filter: blur(10px);
+
+ .chart-block {
+ width: 100%;
+
+ .block-title {
+ font-size: 18px;
+ font-weight: 600;
+ margin-bottom: 20px;
+ color: #fff;
+ padding-bottom: 12px;
+ border-bottom: 2px solid rgba(91, 129, 249, 0.5);
+ }
+ }
+}
+
+:deep(.ant-table) {
+ background: rgba(255, 255, 255, 0.05);
+ border-radius: 12px;
+ border: 1px solid rgba(255, 255, 255, 0.1);
+
+ .ant-table-thead > tr > th {
+ background: rgba(91, 129, 249, 0.2);
+ color: #fff;
+ font-weight: 600;
+ border-bottom: 2px solid rgba(91, 129, 249, 0.5);
+ }
+
+ .ant-table-tbody > tr > td {
+ background: transparent;
+ color: rgba(255, 255, 255, 0.85);
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
+ }
+
+ .ant-table-tbody > tr:hover > td {
+ background: rgba(91, 129, 249, 0.1);
+ }
+}
+
+:deep(.ant-btn-primary) {
+ background: linear-gradient(135deg, #5b81f9 0%, #3d5cc9 100%);
+ border: none;
+ box-shadow: 0 4px 12px rgba(91, 129, 249, 0.3);
+
+ &:hover {
+ background: linear-gradient(135deg, #6d92ff 0%, #4d6ee0 100%);
+ box-shadow: 0 6px 16px rgba(91, 129, 249, 0.4);
+ }
+}
+
+:deep(.ant-select) {
+ background: rgba(255, 255, 255, 0.05);
+ border: 1px solid rgba(255, 255, 255, 0.2);
+ border-radius: 8px;
+
+ .ant-select-selection {
+ background: transparent;
+ border: none;
+ color: rgba(255, 255, 255, 0.85);
+ }
+}
+
+:deep(.ant-form-item-label > label) {
+ color: rgba(255, 255, 255, 0.85);
+ font-weight: 500;
+}
+
+:deep(.a-switch) {
+ background: rgba(91, 129, 249, 0.3);
+}
+</style>
\ No newline at end of file
diff --git a/src/views/dataAnalysis/components/DepartLabelModal.vue b/src/views/dataAnalysis/components/DepartLabelModal.vue
new file mode 100644
index 0000000..d9bc380
--- /dev/null
+++ b/src/views/dataAnalysis/components/DepartLabelModal.vue
@@ -0,0 +1,132 @@
+<template>
+ <a-modal
+ :title="title"
+ :width="600"
+ :visible="visible"
+ :confirmLoading="confirmLoading"
+ @ok="handleOk"
+ @cancel="handleCancel"
+ cancelText="鍏抽棴"
+ >
+ <a-spin :spinning="confirmLoading">
+ <a-form :form="form">
+ <a-form-item
+ :labelCol="labelCol"
+ :wrapperCol="wrapperCol"
+ label="鏍囩鍚嶇О"
+ hasFeedback
+ >
+ <a-select
+ v-decorator="['labelName', { rules: [{ required: true, message: '璇烽�夋嫨鏍囩鍚嶇О' }] }]"
+ placeholder="璇烽�夋嫨鏍囩鍚嶇О"
+ >
+ <a-select-option v-for="label in labelList" :key="label" :value="label">
+ {{ label }}
+ </a-select-option>
+ </a-select>
+ </a-form-item>
+ </a-form>
+ </a-spin>
+ </a-modal>
+</template>
+
+<script>
+import { postAction, getAction } from '@tievd/cube-block/lib/api/manage'
+
+export default {
+ name: 'DepartLabelModal',
+ props: {
+ parentCode: {
+ type: String,
+ default: ''
+ },
+ parentId: {
+ type: String,
+ default: ''
+ }
+ },
+ data() {
+ return {
+ title: '娣诲姞鏍囩',
+ visible: false,
+ confirmLoading: false,
+ labelCol: {
+ xs: { span: 24 },
+ sm: { span: 5 }
+ },
+ wrapperCol: {
+ xs: { span: 24 },
+ sm: { span: 16 }
+ },
+ form: this.$form.createForm(this),
+ url: {
+ add: '/jyz/departLabel/add',
+ listLabels: '/jyz/departLabel/listLabels'
+ },
+ labelList: [],
+ currentDepartId: null
+ }
+ },
+ created() {
+ this.loadLabelList()
+ },
+ watch: {
+ parentCode() {
+ this.loadLabelList()
+ },
+ parentId() {
+ this.loadLabelList()
+ }
+ },
+ methods: {
+ loadLabelList() {
+ const params = {}
+ if (this.parentCode) {
+ params.parentCode = this.parentCode
+ }
+ if (this.parentId) {
+ params.parentId = this.parentId
+ }
+ getAction(this.url.listLabels, params).then((res) => {
+ if (res.success) {
+ this.labelList = res.result
+ }
+ })
+ },
+ add(record) {
+ this.form.resetFields()
+ this.currentDepartId = record.depart_id
+ this.visible = true
+ },
+ handleOk() {
+ const that = this
+ this.form.validateFields((err, values) => {
+ if (!err) {
+ that.confirmLoading = true
+ const params = {
+ departId: that.currentDepartId,
+ labelName: values.labelName
+ }
+ postAction(that.url.add, params).then((res) => {
+ if (res.success) {
+ that.$message.success('娣诲姞鎴愬姛')
+ that.$emit('ok')
+ that.visible = false
+ } else {
+ that.$message.error(res.message || '娣诲姞澶辫触')
+ }
+ }).finally(() => {
+ that.confirmLoading = false
+ })
+ }
+ })
+ },
+ handleCancel() {
+ this.visible = false
+ }
+ }
+}
+</script>
+
+<style scoped>
+</style>
\ No newline at end of file
diff --git a/src/views/user/Login.vue b/src/views/user/Login.vue
index 022bf85..62db8d4 100644
--- a/src/views/user/Login.vue
+++ b/src/views/user/Login.vue
@@ -283,7 +283,7 @@
})
},
loginSuccess() {
- this.$router.push({path: '/dashboard/analysis'}).catch(() => {
+ this.$router.push({path: '/analysisScreen/operationBigdata'}).catch(() => {
console.log('鐧诲綍璺宠浆棣栭〉鍑洪敊,杩欎釜閿欒浠庡摢閲屾潵鐨�')
})
this.$notification.success({
--
Gitblit v1.8.0