fks-yangshouda 1 month ago
parent
commit
cb4fb86cf4
  1. 2
      hx-ai-intelligent/src/api/IlluminationInfo.ts
  2. 2
      hx-ai-intelligent/src/api/airConditionControlSystem.ts
  3. 1
      hx-ai-intelligent/src/api/carbonEmissionFactorLibrary.ts
  4. 4
      hx-ai-intelligent/src/api/planManage.ts
  5. 2
      hx-ai-intelligent/src/api/ventilatingSystem.ts
  6. 42
      hx-ai-intelligent/src/components/ns-steps.vue
  7. BIN
      hx-ai-intelligent/src/icon/add.png
  8. 4
      hx-ai-intelligent/src/icon/carbonInventoryCheck.svg
  9. BIN
      hx-ai-intelligent/src/icon/del.png
  10. 6
      hx-ai-intelligent/src/icon/del.svg
  11. 218
      hx-ai-intelligent/src/view/alarmManagement/alarmSettings/energyAlarm/editConfigureEnergyAlarm.vue
  12. 224
      hx-ai-intelligent/src/view/alarmManagement/alarmSettings/equipmentAlarm/editConfigureDeviceAlarm.vue
  13. 2
      hx-ai-intelligent/src/view/alarmManagement/alarmSettings/equipmentAlarm/editeEquipmentAlarm.vue
  14. 9
      hx-ai-intelligent/src/view/alarmManagement/energyAlarm/index.vue
  15. 49
      hx-ai-intelligent/src/view/alarmManagement/energyAlarm/look.vue
  16. 18
      hx-ai-intelligent/src/view/alarmManagement/energyAlarm/status.vue
  17. 9
      hx-ai-intelligent/src/view/alarmManagement/equipmentAlarm/index.vue
  18. 53
      hx-ai-intelligent/src/view/alarmManagement/equipmentAlarm/look.vue
  19. 18
      hx-ai-intelligent/src/view/alarmManagement/equipmentAlarm/status.vue
  20. 9
      hx-ai-intelligent/src/view/alarmManagement/gatewayAlarm/index.vue
  21. 51
      hx-ai-intelligent/src/view/alarmManagement/gatewayAlarm/look.vue
  22. 18
      hx-ai-intelligent/src/view/alarmManagement/gatewayAlarm/status.vue
  23. 129
      hx-ai-intelligent/src/view/carbonEmissionManage/carbonAssets/carbonAssetsDetail/index.vue
  24. 76
      hx-ai-intelligent/src/view/carbonEmissionManage/carbonEmissionFactorLibrary/index.vue
  25. 43
      hx-ai-intelligent/src/view/carbonEmissionManage/carbonEmissionStatistics/carbonEmissions/index.vue
  26. 179
      hx-ai-intelligent/src/view/carbonEmissionManage/carbonEmissionStatistics/energyConsumption/index.vue
  27. 8
      hx-ai-intelligent/src/view/carbonEmissionManage/carbonEmissionStatistics/quickCalculation/index.vue
  28. 325
      hx-ai-intelligent/src/view/carbonEmissionManage/carbonInventoryCheck/fillInPage/index copy.vue
  29. 381
      hx-ai-intelligent/src/view/carbonEmissionManage/carbonInventoryCheck/fillInPage/index.vue
  30. 36
      hx-ai-intelligent/src/view/carbonEmissionManage/carbonInventoryCheck/index.vue
  31. 106
      hx-ai-intelligent/src/view/carbonEmissionManage/carbonPlanning/all/index.vue
  32. 27
      hx-ai-intelligent/src/view/carbonEmissionManage/carbonPlanning/category/categoryDeatil.vue
  33. 117
      hx-ai-intelligent/src/view/carbonEmissionManage/carbonPlanning/category/index.vue
  34. 36
      hx-ai-intelligent/src/view/carbonEmissionManage/carbonPlanning/index.vue
  35. 47
      hx-ai-intelligent/src/view/equipmentControl/airConditionControlSystem/tabs2.vue
  36. 17
      hx-ai-intelligent/src/view/equipmentControl/airConditionControlSystem/tabs3.vue
  37. 28
      hx-ai-intelligent/src/view/equipmentControl/lightingManage/indexs.vue
  38. 12
      hx-ai-intelligent/src/view/equipmentControl/lightingManage/light.vue
  39. 97
      hx-ai-intelligent/src/view/equipmentControl/lightingManage/tabs1.vue
  40. 56
      hx-ai-intelligent/src/view/equipmentControl/lightingManage/tabs2.vue
  41. 34
      hx-ai-intelligent/src/view/equipmentControl/lightingManage/tabs3.vue
  42. 1
      hx-ai-intelligent/src/view/equipmentControl/style/color.less
  43. 1
      hx-ai-intelligent/src/view/equipmentControl/style/dialogStyle.less
  44. 118
      hx-ai-intelligent/src/view/equipmentControl/ventilationSystem/components/fanControl.vue
  45. 33
      hx-ai-intelligent/src/view/equipmentControl/ventilationSystem/components/fanLog.vue
  46. 48
      hx-ai-intelligent/src/view/equipmentControl/ventilationSystem/components/fanPlant.vue
  47. 150
      hx-ai-intelligent/src/view/equipmentControl/ventilationSystem/index.vue

2
hx-ai-intelligent/src/api/IlluminationInfo.ts

