Browse Source

Merge branch 'temp' of http://123.60.103.97:3000/xuziqiang/SaaS-lib into temp

deploy-dev
xuziqiang 2 months ago
parent
commit
b06c9ddc84
  1. 11
      hx-ai-intelligent/src/api/carbonEmissionFactorLibrary.ts
  2. 20
      hx-ai-intelligent/src/router/alarmManagement.ts
  3. 6
      hx-ai-intelligent/src/view/alarmManagement/alarmSettings/energyAlarm/editConfigureEnergyAlarm.vue
  4. 5
      hx-ai-intelligent/src/view/alarmManagement/alarmSettings/equipmentAlarm/editConfigureDeviceAlarm.vue
  5. 166
      hx-ai-intelligent/src/view/alarmManagement/alarmSettings/notificationManagement/index.vue
  6. 22
      hx-ai-intelligent/src/view/alarmManagement/alarmSettings/notificationManagement/linkPeople/config.ts
  7. 337
      hx-ai-intelligent/src/view/alarmManagement/alarmSettings/notificationManagement/linkPeople/index.vue
  8. 28
      hx-ai-intelligent/src/view/alarmManagement/equipmentAlarm/index.vue
  9. 283
      hx-ai-intelligent/src/view/alarmManagement/equipmentAlarm/look.vue
  10. 108
      hx-ai-intelligent/src/view/alarmManagement/equipmentAlarm/notificationManagementMock.json
  11. 39
      hx-ai-intelligent/src/view/alarmManagement/equipmentAlarm/status.vue
  12. 164
      hx-ai-intelligent/src/view/alarmManagement/equipmentAlarm/ts/config.ts
  13. 241
      hx-ai-intelligent/src/view/carbonEmissionManage/carbonEmissionFactorLibrary/index.vue
  14. 42
      hx-ai-intelligent/src/view/carbonEmissionManage/carbonEmissionStatistics/config.ts
  15. 1
      hx-ai-intelligent/src/view/carbonEmissionManage/carbonEmissionStatistics/energyConsumption/index.vue
  16. 401
      hx-ai-intelligent/src/view/carbonEmissionManage/carbonEmissionStatistics/quickCalculation/index copy.vue
  17. 180
      hx-ai-intelligent/src/view/carbonEmissionManage/carbonEmissionStatistics/quickCalculation/index.vue
  18. 48
      hx-ai-intelligent/src/view/monitor/energyMonitor/tree/index.vue
  19. 160
      hx-ai-intelligent/src/view/monitor/environmentMonitor/aggregateData/index.vue

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

