合并冲突

This commit is contained in:
zhoumengru
2025-09-12 16:37:27 +08:00
36 changed files with 734 additions and 870 deletions

View File

@@ -163,8 +163,6 @@ onMounted(async () => {
data.realTableData = [...props.tableData]
await nextTick()
// console.log(props.tableH, 'props.tableH');
console.log(comtable.value.offsetHeight,'comtable.value.offsetHeight');
scroll.value = { y: comtable.value.offsetHeight - 56 }
@@ -387,11 +385,15 @@ defineExpose({ ...toRefs(data), loading, mountedScroll, scroll: data.scroll })
background: #082e4a !important;
}
:deep(.ant-table.ant-table-has-fix-left.ant-table-middle.ant-table-bordered){
border-radius: 20px !important;
}
:deep(.ant-table-body) {
color:#fff;
background: $table-bg !important;
border: 1px solid $table-border;
border-radius: 0px 0px 20px 20px;
// border: 1px solid $table-border;
border-radius: 20px!important;
.ant-table-cell {
background: var(--theme-bg) !important;
}
@@ -424,6 +426,8 @@ defineExpose({ ...toRefs(data), loading, mountedScroll, scroll: data.scroll })
}
:deep(.ant-table-wrapper .ant-table) {
border: 1px solid $table-border!important;
background-color: transparent !important;
}

View File

@@ -455,7 +455,6 @@ function confirm() {
resolve(true)
})
.catch((error) => {
console.log('error', error)
resolve(false)
})
}

View File