@ -1,4 +1,4 @@
const prefix = '/carbon-smart';
const prefix = '/carbon-smart/api';
// 照明系统及相关接口
export enum lightingManage {
// 主页 ========================================================

2
hx-ai-intelligent/src/api/airConditionControlSystem.ts

@ -1,4 +1,4 @@
const prefix = '/carbon-smart';
const prefix = '/carbon-smart/api';
// 空调系统及相关接口
export enum airConditionControl {
// 主页 ======================================================

1
hx-ai-intelligent/src/api/carbonEmissionFactorLibrary.ts

@ -108,4 +108,5 @@ export enum carbonPlanning {
benchmarkSetting = '/carbon-smart/api/carbon/planning/benchmarkSetting',
monthBenchmarkSetting = '/carbon-smart/api/carbon/planning/monthBenchmarkSetting',
benchmarkSubmit = '/carbon-smart/api/carbon/planning/benchmarkSubmit',
autoObtained = '/carbon-smart/api/carbon/planning/autoObtained',
}

4
hx-ai-intelligent/src/api/planManage.ts

@ -1,4 +1,4 @@
const prefix = '/carbon-smart';
const prefix = '/carbon-smart/api';
// 照明系统及相关接口
export enum planManage {
/**
@ -10,4 +10,6 @@ export enum planManage {
getTableData = prefix + '/deviceCtrlPlan/getActivatedPlanList',
// 提交计划状态修改
submitTransData = prefix + '/deviceCtrlPlan/activePlanByIdList',
// 用于确认当前是否有计划正在运行
getRunningPlan = prefix + '/deviceCtrlPlan/getRunningPlan',
}

2
hx-ai-intelligent/src/api/ventilatingSystem.ts

@ -1,5 +1,5 @@
// 前缀
const prefix = '/carbon-smart';
const prefix = '/carbon-smart/api';
// 通风系统相关接口
export enum ventilating {
// 排风扇相关 =============================================

42
hx-ai-intelligent/src/components/ns-steps.vue

@ -1,18 +1,33 @@
<template>
<a-steps direction="vertical" :current="size">
<template v-for="(item, index) in dataSource" :key="index">
<a-step>
<a-step title="">
<template #icon>
<ns-icon size="20" :name="item.src" />
</template>
<template #description>
<div class="card">
<div class="card-title">
<a-tag class="card-title-tag" :color="item.color">{{ item.stateName }}</a-tag>
<div class="name">{{ item.realName }}</div>
<a-tag
class="card-title-tag"
:style="{
background: item.bgColor,
border: '1px solid ' + item.color,
color: item.color,
}"
>{{ item.stateName }}</a-tag
>
<div class="time">{{ item.createTime }}</div>
</div>
<div style="width: 100%; color: #3a3a3a; height: 25px; overflow: auto">
<div
style="
width: 100%;
color: rgba(0, 0, 0, 0.45);
height: 27px;
overflow: auto;
padding: 7px 0px;
">
{{ item.remarks }}</div
>
</div>
@ -41,36 +56,37 @@
margin-top: 10px;
}
.card {
width: 400px;
width: 450px;
min-height: 0px;
background-color: #f8fafc;
margin-left: 20px;
background: rgba(191, 205, 226, 0.3);
border-radius: 4px; /* 设置圆角半径 */
padding: 12px;
margin-left: 8px;
.card-title {
width: 100%;
height: 30px;
display: flex;
position: relative;
.card-title-tag {
width: 60px;
height: 20px;
width: 50px;
height: 24px;
text-align: center;
line-height: 24px;
margin-left: 12px;
}
}
}
.name {
position: absolute;
left: 35%;
left: 12px;
top: -2px;
transform: translateX(-50%);
color: #3a3a3a;
font-size: 16px;
color: rgba(153, 153, 153, 1);
}
.time {
position: absolute;
right: 10px;
top: -2px;
color: #ff7602;
color: rgba(0, 0, 0, 0.45);
}
:deep(.ant-steps-item-tail) {
position: absolute !important;

BIN
hx-ai-intelligent/src/icon/add.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 B

4
hx-ai-intelligent/src/icon/carbonInventoryCheck.svg

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="11.05419921875" height="11.55615234375" viewBox="0 0 11.05419921875 11.55615234375" fill="none">
<path d="M10.9138 2.84916C10.8847 2.81354 10.8562 2.77791 10.8239 2.74831C10.7389 2.6699 10.6445 2.6025 10.5427 2.54769C9.03643 1.74524 7.53183 0.940587 6.02611 0.138129C5.89809 0.0686747 5.759 0.0219399 5.61502 8.98451e-08L5.4747 0C5.12499 0.0696122 4.82407 0.271323 4.51219 0.435761C3.14669 1.1531 1.7835 1.87517 0.422787 2.60189C0.210487 2.71542 0.0460472 2.89521 0.00767517 3.17037C0.00658035 3.18024 0.00274277 3.18901 0 3.19778L0 3.31453C0.0219307 3.44005 0.0586548 3.55899 0.137035 3.65875C0.16444 3.69274 0.190201 3.72836 0.221451 3.75632C0.30476 3.82922 0.389175 3.89938 0.486191 3.95145C2.00341 4.75994 3.51843 5.57171 5.0373 6.37746C5.16556 6.44653 5.29766 6.5134 5.44565 6.52765C5.59584 6.543 5.73671 6.51504 5.86935 6.44488L10.4747 3.99969C10.5262 3.97173 10.58 3.94816 10.6282 3.91583C10.7724 3.8221 10.9072 3.71412 10.9828 3.54529C11.0157 3.47349 11.03 3.39182 11.0541 3.31453L11.0541 3.19778C11.03 3.07061 10.9927 2.94893 10.9132 2.84917L10.9138 2.84916ZM10.3952 5.04387C10.2329 5.00984 10.0637 5.0339 9.91727 5.11184C9.62566 5.2686 9.33626 5.43249 9.04191 5.58542C7.88811 6.18507 6.73156 6.78143 5.57719 7.37999C5.54431 7.39643 5.5169 7.39917 5.48292 7.38163L1.23986 5.15789C1.01208 5.03459 0.748119 4.99558 0.494411 5.04771C0.231308 5.10197 0.0487823 5.33712 0.0120583 5.63585C0.00986099 5.6523 0.00383377 5.66874 0.000545502 5.68518L0.000545502 5.83647C0.0224686 5.95925 0.0591965 6.07545 0.133739 6.17521C0.204994 6.26894 0.287212 6.34677 0.386429 6.39939C1.94036 7.2331 3.49541 8.06789 5.05154 8.89722C5.17596 8.96299 5.30532 9.02877 5.45057 9.04137C5.59638 9.05453 5.7345 9.02822 5.86441 8.9608C7.46275 8.13313 9.06109 7.30655 10.6572 6.47504C10.871 6.36322 10.9932 6.16534 11.0415 5.91595C11.0464 5.89786 11.0497 5.87867 11.0541 5.86004L11.0541 5.71972C11.0393 5.66874 11.03 5.61448 11.0108 5.56624C10.8979 5.26532 10.6852 5.10033 10.3952 5.04442L10.3952 5.04387ZM10.3963 7.55319C10.2338 7.51913 10.0644 7.54318 9.91782 7.62116C9.62183 7.78012 9.32913 7.94456 9.03205 8.10023C7.88317 8.69659 6.73429 9.28967 5.58541 9.88602C5.5499 9.90681 5.50577 9.90618 5.47086 9.88438C4.06491 9.1455 2.65787 8.40882 1.25082 7.66994C1.04099 7.56197 0.804203 7.51759 0.569508 7.54223C0.295444 7.56415 0.0838623 7.78066 0.0241203 8.08104C0.0158997 8.11886 0.00767517 8.15558 0.000556946 8.19285L0.000556946 8.34414C0.0224762 8.46473 0.0581055 8.57983 0.12991 8.67849C0.202263 8.77661 0.287773 8.85554 0.390812 8.91035C1.94312 9.74351 3.49596 10.5767 5.0499 11.4043C5.18254 11.4756 5.32232 11.5414 5.47415 11.5562L5.58158 11.5562C5.70617 11.5342 5.82623 11.4916 5.93677 11.4301C6.08257 11.3506 6.23659 11.287 6.38404 11.2103C7.8026 10.4725 9.2206 9.73365 10.6375 8.99532C10.8622 8.87802 10.9922 8.68014 11.0426 8.41869L11.0541 8.36826L11.0541 8.22794C11.0393 8.17696 11.03 8.1227 11.0108 8.07446C10.8995 7.77299 10.6857 7.60856 10.3963 7.55374L10.3963 7.55319Z" fill="#4388FB" >
</path>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

BIN
hx-ai-intelligent/src/icon/del.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 B

6
hx-ai-intelligent/src/icon/del.svg

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="12px" height="12px" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1 0 0 1 -347 -469 )">
<path d="M 10.684322033898304 5.219491525423729 C 10.685593220338983 4.930932203389831 10.452966101694914 4.698305084745764 10.165677966101695 4.698305084745764 C 9.878389830508475 4.698305084745764 9.644491525423728 4.930932203389831 9.644491525423728 5.219491525423729 L 9.644491525423728 10.426271186440678 C 9.644491525423728 10.7135593220339 9.410593220338983 10.947457627118645 9.123305084745763 10.947457627118645 L 2.8754237288135593 10.947457627118645 C 2.588135593220339 10.947457627118645 2.354237288135593 10.7135593220339 2.354237288135593 10.426271186440678 L 2.354237288135593 5.219491525423729 C 2.354237288135593 4.932203389830509 2.1216101694915253 4.698305084745764 1.833050847457627 4.698305084745764 C 1.5444915254237288 4.698305084745764 1.3118644067796608 4.930932203389831 1.3118644067796608 5.219491525423729 L 1.3118644067796608 10.426271186440678 C 1.3118644067796608 11.288135593220339 2.01228813559322 11.988559322033899 2.8741525423728818 11.988559322033899 L 9.122033898305085 11.988559322033899 C 9.983898305084745 11.988559322033899 10.684322033898304 11.288135593220339 10.684322033898304 10.426271186440678 L 10.684322033898304 5.219491525423729 Z M 11.98728813559322 2.8766949152542374 C 11.98728813559322 2.589406779661017 11.753389830508475 2.3555084745762715 11.467372881355931 2.3555084745762715 L 9.12457627118644 2.3555084745762715 L 9.12457627118644 1.314406779661017 C 9.12457627118644 0.5961864406779662 8.539830508474576 0.012711864406779662 7.8228813559322035 0.012711864406779662 L 4.177118644067797 0.012711864406779662 C 3.458898305084746 0.012711864406779662 2.87542372881356 0.5961864406779662 2.87542372881356 1.314406779661017 L 2.87542372881356 2.3555084745762715 L 0.5326271186440679 2.3555084745762715 C 0.24661016949152548 2.3555084745762715 0.011440677966101768 2.589406779661017 0.011440677966101768 2.8766949152542374 C 0.011440677966101768 3.1627118644067798 0.2453389830508475 3.3978813559322036 0.5326271186440679 3.3978813559322036 L 11.466101694915254 3.3978813559322036 C 11.752118644067796 3.3978813559322036 11.98728813559322 3.163983050847458 11.98728813559322 2.8766949152542374 Z M 8.083474576271188 2.3555084745762715 L 3.917796610169492 2.3555084745762715 L 3.917796610169492 1.314406779661017 C 3.917796610169492 1.1707627118644068 4.034745762711864 1.053813559322034 4.1783898305084755 1.053813559322034 L 7.822881355932205 1.053813559322034 C 7.966525423728815 1.053813559322034 8.083474576271188 1.1707627118644068 8.083474576271188 1.314406779661017 L 8.083474576271188 2.3555084745762715 Z M 4.698305084745764 9.385169491525422 C 4.985593220338984 9.385169491525422 5.219491525423729 9.149999999999999 5.219491525423729 8.863983050847457 L 5.219491525423729 5.739406779661016 C 5.219491525423729 5.453389830508475 4.985593220338984 5.21822033898305 4.698305084745764 5.21822033898305 C 4.411016949152542 5.21822033898305 4.177118644067797 5.452118644067796 4.177118644067797 5.739406779661016 L 4.177118644067797 8.863983050847457 C 4.177118644067797 9.149999999999999 4.411016949152542 9.385169491525422 4.698305084745764 9.385169491525422 Z M 7.301694915254236 9.385169491525422 C 7.58771186440678 9.383898305084745 7.8228813559322035 9.149999999999999 7.8228813559322035 8.863983050847457 L 7.8228813559322035 5.739406779661016 C 7.8228813559322035 5.453389830508475 7.5889830508474585 5.21822033898305 7.301694915254236 5.21822033898305 C 7.015677966101695 5.21822033898305 6.780508474576271 5.452118644067796 6.780508474576271 5.739406779661016 L 6.780508474576271 8.863983050847457 C 6.780508474576271 9.149999999999999 7.014406779661017 9.385169491525422 7.301694915254236 9.385169491525422 Z " fill-rule="nonzero" fill="#d9001b" stroke="none" transform="matrix(1 0 0 1 347 469 )" />
</g>
</svg>

218
hx-ai-intelligent/src/view/alarmManagement/alarmSettings/energyAlarm/editConfigureEnergyAlarm.vue

@ -92,40 +92,64 @@
:showSearch="false"
placeholder="请选择对比类型" />
</a-form-item>
<template v-for="index in infoObject.alarmList?.length" :key="index">
<div style="width: 100%; display: flex; margin-left: 42px; padding: 12px">
<span style="line-height: 32px">{{ `逻辑${index}:` }}</span>
<a-select
v-model:value="infoObject.alarmList[index - 1].logic"
style="width: 70px; margin-left: 12px"
:options="logicEnum" />
<span style="line-height: 32px; margin-left: 32px">{{ `数值${index}:` }}</span>
<a-input
style="width: 65px; margin-left: 6px"
type="number"
v-model:value="infoObject.alarmList[index - 1].num" />
<div class="card-log">
<template v-for="index in infoObject.alarmList?.length" :key="index">
<div style="width: 100%; display: flex; margin-left: 22px; padding: 12px 14px 12px 0px">
<span class="title-name" style="line-height: 32px">{{ `逻辑${index}:` }}</span>
<a-select
v-model:value="infoObject.alarmList[index - 1].logic"
style="width: 110px; margin-left: 12px"
placeholder="请选择逻辑"
:options="logicEnum" />
<span class="title-name" style="line-height: 32px; margin-left: 32px">{{
`数值${index}:`
}}</span>
<a-input
style="width: 110px; margin-left: 6px"
type="number"
placeholder="请输入数值"
v-model:value="infoObject.alarmList[index - 1].num" />
<div
v-if="index > 1 && index === infoObject.alarmList?.length"
style="
cursor: pointer;
width: 20px;
height: 32px;
display: flex;
align-items: center;
margin-left: 16px;
"
@click="addAlarmList">
<img style="width: 16px" src="../../../../../src/icon/add.png" />
</div>
<div
v-if="index > 1 && infoObject.alarmList?.length > 2"
style="
cursor: pointer;
width: 20px;
height: 32px;
display: flex;
align-items: center;
margin-left: 16px;
"
@click="deleteAlarmList(index - 1)">
<img style="width: 16px" src="../../../../../src/icon/del.png" />
</div>
</div>
<div
style="width: 70px; align-items: center; cursor: pointer"
@click="deleteAlarmList(index - 1)">
<img style="width: 14px; margin: 0 12px" src="../../../../../src/icon/del.svg" />
v-if="
infoObject.alarmList[index - 1]?.num === '' ||
infoObject.alarmList[index - 1]?.logic === null
"
style="width: 100%; color: #ff4d4f; text-align: center; margin-bottom: 5px">
请选择正确的逻辑{{ index }} 输入正确的数值{{ index }}
</div>
</div>
</template>
<div
v-if="
infoObject.alarmList[index - 1]?.num === null ||
infoObject.alarmList[index - 1]?.logic === null
"
v-if="infoObject.alarmList?.length < 2"
style="width: 100%; color: #ff4d4f; text-align: center; margin-bottom: 5px">
请选择正确的逻辑{{ index }} 输入正确的数值{{ index }}
逻辑至少2条
</div>
</template>
<div
v-if="infoObject.alarmList?.length < 2"
style="width: 100%; color: #ff4d4f; text-align: center; margin-bottom: 5px">
逻辑至少2条
</div>
<div style="width: 100%; margin-top: 12px; display: flex; justify-content: flex-end">
<a-button type="primary" @click="addAlarmList"> 新增</a-button>
</div>
</a-form>
</div>
@ -157,7 +181,10 @@
abnormalDescription: null,
dataSources: null,
enableRules: 0,
alarmList: [{ id: null, logic: null, num: null, isDelete: 0 }],
alarmList: [
{ id: null, logic: null, num: '', isDelete: 0 },
{ id: null, logic: null, num: '', isDelete: 0 },
],
});
const emit = defineEmits(['editObject']);
//
@ -346,7 +373,10 @@
abnormalDescription: null,
dataSources: null,
enableRules: 0,
alarmList: [{ id: null, logic: null, num: null, isDelete: 0 }],
alarmList: [
{ id: null, logic: null, num: '', isDelete: 0 },
{ id: null, logic: null, num: '', isDelete: 0 },
],
};
infoObject.value.site = orgId.value;
}
@ -374,61 +404,68 @@
},
],
};
//
const btnClick = () => {
infoObject.value.alarmList.forEach((item) => {
if (item.logic === null || item.num === null) {
return;
const getBoolean = () => {
for (const item of infoObject.value.alarmList) {
if (item.logic === null || item.num === '') {
return false;
}
});
}
if (infoObject.value.alarmList.length < 2) {
NsMessage.error('请选择逻辑和数值');
return;
return false;
}
return true;
};
//
const btnClick = async () => {
let formBoolean = await getBoolean();
//
formRef.value.validate().then(() => {
//
let data = { ...infoObject.value };
if (!data.orgId) {
data.orgId = orgId.value;
}
//id
data.energyConsumptionAlarmId = energyAlarm.value.id;
data.errorCode = energyAlarm.value.errorCode;
data.dataSourcesType = data.dataSources[0];
data.dataSourcesWay = data.dataSources[1];
delete data.dataSources;
data.hxAlarmRuleLogicList = [...infoObject.value.alarmList, ...delAlarmList.value];
data.comparisonType = data.comparisonType.toString();
data.hxAlarmRuleLogicList.forEach((item) => {
const num = Number(item.num);
if (!isNaN(num)) {
item.num = Number(num.toFixed(2));
} else {
item.num = 0; // 0
if (formBoolean) {
formRef.value.validate().then(() => {
//
let data = { ...infoObject.value };
if (!data.orgId) {
data.orgId = orgId.value;
}
});
data.ruleType = Number(data.ruleType);
delete data.alarmList;
http
.post(energyAlarms.configAddOrUpNewData, data)
.then((res) => {
if (res.msg === 'success') {
//
if (data.id) {
NsMessage.success('告警规则编辑成功');
} else {
NsMessage.success('告警规则新增成功');
}
emit('editObject', null);
handleClose();
//id
data.energyConsumptionAlarmId = energyAlarm.value.id;
data.errorCode = energyAlarm.value.errorCode;
data.dataSourcesType = data.dataSources[0];
data.dataSourcesWay = data.dataSources[1];
delete data.dataSources;
data.hxAlarmRuleLogicList = [...infoObject.value.alarmList, ...delAlarmList.value];
data.comparisonType = data.comparisonType.toString();
data.hxAlarmRuleLogicList.forEach((item) => {
const num = Number(item.num);
if (!isNaN(num)) {
item.num = Number(num.toFixed(2));
} else {
item.num = 0; // 0
}
})
.catch((error) => {
//
console.error('请求失败:', error);
});
});
data.ruleType = Number(data.ruleType);
delete data.alarmList;
http
.post(energyAlarms.configAddOrUpNewData, data)
.then((res) => {
if (res.msg === 'success') {
//
if (data.id) {
NsMessage.success('告警规则编辑成功');
} else {
NsMessage.success('告警规则新增成功');
}
emit('editObject', null);
handleClose();
}
})
.catch((error) => {
//
console.error('请求失败:', error);
});
});
}
};
//
const handleClose = () => {
@ -443,7 +480,10 @@
abnormalDescription: null,
dataSources: null,
enableRules: 0,
alarmList: [{ id: null, logic: null, num: null, isDelete: 0 }],
alarmList: [
{ id: null, logic: null, num: '', isDelete: 0 },
{ id: null, logic: null, num: '', isDelete: 0 },
],
};
visible.value = false;
delAlarmList.value = [];
@ -451,9 +491,9 @@
//
const addAlarmList = () => {
if (infoObject.value.alarmList) {
infoObject.value.alarmList.push({ id: null, logic: null, num: null, isDelete: 0 });
infoObject.value.alarmList.push({ id: null, logic: null, num: '', isDelete: 0 });
} else {
infoObject.value.alarmList = [{ id: null, logic: null, num: null, isDelete: 0 }];
infoObject.value.alarmList = [{ id: null, logic: null, num: '', isDelete: 0 }];
}
};
//
@ -522,4 +562,20 @@
text-align: right;
width: 20%;
}
.card-log {
width: 100%;
height: auto;
border-radius: 4px;
background: rgba(250, 250, 250, 1);
padding-bottom: 12px;
.title-name::before {
display: inline-block;
margin-right: 4px;
color: #ff4d4f;
font-size: 14px;
font-family: SimSun, sans-serif;
line-height: 1;
content: '*';
}
}
</style>

224
hx-ai-intelligent/src/view/alarmManagement/alarmSettings/equipmentAlarm/editConfigureDeviceAlarm.vue

@ -103,48 +103,64 @@
<a-radio value="2"> (or) </a-radio>
</a-radio-group>
</a-form-item>
<template v-for="index in infoObject.alarmList?.length" :key="index">
<div
style="
width: 100%;
display: flex;
margin-left: 42px;
padding: 12px;
border-color: #ff4d4f !important;
">
<span style="line-height: 32px">{{ `逻辑${index}:` }}</span>
<a-select
v-model:value="infoObject.alarmList[index - 1].logic"
style="width: 70px; margin-left: 12px"
:options="logicEnum" />
<span style="line-height: 32px; margin-left: 32px">{{ `数值${index}:` }}</span>
<a-input
style="width: 65px; margin-left: 6px"
type="number"
status="error"
v-model:value="infoObject.alarmList[index - 1].num" />
<div class="card-log">
<template v-for="index in infoObject.alarmList?.length" :key="index">
<div style="width: 100%; display: flex; margin-left: 22px; padding: 12px 14px 12px 0px">
<span class="title-name" style="line-height: 32px">{{ `逻辑${index}:` }}</span>
<a-select
v-model:value="infoObject.alarmList[index - 1].logic"
style="width: 110px; margin-left: 12px"
placeholder="请选择逻辑"
:options="logicEnum" />
<span class="title-name" style="line-height: 32px; margin-left: 32px">{{
`数值${index}:`
}}</span>
<a-input
style="width: 110px; margin-left: 6px"
type="number"
placeholder="请输入数值"
v-model:value="infoObject.alarmList[index - 1].num" />
<div
v-if="index > 1 && index === infoObject.alarmList?.length"
style="
cursor: pointer;
width: 20px;
height: 32px;
display: flex;
align-items: center;
margin-left: 16px;
"
@click="addAlarmList">
<img style="width: 16px" src="../../../../../src/icon/add.png" />
</div>
<div
v-if="index > 1 && infoObject.alarmList?.length > 2"
style="
cursor: pointer;
width: 20px;
height: 32px;
display: flex;
align-items: center;
margin-left: 16px;
"
@click="deleteAlarmList(index - 1)">
<img style="width: 16px" src="../../../../../src/icon/del.png" />
</div>
</div>
<div
style="width: 70px; align-items: center; cursor: pointer"
@click="deleteAlarmList(index - 1)">
<img style="width: 14px; margin: 0 12px" src="../../../../../src/icon/del.svg" />
v-if="
infoObject.alarmList[index - 1]?.num === '' ||
infoObject.alarmList[index - 1]?.logic === null
"
style="width: 100%; color: #ff4d4f; text-align: center; margin-bottom: 5px">
请选择正确的逻辑{{ index }} 输入正确的数值{{ index }}
</div>
</div>
</template>
<div
v-if="
infoObject.alarmList[index - 1]?.num === null ||
infoObject.alarmList[index - 1]?.logic === null
"
v-if="infoObject?.alarmList?.length < 2"
style="width: 100%; color: #ff4d4f; text-align: center; margin-bottom: 5px">
请选择正确的逻辑{{ index }} 输入正确的数值{{ index }}
逻辑至少2条
</div>
</template>
<div
v-if="infoObject?.alarmList?.length < 2"
style="width: 100%; color: #ff4d4f; text-align: center; margin-bottom: 5px">
逻辑至少2条
</div>
<div style="width: 100%; margin-top: 12px; display: flex; justify-content: flex-end">
<a-button type="primary" @click="addAlarmList"> 新增</a-button>
</div>
</a-form>
</div>
@ -173,7 +189,10 @@
valueType: null,
deviceInfoCode: null,
enableRules: 0,
alarmList: [{ logic: null, num: null, isDelete: 0 }],
alarmList: [
{ logic: null, num: '', isDelete: 0 },
{ id: null, logic: null, num: '', isDelete: 0 },
],
});
//
const delAlarmList = ref([]);
@ -363,7 +382,10 @@
valueType: null,
deviceInfoCode: null,
enableRules: 0,
alarmList: [{ logic: null, num: null, isDelete: 0 }],
alarmList: [
{ logic: null, num: '', isDelete: 0 },
{ logic: null, num: '', isDelete: 0 },
],
};
infoObject.value.site = orgId.value;
}
@ -396,60 +418,67 @@
alarm: [{ required: true, message: '请选择逻辑', trigger: 'blur' }],
number: [{ required: true, message: '请输入数值', trigger: 'blur' }],
};
//
const btnClick = () => {
infoObject.value.alarmList.forEach((item) => {
if (item.logic === null || item.num === null) {
return;
const getBoolean = () => {
for (const item of infoObject.value.alarmList) {
if (item.logic === null || item.num === '') {
return false;
}
});
}
if (infoObject.value.alarmList.length < 2) {
NsMessage.error('请选择逻辑和数值');
return;
return false;
}
return true;
};
//
const btnClick = async () => {
let formBoolean = await getBoolean();
//
formRef.value.validate().then(() => {
let data = { ...infoObject.value };
if (!data.orgId) {
data.orgId = orgId.value;
}
// id
data.equipmentAlarmId = equipmentAlarm.value.id;
//
data.hxAlarmRuleLogicList = [...infoObject.value.alarmList, ...delAlarmList.value];
data.hxAlarmRuleLogicList.forEach((item) => {
const num = Number(item.num);
if (!isNaN(num)) {
item.num = Number(num.toFixed(2));
} else {
item.num = 0; // 0
if (formBoolean) {
formRef.value.validate().then(() => {
let data = { ...infoObject.value };
if (!data.orgId) {
data.orgId = orgId.value;
}
});
// id
data.deviceType = infoObject.value.deviceType[infoObject.value.deviceType.length - 1];
data.ruleType = Number(data.ruleType);
data.errorCode = equipmentAlarm.value.errorCode;
delete data.alarmList;
// HTTP POST
http
.post(deviceAlarms.configAddOrUpNewData, data)
.then((res) => {
if (res.msg === 'success') {
//
if (data.id) {
NsMessage.success('告警规则编辑成功');
} else {
NsMessage.success('告警规则新增成功');
}
emit('editObject', null);
handleClose();
// id
data.equipmentAlarmId = equipmentAlarm.value.id;
//
data.hxAlarmRuleLogicList = [...infoObject.value.alarmList, ...delAlarmList.value];
data.hxAlarmRuleLogicList.forEach((item) => {
const num = Number(item.num);
if (!isNaN(num)) {
item.num = Number(num.toFixed(2));
} else {
item.num = 0; // 0
}
})
.catch((error) => {
//
console.error('请求失败:', error);
});
});
// id
data.deviceType = infoObject.value.deviceType[infoObject.value.deviceType.length - 1];
data.ruleType = Number(data.ruleType);
data.errorCode = equipmentAlarm.value.errorCode;
delete data.alarmList;
// HTTP POST
http
.post(deviceAlarms.configAddOrUpNewData, data)
.then((res) => {
if (res.msg === 'success') {
//
if (data.id) {
NsMessage.success('告警规则编辑成功');
} else {
NsMessage.success('告警规则新增成功');
}
emit('editObject', null);
handleClose();
}
})
.catch((error) => {
//
console.error('请求失败:', error);
});
});
}
};
//
const handleClose = () => {
@ -466,7 +495,10 @@
valueType: null,
deviceInfoCode: null,
enableRules: 0,
alarmList: [{ logic: null, num: null, isDelete: 0 }],
alarmList: [
{ logic: null, num: '', isDelete: 0 },
{ logic: null, num: '', isDelete: 0 },
],
};
visible.value = false;
//
@ -475,9 +507,9 @@
//
const addAlarmList = () => {
if (infoObject.value.alarmList) {
infoObject.value.alarmList.push({ logic: null, num: null, isDelete: 0 });
infoObject.value.alarmList.push({ logic: null, num: '', isDelete: 0 });
} else {
infoObject.value.alarmList = [{ logic: null, num: null, isDelete: 0 }];
infoObject.value.alarmList = [{ logic: null, num: '', isDelete: 0 }];
}
};
//
@ -550,4 +582,20 @@
width: 20%;
position: relative;
}
.card-log {
width: 100%;
height: auto;
border-radius: 4px;
background: rgba(250, 250, 250, 1);
padding-bottom: 12px;
.title-name::before {
display: inline-block;
margin-right: 4px;
color: #ff4d4f;
font-size: 14px;
font-family: SimSun, sans-serif;
line-height: 1;
content: '*';
}
}
</style>

2
hx-ai-intelligent/src/view/alarmManagement/alarmSettings/equipmentAlarm/editeEquipmentAlarm.vue

@ -326,8 +326,6 @@
data.intervalDuration = null;
data.intervalDurationUnit = null;
}
console.log(data, '数据');
if (!data.orgId) {
data.orgId = orgId.value;
}

9
hx-ai-intelligent/src/view/alarmManagement/energyAlarm/index.vue

@ -14,7 +14,7 @@
</template>
</ns-view-list-table>
<!-- 详情页面 -->
<Look ref="look" />
<Look class="look-energy" ref="look" />
<!-- 状态页面 -->
<Status ref="status" @logAdd="logAdd" />
</template>
@ -46,3 +46,10 @@
},
};
</script>
<style lang="less">
.look-energy {
.ant-drawer-body {
padding: 24px 40px !important;
}
}
</style>

49
hx-ai-intelligent/src/view/alarmManagement/energyAlarm/look.vue

@ -11,9 +11,7 @@
<div style="width: 100%; height: 100%; overflow-y: auto; overflow-x: hidden">
<!-- top -->
<div class="boxstyle">
<div
class="ns-title-extra-box"
style="left: 5px; position: absolute; height: 35px; line-height: 30px">
<div class="ns-title-extra-box" style="position: absolute; height: 35px; line-height: 30px">
告警编号{{ infoObject.alarmCode }}
</div>
<div style="right: 20px; position: absolute; height: 35px; line-height: 30px">
@ -21,7 +19,7 @@
</div>
</div>
<!-- center -->
<div style="width: 100%; height: 400px">
<div style="width: 100%; height: 300px">
<div style="width: 100%; height: 100%" ref="graphChart"></div>
</div>
<!-- bottom -->
@ -214,19 +212,14 @@
//
dataZoom: [
{
type: 'inside',
start: 0,
end: 100,
},
{
type: 'slider',
// backgroundColor: 'yellow',
// fillerColor: 'yellow',
height: 12, // slider15
start: 0,
end: 100,
right: 60,
left: 60,
right: 11,
left: 10,
bottom: 10,
handleIcon:
'path://M30.9,53.2C16.8,53.2,5.3,41.7,5.3,27.6S16.8,2,30.9,2C45,2,56.4,13.5,56.4,27.6S45,53.2,30.9,53.2z M30.9,3.5M36.9,35.8h-1.3z M27.8,35.8 h-1.3H27L27.8,35.8L27.8,35.8z', // 使 axisPointer
@ -257,15 +250,20 @@
name: '电压值',
type: 'line',
itemStyle: {
color: '#fff',
borderColor: 'rgba(67, 136, 251, 1)',
borderWidth: 2,
},
lineStyle: {
normal: {
barBorderRadius: 0,
color: '#2778FF',
color: 'rgba(67, 136, 251, 1)',
width: 2,
},
},
symbol: 'circle', //
symbolSize: 8,
label: {
show: true,
show: false,
color: 'rgb(89, 89, 89)',
position: 'top',
top: '10',
@ -273,6 +271,29 @@
return Number(energyAlarm[value.dataIndex]) + 'V';
},
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[
{
offset: 0,
color: 'rgba(22, 127, 255, 0.4)',
},
{
offset: 1,
color: 'rgba(22, 127, 255, 0)',
},
],
false,
),
shadowColor: 'rgba(22, 127, 255, 0.4)',
shadowBlur: 20,
},
},
data: energyAlarm,
},
],