@ -11,6 +11,9 @@ export enum carbonEmissionFactorLibrary {
// 单位管理
dictionaryUnitManagement = '/carbon-smart/api/carbon/emission/factor/dictionaryUnitManagement',
findOutermost = '/carbon-smart/api/carbon/emission/factor/findOutermost',
createDictionary = '/carbon-smart/api/carbon/emission/factor/createDictionary',
updateDictionary = '/carbon-smart/api/carbon/emission/factor/updateDictionary',
delDictionary = '/carbon-smart/api/carbon/emission/factor/delDictionary',
}
// 碳排管理-碳排统计接口
export enum energyConsumption {
@ -21,3 +24,11 @@ export enum energyConsumption {
update = '/carbon-smart/api/carbon/stats/update',
del = '/carbon-smart/api/carbon/stats/del',
}
// 碳排管理-碳排速算接口
export enum quickCalculation {
carbonQuickTree = '/carbon-smart/api/carbon/energy/correlation/carbonQuickTree',
queryCarbonEmissionPage = '/carbon-smart/api/carbon/energy/correlation/queryCarbonEmissionPage',
creat = '/carbon-smart/api/carbon/energy/correlation/creat',
update = '/carbon-smart/api/carbon/energy/correlation/update',
del = '/carbon-smart/api/carbon/energy/correlation/del',
}

20
hx-ai-intelligent/src/router/alarmManagement.ts

@ -26,6 +26,26 @@ const alarmManagement = {
],
},
{
path: 'equipmentAlarm ',
name: 'EquipmentAlarm',
meta: { title: '设备告警', hideChildren: true, icon: 'gaojingguanli' },
component: Base,
redirect: { name: 'equipmentAlarmIndex' },
children: [
{
path: 'index',
name: 'equipmentAlarmIndex',
// component: () => import('/nerv-lib/saas/view/menuManage/index.vue'),
component: () => import('/@/view/alarmManagement/equipmentAlarm/index.vue'),
meta: {
title: '设备告警',
keepAlive: true,
// backApi: [],
},
},
],
},
{
path: 'alarmSettings',
name: 'AlarmSettings',
meta: { title: '告警设置', hideChildren: true, icon: 'gaojingguanli' },

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

@ -229,7 +229,7 @@
.post(device.queryDevicePage, {
pageNum: 1,
pageSize: 999,
energyType: selectedOptions[0].cnValue,
energyType: selectedOptions[0].dicKey,
orgId: orgId.value,
})
.then((res) => {
@ -241,7 +241,7 @@
.post(group.queryDeviceGroupTree, {
pageNum: 1,
pageSize: 999,
energyType: selectedOptions[0].cnValue,
energyType: selectedOptions[0].dicKey,
orgId: orgId.value,
})
.then((res) => {
@ -502,7 +502,7 @@
.grey-background.ant-switch .ant-switch-handle {
background-color: grey !important;
}
/deep/ .ant-form-item-label {
:deep(.ant-form-item-label) {
z-index: 20;
text-align: right;
width: 23%;

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

@ -146,7 +146,7 @@
</template>
<script lang="ts" setup>
import { NsMessage } from '/nerv-lib/component';
import { ref, toRaw } from 'vue';
import { ref } from 'vue';
import type { SelectProps } from 'ant-design-vue';
import type { ShowSearchType } from 'ant-design-vue/es/cascader';
import { device } from '/@/api/deviceManage';
@ -154,7 +154,6 @@
import { http } from '/nerv-lib/util';
import type { Rule } from 'ant-design-vue/es/form';
import { async } from '@antv/x6/lib/registry/marker/async';
const visible = ref(false);
@ -505,7 +504,7 @@
.grey-background.ant-switch .ant-switch-handle {
background-color: grey !important;
}
/deep/ .ant-form-item-label {
:deep(.ant-form-item-label) {
z-index: 20;
text-align: right;
width: 23%;

166
hx-ai-intelligent/src/view/alarmManagement/alarmSettings/notificationManagement/index.vue

@ -73,7 +73,11 @@
</a-table>
</div>
</div>
<linkPeople v-show="visibleModel" ref="linkPeoples" @handleCancel="handleCancel" />
<linkPeople
v-show="visibleModel"
ref="linkPeoples"
@handleCancel="handleCancel"
@handleOk="handleOk" />
</ns-drawer>
</template>
<script lang="ts" setup>
@ -98,10 +102,10 @@
},
{
title: '姓名',
dataIndex: 'name',
dataIndex: 'deviceName',
width: 80,
fixed: 'left',
key: 'name',
key: 'deviceName',
},
{
title: '性别',
@ -127,127 +131,7 @@
},
];
const visibleModel = ref(false);
const dataSource = ref([
{
id: 1,
name: '张三1',
sex: '男',
site: '济阳站',
department: '济阳站/产品/产品经理',
},
{
id: 2,
name: '张三2',
sex: '男',
site: '济阳站',
department: '济阳站/产品/产品经理',
},
{
id: 3,
name: '张三3',
sex: '男',
site: '济阳站',
department: '济阳站/产品/产品经理',
},
{
id: 4,
name: '张三',
sex: '男',
site: '济阳站',
department: '济阳站/产品/产品经理',
},
{
id: 5,
name: '张三',
sex: '男',
site: '济阳站',
department: '济阳站/产品/产品经理',
},
{
id: 6,
name: '张三',
sex: '男',
site: '济阳站',
department: '济阳站/产品/产品经理',
},
{
id: 7,
name: '张三',
sex: '男',
site: '济阳站',
department: '济阳站/产品/产品经理',
},
{
id: 8,
name: '张三',
sex: '男',
site: '济阳站',
department: '济阳站/产品/产品经理',
},
{
id: 9,
name: '张三',
sex: '男',
site: '济阳站',
department: '济阳站/产品/产品经理',
},
{
id: 10,
name: '张三',
sex: '男',
site: '济阳站',
department: '济阳站/产品/产品经理',
},
{
id: 11,
name: '张三',
sex: '男',
site: '济阳站',
department: '济阳站/产品/产品经理',
},
{
id: 12,
name: '张三',
sex: '男',
site: '济阳站',
department: '济阳站/产品/产品经理',
},
{
id: 13,
name: '张三',
sex: '男',
site: '济阳站',
department: '济阳站/产品/产品经理',
},
{
id: 14,
name: '张三',
sex: '男',
site: '济阳站',
department: '济阳站/产品/产品经理',
},
{
id: 15,
name: '张三',
sex: '男',
site: '济阳站',
department: '济阳站/产品/产品经理',
},
{
id: 16,
name: '张三',
sex: '男',
site: '济阳站',
department: '济阳站/产品/产品经理',
},
{
id: 17,
name: '张三',
sex: '男',
site: '济阳站',
department: '济阳站/产品/产品经理',
},
]);
const dataSource = ref([]);
const visible = ref(false);
const linkPeoples = ref(null);
const handleChangePage = (current: number, pageSize: number) => {
@ -269,12 +153,21 @@
//
const chengUser = () => {
visibleModel.value = true;
linkPeoples.value.getData();
let ids = [];
dataSource.value.forEach((item) => {
ids.push(item.id);
});
linkPeoples.value.getData({ id: ids, data: dataSource });
};
//
const handleCancel = () => {
visibleModel.value = false;
};
//
const handleOk = (data: any) => {
visibleModel.value = false;
dataSource.value = data.data;
};
//
const infoObject = ref({
enableRules: 0,
@ -306,10 +199,20 @@
const toggle = (value: any) => {
//
if (value) {
// infoObject.value = value;
//
infoObject.value = {
enableRules: 0,
};
// await http
// .post(group.queryDeviceGroupTree, {
// pageNum: 1,
// pageSize: 999,
// energyType: selectedOptions[0].dicKey,
// orgId: orgId.value,
// })
// .then((res) => {
// jdTreeData.value = res.data;
// });
} else {
infoObject.value = {
enableRules: 0,
@ -328,6 +231,15 @@
};
const btnClick = () => {
console.log(infoObject.value);
//
let obj = {};
obj.selectList = [];
dataSource.value.forEach((item) => {
obj.selectList.push({
people: item.id,
});
});
console.log(obj, '数据');
//
formRef.value.validate().then(() => {
//
@ -381,7 +293,7 @@
.grey-background.ant-switch .ant-switch-handle {
background-color: grey !important;
}
/deep/ .ant-form-item-label {
:deep(.ant-form-item-label) {
z-index: 20;
text-align: left;
width: 20%;

22
hx-ai-intelligent/src/view/alarmManagement/alarmSettings/notificationManagement/linkPeople/config.ts

@ -0,0 +1,22 @@
import { department } from '/@/api/origanizemanage';
export const editTreeConfig = (orgId) => ({
selectedKeys: ['0-0'],
defaultExpandAll: true,
api: department.queryDeptTree,
params: { orgId },
resultField: 'data.orgInfos',
fieldNames: { title: 'orgName', key: 'orgId' },
formConfig: {
schemas: [
{
field: 'orgName',
component: 'NsInput',
autoSubmit: true,
componentProps: {
placeholder: '请输入企业名称',
},
},
],
},
});

337
hx-ai-intelligent/src/view/alarmManagement/alarmSettings/notificationManagement/linkPeople/index.vue

@ -2,75 +2,63 @@
<a-modal
v-model:visible="show"
width="1100px"
style="top: 50%; transform: translateY(-50%)"
style="top: 50%; transform: translateY(-50%); overflow-y: hidden"
title="添加联系人"
@ok="handleOk"
@cancel="handleCancel">
<div style="width: 100%; height: 480px; display: flex">
<div style="width: 300px; height: 100%; overflow-y: auto; padding: 0, 12px; gap: 5px">
<div class="box">
<div class="box-left">
<div style="width: 100%; display: flex; position: relative">
<div
style="
border-width: 0px;
position: absolute;
left: 0px;
top: 5px;
width: 5px;
height: 15px;
background: inherit;
background-color: rgba(251, 156, 67, 1);
border: none;
border-radius: 5px;
-moz-box-shadow: none;
-webkit-box-shadow: none;
box-shadow: none;
"></div>
<div class="border-card"></div>
<span style="margin-left: 24px; color: #333333">联系人名单</span>
</div>
<img
style="width: 100%; margin-top: -10px"
style="width: 100%; height: 2px"
src="https://files.axshare.com/gsc/4T0UQR/7e/5d/a2/7e5da2a277344db8af30521cefeb70cc/images/告警设置/u150.svg?pageId=1f58c1ba-b461-4fe8-a2b3-295f1e7b0aa0" />
<a-input-search
v-model:value="searchValue"
style="margin-bottom: 8px"
placeholder="请输入关键字" />
<img
style="width: 100%; margin-top: -10px"
style="width: 100%; height: 2px"
src="https://files.axshare.com/gsc/4T0UQR/7e/5d/a2/7e5da2a277344db8af30521cefeb70cc/images/告警设置/u150.svg?pageId=1f58c1ba-b461-4fe8-a2b3-295f1e7b0aa0" />
<div style="width: 100%; height: 370px; overflow-y: auto">
<a-tree
:expanded-keys="expandedKeys"
:auto-expand-parent="autoExpandParent"
:tree-data="gData"
@expand="onExpand">
<template #title="{ title }">
<span v-if="title.indexOf(searchValue) > -1">
{{ title.substr(0, title.indexOf(searchValue)) }}
<span style="color: #f50">{{ searchValue }}</span>
{{ title.substr(title.indexOf(searchValue) + searchValue.length) }}
</span>
<span v-else>{{ title }}</span>
</template>
</a-tree>
@select="onSelect"
@expand="onExpand"
/></div>
<!-- <ns-tree-api v-bind="config" @select="treeSelect" /> -->
</div>
<div style="width: calc(100% - 200px); height: 100%; padding: 0, 24px; overflow-y: auto">
<div class="box-right">
<div style="width: 100%; display: flex; position: relative">
<div
style="
border-width: 0px;
position: absolute;
left: 0px;
top: 5px;
width: 5px;
height: 15px;
background: inherit;
background-color: rgba(251, 156, 67, 1);
border: none;
border-radius: 5px;
-moz-box-shadow: none;
-webkit-box-shadow: none;
box-shadow: none;
"></div>
<div class="border-card"></div>
<span style="margin-left: 24px; color: #333333">人员列表 </span>
<a-input-search
v-model:value="name"
style="margin-bottom: 8px; width: 280px; position: absolute; right: 20px"
placeholder="请输入"
allowClear="true"
@search="onSearch" />
</div>
<img
style="width: 100%; height: 2px"
src="https://files.axshare.com/gsc/4T0UQR/7e/5d/a2/7e5da2a277344db8af30521cefeb70cc/images/告警设置/u150.svg?pageId=1f58c1ba-b461-4fe8-a2b3-295f1e7b0aa0" />
<div style="width: 100%; height: 450px; overflow-y: auto; padding: 12px 0">
<a-table
:row-selection="{
selectedRowKeys: selectedRowKey,
preserveSelectedRowKeys: true,
onChange: onSelectChange,
}"
:columns="columns"
:data-source="dataSource"
:rowKey="(record: any) => record.id"
:pagination="pagination"
:bordered="true"
:size="'middle'" />
</div>
</div>
</div>
@ -78,33 +66,276 @@
</template>
<script lang="ts">
import { ref } from 'vue';
import { ref, watch, computed } from 'vue';
import { defineComponent } from 'vue';
import type { TreeProps } from 'ant-design-vue';
import { device } from '/@/api/deviceManage';
import { http } from '/nerv-lib/util';
// import { editTreeConfig } from './config';
const x = 3;
const y = 2;
const z = 1;
const genData: TreeProps['treeData'] = [];
const generateData = (_level: number, _preKey?: string, _tns?: TreeProps['treeData']) => {
const preKey = _preKey || '0';
const tns = _tns || genData;
const children = [];
for (let i = 0; i < x; i++) {
const key = `${preKey}-${i}`;
tns.push({ title: key, key });
if (i < y) {
children.push(key);
}
}
if (_level < 0) {
return tns;
}
const level = _level - 1;
children.forEach((key, index) => {
tns[index].children = [];
return generateData(level, key, tns[index].children);
});
};
generateData(z);
const dataList: TreeProps['treeData'] = [];
const generateList = (data: TreeProps['treeData']) => {
for (let i = 0; i < data.length; i++) {
const node = data[i];
const key = node.key;
dataList.push({ key, title: key });
if (node.children) {
generateList(node.children);
}
}
};
generateList(genData);
const getParentKey = (
key: string | number,
tree: TreeProps['treeData'],
): string | number | undefined => {
let parentKey;
for (let i = 0; i < tree.length; i++) {
const node = tree[i];
if (node.children) {
if (node.children.some((item) => item.key === key)) {
parentKey = node.key;
} else if (getParentKey(key, node.children)) {
parentKey = getParentKey(key, node.children);
}
}
}
return parentKey;
};
export default defineComponent({
setup(props, { emit }) {
// const config = computed(() => {
// return editTreeConfig(result);
// });
//
const orgId = ref('');
const result = JSON.parse(sessionStorage.getItem('ORGID')!);
orgId.value = result;
const dataSource = ref([]);
const selectedRowKey = ref([]);
const selectedRow = ref([]);
const name = ref(null);
const onSearch = () => {
http
.post(device.queryDevicePage, {
pageNum: pagination.value.current,
pageSize: pagination.value.pageSize,
deviceName: name.value,
orgId: orgId.value,
})
.then((res) => {
dataSource.value = res.data.records;
pagination.value.total = res.data.total;
});
};
const onSelect = (selectedKeys: any, info: any) => {
console.log('selected', selectedKeys, info.node.dataRef);
pagination.value.current = 1;
onSearch();
};
const handleChangePage = (current: number, pageSize: number) => {
pagination.value.current = current;
pagination.value.pageSize = pageSize;
http
.post(device.queryDevicePage, {
pageNum: pagination.value.current,
pageSize: pagination.value.pageSize,
orgId: orgId.value,
})
.then((res) => {
dataSource.value = res.data.records;
pagination.value.total = res.data.total;
});
console.log(selectedRowKey.value, selectedRow.value);
};
const onSelectChange = (selectedRowKeys: any, selectedRows: any) => {
console.log(selectedRowKeys, selectedRows);
console.log(selectedRows, '数据');
selectedRowKey.value = selectedRowKeys;
selectedRow.value = selectedRows;
};
const pagination = ref({
total: 0,
size: 'small',
current: 1,
pageSize: 10,
showQuickJumper: true,
showLessItems: true,
// showSizeChanger: true,
showTotal: (total: number, range: any) =>
total && range ? `显示第${range[0]}${range[1]}条记录,共 ${total} 条记录` : '',
onChange: handleChangePage,
});
const columns = [
{
title: '序号',
dataIndex: 'address',
customRender: (text: any) => {
return text.index + 1;
},
},
{
title: '姓名',
dataIndex: 'deviceName',
},
{
title: '性别',
dataIndex: 'sex',
},
{
title: '组织关系',
dataIndex: 'address',
},
{
title: '部门 ',
dataIndex: 'address',
},
];
const handleOk = () => {
//
console.log('点击了确定按钮');
emit('handleOk', { id: selectedRowKey.value, data: selectedRow.value });
show.value = false;
pagination.value.current = 1;
};
const searchValue = ref<string>('');
const getData = () => {
const getData = (data: any) => {
selectedRow.value = data.data;
selectedRowKey.value = data.id;
show.value = true;
http
.post(device.queryDevicePage, {
pageNum: pagination.value.current,
pageSize: pagination.value.pageSize,
orgId: orgId.value,
})
.then((res) => {
dataSource.value = res.data.records;
pagination.value.total = res.data.total;
});
};
const show = ref(false);
const handleCancel = () => {
//
console.log('点击了取消按钮');
pagination.value.current = 1;
emit('handleCancel', null);
show.value = false;
};
//
const expandedKeys = ref<(string | number)[]>([]);
const searchValue = ref<string>('');
const deviceName = ref<string>('');
const autoExpandParent = ref<boolean>(true);
const gData = ref<TreeProps['treeData']>(genData);
const onExpand = (keys: string[]) => {
expandedKeys.value = keys;
autoExpandParent.value = false;
console.log(keys, '数据');
};
watch(searchValue, (value) => {
console.log(gData.value, '数据');
const expanded = dataList
.map((item: TreeProps['treeData'][number]) => {
if (item.title.indexOf(value) > -1) {
return getParentKey(item.key, gData.value);
}
return null;
})
.filter((item, i, self) => item && self.indexOf(item) === i);
expandedKeys.value = expanded;
searchValue.value = value;
autoExpandParent.value = true;
console.log(expandedKeys.value, '数据');
});
return {
columns,
name,
orgId,
// config,
onSearch,
dataSource,
onSelect,
gData,
onExpand,
selectedRow,
selectedRowKey,
autoExpandParent,
expandedKeys,
onSelectChange,
pagination,
handleOk,
show,
getData,
searchValue,
deviceName,
handleCancel,
};
},
});
</script>
<style scoped lang="less">
.border-card {
border-width: 0px;
position: absolute;
left: 0px;
top: 5px;
width: 5px;
height: 15px;
background: inherit;
background-color: rgba(251, 156, 67, 1);
border: none;
border-radius: 5px;
-moz-box-shadow: none;
-webkit-box-shadow: none;
box-shadow: none;
}
.box {
width: 100%;
height: 500px;
display: flex;
.box-left {
width: 300px;
height: 100%;
overflow-y: auto;
padding: 0, 12px;
gap: 5px;
}
.box-right {
width: calc(100% - 200px);
height: 100%;
padding: 0 12px;
overflow-y: auto;
}
}
</style>

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

@ -0,0 +1,28 @@
<template>
<ns-view-list-table v-bind="config" ref="mainRef" />
<!-- 详情页面 -->
<Look ref="look" />
<!-- 状态页面 -->
<Status ref="status" />
</template>
<script lang="ts">
import { notificationtableConfig } from './ts/config';
import Look from './look.vue';
import Status from './status.vue';
import { ref } from 'vue';
export default {
components: { Look, Status },
setup() {
const look = ref(null);
const status = ref(null);
const config = notificationtableConfig(look, status);
return {
config,
look,
status,
};
},
};
</script>

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

@ -0,0 +1,283 @@
<template>
<ns-drawer
v-model:visible="visible"
width="520"
:title="' '"
:footer-style="{ textAlign: 'right' }"
:ok="btnClick"
:cancel="handleClose"
placement="right"
@close="handleClose">
<div style="width: 100%; height: 100%; overflow-y: auto">
<!-- top -->
<div
style="
width: 100%;
height: 35px;
display: flex;
position: relative;
font-size: 16px;
border-bottom: 1px solid rgb(255, 118, 2); /* 设置底部边框为1像素实线,并指定颜色 */
">
<div class="card"></div>
<div style="left: 25px; position: absolute; height: 35px; line-height: 35px">
告警编号20230310001
</div>
<div style="right: 20px; position: absolute; height: 35px; line-height: 35px">
15点08分
</div>
</div>
<!-- center -->
<div style="width: 100%; height: 300px; border: 1px solid red" ref="graphChart"></div>
</div>
</ns-drawer>
</template>
<script>
import { defineComponent } from 'vue';
import { ref } from 'vue';
import * as echarts from 'echarts';
export default defineComponent({
setup() {
let chartInstance = null;
const graphChart = ref(null);
const visible = ref(false);
const handleClose = () => {
visible.value = false;
};
const btnClick = () => {
console.log('btnClick');
};
const toggle = (data) => {
console.log(data, 'data');
visible.value = true;
getChatr();
};
const getChatr = () => {
let dayData = [];
let energyAlarm = [];
let wgAlarm = [];
let equipmentAlarm = [];
let total = [];
// Extend data for 30 days
for (let i = 1; i < 30; i++) {
dayData.push(`3/${i}`);
energyAlarm.push(Math.floor(Math.random() * 11)); // Assuming the same value for simplicity
wgAlarm.push(Math.floor(Math.random() * 11)); // Assuming the same value for simplicity
equipmentAlarm.push(Math.floor(Math.random() * 11)); // Assuming the same value for simplicity
total.push(0); // Assuming the same value for simplicity
}
if (chartInstance) {
chartInstance.dispose();
}
chartInstance = echarts.init(graphChart.value);
const option = {
title: {
text: '告警趋势/ 近30天',
textStyle: {
fontSize: 16,
fontWeight: 'normal',
color: '#aaaaaa',
},
left: '1%',
top: '2%',
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
},
formatter: function (params) {
let res =
params[0].axisValue +
'<br/>' +
params[0].marker +
' ' +
params[0].seriesName +
' : ' +
params[0].data +
'<br/>' +
params[1].marker +
' ' +
params[1].seriesName +
' : ' +
params[1].data +
'<br/>' +
params[2].marker +
' ' +
params[2].seriesName +
' : ' +
params[2].data +
'<br/>';
return res;
},
},
grid: {
left: '2%', //
right: '2%', //
borderWidth: 0,
y2: 60, //
},
legend: [
{
top: 5,
left: 'center', //
textStyle: {
color: 'rgb(89, 89, 89)',
fontSize: '14',
fontWeight: 'normal',
}, //
data: ['设备告警', '网关告警', '能源告警'],
itemGap: 30, //
},
],
toolbox: {
show: true,
feature: {
restore: {},
saveAsImage: {},
},
},
calculable: true,
xAxis: [
{
type: 'category',
splitLine: {
show: false,
},
axisTick: {
show: false,
},
splitArea: {
show: false,
},
data: dayData,
},
],
yAxis: [
{
type: 'value',
shwo: false,
splitLine: {
show: true,
},
axisLine: {
show: false,
},
axisTick: {
show: false,
},
splitArea: {
show: false,
},
axisLabel: {
show: false, //
},
},
],
dataZoom: [
{
height: 12,
start: 0,
end: 100,
handleSize: '300%', //
bottom: 15,
},
],
series: [
{
name: '能源告警',
type: 'bar',
stack: '能源告警',
barMaxWidth: 40,
barGap: '10%',
itemStyle: {
normal: {
barBorderRadius: 0,
color: 'rgb(246, 189, 22)',
},
},
data: energyAlarm,
},
{
name: '网关告警',
type: 'bar',
stack: '能源告警',
barMaxWidth: 40,
barGap: '10%',
itemStyle: {
normal: {
barBorderRadius: 0,
color: 'rgb(91, 143, 249)',
},
},
data: wgAlarm,
},
{
name: '设备告警',
type: 'bar',
stack: '能源告警',
barMaxWidth: 40,
barGap: '10%',
itemStyle: {
normal: {
barBorderRadius: 0,
color: 'rgb(48, 191, 120)',
},
},
data: equipmentAlarm,
},
{
name: '总数',
type: 'bar',
stack: '能源告警',
barMaxWidth: 40,
barHight: 0,
itemStyle: {
normal: {
barBorderRadius: 0,
color: 'rgba(0,0,0,0)',
},
},
label: {
show: true,
color: '#000000',
position: 'top',
top: '10',
formatter: function (value) {
return (
Number(energyAlarm[value.dataIndex]) +
Number(wgAlarm[value.dataIndex]) +
Number(equipmentAlarm[value.dataIndex])
);
},
},
data: total,
},
],
};
chartInstance = echarts.init(graphChart.value);
chartInstance.setOption(option);
};
return {
btnClick,
visible,
chartInstance,
handleClose,
toggle,
graphChart,
getChatr,
};
},
});
</script>
<style scoped lang="less">
.card {
position: absolute;
left: 0px;
top: 0px;
width: 5px;
height: 35px;
background-color: rgb(254, 118, 2);
}
</style>

108
hx-ai-intelligent/src/view/alarmManagement/equipmentAlarm/notificationManagementMock.json

@ -0,0 +1,108 @@
{
"listData":[
{
"id": "d4",
"isDel": "0",
"officesId": "84",
"deviceCode": "37430200143",
"deviceName": "地听测试电表",
"category": "1",
"type": "1001",
"energyCount": "1",
"serialNumber": "69",
"pidCode": null,
"brand": "",
"types": "",
"manufacturer": "elit non in",
"contacts": "ad reprehenderit",
"phonenumber": "34",
"position": "in esse commodo1",
"activeState": "1",
"measurementDirection": "1",
"deviceMagnification": 62,
"deviceAccuracy": "89",
"frequency": "anim consequat irure",
"standardFrequency": "ut elit",
"deviceHead": "pariatur ex velit",
"constructor": "84566",
"voltageType": "cillum aliquip reprehenderit",
"pt": 61,
"ct": 64,
"communicationProtocol": "cupidatat nisi ea ad",
"ip": "",
"port": "",
"com": "",
"slaveAddress": "",
"dlt": "",
"conversionIdentifier": "48",
"multiplicationAdjustment": "1",
"accessMethod": "1",
"replacementFrequency": "0",
"dataDetail": "sit",
"insertTime": null,
"children": null,
"devicePointList": null,
"insertUser": null,
"priority": "1",
"alarmTitle": "电压异常告警",
"errorCode": "A001",
"monitorTime":"1",
"repetitions":"1",
"monitorTimeUnit": "分",
"enableRules": "1",
"isUse":true
} , {
"id": "d5",
"isDel": "0",
"officesId": "84",
"deviceCode": "37430200143",
"deviceName": "地听测试电表",
"category": "1",
"type": "1001",
"energyCount": "1",
"serialNumber": "69",
"pidCode": null,
"brand": "",
"types": "",
"manufacturer": "elit non in",
"contacts": "ad reprehenderit",
"phonenumber": "34",
"position": "in esse commodo2",
"activeState": "1",
"measurementDirection": "1",
"deviceMagnification": 62,
"deviceAccuracy": "89",
"frequency": "anim consequat irure",
"standardFrequency": "ut elit",
"deviceHead": "pariatur ex velit",
"constructor": "84566",
"voltageType": "cillum aliquip reprehenderit",
"pt": 61,
"ct": 64,
"communicationProtocol": "cupidatat nisi ea ad",
"ip": "",
"port": "",
"com": "",
"slaveAddress": "",
"dlt": "",
"conversionIdentifier": "48",
"multiplicationAdjustment": "1",
"accessMethod": "1",
"replacementFrequency": "0",
"dataDetail": "sit",
"insertTime": null,
"children": null,
"devicePointList": null,
"insertUser": null,
"priority": "1",
"alarmTitle": "电压异常告警",
"errorCode": "A001",
"monitorTime":"1",
"repetitions":"1",
"monitorTimeUnit": "分",
"enableRules": "0",
"isUse":true
}
]
}

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

@ -0,0 +1,39 @@
<template>
<ns-drawer
v-model:visible="visible"
width="520"
:title="' '"
:footer-style="{ textAlign: 'right' }"
:ok="btnClick"
:cancel="handleClose"
placement="right"
@close="handleClose">
状态
</ns-drawer>
</template>
<script>
import { defineComponent } from 'vue';
import { ref } from 'vue';
export default defineComponent({
setup() {
const visible = ref(false);
const handleClose = () => {
visible.value = false;
};
const btnClick = () => {
console.log('btnClick');
};
const toggle = (data) => {
console.log(data, 'data');
visible.value = true;
};
return {
btnClick,
visible,
handleClose,
toggle,
};
},
});
</script>

164
hx-ai-intelligent/src/view/alarmManagement/equipmentAlarm/ts/config.ts

@ -0,0 +1,164 @@
import { dateUtil } from '/nerv-lib/util/date-util';
import data from '../notificationManagementMock.json';
import { http } from '/nerv-lib/util';
import { ref } from 'vue';
const tableKeyMap = [
{
title: '序号',
dataIndex: 'address',
customRender: (text: any) => {
return text.index + 1;
},
},
{
title: '告警编号',
dataIndex: 'id',
},
{
title: '告警描述',
dataIndex: 'deviceCode',
},
{
title: '优先级',
dataIndex: 'deviceName',
},
{
title: '状态',
dataIndex: 'position',
},
{
title: '错误码',
dataIndex: 'position',
textEllipsis: true,
},
{
title: '设备信息',
dataIndex: 'position',
},
{
title: '更新时间',
dataIndex: 'enableRules',
},
{
title: '重复次数',
dataIndex: 'enableRules',
},
];
const mockData = ref(data.listData);
export const notificationtableConfig = (look: any, status: any) => {
return {
title: '告警记录',
// api: '/carbon_emission/device/getDeviceList',
value: mockData.value,
headerActions: [{}],
columns: tableKeyMap,
// rowSelection: null, 选择按钮
columnActions: {
title: '操作',
actions: [
{
label: '详情',
name: 'FeedBackDetail',
dynamicParams: ['uuid', 'appealType'],
handle: (data: any) => {
console.log(look.value);
look.value.toggle(data);
},
},
{
label: '状态',
name: 'FeedBackDetail',
dynamicParams: ['uuid', 'appealType'],
handle: (data: any) => {
status.value.toggle(data);
},
},
],
},
formConfig: {
schemas: [
{
field: 'name',
label: '告警类型',
component: 'NsSelect',
componentProps: {
placeholder: '请选择告警优先级',
options: [
{
label: '紧急',
value: '1',
},
{
label: '重要',
value: '2',
},
{
label: '一般',
value: '3',
},
],
},
},
{
field: 'provider',
label: '状态',
component: 'NsSelect',
componentProps: {
placeholder: '请选择状态',
options: [
{
label: '待处理',
value: '1',
},
{
label: '处理中',
value: '2',
},
{
label: '已完成',
value: '3',
},
{
label: '超时',
value: '4',
},
{
label: '关闭',
value: '5',
},
],
},
},
{
field: 'provider',
label: '告警标题',
component: 'NsInput',
componentProps: {
placeholder: '请输入告警标题关键字',
},
},
{
field: 'provider',
label: '错误码',
component: 'NsInputApi',
componentProps: {
placeholder: '请输入告警错误码',
},
},
{
field: 'createTime',
label: '生产日期',
component: 'NsRangePicker',
fieldMap: ['manufactureBeginDate', 'manufactureEndDate'],
componentProps: {
valueFormat: 'YYYY-MM-DD',
placeholder: ['设备生产开始日期', '设备生产结束日期'],
},
},
],
},
// pagination: { pageSizeOptions: false },
rowKey: 'id',
};
};

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

@ -46,18 +46,18 @@
</span>
<span v-else>{{ data.emissionName }}</span>
</div>
<a-popover placement="rightTop" trigger="focus">
<template #content>
<div style="display: flex;flex-direction: column;">
<a-button type="text" @click="editTreeNodeData">编辑</a-button>
<a-button type="text" @click="addTreeNodeData">新增子节点</a-button>
<a-button type="text">上移</a-button>
<a-button type="text">下移</a-button>
<a-button type="text" @click="deleteTreeNode">删除</a-button>
</div>
<a-dropdown>
<ns-icon name="actionMore" size="14" class="actionMore" />
<template #overlay>
<a-menu>
<a-menu-item @click="editTreeNodeData">编辑</a-menu-item>
<a-menu-item @click="addTreeNodeData">新增子节点</a-menu-item>
<a-menu-item>上移</a-menu-item>
<a-menu-item>下移</a-menu-item>
<a-menu-item @click="deleteTreeNode">删除</a-menu-item>
</a-menu>
</template>
<MoreOutlined class="actionMore" />
</a-popover>
</a-dropdown>
</div>
</template>
</a-tree>
@ -107,61 +107,89 @@
title="单位管理"
@close="closeUnitManag">
<div class="addButton">
<a-button type="primary">新增分组</a-button>
<a-button type="primary">新增单位</a-button>
<a-button type="primary" @click="addGroup">新增分组</a-button>
<a-button type="primary" @click="addUnit">新增单位</a-button>
</div>
<div class="treePart">
<div style="width: 100%;height: 7%;display: flex;justify-content: center;align-items: center;">
<a-select
ref="select"
:value="unitTreeParams.cnValue"
:value="unitTreeParams.id"
allowClear
style="width: 96%"
placeholder="选择分组"
@change="handleChange"
>
<a-select-option v-for="(item, index) in groupData" :key="index" :value="item.cnValue">
<a-select-option v-for="(item, index) in groupData" :key="index" :value="item.id">
{{ item.cnValue }}
</a-select-option>
</a-select>
</div>
<a-tree
:expandedKeys="unitExpandedKeys"
:expanded-keys="unitExpandedKeys"
:selectedKeys="unitSelectedKeys"
:tree-data="unitTreeData"
v-if="unitTreeData && unitTreeData.length > 0"
>
class="draggable-tree"
block-node>
<template #title="data">
<div class="treeRow">
<div>
<span>{{ data.cnValue }}</span>
</div>
<a-popover placement="rightTop" trigger="focus">
<template #content>
<div style="display: flex;flex-direction: column;">
<a-button type="text" @click="editTreeNodeData">编辑</a-button>
<a-button type="text" @click="addTreeNodeData">新增子节点</a-button>
<a-button type="text">上移</a-button>
<a-button type="text">下移</a-button>
<a-button type="text" @click="deleteTreeNode">删除</a-button>
<div class="actionMore">
<EditOutlined v-if="!data.parentId" @click="editGroup(data)" />
<EditOutlined v-else @click="editUnit(data)" />
<MinusCircleOutlined style="margin-left: 6px;" @click="delUnit(data)" />
<PlusCircleOutlined v-if="!data.parentId" style="margin-left: 6px;" @click="addUnit(data)" />
</div>
</template>
<MoreOutlined class="actionMore" />
</a-popover>
</div>
</template>
</a-tree>
</div>
<template #footer>
<a-button style="margin-right: 8px" @click="closeUnitManag">取消</a-button>
<a-button type="primary" @click="onEdit">确定</a-button>
</template>
</a-drawer>
<!-- 新增分组管理 -->
<ns-modal :visible="addGroupManage" :title="addGroupTitle" @ok="unitOrGroupOk" @cancel="groupCancel">
<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="请输入分组名称" />
</a-form-item>
</a-form>
</ns-modal>
<!-- 新增单位 -->
<ns-modal :visible="addUnitManage" :title="addUnitTitle" @ok="unitOrGroupOk" @cancel="unitCancel">
<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="请输入单位名称" />
</a-form-item>
<a-form-item label="选择分组" name="parentId" :required="true">
<a-select v-model:value="formState.parentId" placeholder="请选择所属分组" :disabled="canSelect">
<a-select-option v-for="(item, index) in groupData" :key="index" :value="item.id">
{{ item.cnValue }}
</a-select-option>
</a-select>
</a-form-item>
</a-form>
</ns-modal>
</div>
</template>
<script lang="ts" setup>
import { MoreOutlined,ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { MoreOutlined,ExclamationCircleOutlined,EditOutlined,PlusCircleOutlined,MinusCircleOutlined } from '@ant-design/icons-vue';
import { Modal } from 'ant-design-vue';
import { computed, createVNode, defineComponent, reactive, ref, watchEffect,watch } from 'vue';
import { computed, createVNode, defineComponent, reactive, ref, watchEffect,watch,toRaw } from 'vue';
import { http } from '/nerv-lib/util/http';
import { NsMessage, NsModal } from '/nerv-lib/component';
import { formConfig, formConfig2 } from './config';
@ -215,7 +243,7 @@
const y = 2;
const z = 1;
const genData: TreeProps['treeData'] = [];
const checkedTreeNodeKeys = ref<string[]>(['0-0']);
const checkedTreeNodeKeys = ref<string[]>();
const generateData = (_level: number, _preKey?: string, _tns?: TreeProps['treeData']) => {
const preKey = _preKey || '0';
@ -423,15 +451,15 @@
fetch(carbonEmissionFactorLibrary.getCarbonFactorTree, params).then((res) => {
gData.value = res.data
//
const selectedNodes = [];
checkedTreeNodeKeys.value.forEach(key => {
const [parentId, childId] = key.split('-').map(Number);
if (parentId >= 0 && childId >= 0 && gData.value[parentId]?.children?.[childId]) {
selectedNodes.push(gData.value[parentId]);
}
});
// const selectedNodes = [];
// checkedTreeNodeKeys.value.forEach(key => {
// const [parentId, childId] = key.split('-').map(Number);
// if (parentId >= 0 && childId >= 0 && gData.value[parentId]?.children?.[childId]) {
// selectedNodes.push(gData.value[parentId]);
// }
// });
// id
getDefaultIds(selectedNodes)
// getDefaultIds(selectedNodes)
});
};
const defaultIds = ref([])
@ -494,6 +522,9 @@
userAuthList.value.splice(0);
};
const closeUnitManag = () => {
unitTreeParams.value = {
grp: 'MEASUREMENT_UNIT'
}
unitManagement.value = false;
};
const onEdit = () => {
@ -573,9 +604,7 @@
fetch(carbonEmissionFactorLibrary.findOutermost).then((res) => {
groupData.value = res.data
});
fetch(carbonEmissionFactorLibrary.dictionaryUnitManagement, unitTreeParams.value).then((res) => {
unitTreeData.value = res.data
});
getUnitTree()
},
},
],
@ -770,10 +799,134 @@
const groupData = ref([])
const unitTreeData = ref<TreeProps['treeData']>(genData);
const handleChange = (value: string) => {
unitTreeParams.value.cnValue = value
unitTreeParams.value.id = value
getUnitTree()
};
const getUnitTree = () => {
fetch(carbonEmissionFactorLibrary.dictionaryUnitManagement, unitTreeParams.value).then((res) => {
unitTreeData.value = res.data
});
}
//
const labelCol = { span: 5 };
const wrapperCol = { span: 19 };
const unitFormRef = ref();
const addGroupManage = ref(false);
const addUnitManage = ref(false);
const canSelect = ref(false);
const formState = ref({
grp: 'MEASUREMENT_UNIT',
grpDesc: '计量单位',
})
const addGroupTitle = ref<string>('新增分组');
const addUnitTitle = ref<string>('新增单位');
const addGroup = () => {
addGroupTitle.value = '新增分组'
addGroupManage.value = true
};
const editGroup = (data) => {
addGroupTitle.value = '编辑分组'
addGroupManage.value = true
formState.value.id = data.id
formState.value.cnValue = data.cnValue
};
const groupCancel = () => {
addGroupManage.value = false
unitFormRef.value.resetFields();
formState.value = {
grp: 'MEASUREMENT_UNIT',
grpDesc: '计量单位',
}
};
const addUnit = (data) => {
if(data.id){
canSelect.value = true
formState.value.parentId = data.id
}else{
canSelect.value = false
}
fetch(carbonEmissionFactorLibrary.findOutermost).then((res) => {
groupData.value = res.data
});
addUnitTitle.value = '新增单位'
addUnitManage.value = true
};
const editUnit = (data) => {
addUnitTitle.value = '编辑单位'
addUnitManage.value = true
canSelect.value = true
formState.value.parentId = data.parentId
formState.value.id = data.id
formState.value.cnValue = data.cnValue
};
const unitCancel = () => {
addUnitManage.value = false
unitFormRef.value.resetFields();
formState.value = {
grp: 'MEASUREMENT_UNIT',
grpDesc: '计量单位',
}
};
const unitOrGroupOk = () => {
unitFormRef.value
.validate()
.then(() => {
console.log('values', formState, toRaw(formState));
if(formState.value.id){
fetch(carbonEmissionFactorLibrary.updateDictionary, formState.value).then((res) => {
unitTreeData.value = res.data
if(formState.value.parentId){
addUnitManage.value = false
}else{
addGroupManage.value = false
}
unitFormRef.value.resetFields();
formState.value = {
grp: 'MEASUREMENT_UNIT',
grpDesc: '计量单位',
}
getUnitTree()
});
}else{
fetch(carbonEmissionFactorLibrary.createDictionary, formState.value).then((res) => {
unitTreeData.value = res.data
if(formState.value.parentId){
addUnitManage.value = false
}else{
addGroupManage.value = false
}
unitFormRef.value.resetFields();
formState.value = {
grp: 'MEASUREMENT_UNIT',
grpDesc: '计量单位',
}
getUnitTree()
});
}
})
.catch(error => {
console.log('error', error);
});
};
//
const delUnit = (data) => {
formState.value.id = data.id
Modal.confirm({
title: '警告',
content: '确定要删除吗?',
okText: '确定',
okType: 'primary',
cancelText: '取消',
onOk() {
fetch(carbonEmissionFactorLibrary.delDictionary , formState.value).then((res) => {
message.success('操作成功!');
getUnitTree()
});
},
onCancel() {
console.log('Cancel');
},
});
};
</script>

42
hx-ai-intelligent/src/view/carbonEmissionManage/carbonEmissionStatistics/config.ts

@ -87,32 +87,32 @@ export const columns = [
},
{
title: '因子值',
dataIndex: 'energyType',
dataIndex: 'emissionFactors',
},
{
title: '计量单位',
className: 'unit',
dataIndex: 'unit',
className: 'carbonEmissionSuffix',
dataIndex: 'carbonEmissionSuffix',
},
{
title: '更新时间',
className: 'unit',
dataIndex: 'unit',
className: 'updateTime',
dataIndex: 'updateTime',
},
{
title: '启用时间',
className: 'unit',
dataIndex: 'unit',
className: 'startTime ',
dataIndex: 'startTime ',
},
{
title: '结束时间',
className: 'unit',
dataIndex: 'unit',
className: 'endTime',
dataIndex: 'endTime',
},
{
title: '数据来源',
className: 'unit',
dataIndex: 'unit',
className: 'dataSources',
dataIndex: 'dataSources',
},
{
title: '操作',
@ -120,3 +120,23 @@ export const columns = [
width: 130
},
];
export const drawerColumns = [
{
title: '名称',
dataIndex: 'emissionSources',
},
{
title: '因子值',
dataIndex: 'emissionFactors',
},
{
title: '排放环节',
className: 'emissionProcess',
dataIndex: 'emissionProcess',
},
{
title: '数据来源',
className: 'dataSources',
dataIndex: 'dataSources',
},
];

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

@ -181,6 +181,7 @@
const queryParams = ref({
pageNum: 1,
pageSize: 10,
orgId: orgId.value,
})
const isRequired = ref(false);
const visible = ref(false);

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

@ -1,401 +0,0 @@
<!-- @format -->
<template>
<div class="main">
<div class="left">
<div class="top">
<a-form style="width: 100%;margin: 0 auto;">
<div class="ns-form-title"><span>排放分类</span></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="selectTreeDataValue"
placeholder="请输入关键词"
@search="onSearchTreeData"
/>
</a-col>
</a-row>
</div>
</a-form>
<a-tree
v-if="gData && gData.length > 0"
class="draggable-tree"
style="padding: 0 16px !important;"
show-line
block-node
:tree-data="gData"
:checkedKeys="checkedTreeNodeKeys"
:selectedKeys="selectedKeys"
@check="checkTreeNode"
@select="onSelect"
:expanded-keys="expandedKeys"
:auto-expand-parent="autoExpandParent"
@expand="onExpand">
<template #title="{ emissionName }">
<span v-if="emissionName && selectTreeDataValue && emissionName.indexOf(selectTreeDataValue) > -1">
{{ emissionName.substring(0, emissionName.indexOf(selectTreeDataValue)) }}
<span style="color: #f50">{{ selectTreeDataValue }}</span>
{{ emissionName.substring(emissionName.indexOf(selectTreeDataValue) + selectTreeDataValue.length) }}
</span>
<span v-else>{{ emissionName }}</span>
</template>
</a-tree>
</div>
</div>
<div class="right">
<a-table :columns="columns" :data-source="tableData" bordered :pagination="false">
<template #bodyCell="{ column, text }">
<template v-if="column.dataIndex === 'name'">
<a>{{ text }}</a>
</template>
</template>
<template #title>Header</template>
</a-table>
</div>
<!-- 新增树节点 -->
<ns-modal :visible="treeNodeAdd" :title="operationTree" @ok="handleOk" @cancel="handleCancel">
<ns-input
v-model:value="addTreeNode"
class="input"
placeholder="请输入排放类型"/>
</ns-modal>
<!-- 新增数据库数据 -->
<a-drawer
:width="500"
:visible="visible"
:body-style="{ paddingBottom: '80px' }"
:footer-style="{ textAlign: 'right' }"
destroyOnClose
@close="onClose">
<ns-form
ref="formRef"
:model="formData"
class="form"
:wrapperCol="{ span: 20 }"
formLayout="vertical" />
<template #footer>
<a-button style="margin-right: 8px" @click="onClose">取消</a-button>
<a-button type="primary" @click="onEdit">确定</a-button>
</template>
</a-drawer>
</div>
</template>
<script lang="ts" setup>
import { Modal } from 'ant-design-vue';
import { computed, createVNode, defineComponent, reactive, ref, watchEffect,watch } from 'vue';
import { http } from '/nerv-lib/util/http';
import { NsMessage, NsModal } from '/nerv-lib/component';
import { carbonEmissionFactorLibrary } from '/@/api/carbonEmissionFactorLibrary';
import type {
AntTreeNodeDragEnterEvent,
AntTreeNodeDropEvent,
TreeProps,
} from 'ant-design-vue/es/tree';
import { log } from 'node:console';
defineOptions({ name: 'QuickCalculation' });
const selectTreeDataValue = ref<string>('');
const data = reactive({});
let formData = ref({});
const formRef = ref();
const visible = ref(false);
const searchValue = ref<string>('');
const searchValue2 = ref<string>('');
const disabled = ref(false);
const treeNodeAdd = ref<boolean>(false);
const operationTree = ref<string>('新增');
const opMap: any = ref({
type: 'add',
fuc: () => {},
record: {},
});
watchEffect(() => {
disabled.value = opMap.value.type === 'edit';
});
const casData = ref([]);
const treeData = ref([]);
const userAuthList = ref([]);
const orgId = ref('');
const result = JSON.parse(sessionStorage.getItem('ORGID')!);
orgId.value = result;
const dynamicDisabled = computed(() => {
return formRef.value?.validateResult && userAuthList.value?.length;
});
const fetch = (api, params = { orgId }) => {
return http.post(api, params);
};
//
const x = 3;
const y = 2;
const z = 1;
const genData: TreeProps['treeData'] = [];
const generateData = (_level: number, _preKey?: string, _tns?: TreeProps['treeData']) => {
const preKey = _preKey || '0';
const tns = _tns || genData;
const children = [];
for (let i = 0; i < x; i++) {
const key = `${preKey}-${i}`;
tns.push({ title: key, key });
if (i < y) {
children.push(key);
}
}
if (_level < 0) {
return tns;
}
const level = _level - 1;
children.forEach((key, index) => {
tns[index].children = [];
return generateData(level, key, tns[index].children);
});
};
generateData(z);
type TreeDataItem = TreeProps['treeData'][number];
const gData = ref<TreeProps['treeData']>(genData);
const dataList: TreeProps['treeData'] = [];
const generateList = (data: TreeProps['treeData']) => {
for (let i = 0; i < data.length; i++) {
const node = data[i];
const key = node.key;
dataList.push({ key, title: key });
if (node.children) {
generateList(node.children);
}
}
};
generateList(genData);
const getParentKey = (
key: string | number,
tree: TreeProps['treeData'],
): string | number | undefined => {
let parentKey;
for (let i = 0; i < tree.length; i++) {
const node = tree[i];
if (node.children) {
if (node.children.some(item => item.key === key)) {
parentKey = node.key;
} else if (getParentKey(key, node.children)) {
parentKey = getParentKey(key, node.children);
}
}
}
return parentKey;
};
const expandedKeys = ref<(string | number)[]>([]);
const autoExpandParent = ref<boolean>(true);
const onExpand = (keys: string[]) => {
expandedKeys.value = keys;
autoExpandParent.value = false;
};
watch(selectTreeDataValue, value => {
const expanded = dataList
.map((item: TreeProps['treeData'][number]) => {
if (item.title.indexOf(value) > -1) {
return getParentKey(item.key, gData.value);
}
return null;
})
.filter((item, i, self) => item && self.indexOf(item) === i);
expandedKeys.value = expanded;
selectTreeDataValue.value = value;
autoExpandParent.value = true;
});
//
const onSearchTreeData = (selectTreeDataValue: string) => {
console.log('use value', selectTreeDataValue);
console.log('or use this.value', value.value);
};
//
const checkedIds = ref([])
const emissionType = ref()
const checkTreeNode = (checkedKeys, info) => {
checkedIds.value = []
info.checkedNodes.forEach(item=>{
checkedIds.value.push(item.id)
})
sessionStorage.setItem('checkedTreeNode', checkedIds.value);
emissionType.value = checkedIds.value.join(',')
}
// /
const addTreeNode =ref()
const handleOk = (e: MouseEvent) => {
editTreeNode.value.emissionName = addTreeNode.value
http.post(carbonEmissionFactorLibrary.creat,editTreeNode.value).then(() => {
getOrgTree()
NsMessage.success('操作成功');
addTreeNode.value = ''
treeNodeAdd.value = false;
});
};
const handleCancel = () => {
addTreeNode.value = ''
treeNodeAdd.value = false;
};
//
const getOrgTree = (params?) => {
fetch(carbonEmissionFactorLibrary.getCarbonFactorTree, params).then((res) => {
gData.value = res.data
//
const selectedNodes = [];
checkedTreeNodeKeys.value.forEach(key => {
const [parentId, childId] = key.split('-').map(Number);
if (parentId >= 0 && childId >= 0 && gData.value[parentId]?.children?.[childId]) {
selectedNodes.push(gData.value[parentId]);
}
});
});
};
getOrgTree();
//
const editTreeNode = ref({})
const onSelect = (selectedKeys: string[], info: any) => {
if(info.selected){
editTreeNode.value = {
id:info.selectedNodes[0].id,
level:info.selectedNodes[0].level,
dataNumber:info.selectedNodes[0].dataNumber,
sortNumber:info.selectedNodes[0].sortNumber,
parentEmissionId:info.selectedNodes[0].parentEmissionId,
}
}
};
const onSearch = () => {
console.log(searchValue.value);
getOrgTree({ orgName: searchValue.value, orgId });
};
const tableFetch = (params) => {
console.log(params, 'sdfasfasdfasdfasdf');
setTimeout(() => {
mainRef.value?.nsTableRef.reload();
}, 100);
};
const handleSelect = (selectedKeys: any, info: any) => {
fetch(carbonEmissionFactorLibrary.queryDeptTree, { orgId: info.node?.orgInfo.orgId }).then((res) => {
treeData2.value = res.data;
});
tableFetch({ orgId: info.node?.orgInfo.orgId });
};
const columns = [
{
title: 'Name',
dataIndex: 'name',
},
{
title: 'Cash Assets',
className: 'column-money',
dataIndex: 'money',
},
{
title: 'Address',
dataIndex: 'address',
},
];
const tableData = [
{
key: '1',
name: 'John Brown',
money: '¥300,000.00',
address: 'New York No. 1 Lake Park',
},
{
key: '2',
name: 'Jim Green',
money: '¥1,256,000.00',
address: 'London No. 1 Lake Park',
},
{
key: '3',
name: 'Joe Black',
money: '¥120,000.00',
address: 'Sidney No. 1 Lake Park',
},
];
const onClose = () => {
visible.value = false;
formData.value = {};
userAuthList.value.splice(0);
};
const onEdit = () => {
formRef.value?.triggerSubmit().then(() => {
console.log(formData.value, 'formData.value');
// if (!userAuthList.value.length) {
// NsMessage.error('');
// return;
// }
opMap.value.fuc &&
opMap.value.fuc({ ...formData.value });
});
};
</script>
<style lang="less" scoped>
.main {
background-color: @ns-content-bg;
display: flex;
height: 100%;
}
.left {
width: 300px;
// max-height: calc(100vh - 96px);
margin-right: @ns-gap;
min-width: fit-content;
> div {
background-color: @white;
// box-shadow: @ns-content-box-shadow;
flex: 1;
}
display: flex;
flex-direction: column;
.top{
position: relative;
.addTreeNode{
width: 100%;
padding: 16px;
position: absolute;
bottom: 0;
}
}
}
.right {
flex: 1;
min-width: 0;
}
::v-deep .ant-table-container{
padding: 0px 16px;
}
.top {
overflow: auto;
// height: 50%;
// border-bottom: 5px solid rgb(229, 235, 240);
// overflow-y: auto;
}
.ns-form-title{
font-weight: bold;
user-select: text;
padding: 16px;
margin-bottom: 16px;
padding-bottom: 10px;
border-bottom: 1px solid #e9e9e9;
}
</style>
<style scoped>
th.column-money,
td.column-money {
text-align: right !important;
}
</style>

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

@ -17,19 +17,22 @@
</div>
</a-form>
<a-tree
v-if="gData && gData.length > 0"
:expanded-keys="expandedKeys"
:auto-expand-parent="autoExpandParent"
:tree-data="gData"
show-line
@expand="onExpand"
@select="onSelect"
style="padding: 0 16px !important;"
>
<template #title="{ title }">
<span v-if="title.indexOf(searchValue) > -1">
{{ title.substring(0, title.indexOf(searchValue)) }}
<template #title="data">
<span v-if="data.energyType && searchValue && data.energyType.indexOf(searchValue) > -1">
{{ data.energyType.substring(0, data.energyType.indexOf(searchValue)) }}
<span style="color: #f50">{{ searchValue }}</span>
{{ title.substring(title.indexOf(searchValue) + searchValue.length) }}
{{ data.energyType.substring(data.energyType.indexOf(searchValue) + searchValue.length) }}
</span>
<span v-else>{{ title }}</span>
<span v-else>{{ data.energyType }}</span>
</template>
</a-tree>
</div>
@ -66,7 +69,7 @@
@change="onChange" />
<!-- 新增/编辑 -->
<a-drawer
:width="500"
:width="700"
:visible="visible"
:body-style="{ paddingBottom: '80px' }"
:footer-style="{ textAlign: 'right' }"
@ -79,35 +82,34 @@
:label-col="labelCol"
:wrapper-col="wrapperCol"
>
<a-row>
<a-col :span="12">
<a-form-item ref="name" label="能源种类" name="energyType">
<a-input v-model:value="formState.energyType" placeholder="请输入能源种类" />
</a-form-item>
<a-form-item label="计量单位" name="unit">
<a-cascader v-model:value="formState.unit" :options="options" />
</a-form-item>
<a-form-item label="自动采集节点" name="collectionNode">
<a-tree-select
v-model:value="formState.collectionNode"
:tree-line="true"
:tree-data="treeData"
tree-node-filter-prop="title"
>
</a-tree-select>
<a-range-picker v-model:value="formState.energyType" picker="month" style="width:200px;" />
</a-form-item>
<a-form-item label="计算碳排" name="isComputeCarbon">
<a-radio-group v-model:value="formState.isComputeCarbon" @change="changeRadio">
<a-radio :value="0"></a-radio>
<a-radio :value="1"></a-radio>
</a-radio-group>
</a-col>
<a-col :span="12">
<a-form-item ref="name" label="排放因子" name="energyType">
<ns-input v-model:value="formState.emissionFactors" disabled />
</a-form-item>
<a-form-item label="排放类型" name="emissionType">
<a-select v-model:value="formState.emissionType" placeholder="请选择排放类型">
<a-select-option v-for="(item, index) in emissionTypeDic" :key="index" :value="item.cnValue">
{{ item.cnValue }}
</a-select-option>
</a-select>
</a-col>
</a-row>
<a-row>
<a-col :span="12">
<a-form-item ref="name" label="关键词">
<ns-input v-model:value="selectData" />
</a-form-item>
</a-col>
</a-row>
</a-form>
<a-table
:columns="drawerColumns"
:data-source="newTableData"
bordered
rowKey="id"
:rowSelection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectionChange, type: 'radio' }"
:pagination="false">
</a-table>
<template #footer>
<a-button style="margin-right: 8px" @click="onClose">取消</a-button>
<a-button type="primary" @click="onSubmit">确定</a-button>
@ -118,11 +120,12 @@
</template>
<script lang="ts" setup>
import { ref, watch } from 'vue';
import { ref, watch, toRaw } from 'vue';
import type { TreeProps } from 'ant-design-vue';
import { Pagination } from 'ant-design-vue';
import { columns } from '../config';
import { Pagination,Modal } from 'ant-design-vue';
import { columns,drawerColumns } from '../config';
import { http } from '/nerv-lib/util/http';
import { quickCalculation,carbonEmissionFactorLibrary } from '/@/api/carbonEmissionFactorLibrary';
defineOptions({
energyType: 'quickCalculation', // name
components: {
@ -203,6 +206,13 @@
expandedKeys.value = keys;
autoExpandParent.value = false;
};
//
const onSelect = (selectedKeys: string[], info: any) => {
if(info.selected){
queryParams.value.energyType = info.node.id
getTableList()
}
};
watch(searchValue, value => {
const expanded = dataList
@ -217,57 +227,113 @@
searchValue.value = value;
autoExpandParent.value = true;
});
//
const onSearchTreeData = () => {
};
//
const getTreeData = () => {
fetch(quickCalculation.carbonQuickTree).then((res) => {
gData.value = res.data
});
};
getTreeData()
//
const total = ref<number>()
const queryParams = ref({
pageNum: 1,
pageSize: 10,
orgId: orgId.value,
})
const tableData = [
{
key: '1',
name: 'John Brown',
money: '¥300,000.00',
address: 'New York No. 1 Lake Park',
},
{
key: '2',
name: 'Jim Green',
money: '¥1,256,000.00',
address: 'London No. 1 Lake Park',
},
{
key: '3',
name: 'Joe Black',
money: '¥120,000.00',
address: 'Sidney No. 1 Lake Park',
},
];
const tableData = ref([]);
//
const getTableList = () => {
fetch(quickCalculation.queryCarbonEmissionPage,queryParams.value).then((res) => {
tableData.value = res.data.records
total.value = res.data.total
});
};
getTableList()
//
const onChange = (pageNumber: number,size: number) => {
queryParams.value.pageNum = pageNumber;
queryParams.value.pageSize = size;
// getTableList()
getTableList()
};
// /
const formRef = ref();
const labelCol = { span: 5 };
const wrapperCol = { span: 19 };
const labelCol = { span: 6 };
const wrapperCol = { span: 18 };
const formState = ref({})
const visible = ref(false);
// form
const rules: Record<string, Rule[]> = {
energyType: [{ required: true, message: '请输入能源种类', trigger: 'change' }],
isComputeCarbon: [{ required: true, message: '请选择是否计算碳排', trigger: 'change' }]
};
//
const addNewData = () => {
visible.value = true
getNewTable()
};
//
const selectedRowKeys = ref([]);
const onSelectionChange = (selectedKeys, selectedRows) => {
selectedRowKeys.value = selectedKeys;
formState.value.emissionFactors = selectedRows[0].emissionFactors
};
const queryData = ref({
orgId: orgId.value,
pageNum: 1,
pageSize: 999
})
const newTableData = ref([])
const getNewTable = () => {
fetch(carbonEmissionFactorLibrary.getTableList,queryData.value).then((res) => {
newTableData.value = res.data.records
});
};
//
const editData = (record) =>{
visible.value = true
};
//
const onSubmit = () => {
formRef.value
.validate()
.then(() => {
console.log('values', formState, toRaw(formState));
fetch(quickCalculation.creat,formState.value).then((res) => {
console.log(res);
});
})
.catch(error => {
console.log('error', error);
});
};
//
const delData = (record) => {
Modal.confirm({
title: '警告',
content: '确定要删除吗?',
okText: '确定',
okType: 'primary',
cancelText: '取消',
onOk() {
fetch(quickCalculation.del , {id : record.id }).then((res) => {
message.success('操作成功!');
getTableList()
});
},
onCancel() {
console.log('Cancel');
},
});
};
//
const onClose = () => {
visible.value = false;
selectedRowKeys.value = [];
formRef.value.resetFields();
};
</script>

48
hx-ai-intelligent/src/view/monitor/energyMonitor/tree/index.vue

@ -40,18 +40,22 @@
<div class="fixed-bottom">
<a-divider />
<a-select
v-model:value="frequencyValue"
placeholder="请选择采集频率"
v-model:value="dateTypeValue"
placeholder="请选择日期类型"
style="width: 100%; margin-bottom: 10px"
:options="options2" />
<a-range-picker
<a-date-picker
style="width: 100%; margin-bottom: 10px"
v-model:value="dateValue"
:picker="dateTypeValue" />
<!-- <a-range-picker
:value="hackValue || dateRange"
:disabled-date="disabledDate"
@change="onChange"
@openChange="onOpenChange"
@calendarChange="onCalendarChange"
style="width: 100%; margin-bottom: 10px"
:placeholder="['请选择日期', '请选择日期']" />
:placeholder="['请选择日期', '请选择日期']" /> -->
<a-button type="primary" style="width: 100%; margin-bottom: 10px" @click="getSelect">
查询
</a-button>
@ -89,15 +93,15 @@
// list
const options1 = ref<SelectProps['options']>([]);
// list
// list
const options2 = ref<SelectProps['options']>([]);
const mode = ref<String>('1');
//
const selectedValue = ref<string | number | null | undefined>();
//
const frequencyValue = ref<string | undefined>();
//
const dateTypeValue = ref<string | undefined>();
//
const dateRange = ref<[Dayjs, Dayjs] | undefined>();
const dateValue = ref<[Dayjs, Dayjs] | undefined>();
//
const getOptionsList = async () => {
@ -115,20 +119,12 @@
}
options2.value = [
{
value: '1',
label: '5分钟',
},
{
value: '2',
label: '10分钟',
value: 'month',
label: '月',
},
{
value: '3',
label: '30分钟',
},
{
value: '4',
label: '1小时',
value: 'year',
label: '年',
},
];
};
@ -691,9 +687,9 @@
}
};
const onChange = (val: RangeValue) => {
dateRange.value = val;
};
// const onChange = (val: RangeValue) => {
// dateRange.value = val;
// };
const onCalendarChange = (val: RangeValue) => {
dates.value = val;
@ -716,8 +712,8 @@
options2,
mode,
selectedValue,
frequencyValue,
dateRange,
dateTypeValue,
dateValue,
getOptionsList,
getSelect,
getSelect11,
@ -725,7 +721,7 @@
disabledDate,
onCalendarChange,
onOpenChange,
onChange,
// onChange,
hackValue,
treeLoading,
changeEnergyType,

160
hx-ai-intelligent/src/view/monitor/environmentMonitor/aggregateData/index.vue

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save