@@ -8,6 +8,24 @@
:ref="'detailInfo' + index"
:disabled="disabled"
>
<template #work_mode="item">
<a-select
:dropdown-match-select-width="false"
v-model:value="workModeIdSelect"
:placeholder="'请选择' + item.label"
:disabled="disabled"
allow-clear
>
<a-select-option
:value="selectItem.value"
v-for="selectItem in workModeList"
:key="selectItem.value"
>
{{ selectItem.label }}
</a-select-option>
</a-select>
</template>
<template #role_id="item">
<a-select
@@ -110,6 +128,31 @@ export default {
data() {
return {
workModeIdSelect: undefined,
workModeList: [
{
label: '峰谷套利',
value: '1'
},
{
label: '增网配容',
value: '2'
},
{
label: '应急供电',
value: '3'
},
{
label: '并网保电',
value: '4'
},
{
label: '自定时段',
value: '5'
}
],
tip: '正在加载...',
roleIdList: [],
transferDialog: false,
@@ -132,6 +175,27 @@ export default {
},
computed: {},
watch: {
workModeIdSelect: {
handler(n) {
switch (n) {
case '1':
this.detailInfos[0].list[this.detailInfos[0].list.length-1].type='select'
break;
case '5':
this.detailInfos[0].list[this.detailInfos[0].list.length-1].type='select'
break;
default:
this.detailInfos[0].list[this.detailInfos[0].list.length-1].type='unshow'
break;
}
},
// immediate: true
},
action: {
handler(n) {
if (n === 'read') {
@@ -155,7 +219,6 @@ export default {
// this.formRules = menuFormRules
break
case 'permission':
break
case 'role':
@@ -166,6 +229,7 @@ export default {
case 'station':
this.detailInfos = stationOptions
this.formRules = stationFormRules
this.workModeIdSelect=this.detailInfos[0].ruleForm['work_mode']
break
case 'device':
@@ -312,26 +376,11 @@ export default {
add: '/insertRole',
edit: '/updateRole'
}
const { selectedRowKeys ,selectedArr} = this.$refs.treeTable[0]
console.log(selectedRowKeys,selectedArr, 'selectedRowKeys')
// const arr = selectedArr.map((item) => ({
// ...item,
const { selectedRowKeys } = this.$refs.treeTable[0]
// // 转换操作权限为布尔值
// ...this.getPerOperBoolean(item),
// // 递归处理children
// children: item.children
// ? item.children.map((child) => ({
// ...child,
// ...this.getPerOperBoolean(child),
// }))
// : []
// }))
// console.log(arr,"arr")
const data=this.filterTreeData(selectedRowKeys,this.$refs.treeTable[0].tableData)
const arr = data.map((item) => ({
const data = this.filterTreeData(selectedRowKeys, this.$refs.treeTable[0].tableData)
const arr = data.map((item) => ({
...item,
// 转换操作权限为布尔值
@@ -340,14 +389,13 @@ export default {
children: item.children
? item.children.map((child) => ({
...child,
...this.getPerOperBoolean(child),
...this.getPerOperBoolean(child)
}))
: []
}))
const paramsDate = {
...this.form,
permission:arr
permission: arr
}
if (this.action == 'edit') {
@@ -368,61 +416,57 @@ export default {
},
// 定义筛选树形数据的函数
filterTreeData(list1, list2) {
const keySet = new Set(list1);
const keySet = new Set(list1)
// 递归处理节点的函数
const filterNode = (node) => {
// 创建新节点对象(浅拷贝)
const newNode = Object.assign({}, node);
const newNode = Object.assign({}, node)
// 临时删除children属性以便处理
const { children, ...rest } = newNode;
const { children, ...rest } = newNode
// 处理子节点
let newChildren = [];
let newChildren = []
if (children) {
newChildren = children
.map((child) => filterNode(child))
.filter((child) => child !== null);
newChildren = children.map((child) => filterNode(child)).filter((child) => child !== null)
}
// 重建新节点
const resultNode = Object.assign(rest, {});
const resultNode = Object.assign(rest, {})
if (newChildren.length > 0) {
resultNode.children = newChildren;
resultNode.children = newChildren
}
// 判断是否保留节点
if (keySet.has(node.key)) {
return resultNode;
return resultNode
}
// 保留有符合条件子节点的父节点移除自身key
if (newChildren.length > 0) {
return resultNode;
return resultNode
}
return null;
};
return null
}
// 处理根节点
const result = list2
.map((node) => filterNode(node))
.filter((node) => node !== null);
const result = list2.map((node) => filterNode(node)).filter((node) => node !== null)
return result;
return result
},
getPerOperBoolean(data) {
return {
is_add: Boolean(data.is_add)? '1' : '0',
is_del: Boolean(data.is_del)? '1' : '0',
is_edit: Boolean(data.is_edit)? '1' : '0',
is_view: Boolean(data.is_view)? '1' : '0'
is_add: Boolean(data.is_add) ? '1' : '0',
is_del: Boolean(data.is_del) ? '1' : '0',
is_edit: Boolean(data.is_edit) ? '1' : '0',
is_view: Boolean(data.is_view) ? '1' : '0'
}
},
getPermissionData(keys,list){
const arr=[]
getPermissionData(keys, list) {
const arr = []
// list.forEach(item=>{
// if(keys.include(item.key)){
// arr.push(item)

View File

@@ -141,7 +141,7 @@ export default {
}
},
legend: {
top: 20,
top: 10,
textStyle: {
color: '#fff'
}
@@ -150,7 +150,8 @@ export default {
left: '3%',
right: '4%',
bottom: '5%',
containLabel: true
top: '32%',
// containLabel: true
},
xAxis: {
type: 'category',
@@ -192,44 +193,4 @@ export default {
}
}
.text_Cur {
border-bottom: 1px solid transparent;
border-top: 1px solid transparent;
border-image: linear-gradient(to right, transparent, #1d8a7b, transparent) 1;
padding: 0px 15px;
font-size: 14px;
margin: 3px 0px;
height: 45px;
display: flex;
justify-content: space-between;
align-items: center;
.mark {
font-size: 16px;
margin-right: 2px;
}
& > div:nth-child(2),
& > div:nth-child(3) {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
& > div:last-child{
display: flex;
flex-direction: column;
justify-content: center;
align-items: end;
}
background: linear-gradient(
90deg,
rgba(0, 186, 173, 0.15) 0%,
rgba(61, 254, 250, 0.15) 49.2%,
rgba(61, 254, 250, 0) 100%
);
.d {
margin-left: 1px;
font-size: 12px;
}
}
</style>

View File

@@ -154,6 +154,8 @@ export default {
},
drawLineChart(activeKey) {
console.log(this.$refs.charge)
// const labelCount = Math.floor(500 / 30);
this.getChargeData(activeKey)
if(this.chargeChart){
this.chargeChart.dispose()
@@ -170,7 +172,7 @@ export default {
}
},
legend: {
top: 20,
top: 10,
textStyle: {
color: '#fff'
}
@@ -178,8 +180,9 @@ export default {
grid: {
left: '3%',
right: '4%',
bottom: '5%',
containLabel: true
bottom: '1%',
top: '32%',
// containLabel: true
},
xAxis: {
type: 'category',
@@ -197,10 +200,11 @@ export default {
lineStyle: { type: 'dashed', color: '#435463' }
},
axisLabel: {
interval: 4,
// margin: 10,
// interval: 60,
color: '#fff',
fontSize:12
fontSize:12,
// padding: [5, 0, 0, 0]
}
},
series: this.chargeChartData.ydata
@@ -226,37 +230,5 @@ export default {
}
}
.text_Cur {
border-bottom: 1px solid transparent;
border-top: 1px solid transparent;
border-image: linear-gradient(to right, transparent, #1d8a7b, transparent) 1;
padding: 0px 15px;
font-size: 14px;
margin: 3px 0px;
height: 45px;
display: flex;
justify-content: space-between;
align-items: center;
& > div:last-child {
display: flex;
flex-direction: column;
justify-content: center;
align-items: end;
}
.mark {
font-size: 16px;
margin-right: 2px;
}
background: linear-gradient(
90deg,
rgba(0, 186, 173, 0.15) 0%,
rgba(61, 254, 250, 0.15) 49.2%,
rgba(61, 254, 250, 0) 100%
);
.d {
margin-left: 1px;
font-size: 12px;
}
}
</style>

View File

@@ -105,7 +105,7 @@ export default {
this.energyChartData.ydata[index] = {
name: item.name,
smooth: true,
type: 'bar',
type: 'line',
barWidth: 5,
itemStyle: {
borderRadius: [5, 5, 0, 0],
@@ -147,7 +147,8 @@ export default {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
top: '32%',
// containLabel: true
},
xAxis: {
type: 'category',
@@ -165,7 +166,7 @@ export default {
lineStyle: { type: 'dashed', color: '#435463' }
},
axisLabel: {
interval: 4,
// interval: 4,
color: '#fff',
fontSize:12
@@ -193,37 +194,4 @@ export default {
}
}
.text_Cur {
border-bottom: 1px solid transparent;
border-top: 1px solid transparent;
border-image: linear-gradient(to right, transparent, #1d8a7b, transparent) 1;
padding: 0px 15px;
font-size: 14px;
margin: 3px 0px;
height: 45px;
display: flex;
justify-content: space-between;
align-items: center;
& > div:last-child {
display: flex;
flex-direction: column;
justify-content: center;
align-items: end;
}
.mark {
font-size: 16px;
margin-right: 2px;
}
background: linear-gradient(
90deg,
rgba(0, 186, 173, 0.15) 0%,
rgba(61, 254, 250, 0.15) 49.2%,
rgba(61, 254, 250, 0) 100%
);
.d {
margin-left: 1px;
font-size: 12px;
}
}
</style>

View File

@@ -57,7 +57,7 @@ export default {
data() {
return {
center: [116.404, 39.915], // 默认中心点(北京
center: [112.870000,34.180000], // 默认中心点(河南
zoom: 12,
map: null,
currentMarker: {},
@@ -72,12 +72,19 @@ export default {
}
},
mounted() {
this.initMap()
this.$nextTick(()=>{
this.initMap()
})
},
beforeUnmount() {
if(this.map){
// this.map.destory()
this.map=null
}
},
methods: {
init(map) {
this.map = map
this.center= [110.404, 40.915]
this.getMarkList()
},
async getMarkList() {
@@ -114,33 +121,27 @@ export default {
// 备用定位方案
// setFallbackLocation() {
// const fallbackCoords = [116.404, 39.915] // 北京坐标
// this.center = fallbackCoords
// if (this.map) {
// this.map.setCenter(new T.LngLat(...fallbackCoords))
// }
// },
async getSysConfig() {
let sysConfig
try {
const query = {}
const res = await getReq('/', query)
if (res.errcode === 0) {
sysConfig = res.data.value
} else {
throw res
}
} catch (error) {
sysConfig = this.targetKey
}
let sysConfig=this.targetKey
// try {
// const query = {}
// const res = await getReq('/', query)
// if (res.errcode === 0) {
// sysConfig = res.data.value
// } else {
// throw res
// }
// } catch (error) {
// sysConfig = this.targetKey
// }
return sysConfig
},
async clickArrayMarker(currentVal) {
this.changeStationId = currentVal.station_id
this.testVal.name=currentVal.name
this.showCtrModal = true
}
}

View File

@@ -58,7 +58,7 @@ export default {
propsInfo: {
cabId: '',
stationId: '',
stationName: '场站111'
station_name: '场站111'
},
showCtrModal: false,
mapStyle: {

View File

@@ -165,37 +165,4 @@ export default {
}
}
.text_Cur {
border-bottom: 1px solid transparent;
border-top: 1px solid transparent;
border-image: linear-gradient(to right, transparent, #1d8a7b, transparent) 1;
padding: 0px 15px;
font-size: 14px;
margin: 3px 0px;
height: 45px;
display: flex;
justify-content: space-between;
align-items: center;
& > div:last-child {
display: flex;
flex-direction: column;
justify-content: center;
align-items: end;
}
.mark {
font-size: 16px;
margin-right: 2px;
}
background: linear-gradient(
90deg,
rgba(0, 186, 173, 0.15) 0%,
rgba(61, 254, 250, 0.15) 49.2%,
rgba(61, 254, 250, 0) 100%
);
.d {
margin-left: 1px;
font-size: 12px;
}
}
</style>

View File

@@ -1,5 +1,5 @@
<template>
<div class="onLine">
<div class="env">
<div class="content">
<div v-for="item in list" :key="item.key" :class="`item ${item.class}`">
<i
@@ -96,18 +96,14 @@ export default {
handler(newVal, oldVal) {
if (newVal !== oldVal) {
this.list.forEach((item) => {
console.log(this.propsTotal,this.propsTotal[item.key],"this.propsTotal[item.key]")
if (item.key == 'coolingStatus') {
console.log(this.coolingList.find(
(e) => e.value == this.propsTotal[item.key]
))
item.value = this.coolingList.find(
(e) => e.value == this.propsTotal[item.key]
).label
).label ||'关机'
} else if (item.key == 'aircStatus') {
item.value = this.aircList.map(
(e) => e.value == this.propsTotal[item.key]
).label
)[0].label||'关机'
} else {
item.value = this.propsTotal[item.key]
}
@@ -122,7 +118,7 @@ export default {
</script>
<style lang="scss" scoped>
.onLine {
.env {
height: calc(100% - 45px);
display: flex;
justify-content: center;

View File

@@ -1,5 +1,5 @@
<template>
<div class="onLine">
<div class="operationlInfo">
<div class="content">
<div v-for="item in list" :key="item.key" :class="`item ${item.class}`">
<a-image :preview="false" :src="item.iconPath" :width="50" class="left"> </a-image>
@@ -101,7 +101,7 @@ export default {
</script>
<style lang="scss" scoped>
.onLine {
.operationlInfo {
height: calc(100% - 45px);
display: flex;
justify-content: center;
@@ -112,7 +112,7 @@ export default {
.content {
flex-wrap: wrap;
width: 100%;
width: 90%;
display: flex;
align-items: center;
justify-content: space-around;
@@ -120,7 +120,7 @@ export default {
.item {
height: 50%;
width: 30%;
width: 45%;
// height: 47px;
box-sizing: border-box;
display: flex;

View File

@@ -1,5 +1,5 @@
<template>
<div class="onLine">
<div class="prefabCabin">
<div class="content-left">
<div v-for="item in leftList" :key="item.key" :class="`item ${item.class}`">
<div>
@@ -10,7 +10,7 @@
</div>
</div>
<div style="text-align: center; font-weight: 500">
<div class="online-icon"></div>
<div class="prefabCabin-icon"></div>
<span>{{ curStatus }}</span>
</div>
@@ -108,7 +108,7 @@ export default {
key: 'power_rated',
value: 100,
d: 'Kw',
label: 'PCS额定功率',
label: '额定功率',
class: 'item-6'
}
]
@@ -146,7 +146,7 @@ export default {
</script>
<style lang="scss" scoped>
.onLine {
.prefabCabin {
height: calc(100% - 45px);
display: flex;
justify-content: center;
@@ -198,7 +198,7 @@ export default {
width: 120px;
}
.online-icon {
.prefabCabin-icon {
width: 110px;
height: 130px;
background-image: url('@/assets/home/perIcon.png');

View File

@@ -179,37 +179,4 @@ export default {
}
}
.text_Cur {
border-bottom: 1px solid transparent;
border-top: 1px solid transparent;
border-image: linear-gradient(to right, transparent, #1d8a7b, transparent) 1;
padding: 0px 15px;
font-size: 14px;
margin: 3px 0px;
height: 45px;
display: flex;
justify-content: space-between;
align-items: center;
& > div:last-child{
display: flex;
flex-direction: column;
justify-content: center;
align-items: end;
}
.mark {
font-size: 16px;
margin-right: 2px;
}
background: linear-gradient(
90deg,
rgba(0, 186, 173, 0.15) 0%,
rgba(61, 254, 250, 0.15) 49.2%,
rgba(61, 254, 250, 0) 100%
);
.d{
margin-left: 1px;
font-size: 12px;
}
}
</style>

View File

@@ -32,7 +32,7 @@ export default {
key: 'runDays',
value: 26,
d: '天',
label: '场站运行天数',
label: '运行天数',
class: 'item-1',
iconPath: require('@/assets/home/wendu.png')
},
@@ -56,7 +56,7 @@ export default {
key: 'incomeTotal',
value: 26,
d: '元',
label: '场站累计收益',
label: '累计收益',
class: 'item-4',
iconPath: require('@/assets/home/dianliu.png')
},

View File

@@ -158,37 +158,4 @@ export default {
}
}
.text_Cur {
border-bottom: 1px solid transparent;
border-top: 1px solid transparent;
border-image: linear-gradient(to right, transparent, #1d8a7b, transparent) 1;
padding: 0px 15px;
font-size: 14px;
margin: 3px 0px;
height: 45px;
display: flex;
justify-content: space-between;
align-items: center;
& > div:last-child {
display: flex;
flex-direction: column;
justify-content: center;
align-items: end;
}
.mark {
font-size: 16px;
margin-right: 2px;
}
background: linear-gradient(
90deg,
rgba(0, 186, 173, 0.15) 0%,
rgba(61, 254, 250, 0.15) 49.2%,
rgba(61, 254, 250, 0) 100%
);
.d {
margin-left: 1px;
font-size: 12px;
}
}
</style>

View File

@@ -1,25 +1,17 @@
<template>
<div class="Operational">
<div class="oper-bg">{{ currentHoverNumber }}%</div>
<div class="oper-right">
<div v-for="item in curList" :key="item.key" class="oper-item" @mouseover="changeNumber(item)">
<div style="display: flex">
<div :style="`background:${item.lineColor}`" class="item-icon"></div>
<span class="item-name">{{ item.name }}</span>
</div>
<span class="item-value">{{ item.value?item.value:0 }}</span>
</div>
</div>
<div class="operational">
<div id="operational-chart"></div>
</div>
</template>
<script>
export default {
name: '',
props: {
total:{
type:Object,
default:()=>{}
total: {
type: Object,
default: () => {}
},
deviceInfo: {
type: Array,
@@ -28,89 +20,203 @@ export default {
},
data() {
return {
currentHoverNumber: 58,
curList: [
{
name: '收益',
key: 'incomeTotal',
key: 'income',
percentKey: 'connector_online_percent',
lineColor: 'linear-gradient(90deg, rgba(13, 87, 144, 1) 0%, rgba(21, 153, 253, 1) 100%);',
lineColor: '#00BAAD',
value: 0
},
{
name: '利用率',
key: 'usage_rate',
percentKey: 'connector_off_percent',
lineColor:
'linear-gradient(90deg, rgba(53, 120, 124, 1) 0%, rgba(102, 225, 223, 1) 100%);',
lineColor:'#0E68E4',
value: 0
}
]
],
operationalChart: null,
operationalChartData: {
ydata: [],
xdata: []
},
}
},
watch: {
total:{
handler(newVal,oldVal) {
if (newVal!==oldVal) {
let that=this
that.curList.forEach((item)=>{
item.value=that.total[item.key]
deviceInfo: {
handler(newVal, oldVal) {
if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
this.$nextTick(() => {
this.drawLineChart()
})
}
}
},
deep: true // 确保深度比较
}
},
mounted() {},
beforeUnmount() {
window.removeEventListener('resize', this.handleResize)
if (this.operationalChart) {
this.operationalChart.dispose()
this.operationalChart = null
}
},
methods: {
changeNumber(item) {
this.currentHoverNumber = item.percentValue? item.percentValue:0
processData(data, keys) {
data.sort((a, b) => {
return new Date(a.station_name) - new Date(b.station_name)
})
const dates = data.map((item) => item.station_name)
const values = []
keys.forEach((item, index) => {
values[index] = data.map((dataValue) => dataValue[keys[index]])
})
return {
dates,
values
}
},
handleResize() {
if (this.operationalChart) {
this.operationalChart.resize()
}
},
getChargeData() {
const arr = this.curList
const keyList = this.curList.map((item) => item.key)
const result = this.processData(this.deviceInfo, keyList)
this.operationalChartData.xdata = result.dates
arr.forEach((item, index) => {
this.operationalChartData.ydata[index] = {
name: item.name,
smooth: true,
type: 'bar',
barWidth: 5,
itemStyle: {
borderRadius: [5, 5, 0, 0],
color: item.lineColor
},
emphasis: {
focus: 'series'
},
yAxisIndex: index,
global: false,
showSymbol: false,
data: result.values[index]
}
})
},
drawLineChart(activeKey) {
this.getChargeData(activeKey)
if (this.operationalChart) {
this.operationalChart.dispose()
}
const chartDom = document.getElementById('operational-chart')
if (!chartDom) return
let operationalChart = this.$echarts.init(chartDom)
this.operationalChart = operationalChart
const option = {
tooltip: {
trigger: 'axis', // 触发类型:坐标轴触发
// position: function (pos, params, dom, rect, size) {
// // pos: 鼠标位置 [x, y]
// // size: 提示框大小 {viewSize: [width, height], contentSize: [width, height]}
// const x = pos[0] + 10; // 鼠标右侧10px
// const y = pos[1]; // 保持与鼠标同高
// return [x, y];
// }
},
legend: {
top: 10,
textStyle: {
color: '#fff'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '5%',
containLabel: true
},
xAxis: {
type: 'category',
data: this.operationalChartData.xdata,
axisLine: {
lineStyle: { type: 'dashed', color: '#435463' }
},
axisLabel: {
color:"#fff",
// interval:'auto', // 显示所有标签
fontSize: 12,
formatter: function(value) {
return value.length > 8 ? value.substring(0, 8) + '...' : value;
}
}
},
yAxis: [
{
name: '收益(元)',
type: 'value',
splitLine: {
lineStyle: { type: 'dashed', color: '#435463' }
},
nameTextStyle: {
color: '#fff' // 绿色名称
},
axisLabel: {
interval: 4,
color: '#fff',
fontSize:12
},
},
{
name: '利用率(%)',
type: 'value',
nameTextStyle: {
color: '#fff' // 绿色名称
},
splitLine: {
lineStyle: { type: 'dashed', color: '#435463' }
},
axisLabel: {
interval: 4,
color: '#fff',
fontSize:12
},
},
],
series: this.operationalChartData.ydata
}
option && operationalChart.setOption(option)
this.setupResizeListener()
},
setupResizeListener() {
window.removeEventListener('resize', this.handleResize)
window.addEventListener('resize', this.handleResize)
}
}
}
</script>
<style lang="scss" scoped>
.Operational {
display: flex;
justify-content: space-around;
align-items: center;
height: 100%;
.oper-bg {
font-size: 1vw;
display: flex;
justify-content: center;
align-items: center;
background: url('../../assets/home/operBg.png');
background-size: 100% 100%;
width: 9vw;
height: 9vw;
aspect-ratio: 1/1;
}
.oper-right {
font-size: 13px;
.oper-item {
height: 12%;
align-items: center;
color: #fff;
margin-bottom: 10px;
display: flex;
justify-content: space-between;
padding: 5px 15px;
background: url('../../assets/home/leg-bg.png');
background-size: 100% 100%;
.item-icon {
width: 10px;
height: 10px;
}
.item-name {
margin-left: 5px;
margin-right: 60px;
}
}
.operational {
height: calc(100% - 45px);
#operational-chart {
height: 100%;
}
}
</style>

View File

@@ -138,7 +138,7 @@ export default {
}
},
legend: {
top: 20,
top: 10,
textStyle: {
color: '#fff'
}
@@ -147,7 +147,8 @@ export default {
left: '3%',
right: '4%',
bottom: '5%',
containLabel: true
top: '32%',
// containLabel: true
},
xAxis: {
type: 'category',
@@ -165,7 +166,7 @@ export default {
lineStyle: { type: 'dashed', color: '#435463' }
},
axisLabel: {
interval: 4,
// interval: 4,
color: '#fff',
fontSize:12
@@ -193,37 +194,4 @@ export default {
}
}
.text_Cur {
border-bottom: 1px solid transparent;
border-top: 1px solid transparent;
border-image: linear-gradient(to right, transparent, #1d8a7b, transparent) 1;
padding: 0px 15px;
font-size: 14px;
margin: 3px 0px;
height: 45px;
display: flex;
justify-content: space-between;
align-items: center;
& > div:last-child {
display: flex;
flex-direction: column;
justify-content: center;
align-items: end;
}
.mark {
font-size: 16px;
margin-right: 2px;
}
background: linear-gradient(
90deg,
rgba(0, 186, 173, 0.15) 0%,
rgba(61, 254, 250, 0.15) 49.2%,
rgba(61, 254, 250, 0) 100%
);
.d {
margin-left: 1px;
font-size: 12px;
}
}
</style>

View File

@@ -28,7 +28,7 @@ export default {
props: {
infoKey: {
type: String,
default:''
default: ''
},
total: {
type: Object,
@@ -98,20 +98,18 @@ export default {
watch: {
total: {
handler(newVal,oldVal) {
if (newVal&&newVal!==oldVal) {
handler(newVal, oldVal) {
if (newVal && newVal !== oldVal) {
this.curList.forEach((item) => {
item.value = newVal[item.key] || 0;
});
item.value = newVal[item.key] || 0
})
}
},
immediate: true,
deep: true
}
},
mounted() {
console.log(this.total,'total')
},
mounted() {},
methods: {}
}
</script>
@@ -148,14 +146,13 @@ export default {
.content-left,
.content-right {
width: calc((100% - 110px) / 2);
// width: 40%;
width: 40%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
height: 100%;
.item{
.item {
align-items: flex-start;
justify-content: center;
}
@@ -172,7 +169,7 @@ export default {
}
.online-icon {
width: 110px;
width: 20%;
height: 130px;
background-image: url('@/assets/home/onLineIcon.png');
background-size: contain;

View File

@@ -333,7 +333,7 @@ input:-internal-autofill-selected {
justify-content: space-between;
align-items: center;
.button {
margin-left: 10px;
// margin-left: 10px;
}
}
}

View File

@@ -10,7 +10,8 @@
:row-class-name="(record, index) => rowClassName(record, index)"
row-key="key"
size="middle"
:row-selection="rowSelection"
:row-selection="newTableOpt.select
?rowSelection:null"
:indent-size="30"
:check-strictly="false"
@resizeColumn="handleResizeColumn"
@@ -100,6 +101,7 @@ export default {
},
computed: {
rowSelection() {
const { selectedRowKeys } = this
return {
checkStrictly: this.tableOption.checkStrictly,
@@ -152,7 +154,6 @@ export default {
this.selectedRowKeys = selectedRowKeys
this.selectedRows = selectedRows[selectedRows.length - 1]
this.selectedArr=selectedRows
console.log(selectedRowKeys, this.selectedArr ,"selectedRowKeys")
this.$emit('getSelectedIds', selectedRowKeys)
},
onSelect(record, selected) {
@@ -439,8 +440,13 @@ export default {
}
:deep(.ant-table-container > .ant-table-content > table) {
border-inline-start: 1px solid var(--theme-bg) !important;
}
:deep(.ant-table.ant-table-has-fix-left.ant-table-middle.ant-table-bordered){
border-radius: 20px !important;
}
:deep(.ant-pagination-item-link) {
color: var(--theme-text-default) !important;

View File

@@ -376,7 +376,6 @@ export default {
}
},
async openModal(item, val) {
console.log(item, '=============')
this.modalComponent = val
this.modalOpen = true
if (val == 1) {

View File

@@ -173,6 +173,7 @@ export default {
},
// 初始化柱状图
initBarCharts() {
this.chartOptions.forEach((option, index) => {
if (option.type === 'bar') {
const dom = this.$refs[`chartContainer${index}`]?.[0];

View File

@@ -1,7 +1,7 @@
import axios from 'axios'
import openNotification from '../utils/notification'
// import { message } from 'ant-design-vue'
import router from 'vue-router'
const service = axios.create({
baseURL: '/api',
timeout: 120000
@@ -17,13 +17,14 @@ service.interceptors.response.use(
const res = response.data
if (res.errCode !== 0) {
console.log(res, 'res')
if ((res.ERR_TOKEN = 2 || res.errmsg == '校验token过期')) {
setTimeout(() => {
// router.push({ path: '/login' })
}, 1000)
} else {
console.log(res.errmsg, 'res.errmsg')
message.error(res.errmsg)
// message.error(res.errmsg)
// openNotification({
// status: 'error',
// desc: res.tip

View File

@@ -13,41 +13,48 @@ export const routes = [
{
path: '/',
name: '/',
redirect: '/Home',
redirect: '/home',
meta: { requiresAuth: true },
component: () => import(/* webpackChunkName: "main" */ '@/views/MainView.vue'),
children: [
{
path: 'Home',
component: () => import(/* webpackChunkName: "monitor" */ '@/views/sub/Home.vue')
path: 'home',
component: () => import(/* webpackChunkName: "monitor" */ '@/views/sub/Home.vue'),
meta: { requiresAuth: true }
},
{
path: 'monitor',
name: 'monitor',
title: '运行监控',
meta: { requiresAuth: true },
component: () => import(/* webpackChunkName: "monitor" */ '@/views/monitor.vue')
},
{
path: 'predict',
name: 'predict',
title: '预测管理',
meta: { requiresAuth: true },
component: () => import(/* webpackChunkName: "predict" */ '@/views/predict.vue')
},
{
path: 'statisticalAnalysis',
name: 'statisticalAnalysis',
title: '统计分析',
meta: { requiresAuth: true },
component: () => import(/* webpackChunkName: "monitor" */ '@/views/statisticalAnalysis.vue')
},
{
path: 'system',
name: 'system',
redirect: '/system/user',
meta: { requiresAuth: true },
component: () => import(/* webpackChunkName: "system" */ '@/views/system/index.vue'),
children: [
{
path: 'user',
name: 'user',
title: '用户管理',
meta: { requiresAuth: true },
component: () => import(/* webpackChunkName: "system" */ '@/views/system/user.vue')
},
@@ -55,12 +62,14 @@ export const routes = [
name: 'role',
path: 'role',
title: '角色管理',
meta: { requiresAuth: true },
component: () => import(/* webpackChunkName: "system" */ '@/views/system/role.vue')
},
{
name: 'permission',
path: 'permission',
title: '权限管理',
meta: { requiresAuth: true },
component: () =>
import(/* webpackChunkName: "system" */ '@/views/system/permission.vue')
},
@@ -68,36 +77,42 @@ export const routes = [
name: 'station',
path: 'station',
title: '场站管理',
meta: { requiresAuth: true },
component: () => import(/* webpackChunkName: "system" */ '@/views/system/station.vue')
},
{
name: 'service',
path: 'service',
title: '服务管理',
meta: { requiresAuth: true },
component: () => import(/* webpackChunkName: "system" */ '@/views/system/service.vue')
},
{
path: 'policy',
name: 'policy',
title: '策略管理',
meta: { requiresAuth: true },
component: () => import(/* webpackChunkName: "system" */ '@/views/system/policy.vue')
},
{
name: 'device',
path: 'device',
title: '设备管理',
meta: { requiresAuth: true },
component: () => import(/* webpackChunkName: "system" */ '@/views/system/device.vue')
},
{
name: 'alarmlog',
path: 'alarmlog',
title: '告警日志',
meta: { requiresAuth: true },
component: () => import(/* webpackChunkName: "system" */ '@/views/system/alarmLog.vue')
},
{
name: 'syslog',
path: 'syslog',
title: '系统日志',
meta: { requiresAuth: true },
component: () => import(/* webpackChunkName: "system" */ '@/views/system/log.vue')
}
]
@@ -111,22 +126,26 @@ const router = createRouter({
routes
})
// 全局前置守卫
router.beforeEach((to, from, next) => {
console.log(to)
const token = localStorage.getItem('token') || ''
const isLoggedIn = localStorage.getItem('token') // 检查用户是否已登录
if (to.path == '/login') {
if (token && token != '') {
next('/')
// 2. 如果访问登录页且已登录,跳转到首页
if (to.path === '/login' && isLoggedIn) {
next('/')
return
}
// 3. 检查路由权限
if (to.matched.some((record) => record.meta.requiresAuth)) {
if (!isLoggedIn) {
// 未登录则重定向到登录页,并携带原路径
next('/login')
} else {
next()
}
} else {
if (token && token != '') {
next()
} else {
next('/login')
}
next() // 无需认证的路由直接放行
}
})

View File

@@ -18,8 +18,14 @@ $page-border: #cad2dd;
.ant-switch {
background: #b1c4c4;
}
.ant-switch.ant-switch-checked{
background: #00fffb
.ant-switch.ant-switch-checked {
background: #00fffb;
}
.ant-select .ant-select-arrow {
background: transparent !important;
}
.ant-select .ant-select-clear {
background: transparent !important;
}
.ant-switch .ant-switch-handle::before {
@@ -58,9 +64,8 @@ $page-border: #cad2dd;
.ant-picker-input input::placeholder {
color: #ffffff3b !important;
}
.ant-picker-suffix{
.ant-picker-suffix {
color: #ffffff !important;
}
}
.ant-input-affix-wrapper {
@@ -163,3 +168,38 @@ $page-border: #cad2dd;
color: #fff !important;
}
}
// 添加统一布局的样式
.text_Cur {
border-bottom: 1px solid transparent;
border-top: 1px solid transparent;
border-image: linear-gradient(to right, transparent, #1d8a7b, transparent) 1;
padding: 0px 15px;
font-size: 12px;
margin: 3px 0px;
height: 40px;
display: flex;
justify-content: space-between;
align-items: center;
& > div:last-child {
display: flex;
flex-direction: column;
justify-content: center;
align-items: end;
}
.mark {
font-size: 16px;
margin-right: 2px;
}
background: linear-gradient(
90deg,
rgba(0, 186, 173, 0.15) 0%,
rgba(61, 254, 250, 0.15) 49.2%,
rgba(61, 254, 250, 0) 100%
);
.d {
margin-left: 1px;
font-size: 12px;
}
}

View File

@@ -5,8 +5,6 @@ export function getRunDays(date) {
const timeDiff = today - launchDate // 毫秒差
const daysRun = Math.ceil(timeDiff / (1000 * 60 * 60 * 24)) // 转换为天数
console.log(`从 2023-01-01 到今天已经运行了 ${daysRun}`)
return daysRun
}
export function processData(data, keys) {

View File

@@ -76,7 +76,6 @@ export default {
const res = await getReq('/login',this.form )
this.loading = false
console.log(res);
if (res.errcode === 0) {
this.$message.success('登录成功')
@@ -91,7 +90,6 @@ export default {
// this.$message.error(res.message || '登录失败')
// }
} catch (error) {
console.log(error);
this.loading = false
this.$message.error('请求失败,请稍后重试')

View File

@@ -75,7 +75,6 @@ export default {
$route: {
immediate: true,
handler(to) {
console.log(this.dynamicMenuList, 'this.dynamicMenuList')
// // 更新当前激活的菜单项
// // this.currentKey = to.matched[0]?.path || ''
this.menuList = this.dynamicMenuList
@@ -147,7 +146,6 @@ export default {
}
},
generateMenu(routes) {
console.log(routes, 'routes')
return routes.map((route) => ({
...route,
title: route.name,

View File

@@ -20,7 +20,7 @@
>
<template #stationSelect="item">
<a-select
style="width: 120px;"
style="width: 200px"
:dropdown-match-select-width="false"
v-model:value="stationId"
allow-clear
@@ -39,17 +39,17 @@
</div>
<div class="main_content">
<a-spin :spinning="loading.chart || loading.table">
<energyEchart
:key="`${activeKey}_${renderKey}`"
:chart-options="echartsInfo[activeKey].chartOptions"
:chart-data="echartsInfo[activeKey].chartData"
:chart-datav="echartsInfo[activeKey].chartDatav"
:columns="tableList[activeKey].columns"
:page-option="tableList[activeKey].pageOption"
:table-info="tableList[activeKey].tableInfo"
:table-data="tableList[activeKey].tableData"
@pagesizeChange="pagesizeChange()"
></energyEchart>
<energyEchart
:key="`${activeKey}_${renderKey}`"
:chart-options="echartsInfo[activeKey].chartOptions"
:chart-data="echartsInfo[activeKey].chartData"
:chart-datav="echartsInfo[activeKey].chartDatav"
:columns="tableList[activeKey].columns"
:page-option="tableList[activeKey].pageOption"
:table-info="tableList[activeKey].tableInfo"
:table-data="tableList[activeKey].tableData"
@pagesizeChange="pagesizeChange()"
></energyEchart>
</a-spin>
</div>
</div>
@@ -166,7 +166,7 @@ export default {
}
],
chartData: {},
chartDatav: {},
chartDatav: {}
},
2: {
chartOptions: [
@@ -281,19 +281,20 @@ export default {
}
},
activeKey: 1,
interval:null,
interval: null,
tabList: [
{
key: 1,
name: '储能设备'
},
{
key: 2,
name: '光伏设备'
},
{
key: 3,
name: '充电设备'
},
{
key: 2,
name: '光伏设备'
}
],
tableList: {
@@ -505,123 +506,115 @@ export default {
watch: {
activeKey: {
handler(newVal) {
if (!newVal) return;
if (!newVal) return
// 清除之前的数据
this.resetDataForInactiveKey();
this.resetDataForInactiveKey()
// 并行加载新数据
Promise.all([
this.getEchartsListForActiveKey(),
this.getTableListForActiveKey()
]).then(() => {
this.$nextTick(() => {
this.getStatCharts();
});
});
Promise.all([this.getStationList(),this.getEchartsListForActiveKey(), this.getTableListForActiveKey()]).then(
() => {
this.$nextTick(() => {
this.getStatCharts()
})
}
)
},
immediate: true // 添加立即执行
}
},
async mounted() {
// 优先加载第一个页面(activeKey=1)所需的数据
// 优先加载第一个页面(activeKey=1)所需的数据
await Promise.all([
this.getStationList(),
this.getEchartsListForActiveKey(),
this.getTableListForActiveKey()
]);
])
// 初始化实时刷新
this.startRealtimeRefresh();
this.startRealtimeRefresh()
},
beforeUnmount() {
console.log('beforeUnmount')
clearInterval(this.interval); // 组件销毁时清除定时器
clearInterval(this.interval) // 组件销毁时清除定时器
},
methods: {
forceRerender() {
this.renderKey += 1;
this.renderKey += 1
},
resetDataForInactiveKey() {
// 重置非当前激活页面的数据,减少内存占用
// 重置非当前激活页面的数据,减少内存占用
Object.keys(this.echartsInfo).forEach((key) => {
if (key != this.activeKey) {
this.echartsInfo[key].chartData={}
this.echartsInfo[key].chartDatav={}
this.echartsInfo[key].chartData = {}
this.echartsInfo[key].chartDatav = {}
}
});
})
Object.keys(this.tableList).forEach((key) => {
if (key != this.activeKey) {
this.echartsInfo[key].tableData={}
this.echartsInfo[key].tableData = {}
}
});
})
},
async getEchartsListForActiveKey() {
if (!this.activeKey) return;
this.loading.chart = true;
const currentInfo = this.echartsInfo[this.activeKey];
if (!this.activeKey) return
this.loading.chart = true
const currentInfo = this.echartsInfo[this.activeKey]
const query = {
...this.paramsDate,
category: this.activeKey
};
}
try {
const res = await getReq('/queryStatDayList', query);
const res = await getReq('/queryStatDayList', query)
if (res.errcode === 0) {
this.echartsInfo[this.activeKey].chartData=res.data
this.loading.chart = false;
this.echartsInfo[this.activeKey].chartData = res.data
this.loading.chart = false
} else {
throw res;
throw res
}
} catch (error) {
this.loading.chart = false;
this.echartsInfo[this.activeKey].chartData={}
this.loading.chart = false
this.echartsInfo[this.activeKey].chartData = {}
}
},
// 专门获取当前激活页面的表格数据
async getTableListForActiveKey() {
this.loading.table = true;
if (!this.activeKey) return;
const currentInfo = this.tableList[this.activeKey];
this.loading.table = true
if (!this.activeKey) return
const currentInfo = this.tableList[this.activeKey]
const query = {
...this.paramsDate,
category: this.activeKey,
page_size: currentInfo.pageOption.pageSize,
pageNumber: currentInfo.pageOption.page
};
}
try {
const res = await getReq('/queryStatDayList', query);
const res = await getReq('/queryStatDayList', query)
if (res.errcode === 0) {
this.tableList[this.activeKey].tableData=res.data.list || res.data
this.tableList[this.activeKey].pageOption.count=res.data.count || 0
this.loading.table = false;
this.tableList[this.activeKey].tableData = res.data.list || res.data
this.tableList[this.activeKey].pageOption.count = res.data.count || 0
this.loading.table = false
} else {
throw res;
throw res
}
} catch (error) {
this.tableList[this.activeKey].tableData=[]
this.tableList[this.activeKey].pageOption.count= 0
this.loading.table = false;
this.tableList[this.activeKey].tableData = []
this.tableList[this.activeKey].pageOption.count = 0
this.loading.table = false
}
},
startRealtimeRefresh() {
this.interval = setInterval(() => {
if (this.activeKey) {
this.getStatCharts(); // 定时获取最新实时数据
this.getStatCharts() // 定时获取最新实时数据
}
}, 10000); // 30秒刷新一次
}, 10000) // 30秒刷新一次
},
async getStationList() {
const params = {
page_size: 1000,
@@ -655,45 +648,19 @@ export default {
this.tableList[this.activeKey].pageOption.pageSize = e.pageSize
this.tableList[this.activeKey].pageOption.page = e.page
this.getTableListForActiveKey()
},
onSearch(data) {
this.paramsDate.start_date = data.time ? data.time[0] : ''
this.paramsDate.end_date = data.time ? data.time[1] : ''
this.tableList[this.activeKey].pageOption.page = 1
this.getStationList(),
this.getEchartsListForActiveKey(),
this.getTableListForActiveKey()
this.getStationList(), this.getEchartsListForActiveKey(), this.getTableListForActiveKey()
},
changeStation() {
this.getStatCharts();
this.getStatCharts()
},
// async getEchartsList() {
// const key = activeKey || this.activeKey;
// if (!key) return;
// const currentInfo = this.echartsInfo[this.activeKey]
// const query = {
// ...this.paramsDate,
// category: this.activeKey
// }
// try {
// const res = await getReq('/queryStatDayList', query)
// if (res.errcode === 0) {
// this.echartsInfo[this.activeKey].chartData = res.data
// console.log(
// this.echartsInfo[this.activeKey].chartData,
// ' this.echartsInfo[this.activeKey].chartData'
// )
// } else {
// throw res
// }
// } catch (error) {
// this.echartsInfo[this.activeKey].chartData = {}
// }
// },
async getStatCharts() {
const currentInfo = this.echartsInfo[this.activeKey]
const query = {
@@ -704,97 +671,21 @@ export default {
try {
const res = await getReq('/queryStatCharts', query)
if (res.errcode === 0) {
this.echartsInfo[this.activeKey].chartDatav = {
"V":[100.0,100.0,100.0], // 电压曲线
"I":[10.0,10.0,10.0], // 电流曲线
"P":[1000.0,1000.0,1000.0], // 功率曲线
}
this.echartsInfo[this.activeKey].chartDatav = res.data
// x轴0点到24点
} else {
throw res
}
} catch (error) {
this.echartsInfo[this.activeKey].chartDatav = {
"V":[100.0,100.0,100.0], // 电压曲线
"I":[10.0,10.0,10.0], // 电流曲线
"P":[1000.0,1000.0,1000.0], // 功率曲线
V: [100.0, 100.0, 100.0], // 电压曲线
I: [10.0, 10.0, 10.0], // 电流曲线
P: [1000.0, 1000.0, 1000.0] // 功率曲线
}
}
},
}
// async getTableList() {
// const currentInfo = this.tableList[this.activeKey]
// const query = {
// ...this.paramsDate,
// category: this.activeKey,
// page_size: currentInfo.pageOption.pageSize,
// pageNumber: currentInfo.pageOption.page
// }
// try {
// const res = await getReq('/queryStatDayList', query)
// if (res.errcode === 0) {
// this.tableList[this.activeKey].pageOption.tableData = res.data
// this.tableList[this.activeKey].pageOption.pageOption = {
// page: res.data.page,
// pageSize: res.data.page_size,
// count: res.data.count
// }
// } else {
// throw res
// }
// } catch (error) {
// this.tableList[this.activeKey].pageOption.tableData = [
// {
// key1: '1515151515',
// key2: '设备1111',
// key3: '类型',
// key4: '电量',
// key5: '时长',
// key6: '时长',
// key7: 'dianl',
// key8: '时长',
// key9: '时长11'
// },
// {
// key1: '1515151515',
// key2: '设备1111',
// key3: '类型',
// key4: '电量',
// key5: '时长',
// key6: '时长',
// key7: 'dianl',
// key8: '时长',
// key9: '时长11'
// },
// {
// key1: '1515151515',
// key2: '设备1111',
// key3: '类型',
// key4: '电量',
// key5: '时长',
// key6: '时长',
// key7: 'dianl',
// key8: '时长',
// key9: '时长11'
// },
// {
// key1: '1515151515',
// key2: '设备1111',
// key3: '类型',
// key4: '电量',
// key5: '时长',
// key6: '时长',
// key7: 'dianl',
// key8: '时长',
// key9: '时长11'
// }
// ]
// }
// }
}
}
</script>

View File

@@ -48,46 +48,45 @@ import Alarm from '@/components/Home/Alarm.vue'
import Map from '@/components/Home/Map.vue'
import { getReq, postReq } from '@/request/api'
import { getRunDays, getDateDaysAgo } from '@/utils/dealWithData'
import { markRaw } from 'vue';
import { markRaw } from 'vue'
export default {
name: 'Home',
components: { Map },
data() {
return {
showFlag: false,
stationId: null,
deviceInfo: {},
list: [
{
title: '运行状况',
class: 'online-status',
componentId:markRaw(onLine),
componentId: markRaw(onLine),
infoKey: 'onLineTotal'
},
{
title: '运行分析',
class: 'stats-cards',
componentId:markRaw( Operational),
infoKey: ''
componentId: markRaw(Operational),
infoKey: 'operationTotal'
},
{
title: '储能设备',
class: 'energy-status',
componentId:markRaw( Energy),
componentId: markRaw(Energy),
infoKey: 'energy'
},
{
title: '充电设备',
class: 'charge-analysis',
componentId:markRaw( Charge),
componentId: markRaw(Charge),
infoKey: 'charge'
},
{
title: '光伏设备',
class: 'work-order',
componentId:markRaw( Pv),
componentId: markRaw(Pv),
infoKey: 'pv'
},
{
@@ -114,16 +113,28 @@ export default {
await Promise.all([
this.getOnLineList(),
this.getStatTotalList(),
this.getOperTotalList(),
this.getStatDayList(1),
this.getStatDayList(2),
this.getStatDayList(3)
])
// this.showFlag=true
]).then((r) => {
if (
this.deviceInfo.energy.length &&
this.deviceInfo.charge.length &&
this.deviceInfo.pv.length
) {
const newArr = this.mergedArray(
this.deviceInfo.energy,
this.deviceInfo.charge,
this.deviceInfo.pv
)
this.deviceInfo.alarm = newArr
}
})
},
methods: {
getCurrentStation(e) {
console.log(e, 'getCurrentStation')
this.stationId = e
},
// 查询系统统计信息
@@ -134,7 +145,6 @@ export default {
if (res.errcode === 0) {
this.deviceInfo.onLine = JSON.parse(JSON.stringify(res.data))
this.deviceInfo.onLine.runDays = getRunDays(res.data.launch_date)
console.log(JSON.parse(JSON.stringify(res.data)), this.deviceInfo.onLine, '111111111111')
} else {
throw res
}
@@ -151,7 +161,7 @@ export default {
// station_id:场站ID为0或不传查询所有场站总计
// category:类别1:储能设备,2:充电设备,3:光伏设备,为0或不传查询所有类别总计
const query = {
date: new Date(),
date: getDateDaysAgo(0),
stationId: this.stationId,
category: 0
}
@@ -161,28 +171,25 @@ export default {
const { income_charge: incomeCharge, income_elect: incomeElect } =
this.deviceInfo.allTotal
this.deviceInfo.allTotal.incomeTotal = +incomeCharge + +incomeElect
console.log(
this.deviceInfo.allTotal.incomeTotal,
incomeCharge,
incomeElect,
' this.deviceInfo.allTotal.incomeTotal'
)
} else {
throw res
}
} catch (error) {
this.deviceInfo.allTotal = {
storageElectIn: 2,
storageElectOut: 5,
chargeElect: 4,
chargeNum: 5,
incomeCharge: 7,
incomeElect: 7,
solarElectGen: 7,
solarElectGrid: 7
this.deviceInfo.allTotal = {}
this.deviceInfo.allTotal.incomeTotal = 0
}
},
// 运行分析 联调
async getOperTotalList() {
try {
const res = await getReq('/queryStatStation', {})
if (res.errcode === 0) {
this.deviceInfo.operationTotal = res.data
} else {
throw res
}
this.deviceInfo.allTotal.incomeTotal =
this.deviceInfo.allTotal.incomeCharge + this.deviceInfo.allTotal.incomeElect
} catch (error) {
this.deviceInfo.operationTotal = [ ]
}
},
@@ -205,18 +212,6 @@ export default {
if (res.errcode === 0) {
this.list.forEach((item) => {
this.deviceInfo[arr[category]] = res.data
if (
this.deviceInfo.energy.length &&
this.deviceInfo.charge.length &&
this.deviceInfo.pv.length
) {
const newArr = this.mergedArray(
this.deviceInfo.energy,
this.deviceInfo.charge,
this.deviceInfo.pv
)
this.deviceInfo.alarm = newArr
}
})
} else {
throw res
@@ -257,7 +252,7 @@ export default {
}
.tianditu {
width: calc(100% - 520px * 2);
width: 44%;
height: 100%;
margin: 0px 15px;
}
@@ -265,7 +260,7 @@ export default {
.content-left,
.content-right {
height: 100%;
width: 520px;
width: 28%;
display: flex;
flex-direction: column;
align-items: center;

View File

@@ -1,11 +1,6 @@
<template>
<div class="permission">
<searchBox
:btn-option-list="btnOptionList"
@onSearch="onSearch"
:search-options="searchOptions"
@operateForm="operateForm"
></searchBox>
<!-- <searchBox :btn-option-list="btnOptionList" @operateForm="operateForm"></searchBox> -->
<div class="content-table">
<TreeTable
@@ -18,11 +13,13 @@
>
<template #is_open="record">
<!-- 0:禁用; 1:启用 -->
<span>{{ ['禁用', '启用'][record.is_open] }}</span>
<a-tag :color="record.is_open == 0 ? 'red' : 'green'">{{
record.is_open == 0 ? '禁用' : '启用'
}}</a-tag>
</template>
<template #permission="record">
<!-- 0:禁用; 1:启用 -->
<span>{{record.permission.map(item=>item.name).toString() }}</span>
<span>{{ record.permission.map((item) => item.name).toString() }}</span>
</template>
<template #action="record">
@@ -30,7 +27,13 @@
</template>
</TreeTable>
</div>
<a-modal v-model:open="formModal" width="750px" style="top: 80px" :footer="null">
<a-modal
v-model:open="formModal"
width="750px"
style="top: 80px"
:footer="null"
:destroy-on-close="true"
>
<!-- action:edit add -->
<EditCom
:record="record"
@@ -51,9 +54,7 @@ import { createVNode } from 'vue'
export default {
name: '',
components: {
},
components: {},
props: {},
data() {
return {
@@ -65,7 +66,10 @@ export default {
page: 1
},
btnOptionList: [],
paramsDate: {}
paramsDate: {},
tableOption: {
select: false
}
}
},
computed: {},
@@ -104,13 +108,12 @@ export default {
this.$refs.comTable.loading = false
// this.tableData = res.data
this.tableData =JSON.parse( localStorage.getItem('permission')).map((item)=>{
this.tableData = JSON.parse(localStorage.getItem('permission')).map((item) => {
return {
...item,
key:item.permission_id,
key: item.permission_id
}
})
console.log( this.tableData," this.tableData")
this.pageOption = {
page: res.page,
pageSize: res.page_size,
@@ -125,25 +128,9 @@ export default {
}
},
operateForm(type, record = {}) {
console.log(record,record.id,'rrrrrrrrrr')
this.formStatus = type
switch (type) {
// case 'add':
// this.formModal = true
// this.formState = {}
// this.getRuleFormInfo()
// break
// case 'edit':
// case 'read':
// this.formModal = true
// this.formState = record
// this.getRuleFormInfo(record)
// break
case 'del':
// this.handleDelete([record.permission_id],this.getList)
break
case 'back':
@@ -156,7 +143,7 @@ export default {
}
},
// 删除操作
async handleDelete(id,callback) {
async handleDelete(id, callback) {
const that = this
Modal.confirm({
title: '你确认删除数据吗?',
@@ -164,10 +151,10 @@ export default {
async onOk() {
try {
const res = await getReq('/deletepermission',{permission_id:id})
const res = await getReq('/deletepermission', { permission_id: id })
if (res.errcode === 0) {
this.$message.success(res.errmsg)
this.pageOption.page=1
this.pageOption.page = 1
callback()
} else {
throw res
@@ -198,7 +185,6 @@ export default {
row = record
// this.type='edit'
}
},
handlePagesizeChange(pageOption) {
this.pageOption.pageSize = pageOption.pageSize
@@ -212,10 +198,9 @@ export default {
<style lang="scss" scoped>
.permission {
height: 100%;
padding: 20px 20px 0 20px;
.content-table {
height: calc(100% - 70px);
padding: 10px;
height: calc(100% - 92px);
}
}
</style>

View File

@@ -1,11 +1,6 @@
<template>
<div class="role">
<searchBox
:btn-option-list="btnOptionList"
@onSearch="onSearch"
:search-options="searchOptions"
@operateForm="operateForm"
></searchBox>
<searchBox :btn-option-list="btnOptionList" @operateForm="operateForm"></searchBox>
<div class="content-table">
<ComTable
@@ -18,7 +13,9 @@
>
<template #is_open="record">
<!-- 0:禁用; 1:启用 -->
<span>{{ ['禁用', '启用'][record.is_open] }}</span>
<a-tag :color="record.is_open == 0 ? 'red' : 'green'">{{
record.is_open == 0 ? '禁用' : '启用'
}}</a-tag>
</template>
<template #permission="record">
<!-- 0:禁用; 1:启用 -->
@@ -30,7 +27,13 @@
</template>
</ComTable>
</div>
<a-modal v-model:open="formModal" width="950px" style="top: 80px" :footer="null" :destroy-on-close="true">
<a-modal
v-model:open="formModal"
width="950px"
style="top: 80px"
:footer="null"
:destroy-on-close="true"
>
<!-- action:edit add -->
<EditCom
:show-flag="formModal"
@@ -74,8 +77,8 @@ export default {
btnOptionList: [],
paramsDate: {},
tableOption: {
select:false
},
select: false
}
}
},
computed: {},
@@ -125,6 +128,8 @@ export default {
throw err
}
} catch (error) {
this.$refs.comTable.loading = false
//统一处理报错提示
}
},
@@ -140,9 +145,9 @@ export default {
...item,
key: item.permission_id,
is_add: Boolean(+item.is_add) || false,
is_del: Boolean(+item.is_del )|| false,
is_edit: Boolean(+item.is_edit )|| false,
is_view: Boolean(+item.is_view )|| false,
is_del: Boolean(+item.is_del) || false,
is_edit: Boolean(+item.is_edit) || false,
is_view: Boolean(+item.is_view) || false,
// 确保子权限容器存在
children: item.children ? [...item.children] : []
}
@@ -191,10 +196,10 @@ export default {
},
calculateParentPermissions(node) {
if (node.children?.length) {
node.is_view = node.children.some((child) => child.is_view === '1') ? true:false
node.is_add = node.children.some((child) => child.is_add === '1') ? true:false
node.is_edit = node.children.some((child) => child.is_edit === '1') ? true:false
node.is_del = node.children.some((child) => child.is_del === '1') ? true:false
node.is_view = node.children.some((child) => child.is_view === '1') ? true : false
node.is_add = node.children.some((child) => child.is_add === '1') ? true : false
node.is_edit = node.children.some((child) => child.is_edit === '1') ? true : false
node.is_del = node.children.some((child) => child.is_del === '1') ? true : false
}
},
async getPermissionList() {
@@ -240,11 +245,10 @@ export default {
is_add: data ? Boolean(+data.is_add) : false,
is_del: data ? Boolean(+data.is_del) : false,
is_edit: data ? Boolean(+data.is_edit) : false,
is_view: data ? Boolean(+data.is_view ): false
is_view: data ? Boolean(+data.is_view) : false
}
},
operateForm(type, record = {}) {
console.log(record, 'rrrrrrrrrr')
this.formStatus = type
switch (type) {
case 'add':
@@ -293,14 +297,11 @@ export default {
callback()
}
},
onCancel() {
// console.log("Cancel");
},
onCancel() {},
class: 'test'
})
},
async getRuleFormInfo(record) {
function getInfo(data, url) {
return new Promise((reslove, reject) => {
getReq(data, url).then((res) => {
@@ -319,16 +320,16 @@ export default {
perList,
record && record.permission.length ? record.permission : []
)
const newData=JSON.parse(JSON.stringify( this.processedData))
const newData = JSON.parse(JSON.stringify(this.processedData))
roleOptions.forEach((e, index) => {
e.list.forEach((i) => {
if (i.key == 'permission') {
i.tableData = newData
if(record&&record.role_id){
i.selectTableData=this.extractAllIds( record.permission)
}else {
i.selectTableData=[]
if (record && record.role_id) {
i.selectTableData = this.extractAllIds(record.permission)
} else {
i.selectTableData = []
}
} else {
e.ruleForm[i.key] = row ? row[i.key] : ''
@@ -339,25 +340,25 @@ export default {
},
// 定义提取所有ID的函数
extractAllIds(treeData) {
const idSet = new Set();
const idSet = new Set()
// 递归遍历函数
const traverse = (node) => {
// 添加当前节点ID
if (node.permission_id) {
idSet.add(node.permission_id);
idSet.add(node.permission_id)
}
// 递归处理子节点
if (node.children && node.children.length > 0) {
node.children.forEach((child) => traverse(child));
node.children.forEach((child) => traverse(child))
}
};
}
// 处理所有根节点
treeData.forEach((node) => traverse(node));
return Array.from(idSet);
treeData.forEach((node) => traverse(node))
return Array.from(idSet)
},
handlePagesizeChange(pageOption) {
this.pageOption.pageSize = pageOption.pageSize
@@ -372,9 +373,9 @@ export default {
.role {
height: 100%;
padding: 0 20px;
.content-table {
height: calc(100% - 70px);
padding: 10px;
height: calc(100% - 92px);
}
}
</style>

View File

@@ -1,11 +1,6 @@
<template>
<div class="service">
<searchBox
:btn-option-list="btnOptionList"
@onSearch="onSearch"
:search-options="searchOptions"
@operateForm="operateForm"
></searchBox>
<searchBox :btn-option-list="btnOptionList" @operateForm="operateForm"></searchBox>
<div class="content-table">
<ComTable
@@ -17,16 +12,24 @@
:page-option="pageOption"
>
<template #is_open="record">
<span>{{ ['禁用', '启用'][record.is_open] }}</span>
<!-- 0:禁用; 1:启用 -->
<a-tag :color="record.is_open == 0 ? 'red' : 'green'">{{
record.is_open == 0 ? '禁用' : '启用'
}}</a-tag>
</template>
<template #action="record">
<OperateCom :record="record" :operate-list="operateList" @operateForm="operateForm" />
</template>
</ComTable>
</div>
<a-modal v-model:open="formModal" width="750px" style="top: 80px" :footer="null">
<a-modal
v-model:open="formModal"
width="750px"
style="top: 80px"
:footer="null"
:destroy-on-close="true"
>
<!-- action:edit add -->
<EditCom
:record="record"
@@ -50,13 +53,13 @@ export default {
name: '',
components: {
searchBox,
EditCom,
EditCom
},
props: {},
data() {
return {
tableOption: {
select:false
select: false
},
formModal: false,
formState: {},
@@ -67,33 +70,33 @@ export default {
},
btnOptionList: [],
paramsDate: {},
workModeList:[
workModeList: [
{
label:'最优经济化',
value:1
label: '最优经济化',
value: 1
},
{
label:'支撑电网稳定',
value:2
label: '支撑电网稳定',
value: 2
},
{
label:'自定义',
value:3
},
label: '自定义',
value: 3
}
],
policyList:[
policyList: [
{
label:'削峰套利',
value:1
label: '削峰套利',
value: 1
},
{
label:'需求响应',
value:2
label: '需求响应',
value: 2
},
{
label:'自发自用',
value:3
},
label: '自发自用',
value: 3
}
]
}
},
@@ -145,10 +148,10 @@ export default {
}
} catch (error) {
//统一处理报错提示
this.$refs.comTable.loading = false
}
},
operateForm(type, record = {}) {
console.log(record,record.id,'rrrrrrrrrr')
this.formStatus = type
switch (type) {
case 'add':
@@ -163,9 +166,9 @@ export default {
this.formState = record
this.getRuleFormInfo(record)
break
case 'del':
this.handleDelete([record.api_id],this.getList)
this.handleDelete([record.api_id], this.getList)
break
@@ -179,7 +182,7 @@ export default {
}
},
// 删除操作
async handleDelete(id,callback) {
async handleDelete(id, callback) {
const that = this
Modal.confirm({
title: '你确认删除数据吗?',
@@ -187,10 +190,10 @@ export default {
async onOk() {
try {
const res = await getReq('/deleteServiceApi',{api_id:id})
const res = await getReq('/deleteServiceApi', { api_id: id })
if (res.errcode === 0) {
this.$message.success(res.errmsg)
this.pageOption.page=1
this.pageOption.page = 1
callback()
} else {
throw res
@@ -199,9 +202,7 @@ export default {
callback()
}
},
onCancel() {
// console.log("Cancel");
},
onCancel() {},
class: 'test'
})
},
@@ -223,7 +224,6 @@ export default {
}
serviceApiOptions.forEach((e, index) => {
e.list.forEach((i) => {
e.ruleForm[i.key] = row ? row[i.key] : ''
e.ruleForm.id = row.id
})

View File

@@ -1,11 +1,6 @@
<template>
<div class="station">
<searchBox
:btn-option-list="btnOptionList"
@onSearch="onSearch"
:search-options="searchOptions"
@operateForm="operateForm"
></searchBox>
<searchBox :btn-option-list="btnOptionList" @operateForm="operateForm"></searchBox>
<div class="content-table">
<ComTable
@@ -17,23 +12,26 @@
:page-option="pageOption"
>
<template #status="record">
<span>{{ ['未启用', '启用'][record.status] }}</span>
<a-tag :color="record.status == 0 ? 'red' : 'green'">{{
record.status == 0 ? '未投运' : '投运'
}}</a-tag>
<span>{{}}</span>
</template>
<template #work_mode="record">
<span>{{ workModeList.find((item) => record.value == item.value)?.label || '' }}</span>
<span>{{ workModeList.find((item) => record.work_mode == item.value)?.label || '' }}</span>
</template>
<template #policy_id="record">
<span>{{ policyList.find((item) => record.value == item.value)?.label || '' }}</span>
<span>{{ policyList.find((item) => record.policy_id == item.value)?.label || '' }}</span>
</template>
<template #action="record">
<OperateCom :record="record" :operate-list="operateList" @operateForm="operateForm" />
</template>
</ComTable>
</div>
<a-modal v-model:open="formModal" width="750px" style="top: 80px" :footer="null">
<a-modal v-model:open="formModal" width="750px" style="top: 80px" :footer="null" :destroy-on-close="true">
<!-- action:edit add -->
<EditCom
ref="EditCom"
:record="record"
@operateForm="operateForm"
type="station"
@@ -65,7 +63,7 @@ export default {
data() {
return {
tableOption: {
select:false
select: false
},
formModal: false,
formState: {},
@@ -78,16 +76,24 @@ export default {
paramsDate: {},
workModeList: [
{
label: '最优经济化',
value: 1
label: '峰谷套利',
value: '1'
},
{
label: '支撑电网稳定',
value: 2
label: '增网配容',
value: '2'
},
{
label: '自定义',
value: 3
label: '应急供电',
value: '3'
},
{
label: '并网保电',
value: '4'
},
{
label: '自定时段',
value: '5'
}
],
policyList: [
@@ -154,10 +160,10 @@ export default {
}
} catch (error) {
//统一处理报错提示
this.$refs.comTable.loading = false
}
},
operateForm(type, record = {}) {
console.log(record, record.id, 'rrrrrrrrrr')
this.formStatus = type
switch (type) {
case 'add':
@@ -208,9 +214,7 @@ export default {
callback()
}
},
onCancel() {
// console.log("Cancel");
},
onCancel() {},
class: 'test'
})
},
@@ -232,8 +236,27 @@ export default {
}
stationOptions.forEach((e, index) => {
e.list.forEach((i) => {
e.ruleForm[i.key] = row ? row[i.key] : ''
e.ruleForm.id = row.id
if (i.key == 'work_mode') {
console.log(row[i.key], 'rrrrrrrrr')
switch (row[i.key]) {
case '1':
case '5':
e.ruleForm[i.key] =row[i.key]
// this.$refs.EditCom.workModeIdSelect = row[i.key]
e.ruleForm['policy_id'] = row ? row['policy_id'] : ''
stationOptions[0].list[stationOptions[0].list.length - 1].type = 'select'
break
default:
e.ruleForm[i.key] =row[i.key]
console.log('1245')
stationOptions[0].list[stationOptions[0].list.length - 1].type = 'unshow'
break
}
} else {
e.ruleForm[i.key] = row ? row[i.key] : ''
}
})
})
},
@@ -250,9 +273,9 @@ export default {
.station {
height: 100%;
padding: 0 20px;
.content-table {
height: calc(100% - 70px);
padding: 10px;
height: calc(100% - 92px);
}
}
</style>

View File

@@ -1,11 +1,6 @@
<template>
<div class="user">
<searchBox
:btn-option-list="btnOptionList"
@onSearch="onSearch"
:search-options="searchOptions"
@operateForm="operateForm"
></searchBox>
<searchBox :btn-option-list="btnOptionList" @operateForm="operateForm"></searchBox>
<div class="content-table">
<ComTable
@@ -26,7 +21,13 @@
</template>
</ComTable>
</div>
<a-modal v-model:open="formModal" width="750px" style="top: 80px" :footer="null">
<a-modal
v-model:open="formModal"
width="750px"
style="top: 80px"
:footer="null"
:destroy-on-close="true"
>
<!-- action:edit add -->
<EditCom
:record="record"
@@ -48,13 +49,13 @@ import { createVNode } from 'vue'
export default {
name: '',
components: {
EditCom,
EditCom
},
props: {},
data() {
return {
tableOption: {
select:false
select: false
},
formModal: false,
formState: {},
@@ -114,11 +115,12 @@ export default {
throw err
}
} catch (error) {
this.$refs.comTable.loading = false
//统一处理报错提示
}
},
operateForm(type, record = {}) {
console.log(record,record.id,'rrrrrrrrrr')
this.formStatus = type
switch (type) {
case 'add':
@@ -133,9 +135,9 @@ export default {
this.formState = record
this.getRuleFormInfo(record)
break
case 'del':
this.handleDelete([record.user_id],this.getList)
this.handleDelete([record.user_id], this.getList)
break
@@ -149,7 +151,7 @@ export default {
}
},
// 删除操作
async handleDelete(id,callback) {
async handleDelete(id, callback) {
const that = this
this.$Modal.confirm({
title: '你确认删除数据吗?',
@@ -157,10 +159,10 @@ export default {
async onOk() {
try {
const res = await getReq('/deleteUser',{user_id:id})
const res = await getReq('/deleteUser', { user_id: id })
if (res.errcode === 0) {
this.$message.success(res.errmsg)
this.pageOption.page=1
this.pageOption.page = 1
callback()
} else {
throw res
@@ -169,9 +171,7 @@ export default {
callback()
}
},
onCancel() {
// console.log("Cancel");
},
onCancel() {},
class: 'test'
})
},
@@ -193,7 +193,6 @@ export default {
}
userOptions.forEach((e, index) => {
e.list.forEach((i) => {
e.ruleForm[i.key] = row ? row[i.key] : ''
e.ruleForm.id = row.id
})
@@ -211,10 +210,9 @@ export default {
<style lang="scss" scoped>
.user {
height: 100%;
padding: 0 20px;
.content-table {
height: calc(100% - 70px);
padding: 10px;
height: calc(100% - 92px);
}
}
</style>