18
hx-ai-intelligent/src/view/alarmManagement/energyAlarm/status.vue

@ -142,15 +142,23 @@
infoObject.value = { ...logList.value[0] };
infoObject.value.state = infoObject.value.state.value;
let colorMap = {
1: '#ff7602',
2: '#00a1e6',
3: '#04d919',
4: '#d9001b',
5: '#a6a6a6',
1: 'rgba(191, 205, 226, 1)',
2: 'rgba(243, 97, 99, 1)',
3: 'rgba(41, 196, 154, 1)',
4: 'rgba(217, 0, 27,1)',
5: 'rgba(166, 166, 166,1)',
};
let bgColorMap = {
1: 'rgba(191, 205, 226, 0.1)',
2: 'rgba(243, 97, 99, 0.1)',
3: 'rgba(41, 196, 154, 0.1)',
4: 'rgba(217, 0, 27, 0.1)',
5: 'rgba(166, 166, 166,0.1)',
};
logList.value.forEach((item) => {
item.stateName = item.state.label;
item.color = colorMap[item.state.value];
item.bgColor = bgColorMap[item.state];
item.src = 'state-' + item.state.value;
});
config.value.dataSource = logList.value;

9
hx-ai-intelligent/src/view/alarmManagement/equipmentAlarm/index.vue

@ -14,7 +14,7 @@
</template>
</ns-view-list-table>
<!-- 详情页面 -->
<Look ref="look" />
<Look class="look-equipment" ref="look" />
<!-- 状态页面 -->
<Status ref="status" @logAdd="logAdd" />
</template>
@ -46,3 +46,10 @@
},
};
</script>
<style lang="less">
.look-equipment {
.ant-drawer-body {
padding: 24px 40px !important;
}
}
</style>

53
hx-ai-intelligent/src/view/alarmManagement/equipmentAlarm/look.vue

@ -11,9 +11,7 @@
<div style="width: 100%; height: 100%; overflow-y: auto; overflow-x: hidden">
<!-- top -->
<div class="boxstyle">
<div
class="ns-title-extra-box"
style="left: 5px; position: absolute; height: 35px; line-height: 30px">
<div class="ns-title-extra-box" style="position: absolute; height: 35px; line-height: 30px">
告警编号{{ infoObject.alarmCode }}
</div>
<div style="right: 20px; position: absolute; height: 35px; line-height: 30px">
@ -21,7 +19,7 @@
</div>
</div>
<!-- center -->
<div style="width: 100%; height: 400px">
<div style="width: 100%; height: 300px">
<div style="width: 100%; height: 100%" ref="graphChart"></div>
</div>
<!-- bottom -->
@ -134,8 +132,8 @@
},
},
grid: {
left: '10%', //
right: '4%', //
left: '9%', //
right: '3%', //
top: '6%',
borderWidth: 0,
y2: 60, //
@ -213,19 +211,14 @@
//
dataZoom: [
{
type: 'inside',
start: 0,
end: 100,
},
{
type: 'slider',
// backgroundColor: 'yellow',
// fillerColor: 'yellow',
height: 12, // slider15
start: 0,
end: 100,
right: 60,
left: 60,
right: 10,
left: 10,
bottom: 10,
handleIcon:
'path://M30.9,53.2C16.8,53.2,5.3,41.7,5.3,27.6S16.8,2,30.9,2C45,2,56.4,13.5,56.4,27.6S45,53.2,30.9,53.2z M30.9,3.5M36.9,35.8h-1.3z M27.8,35.8 h-1.3H27L27.8,35.8L27.8,35.8z', // 使 axisPointer
@ -256,15 +249,20 @@
name: '电压值',
type: 'line',
itemStyle: {
color: '#fff',
borderColor: 'rgba(67, 136, 251, 1)',
borderWidth: 2,
},
lineStyle: {
normal: {
barBorderRadius: 0,
color: '#2778FF',
color: 'rgba(67, 136, 251, 1)',
width: 2,
},
},
symbol: 'circle', //
symbolSize: 8,
label: {
show: true,
show: false,
color: 'rgb(89, 89, 89)',
position: 'top',
top: '10',
@ -272,6 +270,29 @@
return Number(energyAlarm[value.dataIndex]) + 'V';
},
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[
{
offset: 0,
color: 'rgba(22, 127, 255, 0.4)',
},
{
offset: 1,
color: 'rgba(22, 127, 255, 0)',
},
],
false,
),
shadowColor: 'rgba(22, 127, 255, 0.4)',
shadowBlur: 20,
},
},
data: energyAlarm,
},
],

18
hx-ai-intelligent/src/view/alarmManagement/equipmentAlarm/status.vue

@ -143,15 +143,23 @@
infoObject.value = { ...logList.value[0] };
infoObject.value.state = infoObject.value.state.value;
let colorMap = {
1: '#ff7602',
2: '#00a1e6',
3: '#04d919',
4: '#d9001b',
5: '#a6a6a6',
1: 'rgba(191, 205, 226, 1)',
2: 'rgba(243, 97, 99, 1)',
3: 'rgba(41, 196, 154, 1)',
4: 'rgba(217, 0, 27,1)',
5: 'rgba(166, 166, 166,1)',
};
let bgColorMap = {
1: 'rgba(191, 205, 226, 0.1)',
2: 'rgba(243, 97, 99, 0.1)',
3: 'rgba(41, 196, 154, 0.1)',
4: 'rgba(217, 0, 27, 0.1)',
5: 'rgba(166, 166, 166,0.1)',
};
logList.value.forEach((item) => {
item.stateName = item.state.label;
item.color = colorMap[item.state.value];
item.bgColor = bgColorMap[item.state];
item.src = 'state-' + item.state.value;
});
config.value.dataSource = logList.value;

9
hx-ai-intelligent/src/view/alarmManagement/gatewayAlarm/index.vue

@ -10,7 +10,7 @@
</template>
</ns-view-list-table>
<!-- 详情页面 -->
<Look ref="look" />
<Look class="look-gateWay" ref="look" />
<!-- 状态页面 -->
<Status ref="status" />
</template>
@ -36,3 +36,10 @@
},
};
</script>
<style lang="less">
.look-gateWay {
.ant-drawer-body {
padding: 24px 40px !important;
}
}
</style>

51
hx-ai-intelligent/src/view/alarmManagement/gatewayAlarm/look.vue

@ -11,9 +11,7 @@
<div style="width: 100%; height: 100%; overflow-y: auto; overflow-x: hidden">
<!-- top -->
<div class="boxstyle">
<div
class="ns-title-extra-box"
style="left: 25px; position: absolute; height: 35px; line-height: 30px">
<div class="ns-title-extra-box" style="position: absolute; height: 35px; line-height: 30px">
告警编号{{ infoObject.alarmCode }}
</div>
<div style="right: 30px; position: absolute; height: 35px; line-height: 30px">
@ -21,7 +19,7 @@
</div>
</div>
<!-- center -->
<div style="width: 100%; height: 400px">
<div style="width: 100%; height: 300px">
<div style="width: 100%; height: 100%" ref="graphChart"></div>
</div>
<!-- bottom -->
@ -127,8 +125,8 @@
},
},
grid: {
left: '10%', //
right: '4%', //
left: '3%', //
right: '3%', //
top: '6%',
borderWidth: 0,
y2: 60, //
@ -201,19 +199,14 @@
//
dataZoom: [
{
type: 'inside',
start: 0,
end: 100,
},
{
type: 'slider',
// backgroundColor: 'yellow',
// fillerColor: 'yellow',
height: 12, // slider15
start: 0,
end: 100,
right: 60,
left: 60,
right: 11,
left: 10,
bottom: 10,
handleIcon:
'path://M30.9,53.2C16.8,53.2,5.3,41.7,5.3,27.6S16.8,2,30.9,2C45,2,56.4,13.5,56.4,27.6S45,53.2,30.9,53.2z M30.9,3.5M36.9,35.8h-1.3z M27.8,35.8 h-1.3H27L27.8,35.8L27.8,35.8z', // 使 axisPointer
@ -244,9 +237,14 @@
name: '状态',
type: 'line',
itemStyle: {
color: '#fff',
borderColor: 'rgba(67, 136, 251, 1)',
borderWidth: 2,
},
lineStyle: {
normal: {
barBorderRadius: 0,
color: '#2778FF',
color: 'rgba(67, 136, 251, 1)',
width: 2,
},
},
symbol: 'circle', //
@ -260,6 +258,29 @@
// return Number(energyAlarm[value.dataIndex]) ;
// },
// },
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[
{
offset: 0,
color: 'rgba(22, 127, 255, 0.4)',
},
{
offset: 1,
color: 'rgba(22, 127, 255, 0)',
},
],
false,
),
shadowColor: 'rgba(22, 127, 255, 0.4)',
shadowBlur: 20,
},
},
data: energyAlarm,
},
],

18
hx-ai-intelligent/src/view/alarmManagement/gatewayAlarm/status.vue

@ -60,15 +60,23 @@
5: '已关闭',
};
let colorMap = {
1: '#ff7602',
2: '#00a1e6',
3: '#04d919',
4: '#d9001b',
5: '#a6a6a6',
1: 'rgba(191, 205, 226, 1)',
2: 'rgba(243, 97, 99, 1)',
3: 'rgba(41, 196, 154, 1)',
4: 'rgba(217, 0, 27,1)',
5: 'rgba(166, 166, 166,1)',
};
let bgColorMap = {
1: 'rgba(191, 205, 226, 0.1)',
2: 'rgba(243, 97, 99, 0.1)',
3: 'rgba(41, 196, 154, 0.1)',
4: 'rgba(217, 0, 27, 0.1)',
5: 'rgba(166, 166, 166,0.1)',
};
logList.value.forEach((item) => {
item.stateName = stateMap[item.state];
item.color = colorMap[item.state];
item.bgColor = bgColorMap[item.state];
item.src = 'state-' + item.state;
});
visible.value = true;

129
hx-ai-intelligent/src/view/carbonEmissionManage/carbonAssets/carbonAssetsDetail/index.vue

@ -48,64 +48,70 @@
</div>
<div style="display: flex; margin-top: 20px; height: calc(84% - 20px)">
<div class="detailTable">
<a-card>
<div class="ns-form-title">
<div class="title">交易明细</div>
<div class="operation" style="display: flex">
<a-button type="primary" @click="addDetail">新增</a-button>
<a-upload
v-model:file-list="importFileList"
name="file"
accept=".xlsx"
:showUploadList="false"
:custom-request="importFile">
<a-button type="primary" style="margin-left: 6px">导入</a-button>
</a-upload>
<a-button type="primary" style="margin-left: 6px" @click="exportFile">导出</a-button>
<a-button
type="primary"
style="margin-left: 6px"
:disabled="selectedRowKeys.length === 0"
@click="deleteMore"
>批量删除</a-button
>
</div>
<div class="ns-form-title">
<div class="title">交易明细</div>
<div class="operation" style="display: flex">
<a-button type="primary" @click="addDetail">新增</a-button>
<a-upload
v-model:file-list="importFileList"
name="file"
accept=".xlsx"
:showUploadList="false"
:custom-request="importFile">
<a-button type="primary" style="margin-left: 6px">导入</a-button>
</a-upload>
<a-button type="primary" style="margin-left: 6px" @click="exportFile">导出</a-button>
<a-button
type="primary"
style="margin-left: 6px"
:disabled="selectedRowKeys.length === 0"
@click="deleteMore"
>批量删除</a-button
>
</div>
<a-table
:columns="columns"
:data-source="data"
rowKey="id"
@change="onChange"
:rowSelection="{
selectedRowKeys: selectedRowKeys,
onChange: onSelectionChange,
}"
:scroll="{ x: 1500, y: 400 }"
:pagination="false">
<template #bodyCell="{ column, text, record }">
<template v-if="column.dataIndex === 'accountType'">
<span v-if="record.accountType">{{ record.accountType.label }}</span>
</template>
<template v-if="column.key === 'action'">
<span>
<a @click="editData(record)">编辑</a>
<a-divider type="vertical" />
<a @click="delData(record)">删除</a>
</span>
</template>
</div>
<a-table
:columns="columns"
:data-source="data"
rowKey="id"
@change="onChange"
:rowSelection="{
selectedRowKeys: selectedRowKeys,
onChange: onSelectionChange,
}"
:scroll="{ x: 1500, y: 400 }"
:pagination="false">
<template #bodyCell="{ column, text, record }">
<template v-if="column.dataIndex === 'accountType'">
<span v-if="record.accountType">{{ record.accountType.label }}</span>
</template>
</a-table>
<a-pagination
:current="queryParams.pageNum"
:total="total"
:page-size="queryParams.pageSize"
style="display: flex; justify-content: center; margin-top: 16px"
:show-size-changer="true"
:show-quick-jumper="true"
@change="onChange" />
</a-card>
<template v-if="column.key === 'action'">
<span>
<a @click="editData(record)">编辑</a>
<a-divider type="vertical" />
<a @click="delData(record)">删除</a>
</span>
</template>
</template>
</a-table>
<a-pagination
:current="queryParams.pageNum"
:total="total"
:page-size="queryParams.pageSize"
style="display: flex; justify-content: center; margin-top: 16px"
:show-size-changer="true"
:show-quick-jumper="true"
@change="onChange" />
</div>
<div class="total">
<div class="ns-form-title">
<div class="title">配额统计</div>
<div class="operation" style="display: flex; justify-content: space-around; width: 63%">
<a-button type="primary" @click="getTotalTable(1)">全国配额</a-button>
<a-button type="primary" @click="getTotalTable(2)">地方配额</a-button>
<a-button type="primary" @click="getTotalTable(3)">CCER配额</a-button>
</div>
</div>
<a-table :columns="totalColumns" :data-source="totalData" bordered :pagination="false">
<template #bodyCell="{ column, text }">
<template v-if="column.dataIndex === 'name'">
@ -123,6 +129,9 @@
:footer-style="{ textAlign: 'right' }"
destroyOnClose
@close="onClose">
<div class="ns-form-title" style="display: flex">
<div class="title">{{ text }}</div>
</div>
<a-form
ref="formRef"
:model="formState"
@ -295,6 +304,7 @@
};
const editData = (record) => {
getDictList();
text.value = '编辑';
visible.value = true;
formState.value.id = record.id;
fetch(uploadPic.select, { bizId: record.id, bizType: 1 }).then((res) => {
@ -376,6 +386,7 @@
};
//
const visible = ref(false);
const text = ref('新增');
const formState = ref({
orgId: orgId.value,
});
@ -404,6 +415,7 @@
getDictList();
//
const addDetail = () => {
text.value = '新增';
visible.value = true;
getDictList();
};
@ -447,7 +459,7 @@
// URL
window.URL.revokeObjectURL(url);
selectedRowKeys.value = []
selectedRowKeys.value = [];
})
.catch((error) => {
console.error('下载失败:', error);
@ -545,7 +557,10 @@
formRef.value.resetFields();
};
//
const getTotalTable = () => {
const getTotalTable = (type) => {
if (type) {
queryParams.value.accountType = type;
}
fetch(carbonAssets.quotaStatistics, queryParams.value).then((res) => {
totalData.value = res.data;
});
@ -614,11 +629,13 @@
height: 100%;
background: white;
border-radius: 12px;
padding: 16px;
}
.total {
width: calc(35% - 20px);
height: 100%;
background: white;
border-radius: 12px;
padding: 16px;
}
</style>

76
hx-ai-intelligent/src/view/carbonEmissionManage/carbonEmissionFactorLibrary/index.vue

@ -5,7 +5,7 @@
<div class="left">
<div class="top">
<a-form style="width: 100%; margin: 0 auto">
<div class="ns-form-title"><div class="title">排放分类</div></div>
<div class="ns-form-title"><div class="title">能源分组</div></div>
<div style="padding: 0 16px !important; width: 100%">
<a-row>
<a-col :span="24" style="margin-bottom: 16px">
@ -23,7 +23,6 @@
class="draggable-tree"
style="padding: 0 16px !important"
draggable
show-line
checkable
block-node
:tree-data="gData"
@ -80,9 +79,9 @@
</div>
</template>
</a-tree>
<div class="addTreeNode">
<!-- <div class="addTreeNode">
<a-button type="primary" style="width: 100%" @click="addTreeNodeData">新增</a-button>
</div>
</div> -->
</div>
</div>
<div class="right">
@ -96,7 +95,7 @@
</div>
<!-- 新增树节点 -->
<ns-modal :visible="treeNodeAdd" :title="operationTree" @ok="handleOk" @cancel="handleCancel">
<ns-input v-model:value="addTreeNode" class="input" placeholder="请输入排放类型" />
<ns-input v-model:value="addTreeNode" :maxlength="10" class="input" placeholder="请输入排放类型" />
</ns-modal>
<!-- 新增数据库数据 -->
<a-drawer
@ -106,6 +105,9 @@
:footer-style="{ textAlign: 'right' }"
destroyOnClose
@close="onClose">
<div class="ns-form-title-add" style="display: flex">
<div class="title">{{ text }}</div>
</div>
<ns-form
ref="formRef"
:schemas="formSchema"
@ -129,8 +131,8 @@
@close="closeUnitManag">
<div class="ns-form-title titleUnit">
<div class="title">单位管理</div>
<a-button type="primary" @click="addGroup">新增分组</a-button>
<a-button type="primary" @click="addUnit">新增单位</a-button>
<a-button type="primary" @click="addGroup" ghost>新增分组</a-button>
<a-button type="primary" @click="addUnit" ghost>新增单位</a-button>
</div>
<!-- <div class="addButton">
</div> -->
@ -147,7 +149,7 @@
ref="select"
:value="unitTreeParams.id"
allowClear
style="width: 96%"
style="width: 90%"
placeholder="选择分组"
@change="handleChange">
<a-select-option v-for="(item, index) in groupData" :key="index" :value="item.id">
@ -185,11 +187,12 @@
</template>
</a-drawer>
<!-- 新增分组管理 -->
<ns-modal
:visible="addGroupManage"
:title="addGroupTitle"
@ok="unitOrGroupOk"
@cancel="groupCancel">
<ns-modal :visible="addGroupManage" @ok="unitOrGroupOk" @cancel="groupCancel">
<template #title>
<div style="display: flex; align-items: center">
<span class="titleStyleGroup">{{ addGroupTitle }}</span>
</div>
</template>
<a-form ref="unitFormRef" :model="formState" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-form-item label="分组名称" name="cnValue" :required="true">
<a-input v-model:value="formState.cnValue" placeholder="请输入分组名称" />
@ -197,11 +200,12 @@
</a-form>
</ns-modal>
<!-- 新增单位 -->
<ns-modal
:visible="addUnitManage"
:title="addUnitTitle"
@ok="unitOrGroupOk"
@cancel="unitCancel">
<ns-modal :visible="addUnitManage" @ok="unitOrGroupOk" @cancel="unitCancel">
<template #title>
<div style="display: flex; align-items: center">
<span class="titleStyle">{{ addUnitTitle }}</span>
</div>
</template>
<a-form ref="unitFormRef" :model="formState" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-form-item label="单位名称" name="cnValue" :required="true">
<a-input v-model:value="formState.cnValue" placeholder="请输入单位名称" />
@ -265,6 +269,7 @@
const disabled = ref(false);
const treeNodeAdd = ref<boolean>(false);
const operationTree = ref<string>('新增');
const text = ref('新增数据');
// const showOperation = ref(false);
const opMap: any = ref({
@ -473,7 +478,11 @@
cancelText: '取消',
onOk() {
http
.post(carbonEmissionFactorLibrary.delTreeNode, { orgId: orgId.value, id: data.id })
.post(carbonEmissionFactorLibrary.delTreeNode, {
orgId: orgId.value,
id: data.id,
emissionName: data.emissionName,
})
.then(() => {
getOrgTree();
NsMessage.success('操作成功');
@ -637,6 +646,7 @@
});
};
show.value = false;
text.value = '新增数据';
visible.value = true;
},
},
@ -812,6 +822,7 @@
});
};
show.value = true;
text.value = '编辑数据';
visible.value = true;
},
},
@ -1122,6 +1133,10 @@
padding-bottom: 10px;
border-bottom: 1px solid #e9e9e9;
}
.ns-form-title-add {
font-weight: bold;
user-select: text;
}
.titleUnit {
font-weight: bold;
user-select: text;
@ -1176,6 +1191,7 @@
margin-left: 10%;
flex-direction: column;
border-radius: 12px;
overflow: auto;
}
.actionMore {
display: none;
@ -1198,5 +1214,27 @@
text-align: right;
width: 27%;
}
.titleStyleGroup::before {
content: '';
position: absolute;
left: 16px;
top: 13%;
transform: translateY(-50%);
height: 16px;
width: 3px;
border-radius: 1px;
background-color: #2778ff;
}
.titleStyle::before {
content: '';
position: absolute;
left: 16px;
top: 10.5%;
transform: translateY(-50%);
height: 16px;
width: 3px;
border-radius: 1px;
background-color: #2778ff;
}
</style>
 

43
hx-ai-intelligent/src/view/carbonEmissionManage/carbonEmissionStatistics/carbonEmissions/index.vue

@ -3,15 +3,15 @@
<a-table
:columns="column"
:data-source="data"
:bordered="false"
:bordered="true"
:pagination="false"
:scroll="{ x: 2000, y: 480 }">
<template #title>
<a-date-picker
v-model:value="selectYear"
picker="year"
@change="changeYearData"
valueFormat="YYYY" />
<a-date-picker v-model:value="selectYear" picker="year" valueFormat="YYYY" />
<span style="margin-left: 30px">
<a-button type="primary" @click="changeYearData">查询</a-button>
<a-button type="primary" ghost style="margin-left: 6px" @click="reset">重置</a-button>
</span>
</template>
</a-table>
<a-pagination
@ -57,11 +57,17 @@
queryParams.value.year = selectYear.value;
getTableList();
};
const reset = () => {
selectYear.value = dayjs(new Date().getFullYear().toString());
queryParams.value.year = selectYear.value.format('YYYY');
getTableList();
};
//
const column: TableColumnsType[] = [
{
title: '排放类型',
dataIndex: 'cnValue',
width: 130,
customCell: (record, rowIndex) => {
if (rowIndex == undefined) {
return {
@ -84,66 +90,82 @@
{
title: '能源种类',
dataIndex: 'energyType',
width: 80,
},
{
title: '计量单位',
dataIndex: 'unitName',
width: 80,
},
{
title: '加权平均',
dataIndex: 'averageFactorValue',
width: 80,
},
{
title: '全年',
dataIndex: 'carbonYearly',
width: 80,
},
{
title: '1月',
dataIndex: 'jan',
width: 80,
},
{
title: '2月',
dataIndex: 'feb',
width: 80,
},
{
title: '3月',
dataIndex: 'mar',
width: 80,
},
{
title: '4月',
dataIndex: 'apr',
width: 80,
},
{
title: '5月',
dataIndex: 'may',
width: 80,
},
{
title: '6月',
dataIndex: 'jun',
width: 80,
},
{
title: '7月',
dataIndex: 'jul',
width: 80,
},
{
title: '8月',
dataIndex: 'aug',
width: 80,
},
{
title: '9月',
dataIndex: 'sep',
width: 80,
},
{
title: '10月',
dataIndex: 'oct',
width: 80,
},
{
title: '11月',
dataIndex: 'nov',
width: 80,
},
{
title: '12月',
dataIndex: 'dec',
width: 80,
},
];
//
@ -189,9 +211,12 @@
:deep(.ant-table-container) {
padding: 0px 16px;
}
:deep(.ant-table-cell) {
border: 1px solid #f0f0f0;
}
// :deep(.ant-table-cell) {
// border: 1px solid #f0f0f0;
// }
// :deep(.ant-table-cell::before) {
// display: none;
// }
</style>
<style scoped>
th.column-money,

179
hx-ai-intelligent/src/view/carbonEmissionManage/carbonEmissionStatistics/energyConsumption/index.vue

@ -54,150 +54,18 @@
</a-radio-group>
</a-form-item>
<a-form-item label="排放类型" name="emissionType" :required="isRequired">
<a-select v-model:value="formState.emissionType" placeholder="请选择排放类型">
<a-select
v-model:value="formState.emissionType"
placeholder="请选择排放类型"
:disabled="!isRequired">
<a-select-option v-for="(item, index) in emissionTypeDic" :key="index" :value="item.id">
{{ item.cnValue }}
</a-select-option>
</a-select>
</a-form-item>
</a-form>
<!-- <a-row>
<a-col :span="24" style="display: flex; justify-content: space-around">
<a-form-item
label="1月"
name="janFlag"
:label-col="switchLabelCol"
:wrapper-col="switchWrapperCol">
<a-switch
v-model:checked="formState.janFlag"
:checked-value="1"
:unCheckedValue="0" />
</a-form-item>
<a-form-item
label="2月"
name="febFlag"
:label-col="switchLabelCol"
:wrapper-col="switchWrapperCol">
<a-switch
v-model:checked="formState.febFlag"
:checked-value="1"
:unCheckedValue="0" />
</a-form-item>
<a-form-item
label="3月"
name="marFlag"
:label-col="switchLabelCol"
:wrapper-col="switchWrapperCol">
<a-switch
v-model:checked="formState.marFlag"
:checked-value="1"
:unCheckedValue="0" />
</a-form-item>
</a-col>
<a-col :span="24" style="display: flex; justify-content: space-around">
<a-form-item
label="4月"
name="aprFlag"
:label-col="switchLabelCol"
:wrapper-col="switchWrapperCol">
<a-switch
v-model:checked="formState.aprFlag"
:checked-value="1"
:unCheckedValue="0" />
</a-form-item>
<a-form-item
label="5月"
name="mayFlag"
:label-col="switchLabelCol"
:wrapper-col="switchWrapperCol">
<a-switch
v-model:checked="formState.mayFlag"
:checked-value="1"
:unCheckedValue="0" />
</a-form-item>
<a-form-item
label="6月"
name="junFlag"
:label-col="switchLabelCol"
:wrapper-col="switchWrapperCol">
<a-switch
v-model:checked="formState.junFlag"
:checked-value="1"
:unCheckedValue="0" />
</a-form-item>
</a-col>
<a-col :span="24" style="display: flex; justify-content: space-around">
<a-form-item
label="7月"
name="julFlag"
:label-col="switchLabelCol"
:wrapper-col="switchWrapperCol">
<a-switch
v-model:checked="formState.julFlag"
:checked-value="1"
:unCheckedValue="0" />
</a-form-item>
<a-form-item
label="8月"
name="augFlag"
:label-col="switchLabelCol"
:wrapper-col="switchWrapperCol">
<a-switch
v-model:checked="formState.augFlag"
:checked-value="1"
:unCheckedValue="0" />
</a-form-item>
<a-form-item
label="9月"
name="sepFlag"
:label-col="switchLabelCol"
:wrapper-col="switchWrapperCol">
<a-switch
v-model:checked="formState.sepFlag"
:checked-value="1"
:unCheckedValue="0" />
</a-form-item>
</a-col>
<a-col :span="24" style="display: flex; justify-content: space-around">
<a-form-item
label="10月"
name="octFlag"
:label-col="switchLabelCol"
:wrapper-col="switchWrapperCol">
<a-switch
v-model:checked="formState.octFlag"
:checked-value="1"
:unCheckedValue="0" />
</a-form-item>
<a-form-item
label="11月"
name="novFlag"
:label-col="switchLabelCol"
:wrapper-col="switchWrapperCol">
<a-switch
v-model:checked="formState.novFlag"
:checked-value="1"
:unCheckedValue="0" />
</a-form-item>
<a-form-item
label="12月"
name="decFlag"
:label-col="switchLabelCol"
:wrapper-col="switchWrapperCol">
<a-switch
v-model:checked="formState.decFlag"
:checked-value="1"
:unCheckedValue="0" />
</a-form-item>
</a-col>
</a-row> -->
<div class="ns-form-title"><div class="title">能耗统计</div></div>
<a-table
:columns="addColumns"
:data-source="addData"
size="small"
:pagination="false"
:scroll="{ y: 200 }">
<a-table :columns="addColumns" :data-source="addData" size="small" :pagination="false">
<template #bodyCell="{ column, text, record }">
<template v-if="column.key === 'action'">
<a-switch
@ -267,11 +135,20 @@
<!-- 凭证下载 -->
<a-drawer
:visible="downLoadVisible"
title="凭证列表"
:width="500"
@close="onCloseDownLoad"
:footer-style="{ textAlign: 'right' }">
<div></div>
<div class="ns-form-title" style="display: flex">
<div class="title">凭证列表</div>
<a-button
type="primary"
ghost
style="margin-left: 16px"
@click="onSubmitDownLoad"
:disabled="selectedRowKeysSet.length === 0">
批量下载
</a-button>
</div>
<a-table
:columns="downLoadColumns"
:data-source="downLoadData"
@ -281,6 +158,7 @@
selectedRowKeys: selectedRowKeysSet,
onChange: onSelectionChangeSet,
}"
style="margin-top: 15px"
:pagination="false">
<template #bodyCell="{ column, text, record }">
<template v-if="column.key === 'action'">
@ -485,23 +363,29 @@
customRender: (text: any) => {
return text.index + 1;
},
width: 100,
},
{
title: '能源种类',
dataIndex: 'energyType',
width: 100,
ellipsis: true,
},
{
title: '计量单位',
className: 'unitName',
dataIndex: 'unitName',
width: 100,
},
{
title: '全年',
dataIndex: 'yearly',
width: 100,
},
{
title: '1月',
dataIndex: 'jan',
width: 100,
customRender: (value) => {
let text;
let color;
@ -522,6 +406,7 @@
{
title: '2月',
dataIndex: 'feb',
width: 100,
customRender: (value) => {
let text;
let color;
@ -542,6 +427,7 @@
{
title: '3月',
dataIndex: 'mar',
width: 100,
customRender: (value) => {
let text;
let color;
@ -562,6 +448,7 @@
{
title: '4月',
dataIndex: 'apr',
width: 100,
customRender: (value) => {
let text;
let color;
@ -582,6 +469,7 @@
{
title: '5月',
dataIndex: 'may',
width: 100,
customRender: (value) => {
let text;
let color;
@ -602,6 +490,7 @@
{
title: '6月',
dataIndex: 'jun',
width: 100,
customRender: (value) => {
let text;
let color;
@ -622,6 +511,7 @@
{
title: '7月',
dataIndex: 'jul',
width: 100,
customRender: (value) => {
let text;
let color;
@ -642,6 +532,7 @@
{
title: '8月',
dataIndex: 'aug',
width: 100,
customRender: (value) => {
let text;
let color;
@ -662,6 +553,7 @@
{
title: '9月',
dataIndex: 'sep',
width: 100,
customRender: (value) => {
let text;
let color;
@ -682,6 +574,7 @@
{
title: '10月',
dataIndex: 'oct',
width: 100,
customRender: (value) => {
let text;
let color;
@ -702,6 +595,7 @@
{
title: '11月',
dataIndex: 'nov',
width: 100,
customRender: (value) => {
let text;
let color;
@ -722,6 +616,7 @@
{
title: '12月',
dataIndex: 'dec',
width: 100,
customRender: (value) => {
let text;
let color;
@ -878,6 +773,12 @@
? item.children.map((child) => ({
value: child.id,
label: child.pointName,
children: child.children
? child.children.map((childs) => ({
value: childs.id,
label: childs.pointName,
}))
: [],
}))
: [],
}));

8
hx-ai-intelligent/src/view/carbonEmissionManage/carbonEmissionStatistics/quickCalculation/index.vue

@ -82,7 +82,9 @@
:footer-style="{ textAlign: 'right' }"
destroyOnClose
@close="onClose">
<div class="editTitle"><div class="title">编辑</div></div>
<div class="editTitle">
<div class="title">{{ text }}</div>
</div>
<a-form
ref="formRef"
:model="formState"
@ -162,6 +164,7 @@
return http.post(api, params);
};
const mainRef = ref();
const text = ref('新增');
//
const x = 3;
const y = 2;
@ -290,6 +293,7 @@
name: 'userAdd',
type: 'primary',
handle: () => {
text.value = '新增';
visible.value = true;
// getNewTable();
},
@ -345,6 +349,7 @@
formState.value.emissionFactors = record.emissionFactors;
formState.value.dateRange = [record.startTime, record.endTime];
formState.value.factorId = record.factorId;
text.value = '编辑';
visible.value = true;
emissionSources.value = record.emissionSources;
queryData.value.emissionSources = emissionSources.value;
@ -493,6 +498,7 @@
const onClose = () => {
visible.value = false;
selectedRowKeys.value = [];
newTableData.value = [];
formState.value = {};
selectData.value = '';
formRef.value.resetFields();

325
hx-ai-intelligent/src/view/carbonEmissionManage/carbonInventoryCheck/fillInPage/index copy.vue

@ -45,7 +45,7 @@
</template>
</a-tree>
</div>
<div class="bottom">
<!-- <div class="bottom">
<a-form style="width: 100%; margin: 0 auto">
<div class="ns-form-title"><div class="title">报告相关</div></div>
<div class="button" style="padding: 0 16px !important">
@ -53,80 +53,88 @@
<div :class="{ tplx: isClickedTplx }" @click="showTplx">碳排流向</div>
</div>
</a-form>
</div>
</div> -->
</div>
<div class="right">
<div style="display: flex">
<div class="ns-table-title ns-title-extra-box">排放源</div>
<a-button type="primary" style="margin-left: 12px" @click="changeParentData">返回</a-button>
</div>
<div style="display: flex; height: 100%" v-if="fillInPage">
<div class="mainLeft">
<a-tree
:expandedKeys="expandedKeysR"
:selectedKeys="selectedKeysR"
:checkedKeys="checkedKeys"
:tree-data="treeData"
@select="onSelectR"
block-node>
<template #title="data">
<div class="treeRow">
<div>
<span>{{ data.emissionSource }}</span>
</div>
<div class="actionMore">
<EditOutlined @click="editUnit(data)" />
<MinusCircleOutlined style="margin-left: 6px" @click="delUnit(data)" />
</div>
<a-button
type="primary"
@click="changeParentData"
style="position: absolute; right: 25px; top: 10px; z-index: 99">
返回
</a-button>
<a-tabs v-model:activeKey="activeKey" @change="handleTabChange" style="height: 100%">
<a-tab-pane key="1" tab="排放源">
<div style="display: flex; height: 100%">
<div class="mainLeft">
<a-tree
:expandedKeys="expandedKeysR"
:selectedKeys="selectedKeysR"
:checkedKeys="checkedKeys"
:tree-data="treeData"
@select="onSelectR"
block-node>
<template #title="data">
<div class="treeRow">
<div>
<span>{{ data.emissionSource }}</span>
</div>
<div class="actionMore">
<EditOutlined @click="editUnit(data)" />
<MinusCircleOutlined style="margin-left: 6px" @click="delUnit(data)" />
</div>
</div>
</template>
</a-tree>
<div class="addTreeNode">
<a-button type="primary" style="width: 100%" @click="addTreeNodeData"
>新增</a-button
>
</div>
</template>
</a-tree>
<div class="addTreeNode">
<a-button type="primary" style="width: 100%" @click="addTreeNodeData">新增</a-button>
</div>
<div class="mainRight">
<a-table
:columns="columns"
:data-source="data"
:pagination="false"
bordered
size="middle"
:scroll="{ y: 500 }">
<template #title>
<a-button type="primary" @click="downLoadVoucher">凭证</a-button>
</template>
<template #bodyCell="{ column, text, record }">
<template v-if="column.dataIndex === 'dataSources'">
<span v-if="record.dataSources">{{ record.dataSources.label }}</span>
</template>
<template v-if="column.dataIndex === 'carbonSource'">
<span v-if="record.carbonSource">{{ record.carbonSource.label }}</span>
</template>
<template v-if="column.key === 'action'">
<span>
<a @click="edit(record)">编辑</a>
</span>
</template>
</template>
</a-table>
</div>
</div>
</div>
<div class="mainRight">
</a-tab-pane>
<a-tab-pane key="2" tab="排放统计">
<a-table
:columns="columns"
:data-source="data"
:pagination="false"
:columns="pftjColumn"
:data-source="pftjData"
bordered
size="middle"
:scroll="{ y: 480 }">
<template #title>
<a-button type="primary" @click="downLoadVoucher">凭证</a-button>
</template>
:pagination="false"
:scroll="{ x: 2000, y: 500 }">
<template #bodyCell="{ column, text, record }">
<template v-if="column.dataIndex === 'dataSources'">
<span v-if="record.dataSources">{{ record.dataSources.label }}</span>
</template>
<template v-if="column.dataIndex === 'carbonSource'">
<span v-if="record.carbonSource">{{ record.carbonSource.label }}</span>
</template>
<template v-if="column.key === 'action'">
<span>
<a @click="edit(record)">编辑</a>
</span>
</template>
{{ text || '-' }}
</template>
</a-table>
</div>
</div>
<div v-if="isClickedPftj">
<a-table
:columns="pftjColumn"
:data-source="pftjData"
bordered
:pagination="false"
:scroll="{ x: 2000 }">
<template #bodyCell="{ column, text, record }">
{{ text || '-' }}
</template>
</a-table>
</div>
<div v-if="isClickedTplx" style="width: 100%; height: 100%">
<div ref="tplxChart" style="width: 100%; height: 68vh"></div>
</div>
</a-tab-pane>
<a-tab-pane key="3" tab="碳排流向">
<div ref="tplxChart" style="width: 100%; height: 68vh"></div>
</a-tab-pane>
</a-tabs>
</div>
<!-- 类别配置 -->
<a-drawer
@ -240,7 +248,7 @@
</a-drawer>
<!-- 点击编辑弹出框 -->
<a-drawer
:width="700"
:width="500"
:visible="editData"
:body-style="{ paddingBottom: '80px' }"
:footer-style="{ textAlign: 'right' }"
@ -252,7 +260,7 @@
:label-col="labelCol"
:wrapper-col="wrapperCol">
<a-row>
<a-col :span="12">
<a-col :span="24">
<a-form-item ref="name" label="数据来源" name="dataSources">
<a-select
ref="select"
@ -264,14 +272,29 @@
</a-select>
</a-form-item>
</a-col>
<a-col :span="12">
<a-col :span="24">
<a-form-item ref="name" label="消耗量" name="consumption">
<ns-input v-model:value="editFormState.consumption" :disabled="canEdit" />
</a-form-item>
</a-col>
</a-row>
<a-row v-if="automatic">
<a-col :span="12">
<a-col :span="24">
<a-form-item label="能耗类型">
<a-select
v-model:value="editFormState.energyConsumptionType"
@change="changeEnergyType"
placeholder="请选择能耗类型">
<a-select-option
v-for="(item, index) in energyTypeOptions"
:key="index"
:value="item.dicKey">
{{ item.cnValue }}
</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item ref="name" label="采集节点" name="collectionNode">
<a-tree-select
v-model:value="editFormState.collectionNode"
@ -283,12 +306,12 @@
</a-col>
</a-row>
<a-row>
<a-col :span="12">
<a-col :span="24">
<a-form-item ref="name" label="因子值" name="factorId">
<ns-input v-model:value="editFormState.factorId" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-col :span="24">
<a-form-item ref="name" label="关键字" name="emissionFactors">
<a-input-search
v-model:value="editFormState.emissionFactors"
@ -303,7 +326,8 @@
:data-source="newTableData"
bordered
rowKey="id"
:scroll="{ y: 400 }"
:scroll="{ y: 300 }"
size="small"
style="margin-bottom: 10px"
:rowSelection="{
selectedRowKeys: selectedRowKeysEdit,
@ -313,25 +337,28 @@
:pagination="false">
</a-table>
<a-pagination
:current="queryParams.pageNum"
:current="queryData.pageNum"
:total="total"
:page-size="queryParams.pageSize"
:page-size="queryData.pageSize"
:pageSizeOptions="['5']"
style="display: flex; justify-content: center; margin-top: 16px"
:show-size-changer="true"
:show-quick-jumper="true"
@change="onChange" />
<a-upload
v-model:file-list="fileList"
<a-upload-dragger
v-model:fileList="fileList"
accept=".pdf"
name="file"
accept=".jpg,.jpeg,.png,.gif,.bmp,.pdf"
@remove="handleFileRemove"
:before-upload="beforeUpload"
@change="handleChange">
<a-button>
<upload-outlined></upload-outlined>
点击上传凭证
</a-button>
</a-upload>
<p class="ant-upload-drag-icon">
<inbox-outlined></inbox-outlined>
</p>
<p class="ant-upload-hint">1.仅支持pdf格式文件或文件夹</p>
<p class="ant-upload-hint">2.文件名命名规则为能源种类_年份</p>
<p class="ant-upload-hint">3.每次上传自动覆盖</p>
</a-upload-dragger>
<template #footer>
<a-button style="margin-right: 8px" @click="onCloseEditData">取消</a-button>
<a-button type="primary" @click="submitEditData">确定</a-button>
@ -341,15 +368,16 @@
</template>
<script lang="ts" setup>
import { ref, watch, toRaw, defineEmits } from 'vue';
import { ref, watch, toRaw, defineEmits, nextTick } from 'vue';
import { http } from '/nerv-lib/util/http';
import { Pagination, Modal, message } from 'ant-design-vue';
import { Pagination, Modal, message, Upload } from 'ant-design-vue';
import type { TreeProps, UploadChangeParam } from 'ant-design-vue';
import {
EditOutlined,
PlusCircleOutlined,
MinusCircleOutlined,
UploadOutlined,
InboxOutlined,
} from '@ant-design/icons-vue';
import * as echarts from 'echarts';
import { voucherColumns, drawerColumns } from '../config';
@ -361,6 +389,7 @@
} from '/@/api/carbonEmissionFactorLibrary';
import { group } from '/@/api/deviceManage';
import { debug, log } from 'node:console';
import { dict } from '/@/api';
defineOptions({
energyType: 'fillInPage', // name
components: {
@ -382,12 +411,12 @@
type: String,
},
});
const activeKey = ref('1');
const orgId = ref('');
const result = JSON.parse(sessionStorage.getItem('ORGID')!);
orgId.value = result;
const fetch = (api, params = { orgId: orgId.value }) => {
return http.post(api, params);
const fetch = (api, params = { orgId: orgId.value }, config) => {
return http.post(api, params, config);
};
//
const x = 3;
@ -865,15 +894,17 @@
selectedRowKeys.value.forEach((item) => {
deleteIds.value.append('ids', item);
});
fetch(uploadPic.downloadZip, deleteIds.value)
const config = {
responseType: 'blob',
};
fetch(uploadPic.downloadZip, deleteIds.value, config)
.then((res) => {
// URL blob
const url = window.URL.createObjectURL(new Blob([res.data]));
const url = window.URL.createObjectURL(new Blob([res]));
// <a>
const link = document.createElement('a');
link.href = url;
debugger;
link.setAttribute('download', ''); //
link.setAttribute('download', '碳盘查凭证.zip'); //
document.body.appendChild(link);
link.click();
@ -910,10 +941,15 @@
const queryData = ref({
orgId: orgId.value,
pageNum: 1,
pageSize: 999,
pageSize: 5,
});
const edit = (record) => {
getDictList();
const energyTypeOptions = ref([]);
const acquisitionDate = ref();
const edit = async (record) => {
acquisitionDate.value = record.acquisitionDate;
//
const options = await dict({ params: { dicKey: 'ENERGY_TYPE' } });
energyTypeOptions.value = options.data.data;
getNewTable();
editFormState.value.id = record.id;
editFormState.value.dataSources = record.dataSources;
@ -949,46 +985,66 @@
if (value === '3') {
canEdit.value = true;
automatic.value = true;
} else {
automatic.value = false;
}
};
//
const collectingNodes = ref<TreeSelectProps['treeData']>([]);
const getDictList = () => {
const getTypeConsume = ref();
const changeEnergyType = (value) => {
getTypeConsume.value = value;
//
fetch(group.queryDeviceGroupTree, { energyType: 'ELECTRICITY_USAGE', orgId: orgId.value }).then(
(res) => {
collectingNodes.value = res.data;
collectingNodes.value = collectingNodes.value.map((item) => ({
value: item.id,
label: item.pointName,
children: item.children
? item.children.map((child) => ({
value: child.id,
label: child.pointName,
}))
: [],
}));
},
);
fetch(group.queryDeviceGroupTree, { energyType: value, orgId: orgId.value }).then((res) => {
collectingNodes.value = res.data;
collectingNodes.value = collectingNodes.value.map((item) => ({
value: item.id,
label: item.pointName,
children: item.children
? item.children.map((child) => ({
value: child.id,
label: child.pointName,
}))
: [],
}));
});
};
const selectNode = (value) => {
debugger;
const getConsumeData = ref({
acquisitionDate: acquisitionDate.value,
collectionNode: value,
orgId: orgId.value,
energyConsumptionType: getTypeConsume.value,
});
fetch(carbonInventoryCheck.nodeCancellationConsumption, getConsumeData.value).then((res) => {
editFormState.value.consumption = res.data;
});
};
//
const fileList = ref<UploadProps['fileList']>([]);
const isValidFileName = (filename: string): boolean => {
const regex = /^[\s\S]+_\d{4}\.pdf$/;
return regex.test(filename);
};
const beforeUpload: UploadProps['beforeUpload'] = (file) => {
const filename = file.name;
if (!isValidFileName(filename)) {
message.error('文件名不符合规则');
return Upload.LIST_IGNORE; //
}
return false;
};
const handleChange = (info: UploadChangeParam) => {
fileList.value = [...info.fileList];
if (info.file.status !== 'uploading') {
console.log(info.file, info.fileList);
}
if (info.file.status === 'done') {
message.success(`${info.file.name} 文件上传成功`);
} else if (info.file.status === 'error') {
message.error(`${info.file.name} 文件上传失败`);
// fileList.value = [...info.fileList];
const { fileList: newFileList } = info;
// fileList
if (newFileList.length > 1) {
delIds.value.push(info.fileList[0].uid);
newFileList.shift(); //
}
// fileList
fileList.value = [...newFileList];
};
const delIds = ref([]);
const handleFileRemove = (file) => {
@ -1062,8 +1118,8 @@
};
//
const onChange = (pageNumber: number, size: number) => {
queryParams.value.pageNum = pageNumber;
queryParams.value.pageSize = size;
queryData.value.pageNum = pageNumber;
queryData.value.pageSize = size;
getNewTable();
};
// /
@ -1388,6 +1444,20 @@
chartInstance = echarts.init(tplxChart.value);
chartInstance.setOption(option);
};
const handleTabChange = (key) => {
console.log('Tab changed:', key);
//
if (key === '2') {
nextTick(() => {
getEmissionStatistic();
});
} else if (key === '3') {
nextTick(() => {
getCarbonFlowDirection();
});
}
};
//
const emit = defineEmits(['change-data']);
const changeParentData = () => {
@ -1413,7 +1483,7 @@
flex-direction: column;
.top {
position: relative;
height: 80%;
height: 100%;
margin-bottom: 20px;
.ns-form-title {
font-weight: bold;
@ -1492,10 +1562,13 @@
flex: 1;
min-width: 0;
height: 100%;
padding: @ns-gap;
background-color: @white;
border-radius: @ns-border-radius;
box-shadow: @ns-content-box-shadow;
position: relative;
:deep(.ant-tabs-content-holder) {
padding: 20px;
}
.ns-table-title {
text-align: left;
font-size: 16px;
@ -1552,4 +1625,8 @@
margin-left: 10%;
flex-direction: column;
}
:deep(.ant-upload.ant-upload-drag) {
height: 18vh;
margin-top: 10px;
}
</style>

381
hx-ai-intelligent/src/view/carbonEmissionManage/carbonInventoryCheck/fillInPage/index.vue

@ -1,51 +1,79 @@
<template>
<div class="main">
<div class="left">
<div class="top">
<a-form style="width: 100%; margin: 0 auto">
<div class="ns-form-title">
<div class="title">{{ props.year }}年济阳站碳盘查报告</div>
<div class="standard">
<span>适用标准ISO 14064-1</span>
<a-button type="primary" style="margin-left: 12px" @click="openCategoryConfig"
>类别配置</a-button
>
</div>
</div>
<div style="padding: 0 16px !important; width: 100%">
<a-row>
<a-col :span="24" style="margin-bottom: 16px">
<a-input-search
v-model:value="searchValue"
style="margin-bottom: 8px"
placeholder="请输入关键词" />
</a-col>
</a-row>
</div>
</a-form>
<a-tree
:expanded-keys="expandedKeysL"
:selectedKeys="selectedKeysL"
:auto-expand-parent="autoExpandParent"
:tree-data="gData"
v-if="gData && gData.length > 0"
:height="233"
show-line
style="padding: 0 16px !important"
@expand="onExpandL"
@select="onSelectL"
block-node>
<template #title="{ cnValue }">
<span v-if="cnValue && searchValue && cnValue.indexOf(searchValue) > -1">
{{ cnValue.substring(0, cnValue.indexOf(searchValue)) }}
<span style="color: #f50">{{ searchValue }}</span>
{{ cnValue.substring(cnValue.indexOf(searchValue) + searchValue.length) }}
</span>
<span v-else>{{ cnValue }}</span>
</template>
</a-tree>
<div class="totalTitle">
<div class="ns-form-title">
<div class="title">{{ props.year }}年济阳站碳盘查报告</div>
<div class="standard" style="display: flex; align-items: center">
<img
width="11px"
height="11px"
style="margin-right: 5px"
src="../../../../../src/icon/carbonInventoryCheck.svg" />
<span
style="
font-size: 12px;
font-weight: 400;
letter-spacing: 0px;
line-height: 16.8px;
color: rgba(67, 136, 251, 1);
text-align: left;
vertical-align: top;
">
适用标准ISO 14064-1
</span>
<a-button type="primary" @click="changeParentData" ghost style="margin-left: 6px">
返回
</a-button>
</div>
</div>
<!-- <div class="bottom">
</div>
<div style="display: flex; height: 100%">
<div class="left">
<div class="top">
<a-form style="width: 100%; margin: 0 auto">
<div class="ns-form-title">
<div>能源类别</div>
<div class="standard">
<a-button type="primary" style="margin-left: 12px" @click="openCategoryConfig">
类别配置
</a-button>
</div>
</div>
<div style="padding: 0 16px !important; width: 100%">
<a-row>
<a-col :span="24" style="margin-bottom: 16px">
<a-input-search
v-model:value="searchValue"
style="margin-bottom: 8px"
placeholder="请输入关键词" />
</a-col>
</a-row>
</div>
</a-form>
<a-tree
:expanded-keys="expandedKeysL"
:selectedKeys="selectedKeysL"
:auto-expand-parent="autoExpandParent"
:tree-data="gData"
v-if="gData && gData.length > 0"
:height="233"
show-line
style="padding: 0 16px !important"
@expand="onExpandL"
@select="onSelectL"
block-node>
<template #title="{ cnValue }">
<span v-if="cnValue && searchValue && cnValue.indexOf(searchValue) > -1">
{{ cnValue.substring(0, cnValue.indexOf(searchValue)) }}
<span style="color: #f50">{{ searchValue }}</span>
{{ cnValue.substring(cnValue.indexOf(searchValue) + searchValue.length) }}
</span>
<span v-else>{{ cnValue }}</span>
</template>
</a-tree>
<a-empty v-else />
</div>
<!-- <div class="bottom">
<a-form style="width: 100%; margin: 0 auto">
<div class="ns-form-title"><div class="title">报告相关</div></div>
<div class="button" style="padding: 0 16px !important">
@ -54,87 +82,89 @@
</div>
</a-form>
</div> -->
</div>
<div class="right">
<a-button
type="primary"
@click="changeParentData"
style="position: absolute; right: 25px; top: 10px; z-index: 99">
返回
</a-button>
<a-tabs v-model:activeKey="activeKey" @change="handleTabChange" style="height: 100%">
<a-tab-pane key="1" tab="排放源">
<div style="display: flex; height: 100%">
<div class="mainLeft">
<a-tree
:expandedKeys="expandedKeysR"
:selectedKeys="selectedKeysR"
:checkedKeys="checkedKeys"
:tree-data="treeData"
@select="onSelectR"
block-node>
<template #title="data">
<div class="treeRow">
<div>
<span>{{ data.emissionSource }}</span>
</div>
<div class="actionMore">
<EditOutlined @click="editUnit(data)" />
<MinusCircleOutlined style="margin-left: 6px" @click="delUnit(data)" />
</div>
<div class="right">
<a-tabs v-model:activeKey="activeKey" @change="handleTabChange" style="height: 100%">
<a-tab-pane key="1" tab="排放源">
<div style="display: flex; height: 100%">
<div class="mainLeft">
<a-tree
v-if="treeData && treeData.length > 0"
:expandedKeys="expandedKeysR"
:selectedKeys="selectedKeysR"
:checkedKeys="checkedKeys"
:tree-data="treeData"
@select="onSelectR"
block-node>
<template #title="data">
<div class="treeRow">
<div>
<span>{{ data.emissionSource }}</span>
</div>
<div class="actionMore">
<EditOutlined @click="editUnit(data)" />
<MinusCircleOutlined style="margin-left: 6px" @click="delUnit(data)" />
</div>
</div>
</div>
</template>
</a-tree>
<div class="addTreeNode">
<a-button type="primary" style="width: 100%" @click="addTreeNodeData"
>新增</a-button
>
</div>
</div>
<div class="mainRight">
<a-table
:columns="columns"
:data-source="data"
:pagination="false"
bordered
size="middle"
:scroll="{ y: 500 }">
<template #title>
<a-button type="primary" @click="downLoadVoucher">凭证</a-button>
</template>
<template #bodyCell="{ column, text, record }">
<template v-if="column.dataIndex === 'dataSources'">
<span v-if="record.dataSources">{{ record.dataSources.label }}</span>
</template>
<template v-if="column.dataIndex === 'carbonSource'">
<span v-if="record.carbonSource">{{ record.carbonSource.label }}</span>
</a-tree>
<a-empty v-else />
<div class="addTreeNode">
<a-button type="primary" style="width: 100%" @click="addTreeNodeData">
新增
</a-button>
</div>
</div>
<div class="mainRight">
<a-table
:columns="columns"
v-if="data && data.length > 0"
:data-source="data"
:pagination="false"
bordered
size="middle"
:scroll="{ y: 500 }">
<template #title>
<a-button type="primary" @click="downLoadVoucher">凭证</a-button>
</template>
<template v-if="column.key === 'action'">
<span>
<a @click="edit(record)">编辑</a>
</span>
<template #bodyCell="{ column, text, record }">
<template v-if="column.dataIndex === 'dataSources'">
<span v-if="record.dataSources">{{ record.dataSources.label }}</span>
</template>
<template v-if="column.dataIndex === 'carbonSource'">
<span v-if="record.carbonSource">{{ record.carbonSource.label }}</span>
</template>
<template v-if="column.key === 'action'">
<span>
<a @click="edit(record)">编辑</a>
</span>
</template>
</template>
</template>
</a-table>
</a-table>
<a-empty v-else />
</div>
</div>
</div>
</a-tab-pane>
<a-tab-pane key="2" tab="排放统计">
<a-table
:columns="pftjColumn"
:data-source="pftjData"
bordered
:pagination="false"
:scroll="{ x: 2000, y: 500 }">
<template #bodyCell="{ column, text, record }">
{{ text || '-' }}
</template>
</a-table>
</a-tab-pane>
<a-tab-pane key="3" tab="碳排流向">
<div ref="tplxChart" style="width: 100%; height: 68vh"></div>
</a-tab-pane>
</a-tabs>
</a-tab-pane>
<a-tab-pane key="2" tab="排放统计">
<a-table
:columns="pftjColumn"
v-if="pftjData && pftjData.length > 0"
:data-source="pftjData"
bordered
:pagination="false"
:scroll="{ x: 2000, y: 500 }">
<template #bodyCell="{ column, text, record }">
{{ text || '-' }}
</template>
</a-table>
<a-empty v-else />
</a-tab-pane>
<a-tab-pane key="3" tab="碳排流向">
<div v-if="showChart" ref="tplxChart" style="width: 100%; height: 68vh"></div>
<a-empty v-else />
</a-tab-pane>
</a-tabs>
</div>
</div>
<!-- 类别配置 -->
<a-drawer
@ -144,16 +174,18 @@
:body-style="{ paddingBottom: '80px' }"
:footer-style="{ textAlign: 'right' }"
destroyOnClose
title="类别配置"
@close="closeCategoryConfig">
<div class="search">
<a-input-search
v-model:value="searchcategoryConfig"
placeholder="请输入类别名称"
style="width: 250px"
@search="onSearch" />
<div class="ns-form-title" style="margin-left: 10%">
<div class="title">类别设置</div>
</div>
<div class="treePart">
<div class="search">
<a-input-search
v-model:value="searchcategoryConfig"
placeholder="请输入类别名称"
style="width: 250px"
@search="onSearch" />
</div>
<a-tree
:expanded-keys="categoryExpandedKeys"
:selectedKeys="categorySelectedKeys"
@ -186,6 +218,9 @@
:footer-style="{ textAlign: 'right' }"
destroyOnClose
@close="onClose">
<div class="ns-form-title" style="display: flex">
<div class="title">新增</div>
</div>
<a-form
ref="formRef"
:model="formState"
@ -229,6 +264,9 @@
:footer-style="{ textAlign: 'right' }"
destroyOnClose
@close="onCloseVoucher">
<div class="ns-form-title">
<div class="title">凭证列表</div>
</div>
<a-table
:columns="voucherColumns"
:data-source="voucherData"
@ -254,6 +292,9 @@
:footer-style="{ textAlign: 'right' }"
destroyOnClose
@close="onCloseEditData">
<div class="ns-form-title-edit">
<div class="title">编辑</div>
</div>
<a-form
ref="editFormRef"
:model="editFormState"
@ -321,6 +362,9 @@
</a-col>
</a-row>
</a-form>
<div class="ns-form-title-edit" style="display: flex">
<div class="titleEdit">因子列表</div>
</div>
<a-table
:columns="drawerColumns"
:data-source="newTableData"
@ -345,6 +389,9 @@
:show-size-changer="true"
:show-quick-jumper="true"
@change="onChange" />
<div class="ns-form-title-edit" style="display: flex">
<div class="titleEdit">凭证上传</div>
</div>
<a-upload-dragger
v-model:fileList="fileList"
accept=".pdf"
@ -658,8 +705,8 @@
// /
const addTreeNodeVisible = ref(false);
const formRef = ref();
const labelCol = { span: 5 };
const wrapperCol = { span: 19 };
const labelCol = { span: 4 };
const wrapperCol = { span: 20 };
const formState = ref({
orgId: orgId.value,
year: props.year,
@ -1148,10 +1195,16 @@
});
const linksData = ref([]);
const datalist = ref([]);
const showChart = ref(true);
const getCarbonFlowDirection = () => {
fetch(carbonInventoryCheck.carbonFlowDirection, queryFlowDirection.value).then((res) => {
console.log(res);
linksData.value = res.data[0];
if (linksData.value[0].value !== 0) {
showChart.value = true;
} else {
showChart.value = false;
}
datalist.value = res.data[1];
drawEcharts();
});
@ -1467,14 +1520,18 @@
<style lang="less" scoped>
.main {
background-color: @ns-content-bg;
display: flex;
background-color: #ffffff;
height: 100%;
padding: 16px;
}
.left {
width: 300px;
margin-right: @ns-gap;
min-width: fit-content;
height: 93%;
border-radius: 8px;
background: rgba(255, 255, 255, 1);
box-shadow: 0px 2px 20px rgb(69 123 234 / 20%);
> div {
background-color: @white;
}
@ -1491,7 +1548,6 @@
padding: 16px;
margin-bottom: 16px;
padding-bottom: 10px;
border-bottom: 1px solid #e9e9e9;
}
.title {
text-align: left;
@ -1561,11 +1617,10 @@
.right {
flex: 1;
min-width: 0;
height: 100%;
background-color: @white;
border-radius: @ns-border-radius;
box-shadow: @ns-content-box-shadow;
position: relative;
height: 93%;
border-radius: 8px;
background: rgba(255, 255, 255, 1);
box-shadow: 0px 2px 20px rgb(69 123 234 / 20%);
:deep(.ant-tabs-content-holder) {
padding: 20px;
}
@ -1611,17 +1666,17 @@
}
.search {
width: 70%;
height: 5vh;
display: flex;
align-items: center;
margin-left: 10%;
justify-content: center;
}
.treePart {
width: 70%;
height: 100%;
display: flex;
border: 1px solid #bfbfbf;
border: 1px solid rgba(235, 238, 245, 1);
border-radius: 8px;
margin-left: 10%;
flex-direction: column;
}
@ -1629,4 +1684,48 @@
height: 18vh;
margin-top: 10px;
}
.ns-form-title {
font-weight: bold;
user-select: text;
margin-bottom: 16px;
display: flex;
align-items: center;
justify-content: space-between;
}
.ns-form-title-edit {
font-weight: bold;
user-select: text;
}
.title {
text-align: left;
height: 32px;
line-height: 32px;
font-weight: bold;
user-select: text;
position: relative;
padding-left: 9px;
}
.titleEdit {
text-align: left;
height: 32px;
line-height: 32px;
font-weight: bold;
user-select: text;
position: relative;
}
.title::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
height: 13px;
width: 3px;
border-radius: 1px;
background-color: #2778ff;
}
:deep(.ant-table-title) {
display: flex;
justify-content: right;
}
</style>

36
hx-ai-intelligent/src/view/carbonEmissionManage/carbonInventoryCheck/index.vue

@ -20,6 +20,7 @@
:footer-style="{ textAlign: 'right' }"
destroyOnClose
@close="onClose">
<div class="ns-form-title"><div class="title">{{text}}</div></div>
<a-form
ref="formRef"
:model="formState"
@ -78,8 +79,9 @@
const visible = ref(false);
const formState = ref({});
const formRef = ref();
const labelCol = { span: 5 };
const wrapperCol = { span: 19 };
const labelCol = { span: 4 };
const wrapperCol = { span: 20 };
const text = ref('新增报告')
const disabledDate = (current: moment.Moment | null) => {
if (formState.value.reportPeriod === '2') {
const year = current.year();
@ -140,6 +142,7 @@
name: 'userAdd',
type: 'primary',
handle: () => {
text.value = '新增报告'
visible.value = true;
},
},
@ -183,6 +186,7 @@
label: '编辑',
name: 'userEdit',
handle: (record: any) => {
text.value = '编辑报告'
visible.value = true;
fetch(carbonInventoryCheck.findById, { id: record.id }).then((res) => {
formState.value = res.data;
@ -274,4 +278,30 @@
};
</script>
<style lang="less" scoped></style>
<style lang="less" scoped>
.ns-form-title {
font-weight: bold;
user-select: text;
margin-bottom: 16px;
}
.title {
text-align: left;
height: 32px;
line-height: 32px;
font-weight: bold;
user-select: text;
position: relative;
padding-left: 9px;
}
.title::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
height: 13px;
width: 3px;
border-radius: 1px;
background-color: #2778ff;
}
</style>

106
hx-ai-intelligent/src/view/carbonEmissionManage/carbonPlanning/all/index.vue

@ -2,25 +2,37 @@
<div class="totalContant">
<div class="ns-form-title">
<div class="title">
<span>查询</span>
<a-date-picker
v-if="selectedTime"
style="margin-left: 5%"
valueFormat="YYYY"
v-model:value="selectYear"
@change="changeYear"
picker="year" />
<a-date-picker
v-else
style="margin-left: 5%"
valueFormat="YYYY-MM"
v-model:value="selectMonth"
@change="changeMonth"
picker="month" />
<span>统计数据</span>
</div>
</div>
<div
style="
display: flex;
width: 100%;
height: 5%;
align-items: center;
justify-content: space-between;
margin-bottom: 1%;
">
<a-date-picker
v-if="selectedTime"
valueFormat="YYYY"
v-model:value="selectYear"
@change="changeYear"
picker="year" />
<a-date-picker
v-else
valueFormat="YYYY-MM"
v-model:value="selectMonth"
@change="changeMonth"
picker="month" />
<div class="operation">
<div class="month" :style="monthStyles" @click="changeToMonth"><span></span></div>
<div class="year" :style="yearStyles" @click="changeToYear"><span></span></div>
<div class="month" :style="monthStyles" @click="changeToMonth">
<span :style="monthText">本月</span>
</div>
<div class="year" :style="yearStyles" @click="changeToYear">
<span :style="yearText">本年</span>
</div>
</div>
</div>
<div class="contant">
@ -62,8 +74,10 @@
const selectYear = ref<Dayjs>(dayjs(new Date().getFullYear().toString()));
const selectMonth = ref<Dayjs>(dayjs().startOf('year').month(0));
// /
const monthStyles = ref('background: #f2f2f2');
const monthStyles = ref('background: transparent');
const yearStyles = ref('background: #2778ff');
const monthText = ref('color: #2778ff');
const yearText = ref('color: #ffffff');
const selectedTime = ref(true);
const changeMonth = () => {
queryParams.value.yearMonth = selectMonth.value;
@ -71,7 +85,9 @@
};
const changeToMonth = () => {
monthStyles.value = 'background: #2778ff';
yearStyles.value = 'background: #f2f2f2';
yearStyles.value = 'background: transparent';
monthText.value = 'color: #ffffff';
yearText.value = 'color: #2778ff';
queryParams.value.yearAndMonth = 'month';
queryParams.value.yearMonth = selectMonth.value.format('YYYY-DD');
columns.value[2].title = '月份';
@ -84,8 +100,10 @@
getTableData();
};
const changeToYear = () => {
monthStyles.value = 'background: #f2f2f2';
monthStyles.value = 'background:transparent';
yearStyles.value = 'background: #2778ff';
monthText.value = 'color: #2778ff';
yearText.value = 'color: #ffffff';
queryParams.value.yearAndMonth = 'year';
delete queryParams.value.yearMonth;
// queryParams.value.year = selectYear.value;
@ -218,6 +236,7 @@
const columns = ref([
{
title: '序号',
width: 100,
customRender: (text: any) => {
return text.index + 1;
},
@ -301,32 +320,32 @@
border-radius: 1px;
background-color: #2778ff;
}
.operation {
display: flex;
margin-right: 10px;
font-weight: 400;
height: 70%;
cursor: pointer;
width: 10%;
}
.month {
width: 70px;
display: flex;
align-items: center;
justify-content: center;
// background: #f2f2f2;
}
.year {
width: 70px;
display: flex;
align-items: center;
justify-content: center;
// background: #2778ff;
}
}
.operation {
display: flex;
margin-right: 10px;
font-weight: 400;
height: 90%;
cursor: pointer;
width: 10%;
border-radius: 4px;
border: 1px solid rgba(39, 120, 255, 1);
}
.month {
width: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.year {
width: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.contant {
width: 100%;
height: calc(100% - 5vh);
height: calc(94% - 5vh);
.chartsPart {
width: 100%;
height: 35%;
@ -336,6 +355,7 @@
width: 19%;
height: 100%;
background: rgba(39, 120, 255, 0.05);
border-radius: 8px;
}
}
.tablePart {

27
hx-ai-intelligent/src/view/carbonEmissionManage/carbonPlanning/category/categoryDeatil.vue

@ -88,7 +88,6 @@
selectedRowKeys: selectedRowKeys,
onChange: onSelectionChange,
}"
:scroll="{ x: 1300, y: 400 }"
:pagination="false">
<template #bodyCell="{ column, text, record }">
<template v-if="column.key === 'action'">
@ -209,6 +208,7 @@
import type { UnwrapRef } from 'vue';
import { ref, defineEmits, reactive, toRaw } from 'vue';
import { http } from '/nerv-lib/util/http';
import { message } from 'ant-design-vue';
import {
CaretUpOutlined,
CaretDownOutlined,
@ -402,7 +402,7 @@
//
if (key === '1') {
} else if (key === '2') {
if (selectedRowKeysSet.value) {
if (selectedRowKeysSet.value.length !== 0) {
fetch(carbonPlanning.monthBenchmarkSetting, {
type: props.type,
referenceYear: selectedRowKeysSet.value[0],
@ -413,6 +413,7 @@
monthData.value = res.data;
});
} else {
message.warning('请先选择年基准值!');
activeKey.value = '1';
}
}
@ -420,6 +421,16 @@
//
const changeSwitch = (data: any) => {
data.isAutoObtained = data.isAutoObtained === 0 ? 1 : 0;
if (data.isAutoObtained === 0) {
fetch(carbonPlanning.autoObtained, {
type: props.type,
itemizeId: props.parentId,
orgId: orgId.value,
yearMonth: data.yearMonth,
}).then((res) => {
data.referenceValue = res.data.referenceValue;
});
}
monthData.value = [...monthData.value];
console.log(monthData.value);
};
@ -473,11 +484,18 @@
itemizeId: props.parentId,
}).then((res) => {
visible.value = false;
activeKey.value = '1';
selectedRowKeysSet.value = [];
getTableData();
});
};
const onClose = () => {
activeKey.value = '1';
selectedRowKeysSet.value = [];
if (selectYear.value) {
selectYear.value = '';
queryData.value.referenceYear = selectYear.value;
}
visible.value = false;
};
// echarts
@ -766,9 +784,12 @@
}
.model {
width: 16%;
height: 90%;
height: 100%;
background: #f7f9ff;
padding: 12px;
border-radius: 12px;
background: linear-gradient(180deg, rgba(255, 255, 255, 1) 0%, rgba(222, 255, 246, 1) 100%);
border: 1px solid rgba(18, 174, 132, 1);
.quantity {
font-size: 12px;
font-weight: 400;

117
hx-ai-intelligent/src/view/carbonEmissionManage/carbonPlanning/category/index.vue

@ -4,25 +4,37 @@
<div class="title">
<span>统计数据</span>
<a-button style="margin-left: 5%" type="primary" @click="addNode">新增节点</a-button>
<a-date-picker
v-if="selectedTime"
style="margin-left: 5%"
v-model:value="selectYearValue"
:disabled-date="disabledDate"
valueFormat="YYYY"
@change="changeYear"
picker="year" />
<a-date-picker
v-else
style="margin-left: 5%"
v-model:value="selectMonthValue"
valueFormat="YYYY-MM"
@change="changeMonth"
picker="month" />
</div>
</div>
<div
style="
display: flex;
width: 100%;
height: 5%;
align-items: center;
justify-content: space-between;
margin-bottom: 1%;
">
<a-date-picker
v-if="selectedTime"
v-model:value="selectYearValue"
:disabled-date="disabledDate"
valueFormat="YYYY"
@change="changeYear"
picker="year" />
<a-date-picker
v-else
v-model:value="selectMonthValue"
valueFormat="YYYY-MM"
@change="changeMonth"
picker="month" />
<div class="operation">
<div class="month" :style="monthStyles" @click="changeToMonth"><span></span></div>
<div class="year" :style="yearStyles" @click="changeToYear"><span></span></div>
<div class="month" :style="monthStyles" @click="changeToMonth">
<span :style="monthText">本月</span>
</div>
<div class="year" :style="yearStyles" @click="changeToYear">
<span :style="yearText">本年</span>
</div>
</div>
</div>
<div class="contant">
@ -38,8 +50,7 @@
:pagination="false"
row-key="itemizeId"
:onRow="onRow"
:customRow="customRow"
:scroll="{ x: 1300, y: 250 }">
:customRow="customRow">
<template #bodyCell="{ column, text, record }">
<template v-if="column.key === 'action'">
<span>
@ -61,6 +72,9 @@
</div>
<!-- 新增节点 -->
<a-drawer :visible="visible" :width="500" @close="onClose" :footer-style="{ textAlign: 'right' }">
<div class="ns-form-title">
<div class="title">新增节点</div>
</div>
<a-tree
:expanded-keys="expandedKeys"
:selectedKeys="selectedKeys"
@ -124,12 +138,16 @@
};
// /
const monthStyles = ref('background: #f2f2f2');
const monthStyles = ref('background: #transparent');
const yearStyles = ref('background: #2778ff');
const monthText = ref('color: #2778ff');
const yearText = ref('color: #ffffff');
const selectedTime = ref(true);
const changeToMonth = () => {
monthStyles.value = 'background: #2778ff';
yearStyles.value = 'background: #f2f2f2';
yearStyles.value = 'background: #transparent';
monthText.value = 'color: #ffffff';
yearText.value = 'color: #2778ff';
columns.value[2].title = '月份';
columns.value[2].dataIndex = 'yearMonth';
selectedTime.value = false;
@ -138,8 +156,10 @@
getMonthPillarData();
};
const changeToYear = () => {
monthStyles.value = 'background: #f2f2f2';
monthStyles.value = 'background: #transparent';
yearStyles.value = 'background: #2778ff';
monthText.value = 'color: #2778ff';
yearText.value = 'color: #ffffff';
columns.value[2].title = '年份';
columns.value[2].dataIndex = 'year';
selectedTime.value = true;
@ -574,7 +594,9 @@
user-select: text;
position: relative;
padding-left: 9px;
width: 50%;
width: 100%;
display: flex;
justify-content: space-between;
}
.title::before {
content: '';
@ -587,34 +609,35 @@
border-radius: 1px;
background-color: #2778ff;
}
.operation {
display: flex;
margin-right: 10px;
font-weight: 400;
height: 70%;
cursor: pointer;
width: 10%;
}
.month {
width: 70px;
display: flex;
align-items: center;
justify-content: center;
// background: #f2f2f2;
}
.year {
width: 70px;
display: flex;
align-items: center;
justify-content: center;
// background: #2778ff;
}
}
.operation {
display: flex;
margin-right: 10px;
font-weight: 400;
height: 90%;
cursor: pointer;
width: 10%;
border-radius: 4px;
border: 1px solid rgba(39, 120, 255, 1);
}
.month {
width: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.year {
width: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.contant {
width: 100%;
height: calc(100% - 5vh);
height: calc(94% - 5vh);
overflow-y: auto;
.chartsPart {
width: 100%;
width: 99%;
height: 40%;
display: flex;
justify-content: space-between;

36
hx-ai-intelligent/src/view/carbonEmissionManage/carbonPlanning/index.vue

@ -9,13 +9,13 @@
<a-tab-pane key="3" tab="用水量">
<category ref="useWaterRef" :tabId="tabId" :energyType="energyType" />
</a-tab-pane>
<a-tab-pane key="4" tab="供水量">
<a-tab-pane key="4" tab="用气量">
<category ref="provideWaterRef" :tabId="tabId" :energyType="energyType" />
</a-tab-pane>
<a-tab-pane key="5" tab="碳排">
<a-tab-pane key="5" tab="供热量">
<category ref="carbonEmissionsRef" :tabId="tabId" :energyType="energyType" />
</a-tab-pane>
<a-tab-pane key="6" tab="供热量">
<a-tab-pane key="6" tab="碳排量">
<category ref="provideHotRef" :tabId="tabId" :energyType="energyType" />
</a-tab-pane>
</a-tabs>
@ -51,47 +51,47 @@
}
});
} else if (key === '2') {
tabId.value = 1;
energyType.value = 'ELECTRICITY_USAGE'
tabId.value = 4;
energyType.value = 'ELECTRICITY_USAGE';
nextTick(() => {
if (electricRef.value) {
electricRef.value.electricTotal = true
electricRef.value.electricTotal = true;
electricRef.value.changeToYear(); //
}
});
} else if (key === '3') {
tabId.value = 2;
energyType.value = 'WATER_USAGE'
tabId.value = 5;
energyType.value = 'WATER_USAGE';
nextTick(() => {
if (useWaterRef.value) {
useWaterRef.value.electricTotal = true
useWaterRef.value.electricTotal = true;
useWaterRef.value.changeToYear(); //
}
});
} else if (key === '4') {
tabId.value = 3;
energyType.value = 'gongshuiliang'
tabId.value = 6;
energyType.value = 'gongshuiliang';
nextTick(() => {
if (provideWaterRef.value) {
provideWaterRef.value.electricTotal = true
provideWaterRef.value.electricTotal = true;
provideWaterRef.value.changeToYear(); //
}
});
} else if (key === '5') {
tabId.value = 5;
energyType.value = 'CARBON_EMISSIONS'
tabId.value = 7;
energyType.value = 'CARBON_EMISSIONS';
nextTick(() => {
if (carbonEmissionsRef.value) {
carbonEmissionsRef.value.electricTotal = true
carbonEmissionsRef.value.electricTotal = true;
carbonEmissionsRef.value.changeToYear(); //
}
});
} else if (key === '6') {
tabId.value = 4;
energyType.value = 'HEAT_SUPPLY'
tabId.value = 8;
energyType.value = 'HEAT_SUPPLY';
nextTick(() => {
if (provideHotRef.value) {
provideHotRef.value.electricTotal = true
provideHotRef.value.electricTotal = true;
provideHotRef.value.changeToYear(); //
}
});

47
hx-ai-intelligent/src/view/equipmentControl/airConditionControlSystem/tabs2.vue

@ -1,7 +1,12 @@
<template>
<div class="div-add">
<button class="add" @click="addModal">添加</button>
<a-popconfirm title="是否提交以上修改?" ok-text="确定" cancel-text="取消" @confirm="sendTable">
<a-popconfirm
title="是否提交以上修改?"
placement="bottomLeft"
ok-text="确定"
cancel-text="取消"
@confirm="sendTable">
<button class="add" style="margin-left: 20px">执行</button>
</a-popconfirm>
</div>
@ -47,6 +52,7 @@
title="此操作将移除该数据"
ok-text="确定"
cancel-text="取消"
placement="topRight"
@confirm="deletePlan(row)">
<div class="tabDelete">删除</div>
</a-popconfirm>
@ -55,7 +61,7 @@
</tbody>
</table>
<div class="out-dialog" v-if="addVisible">
<div class="content" v-if="addVisible">
<div class="content">
<div class="div-operation"></div>
<span class="text-operation">计划库</span>
</div>
@ -132,7 +138,15 @@
// /
const togglePlan = (state: number) => {
dataSource.value.forEach((item: any) => {
item.executeStatus.value = state;
//
if (state == 1) {
if (item.executeStatus.value != 2) {
item.executeStatus.value = state;
}
//
} else {
item.executeStatus.value = state;
}
});
};
@ -155,20 +169,33 @@
const deletePlan = (row: any) => {
row.executeStatus.value = 0;
};
// = 1
// = 1
const startPlan = (row: any) => {
if (row.executeStatus.value == 1) {
return message.info('该数据已是待执行状态,无需再次修改');
}
if (row.executeStatus.value == 2) {
return message.info('执行中的状态已被启用,无需修改');
}
row.executeStatus.value = 1;
};
//
const sendTable = () => {
http.post(airConditionControl.submitTableData, dataSource.value).then(() => {
message.success('操作成功');
getTable();
getLeftPlan();
});
http
.post(
airConditionControl.submitTableData +
`?projectId=${state.projectId}${state.siteId ? `&siteId=${state.siteId}` : ''}`,
dataSource.value,
)
.then((res) => {
if (res.retcode == 0) {
message.success('操作成功');
getTable();
getLeftPlan();
} else {
message.info(res.msg);
}
});
};
// tab ====================================================
@ -225,7 +252,7 @@
getLeftPlan();
});
};
// 穿
const filterOption = (inputValue: string, option: any) => {
return option.description.indexOf(inputValue) > -1;
};

17
hx-ai-intelligent/src/view/equipmentControl/airConditionControlSystem/tabs3.vue

@ -11,7 +11,7 @@
</thead>
<tbody>
<tr
:style="{ color: row.ctrlResult == 0 ? 'red' : 'white' }"
:style="{ color: row.ctrlResult == 1 ? 'red' : 'white' }"
v-for="(row, index) in dataSource"
:key="index"
@click="handleRowClick(row.id, index)"
@ -20,7 +20,7 @@
<td>{{ row.startTime }}</td>
<td>{{ row.operationContent }}</td>
<td>{{ row.createUser }}</td>
<td>{{ row.ctrlResult ? '成功' : '失败' }}</td>
<td>{{ row.ctrlResult ? '失败' : '成功' }}</td>
</tr>
</tbody>
</table>
@ -163,6 +163,8 @@
};
//
const reset = () => {
trIndex.value = -1;
logModalVisible.value = false;
pagination.value = {
pageSize: 10,
pageNum: 1,
@ -172,13 +174,8 @@
};
//
const handleRowClick = (id: any, index: any) => {
//
if (index === trIndex.value) {
return;
} else {
trIndex.value = index;
getLogDetail(id);
}
trIndex.value = index;
getLogDetail(id);
};
// ==================================================
@ -200,7 +197,7 @@
const cxList = ref([]);
</script>
<style lang="less" scoped>
@import './dialogStyle.less';
@import '../style/dialogStyle.less';
//
.div-add {

28
hx-ai-intelligent/src/view/equipmentControl/lightingManage/indexs.vue

@ -56,14 +56,15 @@
ref="tabs1Ref"
@reset="reset"
@reload="reload"
@changeArea="changeArea"
@reset-all="resetDrawer"
@change-area="changeArea"
:treeData="treeData" />
</a-tab-pane>
<a-tab-pane key="2" tab="计划列表" force-render>
<tabs2 />
<tabs2 ref="tabs2Ref" @reset-all="resetDrawer" />
</a-tab-pane>
<a-tab-pane key="3" tab="日志">
<tabs3 />
<tabs3 ref="tabs3Ref" @reset-all="resetDrawer" />
</a-tab-pane>
</a-tabs>
</a-drawer>
@ -269,8 +270,29 @@
const toggleDrawer = () => {
visible.value = !visible.value;
};
// tabtab
const resetDrawer = () => {
//
getBulbs();
// tab1
reload();
tabs1Ref.value.refresh();
// tab2 tab3
try {
// tab2
tabs2Ref.value.reset();
} catch {}
try {
// tab3
tabs3Ref.value.reset();
} catch {}
};
// tab1
const tabs1Ref = ref();
// tab2
const tabs2Ref = ref();
// tab3
const tabs3Ref = ref();
</script>
<style lang="less" scoped>
@import './index.less';

12
hx-ai-intelligent/src/view/equipmentControl/lightingManage/light.vue

@ -7,7 +7,9 @@
<img src="/asset/image//bulbLogo/21962.png" alt="" />
<span class="tag-text">{{ blub.regionName + ' > ' + blub.deviceGroupName }}</span></div
>
<button class="right-button">{{ record.runStatus.label }}</button>
<button class="right-button">{{
record?.runStatus?.label ? record.runStatus.label : '--'
}}</button>
</div>
<div class="light-tag-box">
<div class="tag-box-item">
@ -36,25 +38,25 @@
<div class="icon-box" :style="props.blub.styleText">
<!-- 正常=0 -->
<img
v-if="record.runStatus.value == 0"
v-if="record?.runStatus?.value == 0"
class="icon-item"
src="/asset/image/bulbLogo/on.png"
alt="" />
<!-- 故障=1 -->
<img
v-if="record.runStatus.value == 1"
v-if="record?.runStatus?.value == 1"
class="icon-item"
src="/asset/image/bulbLogo/off.png"
alt="" />
<!-- 维修=2 -->
<img
v-if="record.runStatus.value == 2"
v-if="record?.runStatus?.value == 2"
class="icon-item"
src="/asset/image/bulbLogo/repair.png"
alt="" />
<!-- 警告=3 -->
<img
v-if="record.runStatus.value == 3"
v-if="record?.runStatus?.value == 3"
class="icon-item"
src="/asset/image/bulbLogo/alarm.png"
alt="" />

97
hx-ai-intelligent/src/view/equipmentControl/lightingManage/tabs1.vue

@ -265,12 +265,13 @@
</template>
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue';
import { ref, computed, onMounted, watch } from 'vue';
import { DownOutlined, UpOutlined, StopOutlined } from '@ant-design/icons-vue';
import { message } from 'ant-design-vue';
import { message, Modal } from 'ant-design-vue';
//
import { http } from '/nerv-lib/util/http';
import { lightingManage } from '/@/api/IlluminationInfo';
import { planManage } from '/@/api/planManage';
//
import { items } from '/@/store/item';
@ -299,12 +300,24 @@
},
},
});
watch(
() => props.treeData,
(newValue) => {
//
// buttons2.value = newValue[0].childList;
},
{
deep: true,
},
);
/**
* @method changeArea 用于控制俯视图的选中状态
* @method reset 用于重置按钮区
* @method reload 用于刷新一次页面
* @method resetAll 刷新所有tab对计划进行修改时需刷新tab2与tab3
*/
const emit = defineEmits(['changeArea', 'reset', 'reload']);
const emit = defineEmits(['changeArea', 'reset', 'reload', 'resetAll']);
// =======================================================================
@ -666,22 +679,21 @@
changeList.value.forEach((item: any) => {
resetChangeList(item);
});
}
changeList.value = [];
if (!reload) {
lockList.value.forEach((item: any) => {
resetLockList(item);
});
//
let data = props.treeData[0];
//
data.selected = true;
// 1-1
buttons2.value = data.childList;
resetMode();
}
changeList.value = [];
lockList.value = [];
//
let data = props.treeData[0];
//
data.selected = true;
// 1-1
buttons2.value = data.childList;
resetMode();
};
// /
const resetLockList = (item: any) => {
props.treeData.find((v: any) => {
@ -730,6 +742,55 @@
return message.info('未产生任何修改');
}
http
.get(planManage.getRunningPlan, {
deviceType: 1,
projectId: state.projectId,
siteId: state.siteId,
})
.then((res) => {
//
if (res.data && res.data.length) {
// 使confirm
// Modal.confirm({
// title: '',
// content: '""',
// onOk() {
// return new Promise((resolve, reject) => {
// });
// },
// onCancel() { },
// });
let flag = window.confirm('有计划正在执行,点击"确定"将暂停当前计划');
if (flag) {
//
http
.post(lightingManage.submitChangeList, {
projectId: state.projectId,
siteId: state.siteId,
lockList: [],
sceneList: [],
})
.then((res) => {
console.log(res, '成功');
//
if (res.retcode == 0) {
sendChangeList();
//
} else {
message.error('关闭进行中的任务操作失败,请重新尝试');
}
});
}
//
} else {
sendChangeList();
}
});
};
// /
const sendChangeList = () => {
http
.post(lightingManage.getChangeList, {
sceneList: changeList.value,
lockList: lockList.value,
@ -737,11 +798,11 @@
siteId: state.siteId,
})
.then((res) => {
if (res.msg === 'success') {
if (res.retcode == 0) {
diffList.value = res.data;
executeVisible.value = true;
} else {
message.warning('获取修改内容失败');
message.error('获取修改内容失败');
}
})
.catch(() => {});
@ -792,7 +853,7 @@
.then((res) => {
let data = res.data;
//
if (data.retcode != 0) {
if (res.retcode != 0) {
//
return message.warning(data.msg);
}
@ -803,8 +864,8 @@
} else {
message.info(`${data.successList.length}条修改成功,${data.failList.length}条修改失败`);
}
emit('reload');
refresh(true);
emit('resetAll');
})
.catch(() => {});
};
@ -829,8 +890,6 @@
changeLine,
//
refresh,
resetLockList,
resetChangeList,
});
</script>
<style lang="less" scoped>

56
hx-ai-intelligent/src/view/equipmentControl/lightingManage/tabs2.vue

@ -1,7 +1,12 @@
<template>
<div class="div-add">
<button class="add" @click="addModal">添加</button>
<a-popconfirm title="是否提交以上修改?" ok-text="确定" cancel-text="取消" @confirm="sendTable">
<a-popconfirm
title="是否提交以上修改?"
placement="bottomLeft"
ok-text="确定"
cancel-text="取消"
@confirm="sendTable">
<button class="add" style="margin-left: 20px">执行</button>
</a-popconfirm>
</div>
@ -47,6 +52,7 @@
title="此操作将移除该数据"
ok-text="确定"
cancel-text="取消"
placement="topRight"
@confirm="deletePlan(row)">
<div class="tabDelete">删除</div>
</a-popconfirm>
@ -55,7 +61,7 @@
</tbody>
</table>
<div class="out-dialog" v-if="addVisible">
<div class="content" v-if="addVisible">
<div class="content">
<div class="div-operation"></div>
<span class="text-operation">计划库</span>
</div>
@ -93,18 +99,22 @@
// ===========================================================
onMounted(() => {
//
getStateEnum();
//
getTable();
// 穿
getLeftPlan();
// 穿
reset();
});
//
const state = items();
//
const getStateEnum = async () => {
let enumData = await getEnum({ params: { enumType: 'PlanExecuteStatus' } });
stateList.value = enumData.data;
};
/**
* @method resetAll 刷新3个tab中的全部数据修改计划会影响tab1数据信息生成tab3日志
*/
const emit = defineEmits(['resetAll']);
// tab ========================================================
@ -132,7 +142,15 @@
// /
const togglePlan = (state: number) => {
dataSource.value.forEach((item: any) => {
item.executeStatus.value = state;
//
if (state == 1) {
if (item.executeStatus.value != 2) {
item.executeStatus.value = state;
}
//
} else {
item.executeStatus.value = state;
}
});
};
@ -160,6 +178,9 @@
if (row.executeStatus.value == 1) {
return message.info('该数据已是待执行状态,无需再次修改');
}
if (row.executeStatus.value == 2) {
return message.info('执行中的状态已被启用,无需修改');
}
row.executeStatus.value = 1;
};
//
@ -173,14 +194,21 @@
.then((res) => {
if (res.retcode == 0) {
message.success('操作成功');
getTable();
getLeftPlan();
//
emit('resetAll');
} else {
message.info(res.msg);
}
});
};
const reset = () => {
//
getTable();
// 穿
getLeftPlan();
};
// tab ====================================================
//
@ -204,7 +232,7 @@
deviceType: 1,
})
.then((res) => {
let arr = [];
let arr: Array<Object> = [];
res.data.forEach((item: any) => {
arr.push({
key: item.id,
@ -231,14 +259,18 @@
http.post(planManage.submitTransData, targetKeys.value).then(() => {
message.success('添加成功');
//
getTable();
getLeftPlan();
reset();
});
};
const filterOption = (inputValue: string, option: any) => {
return option.description.indexOf(inputValue) > -1;
};
//
defineExpose({
reset,
});
</script>
<style lang="less" scoped>
@import '../style/dialogStyle.less';

34
hx-ai-intelligent/src/view/equipmentControl/lightingManage/tabs3.vue

@ -11,7 +11,7 @@
</thead>
<tbody>
<tr
:style="{ color: row.ctrlResult == 0 ? 'red' : 'white' }"
:style="{ color: row.ctrlResult == 1 ? 'red' : 'white' }"
v-for="(row, index) in dataSource"
:key="index"
@click="handleRowClick(row.id, index)"
@ -20,7 +20,7 @@
<td>{{ row.startTime }}</td>
<td>{{ row.operationContent }}</td>
<td>{{ row.createUser }}</td>
<td>{{ row.ctrlResult ? '成功' : '失败' }}</td>
<td>{{ row.ctrlResult ? '失败' : '成功' }}</td>
</tr>
</tbody>
</table>
@ -31,6 +31,7 @@
show-size-changer
:total="pagination.total"
@change="getTable(true)" />
<div style="width: 100%; height: 40px"></div>
<div class="out-dialog" :class="{ showDialog: logModalVisible }" v-if="logModalVisible">
<div class="content">
@ -54,9 +55,17 @@
<div class="btn-item">
<div class="left">控制模式</div>
<div class="right">
<span>手动</span>
<span>{{
item.autoStatusBefore.label.indexOf('模式') != -1
? item.autoStatusBefore.label.replace('模式', '')
: item.autoStatusBefore.label
}}</span>
<img src="/asset/image/bulbLogo/22406.png" alt="" />
<span>自动</span></div
<span>{{
item.autoStatusAfter.label.indexOf('模式') != -1
? item.autoStatusAfter.label.replace('模式', '')
: item.autoStatusAfter.label
}}</span></div
>
</div>
<div class="btn-item">
@ -163,6 +172,8 @@
};
//
const reset = () => {
trIndex.value = -1;
logModalVisible.value = false;
pagination.value = {
pageSize: 10,
pageNum: 1,
@ -172,13 +183,8 @@
};
//
const handleRowClick = (id: any, index: any) => {
//
if (index === trIndex.value) {
return;
} else {
trIndex.value = index;
getLogDetail(id);
}
trIndex.value = index;
getLogDetail(id);
};
// ==================================================
@ -197,7 +203,13 @@
}
});
};
//
const cxList = ref([]);
//
defineExpose({
reset,
});
</script>
<style lang="less" scoped>
@import '../style/dialogStyle.less';

1
hx-ai-intelligent/src/view/equipmentControl/style/color.less

@ -1,3 +1,4 @@
// 颜色变量
:root {
// 电梯
// 正常

1
hx-ai-intelligent/src/view/equipmentControl/style/dialogStyle.less

@ -1,3 +1,4 @@
// 设备群控 > 抽屉 > 控制面板 & 日志 的附加弹窗
.out-dialog {
position: fixed;
right: 496px;

118
hx-ai-intelligent/src/view/equipmentControl/ventilationSystem/components/fanControl.vue

@ -137,6 +137,7 @@
title="此操作将会撤销修改"
ok-text="确定"
cancel-text="取消"
placement="bottomRight"
@confirm="delBtn(item)"
@cancel="changeCancel">
<button class="cxbtn">撤销</button>
@ -146,9 +147,9 @@
<div class="btn-item">
<div class="left">控制模式</div>
<div class="right">
<span>手动</span>
<span>{{ item.stateBefore.autoStatus.label.replace('模式', '') }}</span>
<img src="/asset/image/bulbLogo/22406.png" alt="" />
<span>自动</span></div
<span>{{ item.stateAfter.autoStatus.label.replace('模式', '') }}</span></div
>
</div>
<div class="btn-item">
@ -230,12 +231,13 @@
</template>
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue';
import { ref, computed, onMounted, watch } from 'vue';
import { DownOutlined, UpOutlined, StopOutlined } from '@ant-design/icons-vue';
import { message } from 'ant-design-vue';
import { message, Modal } from 'ant-design-vue';
//
import { http } from '/nerv-lib/util/http';
import { ventilating } from '/@/api/ventilatingSystem';
import { planManage } from '/@/api/planManage';
//
import { items } from '/@/store/item';
@ -247,12 +249,15 @@
if (props.type == '排风扇') {
url.getList = ventilating.getChangeList1;
url.sendList = ventilating.sendChangeList1;
url.deviceType = 3;
} else if (props.type == '风幕机') {
url.getList = ventilating.getChangeList2;
url.sendList = ventilating.sendChangeList2;
url.deviceType = 4;
} else {
url.getList = ventilating.getChangeList3;
url.sendList = ventilating.sendChangeList3;
url.deviceType = 5;
}
});
// 1-1
@ -266,6 +271,7 @@
const url = {
getList: '',
sendList: '',
deviceType: 0,
};
// ===================================================================
@ -282,12 +288,24 @@
type: String,
},
});
watch(
() => props.treeData,
(newValue) => {
//
// buttons2.value = newValue[0].childList;
},
{
deep: true,
},
);
/**
* @method changeArea 用于控制俯视图的选中状态
* @method reset 用于重置按钮区
* @method reload 用于刷新一次页面
* @method resetAll 刷新所有tab对计划进行修改时需刷新tab2与tab3
*/
const emit = defineEmits(['reset', 'reload']);
const emit = defineEmits(['reset', 'reload', 'resetAll']);
// ======================================================================
@ -613,21 +631,19 @@
changeList.value.forEach((item: any) => {
resetChangeList(item);
});
}
changeList.value = [];
if (!reload) {
lockList.value.forEach((item: any) => {
resetLockList(item);
});
//
let data = props.treeData[0];
//
data.selected = true;
// 1-1
buttons2.value = data.childList;
resetMode();
}
changeList.value = [];
lockList.value = [];
//
let data = props.treeData[0];
//
data.selected = true;
// 1-1
buttons2.value = data.childList;
resetMode();
};
// /
const resetLockList = (item: any) => {
@ -677,6 +693,55 @@
return message.info('未产生任何修改');
}
http
.get(planManage.getRunningPlan, {
deviceType: url.deviceType,
projectId: state.projectId,
siteId: state.siteId,
})
.then((res) => {
//
if (res.data && res.data.length) {
// 使confirm
// Modal.confirm({
// title: '',
// content: '""',
// onOk() {
// return new Promise((resolve, reject) => {
// });
// },
// onCancel() { },
// });
let flag = window.confirm('有计划正在执行,点击"确定"将暂停当前计划');
if (flag) {
//
http
.post(url.getList, {
projectId: state.projectId,
siteId: state.siteId,
lockList: [],
sceneList: [],
})
.then((res) => {
console.log(res, '成功');
//
if (res.retcode == 0) {
sendChangeList();
//
} else {
message.error('关闭进行中的任务操作失败,请重新尝试');
}
});
}
//
} else {
sendChangeList();
}
});
};
// /
const sendChangeList = () => {
http
.post(url.getList, {
sceneList: changeList.value,
lockList: lockList.value,
@ -684,11 +749,11 @@
siteId: state.siteId,
})
.then((res) => {
if (res.msg === 'success') {
if (res.retcode == 0) {
diffList.value = res.data;
executeVisible.value = true;
} else {
message.warning('获取修改内容失败');
message.error('获取修改内容失败');
}
})
.catch(() => {});
@ -736,9 +801,22 @@
projectId: state.projectId,
siteId: state.siteId,
})
.then(() => {
emit('reload');
.then((res) => {
let data = res.data;
//
if (res.retcode != 0) {
//
return message.warning(data.msg);
}
//
if (data.allSucceed) {
message.success('修改完成');
// allSucceedtrue
} else {
message.info(`${data.successList.length}条修改成功,${data.failList.length}条修改失败`);
}
refresh(true);
emit('resetAll');
})
.catch(() => {});
};
@ -759,6 +837,8 @@
defineExpose({
//
changeLine,
//
refresh,
});
</script>
<style lang="less" scoped>

33
hx-ai-intelligent/src/view/equipmentControl/ventilationSystem/components/fanLog.vue

@ -11,7 +11,7 @@
</thead>
<tbody>
<tr
:style="{ color: row.ctrlResult == 0 ? 'red' : 'white' }"
:style="{ color: row.ctrlResult == 1 ? 'red' : 'white' }"
v-for="(row, index) in dataSource"
:key="index"
@click="handleRowClick(row.id, index)"
@ -20,7 +20,7 @@
<td>{{ row.startTime }}</td>
<td>{{ row.operationContent }}</td>
<td>{{ row.createUser }}</td>
<td>{{ row.ctrlResult ? '成功' : '失败' }}</td>
<td>{{ row.ctrlResult ? '失败' : '成功' }}</td>
</tr>
</tbody>
</table>
@ -31,6 +31,7 @@
show-size-changer
:total="pagination.total"
@change="getTable(true)" />
<div style="width: 100%; height: 40px"></div>
<div class="out-dialog" :class="{ showDialog: logModalVisible }" v-if="logModalVisible">
<div class="content">
@ -54,9 +55,17 @@
<div class="btn-item">
<div class="left">控制模式</div>
<div class="right">
<span>手动</span>
<span>{{
item.autoStatusBefore.label.indexOf('模式') != -1
? item.autoStatusBefore.label.replace('模式', '')
: item.autoStatusBefore.label
}}</span>
<img src="/asset/image/bulbLogo/22406.png" alt="" />
<span>自动</span></div
<span>{{
item.autoStatusAfter.label.indexOf('模式') != -1
? item.autoStatusAfter.label.replace('模式', '')
: item.autoStatusAfter.label
}}</span></div
>
</div>
<div class="btn-item">
@ -193,6 +202,8 @@
};
//
const reset = () => {
trIndex.value = -1;
logModalVisible.value = false;
// state.setLoading(true);
pagination.value = {
pageSize: 10,
@ -203,13 +214,8 @@
};
//
const handleRowClick = (id: any, index: any) => {
//
if (index === trIndex.value) {
return;
} else {
trIndex.value = index;
getLogDetail(id);
}
trIndex.value = index;
getLogDetail(id);
};
// ==================================================
@ -229,6 +235,11 @@
});
};
const cxList = ref([]);
//
defineExpose({
reset,
});
</script>
<style lang="less" scoped>
@import '../../style/dialogStyle.less';

48
hx-ai-intelligent/src/view/equipmentControl/ventilationSystem/components/fanPlant.vue

@ -52,6 +52,7 @@
title="此操作将移除该数据"
ok-text="确定"
cancel-text="取消"
placement="topRight"
@confirm="deletePlan(row)">
<div class="tabDelete">删除</div>
</a-popconfirm>
@ -60,7 +61,7 @@
</tbody>
</table>
<div class="out-dialog" v-if="addVisible">
<div class="content" v-if="addVisible">
<div class="content">
<div class="div-operation"></div>
<span class="text-operation">计划库</span>
</div>
@ -126,6 +127,11 @@
}
});
/**
* @method resetAll 刷新3个tab中的全部数据修改计划会影响tab1数据信息生成tab3日志
*/
const emit = defineEmits(['resetAll']);
// tab ========================================================
//
@ -150,7 +156,15 @@
// /
const togglePlan = (state: number) => {
dataSource.value.forEach((item: any) => {
item.executeStatus.value = state;
//
if (state == 1) {
if (item.executeStatus.value != 2) {
item.executeStatus.value = state;
}
//
} else {
item.executeStatus.value = state;
}
});
};
@ -178,6 +192,9 @@
if (row.executeStatus.value == 1) {
return message.info('该数据已是待执行状态,无需再次修改');
}
if (row.executeStatus.value == 2) {
return message.info('执行中的状态已被启用,无需修改');
}
row.executeStatus.value = 1;
};
//
@ -187,13 +204,24 @@
url + `?projectId=${state.projectId}${state.siteId ? `&siteId=${state.siteId}` : ''}`,
dataSource.value,
)
.then(() => {
message.success('操作成功');
getTable();
getLeftPlan();
.then((res) => {
if (res.retcode == 0) {
message.success('操作成功');
//
emit('resetAll');
} else {
message.info(res.msg);
}
});
};
const reset = () => {
//
getTable();
// 穿
getLeftPlan();
};
// tab ====================================================
//
@ -244,14 +272,18 @@
http.post(planManage.submitTransData, targetKeys.value).then(() => {
message.success('添加成功');
//
getTable();
getLeftPlan();
reset();
});
};
const filterOption = (inputValue: string, option: any) => {
return option.description.indexOf(inputValue) > -1;
};
//
defineExpose({
reset,
});
</script>
<style lang="less" scoped>
@import '../../style/dialogStyle.less';

150
hx-ai-intelligent/src/view/equipmentControl/ventilationSystem/index.vue

@ -137,13 +137,17 @@
</div>
<a-tabs v-model:activeKey="activeKey">
<a-tab-pane key="1" tab="控制面板">
<fanControl :treeData="treeData" :type="`排风扇`" />
<fanControl
ref="tabs1Ref"
@reset-all="resetDrawer"
:treeData="treeData"
:type="`排风扇`" />
</a-tab-pane>
<a-tab-pane key="2" tab="计划列表" force-render>
<fanPlant :status="stateList" :type="3" />
<fanPlant ref="tabs2Ref" @reset-all="resetDrawer" :status="stateList" :type="3" />
</a-tab-pane>
<a-tab-pane key="3" tab="日志">
<fanLog :type="3" />
<fanLog ref="tabs3Ref" @reset-all="resetDrawer" :type="3" />
</a-tab-pane>
</a-tabs>
</a-drawer>
@ -194,13 +198,17 @@
</div>
<a-tabs v-model:activeKey="activeKey">
<a-tab-pane key="1" tab="控制面板">
<fanControl :treeData="treeData" :type="`风幕机`" />
<fanControl
ref="tabs1Ref"
@reset-all="resetDrawer"
:treeData="treeData"
:type="`风幕机`" />
</a-tab-pane>
<a-tab-pane key="2" tab="计划列表" force-render>
<fanPlant :status="stateList" :type="4" />
<fanPlant ref="tabs2Ref" @reset-all="resetDrawer" :status="stateList" :type="4" />
</a-tab-pane>
<a-tab-pane key="3" tab="日志">
<fanLog :type="4" />
<fanLog ref="tabs3Ref" @reset-all="resetDrawer" :type="4" />
</a-tab-pane>
</a-tabs>
</a-drawer>
@ -250,13 +258,17 @@
</div>
<a-tabs v-model:activeKey="activeKey">
<a-tab-pane key="1" tab="控制面板">
<fanControl :treeData="treeData" :type="`电动窗`" />
<fanControl
ref="tabs1Ref"
@reset-all="resetDrawer"
:treeData="treeData"
:type="`电动窗`" />
</a-tab-pane>
<a-tab-pane key="2" tab="计划列表" force-render>
<fanPlant :status="stateList" :type="5" />
<fanPlant ref="tabs2Ref" @reset-all="resetDrawer" :status="stateList" :type="5" />
</a-tab-pane>
<a-tab-pane key="3" tab="日志">
<fanLog :type="5" />
<fanLog ref="tabs3Ref" @reset-all="resetDrawer" :type="5" />
</a-tab-pane>
</a-tabs>
</a-drawer>
@ -351,6 +363,15 @@
const toggleDrawer = () => {
visible.value = !visible.value;
};
// URL
let url = '';
//
const reload = () => {
http.get(url, { projectId: state.projectId, siteId: state.siteId }).then((res) => {
const data = res.data;
treeData.value = data[0].childList;
});
};
// tab1 - =================================================================
@ -359,7 +380,6 @@
const getTree = async (type: number, index: number) => {
// tab1
activeKey.value = '1';
let url;
if (type == 1) {
url = ventilating.getTree1;
} else if (type == 2) {
@ -489,93 +509,33 @@
},
]);
//
const fanData = ref([
// {
// title: '',
// styleText: { left: '43.2%', bottom: '77.8%' },
// type: 'fan',
// lineType: '1',
// },
// {
// title: '',
// styleText: { left: '50%', bottom: '77.8%' },
// type: 'fan',
// lineType: '2',
// },
// {
// title: '',
// styleText: { left: '41.2%', bottom: '27.8%' },
// type: 'fan',
// lineType: '1',
// },
// {
// title: '',
// styleText: { left: '51.2%', bottom: '27.8%' },
// type: 'fan',
// lineType: '2',
// },
]);
const fanData = ref([]);
//
const airCurtainData = ref([
// {
// title: '',
// styleText: { left: '38%', bottom: '57.8%' },
// type: 'airCurtain',
// },
// {
// title: '',
// styleText: { left: '58.5%', bottom: '57.3%' },
// type: 'airCurtain',
// },
// {
// title: '',
// styleText: { left: '64.2%', bottom: '22.8%' },
// type: 'airCurtain',
// },
]);
const airCurtainData = ref([]);
//
const windowData = ref([
// {
// title: '1',
// styleText: { left: '32%', bottom: '28%' },
// type: 'window',
// },
// {
// title: '2',
// styleText: { left: '33.5%', bottom: '42.8%' },
// type: 'window',
// },
// {
// title: '3',
// styleText: { left: '35%', bottom: '57.8%' },
// type: 'window',
// },
// {
// title: '4',
// styleText: { left: '36.5%', bottom: '72.8%' },
// type: 'window',
// },
// {
// title: '5',
// styleText: { left: '66%', bottom: '28%' },
// type: 'window',
// },
// {
// title: '6',
// styleText: { left: '64%', bottom: '42.8%' },
// type: 'window',
// },
// {
// title: '7',
// styleText: { left: '62%', bottom: '57.8%' },
// type: 'window',
// },
// {
// title: '8',
// styleText: { left: '60%', bottom: '72.8%' },
// type: 'window',
// },
]);
const windowData = ref([]);
// tabtab
const resetDrawer = () => {
// tab1
reload();
tabs1Ref.value.refresh();
// tab2 tab3
try {
// tab2
tabs2Ref.value.reset();
} catch {}
try {
// tab3
tabs3Ref.value.reset();
} catch {}
};
// tab1
const tabs1Ref = ref();
// tab2
const tabs2Ref = ref();
// tab3
const tabs3Ref = ref();
onMounted(() => {
//
getStateEnum();

Loading…
Cancel
Save