Compare commits

...

38 Commits

Author SHA1 Message Date
a94531bd57 Merge branch 'temp' into deploy-dev 2024-07-16 16:07:24 +08:00
xuziqiang
b06c9ddc84 Merge branch 'temp' of http://123.60.103.97:3000/xuziqiang/SaaS-lib into temp 2024-07-16 15:50:43 +08:00
xuziqiang
40021ba5d0 fix: bug修改 2024-07-16 15:50:42 +08:00
zhaohy
1401d3611f Merge branch 'temp' of http://123.60.103.97:3000/xuziqiang/SaaS-lib into temp 2024-07-16 15:42:52 +08:00
zhaohy
d29c724920 fix:联系方式 2024-07-16 15:42:49 +08:00
fks-xuxinyue
5eba9a35a0 taskid:084 remark:'commit' 2024-07-16 15:36:47 +08:00
fks-yangshouda
6278e3ff17 1.监控中心 - 环境监测 环境指数分析添加查询部分
2.修改 监控中心 - 能耗监测左侧树组件
2024-07-16 15:31:05 +08:00
xuziqiang
0b619fe937 fix: 补充相关限制 2024-07-16 15:22:29 +08:00
xuziqiang
48569345aa feat: 修改密码 2024-07-16 14:31:27 +08:00
xuziqiang
dc0f2a164b fix: 修改登录多重submit 2024-07-16 10:48:10 +08:00
xuziqiang
1aa294b998 fix: 设备型号取消关联 2024-07-15 17:51:30 +08:00
xuziqiang
ef20fa58de Merge branch 'temp' of http://123.60.103.97:3000/xuziqiang/SaaS-lib into temp 2024-07-15 17:15:59 +08:00
xuziqiang
dac2e095e1 fix:分组管理逻辑补充 2024-07-15 17:15:59 +08:00
zhaohy
c68dc4deb7 Merge branch 'temp' of http://123.60.103.97:3000/xuziqiang/SaaS-lib into temp 2024-07-15 17:02:45 +08:00
zhaohy
0e9743f598 fix:换成枚举 2024-07-15 17:02:42 +08:00
xuziqiang
2fe6bb6d81 Merge branch 'temp' of http://123.60.103.97:3000/xuziqiang/SaaS-lib into temp 2024-07-15 16:58:51 +08:00
xuziqiang
58300c60e2 fix:设备台账补充筛选项去重逻辑 2024-07-15 16:58:50 +08:00
zhaohy
3bf19ba70d Merge branch 'temp' of http://123.60.103.97:3000/xuziqiang/SaaS-lib into temp 2024-07-15 16:41:08 +08:00
zhaohy
de0ce4ec2d fix: 添加联系人 2024-07-15 16:41:03 +08:00
zhaohy
8091bc10cc fix:能源告警换枚举 2024-07-15 16:40:03 +08:00
xuziqiang
e90efdb08d Merge branch 'temp' of http://123.60.103.97:3000/xuziqiang/SaaS-lib into temp 2024-07-15 16:26:06 +08:00
xuziqiang
86e0b30e81 fix: 分组逻辑调整 2024-07-15 16:25:55 +08:00
zhaohy
0214356cbb Merge branch 'temp' of http://123.60.103.97:3000/xuziqiang/SaaS-lib into temp 2024-07-15 16:00:15 +08:00
zhaohy
098b4f29fd fix:配置设备告警 联系方式 2024-07-15 16:00:08 +08:00
chenpingsen
3598e3d887 add:增加照明系统前端交互 2024-07-15 15:56:31 +08:00
fks-xuxinyue
4869fd4d16 Merge branch 'temp' of http://123.60.103.97:3000/xuziqiang/SaaS-lib into temp 2024-07-15 15:54:21 +08:00
fks-xuxinyue
b41caf9320 taskid:084 remark:'commit' 2024-07-15 15:54:07 +08:00
xuziqiang
8603732377 Merge branch 'temp' of http://123.60.103.97:3000/xuziqiang/SaaS-lib into temp 2024-07-15 15:53:55 +08:00
xuziqiang
32d1a633b1 feat: 查询补充 2024-07-15 15:53:54 +08:00
fks-yangshouda
5deff41679 1.能耗监测 - 分析 下载图表
2.环境监测 - 综合数据 前台页面
2024-07-15 15:38:28 +08:00
xuziqiang
0681836c02 fix: 设备台账调整搜索 2024-07-15 10:22:51 +08:00
xuziqiang
4526da936e fix: 代码逻辑调整 2024-07-12 17:39:31 +08:00
xuziqiang
c31b5468c7 Merge branch 'temp' of http://123.60.103.97:3000/xuziqiang/SaaS-lib into temp 2024-07-12 17:17:33 +08:00
xuziqiang
e0206a228b feat: 分组管理批量分组,公式编辑 2024-07-12 17:17:32 +08:00
fks-xuxinyue
47614e12ed Merge branch 'temp' of http://123.60.103.97:3000/xuziqiang/SaaS-lib into temp 2024-07-12 17:06:35 +08:00
fks-xuxinyue
d8cc8293bc taskid:083 remark:'commit' 2024-07-12 17:06:23 +08:00
fks-yangshouda
141f2a3e6f Merge branch 'temp' of http://123.60.103.97:3000/xuziqiang/SaaS-lib into temp 2024-07-12 17:05:57 +08:00
fks-yangshouda
4fcdae08de 能耗监测 分析 右侧图 2024-07-12 17:05:41 +08:00
56 changed files with 5331 additions and 3219 deletions

View File

@@ -2,8 +2,8 @@ export enum energyAlarms {
getTableList = '/carbon-smart/api/AlarmEnergyConsumption/selectAlarmEnergyConsumption', //能耗告警分页
addOrUpNewData = '/carbon-smart/api/AlarmEnergyConsumption/creatOrUpdate', //能耗告警添加 修改
del = '/carbon-smart/api/AlarmEnergyConsumption/delete', //能耗删除
configGetTableList = '/carbon-smart/api/AlarmEquipmentRule/selectAlarmEquipmentRule', //配置设备告警分页
configAddOrUpNewData = '/carbon-smart/api/AlarmEquipmentRule/creatOrUpdate', //配置设备告警添加 修改
configFindById = '/carbon-smart/api/AlarmEquipmentRule/findById', //配置设备告警 查询详情
configDel = '/carbon-smart/api/AlarmEquipmentRule/delete', //配置设备告警删除
configGetTableList = '/carbon-smart/api/AlarmEnergyConsumptionRule/selectAlarmEnergyConsumptionRule', //配置设备告警分页
configAddOrUpNewData = '/carbon-smart/api/AlarmEnergyConsumptionRule/creatOrUpdate', //配置设备告警添加 修改
configFindById = '/carbon-smart/api/AlarmEnergyConsumptionRule/findById', //配置设备告警 查询详情
configDel = '/carbon-smart/api/AlarmEnergyConsumptionRule/delete', //配置设备告警删除
}

View File

@@ -8,6 +8,12 @@ export enum carbonEmissionFactorLibrary {
getCarbonFactorTree = '/carbon-smart/api/carbon/emission/type/getCarbonFactorTree',
creat = '/carbon-smart/api/carbon/emission/type/creatOrUpdate',
delTreeNode = '/carbon-smart/api/carbon/emission/type/del',
// 单位管理
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 {
@@ -17,4 +23,12 @@ export enum energyConsumption {
creat = '/carbon-smart/api/carbon/stats/creat',
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',
}

View File

@@ -15,4 +15,17 @@ export enum group {
queryGroupPage = `${BASE_URL}/deviceGroup/queryGroupPage`, // 分组列表
saveGroupList = `${BASE_URL}/deviceGroup/saveGroupList`, // 分组保存
delGroupList = `${BASE_URL}/deviceGroup/delGroupList`, // 分组删除
queryGroupInfoPage = `${BASE_URL}/deviceGroup/queryGroupInfoPage`, // 计算列表
queryEditCompute = `${BASE_URL}/deviceGroup/queryEditCompute`, // 计算树
saveComputeList = `${BASE_URL}/deviceGroup/saveComputeList`, // 计算保存
delComputeList = `${BASE_URL}/deviceGroup/delComputeList`, // 计算删除
queryComputeGroup = `${BASE_URL}/deviceGroup/queryComputeGroup`, // 计算分组列表
saveComputeGroup = `${BASE_URL}/deviceGroup/saveComputeGroup`, // 计算分组新增
saveComputeGroupInfo = `${BASE_URL}/deviceGroup/saveComputeGroupInfo`, // 批量分组
delComputeGroup = `${BASE_URL}/deviceGroup/delComputeGroup`, // 分组删除
computeGroupNum = `${BASE_URL}/deviceGroup/computeGroupNum`, // 分组删除
formula = `${BASE_URL}/deviceGroup/formula`, // 编辑公式
queryFormula = `${BASE_URL}/deviceGroup/queryFormula`, // 公式查询
dropGroupFilter = `${BASE_URL}/deviceGroup/dropGroupFilter`, // 分组列表查询
dropGroupInfoFilter = `${BASE_URL}/deviceGroup/dropGroupInfoFilter`, // 计算列表查询
}

View File

@@ -27,6 +27,7 @@ export const appConfig = {
themeConfig: {
bgImageUrl: `${import.meta.env.VITE_PUBLIC_PATH}/asset/image/login/background.png`,
logoLessUrl: `${import.meta.env.VITE_PUBLIC_PATH}/asset/image/headerIcon.png`,
logoUrl: `${import.meta.env.VITE_PUBLIC_PATH}/asset/image/headerIcon.png`,
},
// userCustomRouterGuard: (to, from, next, whiteNameList, authorizationStore, appConfig) => {
// console.log({ to, from, next, whiteNameList, authorizationStore, appConfig }, 'routeConfig');
@@ -102,7 +103,7 @@ export const appConfig = {
updatePassWordInfo: {
title: '修改密码',
subtitle: 'huaxing平台',
api: '/api/web/objs/User/changePassword',
api: '/carbon-smart/api/user/update/password',
},
// headerBellInfo: {
// isShow: true,

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14.3564453125" height="15.0081787109375" viewBox="0 0 14.3564453125 15.0081787109375" fill="none">
<path d="M14.1739 3.70025C14.1361 3.65398 14.0991 3.60771 14.0571 3.56927C13.9468 3.46744 13.8241 3.37991 13.6919 3.30873C11.7357 2.26657 9.78168 1.22155 7.82619 0.17939C7.65994 0.0891889 7.4793 0.0284937 7.2923 1.16683e-07L7.11007 0C6.6559 0.0904063 6.26508 0.352371 5.86004 0.565929C4.08665 1.49755 2.31626 2.43531 0.54908 3.37911C0.273361 3.52656 0.0597992 3.76005 0.0099678 4.11741C0.00854492 4.13022 0.00356293 4.14161 0 4.153L0 4.30463C0.0284805 4.46764 0.0761719 4.62212 0.177967 4.75167C0.213558 4.79581 0.247017 4.84208 0.287598 4.87839C0.395794 4.97306 0.505424 5.06418 0.63142 5.13181C2.60185 6.1818 4.56944 7.23606 6.54201 8.2825C6.70858 8.3722 6.88014 8.45904 7.07235 8.47755C7.2674 8.49749 7.45034 8.46118 7.62261 8.37006L13.6037 5.19445C13.6706 5.15815 13.7403 5.12754 13.803 5.08554C13.9902 4.96381 14.1653 4.82357 14.2636 4.60432C14.3063 4.51107 14.3248 4.405 14.3561 4.30463L14.3561 4.153C14.3248 3.98785 14.2764 3.82982 14.1732 3.70026L14.1739 3.70025ZM13.5004 6.55054C13.2896 6.50635 13.0699 6.53759 12.8797 6.63881C12.501 6.8424 12.1251 7.05525 11.7429 7.25386C10.2444 8.03264 8.74237 8.80714 7.24318 9.5845C7.20047 9.60585 7.16488 9.60941 7.12074 9.58663L1.61023 6.69862C1.3144 6.53849 0.971592 6.48783 0.642097 6.55553C0.300404 6.62601 0.0633507 6.9314 0.0156593 7.31936C0.0128059 7.34072 0.00497818 7.36207 0.000705719 7.38343L0.000705719 7.5799C0.0291786 7.73936 0.0768776 7.89027 0.173687 8.01983C0.266228 8.14156 0.373005 8.24264 0.501858 8.31098C2.51998 9.39372 4.53954 10.4779 6.5605 11.5549C6.72209 11.6404 6.89009 11.7258 7.07874 11.7422C7.2681 11.7592 7.44748 11.7251 7.61619 11.6375C9.69198 10.5626 11.7678 9.48912 13.8407 8.40922C14.1183 8.264 14.2771 8.00702 14.3397 7.68312C14.3461 7.65963 14.3504 7.63472 14.3561 7.61051L14.3561 7.42828C14.3369 7.36207 14.3248 7.2916 14.2998 7.22896C14.1532 6.83814 13.877 6.62387 13.5004 6.55126L13.5004 6.55054ZM13.5019 9.80944C13.2908 9.7652 13.0708 9.79644 12.8804 9.89771C12.496 10.1042 12.1159 10.3177 11.73 10.5199C10.238 11.2944 8.74591 12.0646 7.25386 12.8391C7.20773 12.8661 7.15042 12.8653 7.10508 12.837C5.27916 11.8774 3.45181 10.9207 1.62446 9.96106C1.35194 9.82084 1.04443 9.7632 0.739628 9.7952C0.383698 9.82367 0.108913 10.1049 0.0313225 10.495C0.0206451 10.5441 0.0099678 10.5918 0.000720978 10.6402L0.000720978 10.8366C0.0291862 10.9933 0.0754585 11.1427 0.168713 11.2709C0.26268 11.3983 0.373734 11.5008 0.507553 11.572C2.52355 12.654 4.54025 13.7361 6.55837 14.811C6.73064 14.9035 6.91217 14.9889 7.10935 15.0082L7.24888 15.0082C7.41069 14.9797 7.56661 14.9243 7.71016 14.8444C7.89952 14.7412 8.09955 14.6586 8.29104 14.559C10.1333 13.6008 11.9749 12.6412 13.8151 11.6823C14.107 11.53 14.2757 11.273 14.3412 10.9335L14.3561 10.868L14.3561 10.6857C14.3369 10.6195 14.3248 10.5491 14.2999 10.4864C14.1554 10.0949 13.8777 9.88134 13.5019 9.81015L13.5019 9.80944Z" fill="#4388FB" >
</path>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -25,6 +25,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',

View File

@@ -5,25 +5,25 @@ const equipment = {
meta: { title: '监控中心', icon: 'jiankongzhongxin', index: 1 },
redirect: { name: 'EnvironmentMonitor' },
children: [
// {
// path: 'environmentMonitor',
// name: 'EnvironmentMonitor',
// meta: { title: '环境监测', hideChildren: true, icon: 'huanjingjiance' },
// component: Base,
// redirect: { name: 'EnvironmentMonitorIndex' },
// children: [
// {
// path: 'index',
// name: 'EnvironmentMonitorIndex',
// component: () => import('/@/view/monitor/environmentMonitor/index.vue'),
// meta: {
// title: '环境监测',
// keepAlive: true,
// // backApi: [],
// },
// },
// ],
// },
{
path: 'environmentMonitor',
name: 'EnvironmentMonitor',
meta: { title: '环境监测', hideChildren: true, icon: 'huanjingjiance' },
component: Base,
redirect: { name: 'EnvironmentMonitorIndex' },
children: [
{
path: 'index',
name: 'EnvironmentMonitorIndex',
component: () => import('/@/view/monitor/environmentMonitor/index.vue'),
meta: {
title: '环境监测',
keepAlive: true,
// backApi: [],
},
},
],
},
{
path: 'deviceMonitor',
name: 'DeviceMonitor',

View File

@@ -30,7 +30,9 @@
style="flex: 1; height: 100%; background-color: white; border-radius: 4px; padding: 12px">
<div ref="echartPieOne" style="width: 100%; height: 100%"></div>
</div>
<div style="flex: 1; height: 100%; background-color: white; border-radius: 4px"> xxxx </div>
<div style="flex: 1; height: 100%; background-color: white; border-radius: 4px">
<div ref="echartPieTow" style="width: 100%; height: 100%"></div>
</div>
</div>
<!-- 告警矩形 echarts -->
<div style="flex: 4; width: 100%; background-color: white; border-radius: 4px; padding: 12px">
@@ -49,8 +51,10 @@
const info = ref({});
let chartInstance: echarts.ECharts | null = null;
let chartInstanceOne: echarts.ECharts | null = null;
let chartInstanceTow: echarts.ECharts | null = null;
const graphChart = ref(null);
const echartPieOne = ref(null);
const echartPieTow = ref(null);
const getGraphChart = () => {
let dayData = [];
let energyAlarm = [];
@@ -294,7 +298,7 @@
},
textAlign: 'center',
x: '44.3%',
y: '46%',
y: '43%',
},
],
tooltip: {
@@ -327,9 +331,10 @@
clockwise: false, //饼图的扇区是否是顺时针排布
avoidLabelOverlap: false,
label: {
show: true,
normal: {
show: true,
position: 'outter',
position: 'outside',
textStyle: {
fontSize: 14,
fontWeight: 'bold',
@@ -342,7 +347,7 @@
labelLine: {
show: true, // 控制标签线是否显示
length: 10, // 标签线长度
length2: 20, // 标签线引出部分长度
length2: 0, // 标签线引出部分长度
// 其他样式属性,如 lineStyle 等
},
data: m2R2Data,
@@ -352,11 +357,107 @@
chartInstanceOne = echarts.init(echartPieOne.value);
chartInstanceOne.setOption(option);
};
const getEchartPieTow = () => {
if (chartInstanceTow) {
chartInstanceTow.dispose();
}
chartInstanceTow = echarts.init(echartPieTow.value);
var m2R2Data = [
{ value: 335, name: '紧急', itemStyle: { color: '#F56E53' } },
{ value: 310, name: '重要', itemStyle: { color: '#F7C122' } },
{ value: 234, name: '一般', itemStyle: { color: '#3BC27F' } },
];
const option = {
title: [
{
text: '优先级 / 近30天',
textStyle: {
fontSize: 16,
fontWeight: 'normal',
color: '#aaaaaa',
},
left: '2%',
top: '2%',
},
{
text: '优先级',
subtext: 12312 + '个',
textStyle: {
fontSize: 24,
color: 'black',
},
subtextStyle: {
fontSize: 24,
fontWeight: '700',
color: 'black',
},
textAlign: 'center',
x: '44.3%',
y: '43%',
},
],
tooltip: {
trigger: 'item',
formatter: function (parms) {
var str = parms.marker + ' :' + parms.data.value;
return str;
},
},
legend: {
// 设置图例靠右,上下居中,垂直排列
right: 50,
top: 'center',
orient: 'vertical',
// 图例图标设置为圆形
icon: 'circle',
itemWidth: 12,
itemHeight: 12,
itemGap: 16,
textStyle: {
fontSize: 14,
},
},
series: [
{
name: '优先级',
type: 'pie',
center: ['45%', '50%'],
radius: ['50%', '70%'],
clockwise: false, //饼图的扇区是否是顺时针排布
avoidLabelOverlap: false,
label: {
show: true,
normal: {
show: true,
position: 'outside',
textStyle: {
fontSize: 14,
fontWeight: 'bold',
},
formatter: function (parms) {
return '[ ' + parms.data.name + ' ] : ' + parms.data.value;
},
},
},
labelLine: {
show: true, // 控制标签线是否显示
length: 10, // 标签线长度
length2: 0, // 标签线引出部分长度
// 其他样式属性,如 lineStyle 等
},
data: m2R2Data,
},
],
};
chartInstanceTow = echarts.init(echartPieTow.value);
chartInstanceTow.setOption(option);
};
onMounted(() => {
//渲染第三个图表
getGraphChart();
//优先级
getEchartPieOne();
getEchartPieTow();
});
</script>
<style lang="less" scoped>

View File

@@ -11,27 +11,23 @@
}"
@click="clickSwitch({ enableRules: record.enableRules, record: record })" />
</template>
<template v-if="column.dataIndex === 'equipmentInfo'">
{{
record?.enableRules
? record.enableRules + '>' + record.deviceType + '>' + record.deviceName
: '-'
}}
<template v-if="column.dataIndex === 'comparisonType'">
{{ getcomparisonType(record) }}
</template>
</template>
</ns-view-list-table>
<!-- 新增or编辑界面 -->
<editConfigureEnergyAlarm ref="editConfigureEnergyAlarms" />
<editConfigureEnergyAlarm ref="editConfigureEnergyAlarms" @editObject="editObject" />
</template>
<script lang="ts">
import { ref, createVNode } from 'vue';
import { http } from '/nerv-lib/util';
import data from '../notificationManagementMock.json';
import { NsMessage, NsModal } from '/nerv-lib/component';
import editConfigureEnergyAlarm from './editConfigureEnergyAlarm.vue';
import { deviceAlarms } from '/@/api/alarmSettings/deviceAlarms';
import { energyAlarms } from '/@/api/alarmSettings/energyAlarm';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { device } from '/@/api/deviceManage';
import { dict } from '/@/api';
export default {
components: { editConfigureEnergyAlarm },
@@ -43,11 +39,37 @@
const tableConfig = ref({});
const mainRef = ref({});
const editConfigureEnergyAlarms = ref({});
const mockData = ref(data.listData);
//组织树
const orgId = ref('');
const result = JSON.parse(sessionStorage.getItem('ORGID')!);
orgId.value = result;
//获取对比类型
const getcomparisonType = (data: any) => {
let datas = data.comparisonType.split(',');
if (datas[0] === '1') {
switch (datas[1]) {
case '1':
return '数值>输入数值';
case '2':
return '数值>同比';
case '3':
return '数值>环比';
case '4':
return '数值>对比基准';
}
} else {
switch (datas[1]) {
case '1':
return '比例>输入比例';
case '2':
return '比例>同比';
case '3':
return '比例>环比';
case '4':
return '比例>对比基准';
}
}
};
const clickSwitch = (data: any) => {
NsModal.confirm({
title: '启用状态',
@@ -55,7 +77,7 @@
content: '确定' + (data.record.enableRules === 1 ? '关闭' : '启用') + '规则吗?',
onOk: () => {
http
.post(deviceAlarms.addOrUpNewData, {
.post(energyAlarms.configAddOrUpNewData, {
id: data.record.id,
enableRules: data.record.enableRules === 1 ? 0 : 1,
})
@@ -80,8 +102,7 @@
show.value = true;
tableConfig.value = {
title: '告警规则',
api: deviceAlarms.getTableList,
value: mockData.value,
api: energyAlarms.configGetTableList,
headerActions: [
{
label: '新增',
@@ -120,14 +141,24 @@
label: '批量删除',
type: 'primary',
name: 'userBatchDel',
confirm: true,
dynamicDisabled: (data: any) => {
return data.list.length === 0;
},
confirm: true,
isReload: true,
isClearCheck: true,
// api: origanizemanage.batchDel,
dynamicParams: { userIds: 'userId[]' },
handle: (data: any) => {
let ids = [];
data.list.forEach((item) => {
ids.push(item.id);
});
data.list = [];
http.post(energyAlarms.configDel, { ids: ids.toString() }).then(() => {
NsMessage.success('告警规则删除成功');
//清空选中
mainRef.value.nsTableRef.clearCheck();
//刷新表单
mainRef.value?.nsTableRef.reload();
});
},
},
],
columns: [
@@ -144,7 +175,7 @@
},
{
title: '设备信息/节点信息',
dataIndex: 'equipmentInfo',
dataIndex: 'deviceInfo',
},
{
title: '对比类型',
@@ -152,11 +183,11 @@
},
{
title: '告警点位',
dataIndex: 'devicePoint',
dataIndex: 'devicePointName',
},
{
title: '判断条件',
dataIndex: 'ruleType',
dataIndex: 'conditionalJudgment',
},
{
title: '异常描述',
@@ -185,8 +216,12 @@
name: 'FeedBackDetail',
dynamicParams: ['uuid', 'appealType'],
confirm: true,
handle: () => {
// mockData.value.splice(0, 1);
handle: (data: any) => {
http.post(energyAlarms.configDel, { ids: data.id }).then(() => {
NsMessage.success('告警规则删除成功');
//刷新表单
mainRef.value?.nsTableRef.reload();
});
},
},
],
@@ -194,78 +229,106 @@
formConfig: {
title: value.errorCode,
schemas: [
// {
// field: 'deviceNode',
// label: '设备名称',
// component: 'nsSelectApi',
// componentProps: {
// api: device.queryDevicePage,
// allowClear: true,
// params: {
// orgId: orgId.value,
// pageNum: 1,
// pageSize: 99,
// },
// placeholder: '请选择设备名称',
// resultField: 'data.records',
// labelField: 'deviceName',
// valueField: 'id',
// showSearch: true,
// filterOption: (input: string, option: any) => {
// return option.deviceName.toLowerCase().indexOf(input.toLowerCase()) >= 0;
// },
// // autoAddLink: true, //默认添加联动
// },
// },
{
field: 'deviceName',
label: '设备名称',
component: 'nsSelectApi',
label: '设备信息/节点信息',
component: 'NsInput',
componentProps: {
api: device.queryDevicePage,
params: {
orgId: orgId.value,
pageNum: 1,
pageSize: 99,
allowClear: true,
placeholder: '请输入设备信息/节点信息关键字',
},
},
{
field: 'dataSourcesType',
label: '告警点位',
component: 'nsSelectApi',
// dynamicParams: {
// id: 'deviceName', //帮定上级联动数据
// },
componentProps: {
api: () => dict({ params: { dicKey: 'ENERGY_TYPE' } }),
immediate: true,
allowClear: true,
labelField: 'cnValue',
valueField: 'id',
placeholder: '请选择告警点位',
showSearch: true,
filterOption: (input: string, option: any) => {
return option.cnValue.toLowerCase().indexOf(input.toLowerCase()) >= 0;
},
placeholder: '请选择设备名称',
resultField: 'data.records',
labelField: 'deviceName',
valueField: 'id',
autoAddLink: true, //默认添加联动
// autoSelectFirst: true,
},
},
{
field: 'devicePoint',
label: '设备点位',
component: 'nsSelectApi',
dynamicParams: {
id: 'deviceName', //帮定上级联动数据
},
componentProps: {
api: device.queryDevicePoint,
resultField: 'data',
placeholder: '请选择设备点位',
labelField: 'code',
valueField: 'id',
dependency: 'deviceName',
},
},
{
field: 'payWay',
field: 'enableRules',
label: '启用状态',
component: 'NsSelect',
componentProps: {
allowClear: true,
placeholder: '请选择启用状态',
options: [
{
label: '启用',
value: '1',
value: 1,
},
{
label: '关闭',
value: '0',
value: 0,
},
],
},
},
{
field: 'provider',
field: 'abnormalDescription',
label: '异常描述',
component: 'NsInput',
componentProps: {
allowClear: true,
placeholder: '请输入异常描述关键字',
},
},
],
},
params: { id: value.id },
params: { equipmentAlarmId: value.id },
// pagination: { pageSizeOptions: false },
rowKey: 'id',
};
};
// 编辑或添加成功 刷新列表
const editObject = () => {
mainRef.value?.nsTableRef.reload();
};
return {
configureEnergyAlarmsData,
show,
clickSwitch,
doWnload,
mainRef,
editObject,
getcomparisonType,
orgId,
tableConfig,
editConfigureEnergyAlarms,

View File

@@ -27,9 +27,9 @@
}"
tree-node-filter-prop="orgName" />
</a-form-item>
<a-form-item label="数据来源" name="sbtype">
<a-form-item label="数据来源" name="dataSources">
<a-cascader
v-model:value="infoObject.sbtype"
v-model:value="infoObject.dataSources"
:options="deviceTypeTreeData"
:field-names="{
children: 'children',
@@ -45,16 +45,19 @@
v-model:value="infoObject.deviceNode"
style="width: 100%"
placeholder="请选择设备节点"
:disabled="!infoObject.sbtype"
:disabled="!infoObject.dataSources"
:tree-line="true && { showLeafIcon: false }"
:tree-data="jdTreeData"
:field-names="{
children: 'children',
label: infoObject.sbtype && infoObject.sbtype[1] === 1 ? 'deviceName' : 'pointName',
label:
infoObject.dataSources && infoObject.dataSources[1] === 1
? 'deviceName'
: 'pointName',
value: 'id',
}" />
</a-form-item>
<a-form-item label="启用规则" name="enableRules">
<a-form-item label="启用规则">
<a-switch
:checked="infoObject.enableRules === 1 ? true : false"
:class="{
@@ -67,6 +70,7 @@
<a-textarea
v-model:value="infoObject.abnormalDescription"
style="height: 32px"
placeholder="请输入异常描述"
:autoSize="{ minRows: 1, maxRows: 1 }"
show-count
:maxlength="30" />
@@ -152,10 +156,11 @@
deviceNode: null,
ruleType: null,
abnormalDescription: null,
sbtype: null,
dataSources: null,
enableRules: 0,
alarmList: [{ id: null, logic: null, num: null, isDelete: 0 }],
});
const emit = defineEmits(['editObject']);
//删除的逻辑列表
const delAlarmList = ref([]);
//对比类型
@@ -224,7 +229,7 @@
.post(device.queryDevicePage, {
pageNum: 1,
pageSize: 999,
energyType: selectedOptions[0].cnValue,
energyType: selectedOptions[0].dicKey,
orgId: orgId.value,
})
.then((res) => {
@@ -236,7 +241,7 @@
.post(group.queryDeviceGroupTree, {
pageNum: 1,
pageSize: 999,
energyType: selectedOptions[0].cnValue,
energyType: selectedOptions[0].dicKey,
orgId: orgId.value,
})
.then((res) => {
@@ -271,19 +276,24 @@
const toggle = async (value: any, info: any) => {
// 数据来源
let energyType = await dict({ params: { dicKey: 'ENERGY_TYPE' } });
energyType.data.data.forEach((item: any) => {
item.children = [
{
id: 1,
cnValue: '设备',
},
{
id: 2,
cnValue: '节点',
},
];
});
deviceTypeTreeData.value = energyType.data.data;
if (energyType.data.data) {
energyType.data.data.forEach((item: any) => {
item.children = [
{
id: 1,
cnValue: '设备',
},
{
id: 2,
cnValue: '节点',
},
];
});
deviceTypeTreeData.value = energyType.data.data;
} else {
deviceTypeTreeData.value = [];
}
//能源告警
energyAlarm.value = info;
// 获取站点数据
@@ -294,16 +304,38 @@
});
//判断 是新增 还是修改
if (value) {
value.ruleType = value.ruleType + '';
value.comparisonType = value.comparisonType.split(',');
value.sbtype = [value.dataSourcesType, value.dataSourcesWay];
delete value.dataSourcesType;
delete value.dataSourcesWay;
infoObject.value = value;
//获取设备/节点
deviceTypeTreeData.value.forEach((item: any) => {
if (item.id === infoObject.value.sbtype[0]) {
selectDeviceType(infoObject.value.sbtype, [{ ...item }]);
await http.post(energyAlarms.configFindById, { id: value.id }).then((res) => {
if (res.msg === 'success') {
infoObject.value = res.data;
// 拼凑成 修改回显形式
infoObject.value.dataSources = [
infoObject.value.dataSourcesType,
infoObject.value.dataSourcesWay,
];
delete infoObject.value.dataSourcesType;
delete infoObject.value.dataSourcesWay;
infoObject.value.comparisonType = infoObject.value.comparisonType.split(',');
infoObject.value.ruleType = infoObject.value.ruleType + '';
//枚举 需要重新赋值
if (
infoObject.value.hxAlarmRuleLogicList &&
infoObject.value.hxAlarmRuleLogicList.length > 0
) {
infoObject.value.hxAlarmRuleLogicList.forEach((item: any) => {
item.logic = item.logic.value;
});
}
infoObject.value.alarmList = infoObject.value.hxAlarmRuleLogicList || [];
delete infoObject.value.hxAlarmRuleLogicList;
//获取设备/节点
if (deviceTypeTreeData && deviceTypeTreeData.value.length > 0) {
deviceTypeTreeData.value.forEach((item: any) => {
if (item.id === infoObject.value.dataSources[0]) {
selectDeviceType(infoObject.value.dataSources, [{ ...item }]);
}
});
}
}
});
} else {
@@ -313,7 +345,7 @@
deviceNode: null,
ruleType: null,
abnormalDescription: null,
sbtype: null,
dataSources: null,
enableRules: 0,
alarmList: [{ id: null, logic: null, num: null, isDelete: 0 }],
};
@@ -324,8 +356,7 @@
//表单 判断规格
const rules = {
site: [{ required: true, message: '请选择站点', trigger: 'change' }],
sbtype: [{ required: true, message: '请选择设备类型', trigger: 'change' }],
enableRules: [{ required: true, message: '请选择启用规则', trigger: 'change' }],
dataSources: [{ required: true, message: '请选择设备类型', trigger: 'change' }],
deviceNode: [{ required: true, message: '请选择设备名称', trigger: 'change' }],
sbAdress: [{ required: true, message: '请选择设备点位', trigger: 'change' }],
comparisonType: [{ required: true, message: '请选择对比类型', trigger: 'change' }],
@@ -344,12 +375,9 @@
},
},
],
logic: [{ required: true, message: '请选择逻辑', trigger: 'blur' }],
num: [{ required: true, message: '请输入数值', trigger: 'blur' }],
};
// 确认按钮
const btnClick = () => {
console.log(infoObject.value, '数据');
infoObject.value.alarmList.forEach((item) => {
if (item.logic === null || item.num === null) {
return;
@@ -361,17 +389,16 @@
}
//数据是否验证通过
formRef.value.validate().then(() => {
console.log(energyAlarm.value, '数据');
//处理数据
let data = { ...infoObject.value };
//关联能耗告警id
data.equipmentAlarmId = energyAlarm.value.id;
data.errorCode = energyAlarm.value.errorCode;
data.dataSourcesType = data.sbtype[0];
data.dataSourcesWay = data.sbtype[1];
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.comparisonType = data.comparisonType.toString();
data.hxAlarmRuleLogicList.forEach((item) => {
const num = Number(item.num);
if (!isNaN(num)) {
@@ -382,24 +409,24 @@
});
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);
// });
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);
});
});
};
//取消按钮
@@ -413,7 +440,7 @@
ruleType: null,
deviceNode: null,
abnormalDescription: null,
sbtype: null,
dataSources: null,
enableRules: 0,
alarmList: [{ id: null, logic: null, num: null, isDelete: 0 }],
};
@@ -475,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%;

View File

@@ -188,9 +188,9 @@
name: 'FeedBackDetail',
dynamicParams: ['uuid', 'appealType'],
confirm: true,
handle: () => {
handle: (data: any) => {
http.post(deviceAlarms.configDel, { ids: data.id }).then(() => {
NsMessage.success('规则删除成功');
NsMessage.success('告警规则删除成功');
mainRef.value?.nsTableRef.reload();
});
},
@@ -216,6 +216,10 @@
resultField: 'data.records',
labelField: 'deviceName',
valueField: 'id',
showSearch: true,
filterOption: (input: string, option: any) => {
return option.deviceName.toLowerCase().indexOf(input.toLowerCase()) >= 0;
},
autoAddLink: true, //默认添加联动
},
},
@@ -234,6 +238,10 @@
labelField: 'code',
valueField: 'id',
dependency: 'deviceName',
showSearch: true,
filterOption: (input: string, option: any) => {
return option.code.toLowerCase().indexOf(input.toLowerCase()) >= 0;
},
},
},
{

View File

@@ -85,6 +85,7 @@
<a-textarea
v-model:value="infoObject.abnormalDescription"
style="height: 32px"
placeholder="请输入异常描述"
:autoSize="{ minRows: 1, maxRows: 1 }"
show-count
:maxlength="30" />
@@ -145,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';
@@ -153,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);
@@ -319,11 +319,19 @@
getDevicePoint({ id: infoObject.value.deviceName });
// 回显 选择设备类型
findParentIds(deviceTypeTreeData.value, infoObject.value.deviceType, selectDevice.value);
//枚举 需要重新赋值
if (
infoObject.value.hxAlarmRuleLogicList &&
infoObject.value.hxAlarmRuleLogicList.length > 0
) {
infoObject.value.hxAlarmRuleLogicList.forEach((item: any) => {
item.logic = item.logic.value;
});
}
infoObject.value.alarmList = infoObject.value.hxAlarmRuleLogicList || [];
delete infoObject.value.hxAlarmRuleLogicList;
infoObject.value.deviceType = selectDevice;
infoObject.value.ruleType = infoObject.value.ruleType + '';
console.log(infoObject.value, '数据');
}
});
} else {
@@ -496,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%;

View File

@@ -40,11 +40,17 @@
</template>
<template v-if="column.dataIndex === 'monitor'">
{{
record?.monitorTime && record?.monitorTimeUnit
? record?.monitorTime + '' + record?.monitorTimeUnit
record.monitorTime && record.monitorTimeUnit
? record.monitorTime + '' + record.monitorTimeUnit.label
: '-'
}}
</template>
<template v-if="column.dataIndex === 'repetition'">
{{ record.repetitions.label }}
</template>
<template v-if="column.dataIndex === 'prioritys'">
{{ record.priority.label }}
</template>
</template>
</ns-view-list-table>
<a-button
@@ -77,6 +83,15 @@
clickSwitch({ type: 3, enableRules: record.enableRules, record: record })
" />
</template>
<template v-if="column.dataIndex === 'monitorFrequencys'">
{{ record.monitorFrequency.label }}
</template>
<template v-if="column.dataIndex === 'rep'">
{{ record.repetitions.label }}
</template>
<template v-if="column.dataIndex === 'prioritys'">
{{ record.priority.label }}
</template>
</template>
</ns-view-list-table>
<a-button

View File

@@ -1,15 +1,15 @@
<template>
<ns-drawer
v-model:visible="visible"
width="520"
:title="' '"
width="600"
:title="'设置通知联系人'"
:ok="btnClick"
:cancel="handleClose"
placement="right"
:footer-style="{ textAlign: 'right' }"
@close="handleClose">
<div style="padding: 18px; width: 100%; overflow: hidden">
<a-form ref="formRef" :model="infoObject" :rules="rules">
<div style="width: 100%; overflow: hidden; overflow-y: hidden; height: 100%">
<a-form ref="formRef" :model="infoObject" :rules="rules" style="width: 80%">
<a-form-item ref="notification" label="通知方式" name="notification">
<a-select
ref="select"
@@ -22,7 +22,7 @@
placeholder="请选择通知方式"
:filter-option="filterDevicePoint" />
</a-form-item>
<a-form-item label="启用规则" name="enableRules">
<a-form-item label="启用规则">
<a-switch
:checked="infoObject.enableRules === 1 ? true : false"
:class="{
@@ -31,28 +31,61 @@
}"
@click="clickSwitch" />
</a-form-item>
<a-form-item label="通知用户" name="user">
<a-cascader
v-model:value="infoObject.user"
style="width: 100%"
multiple
:max-tag-count="1"
:options="options"
:load-data="loadData"
placeholder="请选择通知用户"
:show-checked-strategy="Cascader.SHOW_CHILD" />
</a-form-item>
</a-form>
<a-table :dataSource="dataSource" :columns="columns" :pagination="false" />
<div style="width: 100%; height: 765px; overflow-y: auto">
<div style="margin-bottom: 8px">
<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>
<span style="margin-left: 24px; color: #333333">联系人名单</span>
</div>
<img
style="width: 100%; margin-top: -10px"
src="https://files.axshare.com/gsc/4T0UQR/7e/5d/a2/7e5da2a277344db8af30521cefeb70cc/images/告警设置/u150.svg?pageId=1f58c1ba-b461-4fe8-a2b3-295f1e7b0aa0" />
</div>
<div style="margin-bottom: 16px">
<a-button type="primary" @click="chengUser">选择联系人 </a-button>
</div>
<a-table
:dataSource="dataSource"
:columns="columns"
:scroll="{ x: 800, y: 700 }"
:pagination="pagination">
<template #bodyCell="{ record, column }">
<template v-if="column.dataIndex === 'operation'">
<a style="color: rgb(210, 0, 5)" @click="remove(record)">移除</a>
</template>
</template>
</a-table>
</div>
</div>
<linkPeople
v-show="visibleModel"
ref="linkPeoples"
@handleCancel="handleCancel"
@handleOk="handleOk" />
</ns-drawer>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { Cascader } from 'ant-design-vue';
import { NsMessage } from '/nerv-lib/component';
import { http } from '/nerv-lib/util';
// import { NsMessage } from '/nerv-lib/component';
// import { http } from '/nerv-lib/util';
// import { number } from 'vue-types';
import linkPeople from './linkPeople/index.vue';
// import { deviceAlarms } from '/@/api/alarmSettings/deviceAlarms';
@@ -61,25 +94,80 @@
{
title: '序号',
dataIndex: 'address',
width: 80,
fixed: 'left',
customRender: (text: any) => {
return text.index + 1;
},
},
{
title: '通知名单',
dataIndex: 'name',
key: 'name',
},
];
const dataSource = [
{
name: '运维>运维1部>张三',
title: '姓名',
dataIndex: 'deviceName',
width: 80,
fixed: 'left',
key: 'deviceName',
},
{
name: '运维>运维1部>李四',
title: '性别',
dataIndex: 'sex',
width: 80,
key: 'sex',
},
{
title: '组织关系',
dataIndex: 'site',
key: 'site',
},
{
title: '部门',
dataIndex: 'department',
key: 'department',
},
{
title: '操作',
width: 80,
dataIndex: 'operation',
fixed: 'right',
},
];
const visibleModel = ref(false);
const dataSource = ref([]);
const visible = ref(false);
const linkPeoples = ref(null);
const handleChangePage = (current: number, pageSize: number) => {
pagination.value.current = current;
pagination.value.pageSize = pageSize;
};
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 chengUser = () => {
visibleModel.value = true;
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,
@@ -101,71 +189,30 @@
{ label: '站内信息', value: 1 },
{ label: '邮件', value: 2 },
]);
//通知用户
const options = ref([
{
value: 1,
label: 'Zhejiang',
isLeaf: false,
},
{
value: 2,
label: 'Jiangsu',
isLeaf: false,
},
]);
//加载用户
const loadData = (selectedOptions: any) => {
const targetOption = selectedOptions[selectedOptions.length - 1];
targetOption.loading = true;
// load options lazily
setTimeout(() => {
targetOption.loading = false;
console.log(targetOption, '数据');
targetOption.children = [
{
label: `${targetOption.label} Dynamic 1`,
value: 3,
isLeaf: false,
},
{
label: `${targetOption.label} Dynamic 2`,
value: 4,
isLeaf: false,
},
];
options.value = [...options.value];
}, 1000);
};
const rules = {
notification: [{ required: true, message: '请选择站点', trigger: 'change' }],
enableRules: [{ required: true, message: '请选择启用规则', trigger: 'change' }],
notification: [{ required: true, message: '请选择通知方式', trigger: 'change' }],
user: [{ required: true, message: '请选择通知人', trigger: 'change' }],
abnormalDescription: [
{
required: true,
message: '请输入异常描述',
trigger: 'blur',
validator: (rules: any, abnormalDescription: any, cbfn: any) => {
if (abnormalDescription.trim() !== '') {
cbfn();
} else {
cbfn('告警标题不能为空');
}
},
},
],
alarm: [{ required: true, message: '请选择逻辑', trigger: 'blur' }],
number: [{ required: true, message: '请输入数值', trigger: 'blur' }],
};
const formRef = ref();
const emit = defineEmits(['editObject']);
const toggle = (value: any) => {
//判断 是新增 还是修改
if (value) {
// infoObject.value = value;
infoObject.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,
@@ -173,9 +220,26 @@
}
visible.value = !visible.value;
};
//移除数据
const remove = (data: any) => {
dataSource.value.forEach((item, index) => {
if (item.id === data.id) {
dataSource.value.splice(index, 1);
}
});
dataSource.value = [...dataSource.value];
};
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(() => {
//调用接口
@@ -190,22 +254,13 @@
// 清楚校验错误信息
formRef.value.resetFields();
visible.value = false;
options.value = [
{
value: 'zhejiang',
label: 'Zhejiang',
isLeaf: false,
},
{
value: 'jiangsu',
label: 'Jiangsu',
isLeaf: false,
},
];
visibleModel.value = false;
};
defineExpose({
toggle,
handleClose,
handleCancel,
handleChangePage,
formRef,
});
</script>
@@ -238,9 +293,9 @@
.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%;
text-align: left;
width: 20%;
}
</style>

View File

@@ -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: '请输入企业名称',
},
},
],
},
});

View File

@@ -0,0 +1,341 @@
<template>
<a-modal
v-model:visible="show"
width="1100px"
style="top: 50%; transform: translateY(-50%); overflow-y: hidden"
title="添加联系人"
@ok="handleOk"
@cancel="handleCancel">
<div class="box">
<div class="box-left">
<div style="width: 100%; display: flex; position: relative">
<div class="border-card"></div>
<span style="margin-left: 24px; color: #333333">联系人名单</span>
</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" />
<a-input-search
v-model:value="searchValue"
style="margin-bottom: 8px"
placeholder="请输入关键字" />
<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: 370px; overflow-y: auto">
<a-tree
:expanded-keys="expandedKeys"
:auto-expand-parent="autoExpandParent"
:tree-data="gData"
@select="onSelect"
@expand="onExpand"
/></div>
<!-- <ns-tree-api v-bind="config" @select="treeSelect" /> -->
</div>
<div class="box-right">
<div style="width: 100%; display: flex; position: relative">
<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>
</a-modal>
</template>
<script lang="ts">
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 = () => {
// 处理确定按钮的逻辑
emit('handleOk', { id: selectedRowKey.value, data: selectedRow.value });
show.value = false;
pagination.value.current = 1;
};
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 = () => {
// 处理取消按钮的逻辑
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>

View File

@@ -12,7 +12,7 @@ const tableKeyMap = [
},
{
title: '优先级',
dataIndex: 'priority',
dataIndex: 'prioritys',
},
{
title: '告警标题',
@@ -24,12 +24,11 @@ const tableKeyMap = [
},
{
title: '重复次数',
dataIndex: 'repetitions',
textEllipsis: true,
dataIndex: 'rep',
},
{
title: '监测时长',
dataIndex: 'monitorFrequency',
dataIndex: 'monitorFrequencys',
},
{
title: '是否启用',
@@ -99,6 +98,9 @@ export const energyAlarmConfigs = (
name: 'FeedBackDetail',
dynamicParams: ['uuid', 'appealType'],
handle: (data: any) => {
data.monitorFrequency = data.monitorFrequency.value;
data.priority = data.priority.value;
data.repetitions = data.repetitions.value;
editeEnergyAlarm.value.toggle(data);
},
},

View File

@@ -14,7 +14,7 @@ const tableKeyMap = [
},
{
title: '优先级',
dataIndex: 'priority',
dataIndex: 'prioritys',
},
{
title: '告警标题',
@@ -26,8 +26,7 @@ const tableKeyMap = [
},
{
title: '重复次数',
dataIndex: 'repetitions',
textEllipsis: true,
dataIndex: 'repetition',
},
{
title: '监测时长',
@@ -104,6 +103,9 @@ export const equipmentAlarmTableConfig = (
name: 'FeedBackDetail',
dynamicParams: ['uuid', 'appealType'],
handle: (data: any) => {
data.priority = data.priority.value;
data.repetitions = data.repetitions.value;
data.monitorTimeUnit = data.monitorTimeUnit.value;
editEquipmentAlarm.value.toggle(data);
},
},

View File

@@ -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>

View File

@@ -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>

View File

@@ -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
}
]
}

View File

@@ -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>

View File

@@ -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',
};
};

View File

@@ -36,27 +36,31 @@
: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>
<a-popover v-if="showOperation" 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>
<template #title="data">
<div class="treeRow">
<div>
<span v-if="data.emissionName && selectTreeDataValue && data.emissionName.indexOf(selectTreeDataValue) > -1">
{{ data.emissionName.substring(0, data.emissionName.indexOf(selectTreeDataValue)) }}
<span style="color: #f50" >{{ selectTreeDataValue }}</span>
{{ data.emissionName.substring(data.emissionName.indexOf(selectTreeDataValue) + selectTreeDataValue.length) }}
</span>
<span v-else>{{ data.emissionName }}</span>
</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>
</a-dropdown>
</div>
</template>
<MoreOutlined style="position: absolute;right: 0;top: 16%;font-size: 25px;cursor: pointer;" />
</a-popover>
</a-tree>
<div class="addTreeNode">
<a-button type="primary" style="width:100%;" @click="addTreeNodeData">新增</a-button>
</div>
@@ -82,6 +86,7 @@
@close="onClose">
<ns-form
ref="formRef"
:schemas="formSchema"
:model="formData"
class="form"
:wrapperCol="{ span: 20 }"
@@ -91,12 +96,100 @@
<a-button type="primary" @click="onEdit">确定</a-button>
</template>
</a-drawer>
<!-- 单位管理 -->
<a-drawer
:width="500"
:visible="unitManagement"
v-if="unitManagement"
:body-style="{ paddingBottom: '80px' }"
:footer-style="{ textAlign: 'right' }"
destroyOnClose
title="单位管理"
@close="closeUnitManag">
<div class="addButton">
<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.id"
allowClear
style="width: 96%"
placeholder="选择分组"
@change="handleChange"
>
<a-select-option v-for="(item, index) in groupData" :key="index" :value="item.id">
{{ item.cnValue }}
</a-select-option>
</a-select>
</div>
<a-tree
: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>
<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>
</div>
</template>
</a-tree>
</div>
<template #footer>
<a-button style="margin-right: 8px" @click="closeUnitManag">取消</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';
@@ -106,7 +199,7 @@
AntTreeNodeDropEvent,
TreeProps,
} from 'ant-design-vue/es/tree';
import { log } from 'node:console';
import { log } from 'node:console';
defineOptions({ name: 'OrderListIndex' });
const selectTreeDataValue = ref<string>('');
@@ -115,6 +208,7 @@ import { log } from 'node:console';
let formData = ref({});
const formRef = ref();
const visible = ref(false);
const unitManagement = ref(false);
const searchValue = ref<string>('');
const searchValue2 = ref<string>('');
const disabled = ref(false);
@@ -149,7 +243,7 @@ import { log } from 'node:console';
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';
@@ -357,15 +451,15 @@ import { log } from 'node:console';
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([])
@@ -427,7 +521,12 @@ import { log } from 'node:console';
formData.value = {};
userAuthList.value.splice(0);
};
const closeUnitManag = () => {
unitTreeParams.value = {
grp: 'MEASUREMENT_UNIT'
}
unitManagement.value = false;
};
const onEdit = () => {
formRef.value?.triggerSubmit().then(() => {
console.log(formData.value, 'formData.value');
@@ -496,6 +595,18 @@ import { log } from 'node:console';
api: carbonEmissionFactorLibrary.del,
dynamicParams: { ids: 'id[]' },
},
{
label: '单位管理',
type: 'primary',
name: 'userAdd',
handle: () => {
unitManagement.value = true,
fetch(carbonEmissionFactorLibrary.findOutermost).then((res) => {
groupData.value = res.data
});
getUnitTree()
},
},
],
columns: [
{
@@ -678,6 +789,146 @@ import { log } from 'node:console';
// pagination: { defaultPageSize: 10 },
rowKey: 'id',
});
// 单位管理
const unitExpandedKeys = ref<string[]>();
const unitSelectedKeys = ref<string[]>([]);
const unitTreeParams = ref({
grp: 'MEASUREMENT_UNIT'
})
const groupData = ref([])
const unitTreeData = ref<TreeProps['treeData']>(genData);
const handleChange = (value: string) => {
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>
<style lang="less" scoped>
.main {
@@ -695,7 +946,6 @@ import { log } from 'node:console';
// box-shadow: @ns-content-box-shadow;
flex: 1;
}
display: flex;
flex-direction: column;
.top{
@@ -726,4 +976,34 @@ import { log } from 'node:console';
padding-bottom: 10px;
border-bottom: 1px solid #e9e9e9;
}
.treeRow {
display: flex;
justify-content: space-between;
align-items: center;
}
.addButton{
width: 70%;
height: 5vh;
display: flex;
align-items: center;
justify-content: space-evenly;
}
.treePart{
width: 70%;
height: 100%;
display: flex;
border: 1px solid #bfbfbf;
margin-left: 10%;
flex-direction: column;
}
.actionMore {
display: none;
}
:deep(.ant-tree-node-content-wrapper) {
&:hover {
.actionMore {
display: block;
}
}
}
</style>

View File

@@ -77,4 +77,66 @@ export const tableColumns = [
key: 'action',
width: 130
},
];
export const columns = [
{
title: '序号',
customRender: (text: any) => {
return text.index + 1;
},
},
{
title: '因子值',
dataIndex: 'emissionFactors',
},
{
title: '计量单位',
className: 'carbonEmissionSuffix',
dataIndex: 'carbonEmissionSuffix',
},
{
title: '更新时间',
className: 'updateTime',
dataIndex: 'updateTime',
},
{
title: '启用时间',
className: 'startTime ',
dataIndex: 'startTime ',
},
{
title: '结束时间',
className: 'endTime',
dataIndex: 'endTime',
},
{
title: '数据来源',
className: 'dataSources',
dataIndex: 'dataSources',
},
{
title: '操作',
key: 'action',
width: 130
},
];
export const drawerColumns = [
{
title: '名称',
dataIndex: 'emissionSources',
},
{
title: '因子值',
dataIndex: 'emissionFactors',
},
{
title: '排放环节',
className: 'emissionProcess',
dataIndex: 'emissionProcess',
},
{
title: '数据来源',
className: 'dataSources',
dataIndex: 'dataSources',
},
];

View File

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

View File

@@ -1,16 +1,14 @@
<!-- @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 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"
v-model:value="searchValue"
placeholder="请输入关键词"
@search="onSearchTreeData"
/>
@@ -20,117 +18,131 @@
</a-form>
<a-tree
v-if="gData && gData.length > 0"
class="draggable-tree"
style="padding: 0 16px !important;"
draggable
show-line
checkable
block-node
:tree-data="gData"
:checkedKeys="checkedTreeNodeKeys"
:selectedKeys="selectedKeys"
@dragenter="onDragEnter"
@drop="onDrop"
@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) }}
:tree-data="gData"
show-line
@expand="onExpand"
@select="onSelect"
style="padding: 0 16px !important;"
>
<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>
{{ data.energyType.substring(data.energyType.indexOf(searchValue) + searchValue.length) }}
</span>
<span v-else>{{ emissionName }}</span>
<span v-else>{{ data.energyType }}</span>
</template>
</a-tree>
</div>
</div>
<div class="right">
<ns-view-list-table v-bind="tableConfig" :model="data" ref="mainRef" :scroll="{ x: 2000}"/>
<a-table
:columns="columns"
:data-source="tableData"
bordered
:pagination="false">
<template #bodyCell="{ column, text, record }">
<template v-if="column.key === 'action'">
<span>
<a @click="editData(record)">编辑</a>
<a-divider type="vertical" />
<a @click="delData(record)">删除</a>
</span>
</template>
</template>
<template #title>
<div class="ns-table-title"><span>排放因子库</span></div>
<div class="buttonGroup">
<a-button type="primary" @click="addNewData">新增</a-button>
</div>
</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-drawer
:width="700"
:visible="visible"
:body-style="{ paddingBottom: '80px' }"
:footer-style="{ textAlign: 'right' }"
destroyOnClose
@close="onClose">
<a-form
ref="formRef"
:model="formState"
:rules="rules"
:label-col="labelCol"
:wrapper-col="wrapperCol"
>
<a-row>
<a-col :span="12">
<a-form-item ref="name" label="能源种类" name="energyType">
<a-range-picker v-model:value="formState.energyType" picker="month" style="width:200px;" />
</a-form-item>
</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-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>
</template>
</a-drawer>
</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 { ref, watch, toRaw } from 'vue';
import type { TreeProps } from 'ant-design-vue';
import { Pagination,Modal } from 'ant-design-vue';
import { columns,drawerColumns } from '../config';
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 mainRef = ref();
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: {},
import { quickCalculation,carbonEmissionFactorLibrary } from '/@/api/carbonEmissionFactorLibrary';
defineOptions({
energyType: 'quickCalculation', // 与页面路由name一致缓存才可生效
components: {
'a-pagination': Pagination,
},
});
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 }) => {
const fetch = (api, params = { orgId } ) => {
return http.post(api, params);
};
// 树结构
// 数结构
const x = 3;
const y = 2;
const z = 1;
const genData: TreeProps['treeData'] = [];
const checkedTreeNodeKeys = ref<string[]>(['0-0']);
const generateData = (_level: number, _preKey?: string, _tns?: TreeProps['treeData']) => {
const preKey = _preKey || '0';
@@ -154,70 +166,7 @@ import { log } from 'node:console';
});
};
generateData(z);
type TreeDataItem = TreeProps['treeData'][number];
const gData = ref<TreeProps['treeData']>(genData);
const onDragEnter = (info: AntTreeNodeDragEnterEvent) => {
console.log(info);
// expandedKeys 需要展开时
// expandedKeys.value = info.expandedKeys;
};
const onDrop = (info: AntTreeNodeDropEvent) => {
console.log(info);
const dropKey = info.node.key;
const dragKey = info.dragNode.key;
const dropPos = info.node.pos.split('-');
const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]);
const loop = (data: TreeProps['treeData'], key: string | number, callback: any) => {
data.forEach((item, index) => {
if (item.key === key) {
return callback(item, index, data);
}
if (item.children) {
return loop(item.children, key, callback);
}
});
};
const data = [...gData.value];
// Find dragObject
let dragObj: TreeDataItem;
loop(data, dragKey, (item: TreeDataItem, index: number, arr: TreeProps['treeData']) => {
arr.splice(index, 1);
dragObj = item;
});
if (!info.dropToGap) {
// Drop on the content
loop(data, dropKey, (item: TreeDataItem) => {
item.children = item.children || [];
/// where to insert 示例添加到头部,可以是随意位置
item.children.unshift(dragObj);
});
} else if (
(info.node.children || []).length > 0 && // Has children
info.node.expanded && // Is expanded
dropPosition === 1 // On the bottom gap
) {
loop(data, dropKey, (item: TreeDataItem) => {
item.children = item.children || [];
// where to insert 示例添加到头部,可以是随意位置
item.children.unshift(dragObj);
});
} else {
let ar: TreeProps['treeData'] = [];
let i = 0;
loop(data, dropKey, (_item: TreeDataItem, index: number, arr: TreeProps['treeData']) => {
ar = arr;
i = index;
});
if (dropPosition === -1) {
ar.splice(i, 0, dragObj);
} else {
ar.splice(i + 1, 0, dragObj);
}
}
gData.value = data;
};
const dataList: TreeProps['treeData'] = [];
const generateList = (data: TreeProps['treeData']) => {
for (let i = 0; i < data.length; i++) {
@@ -249,13 +198,23 @@ import { log } from 'node:console';
return parentKey;
};
const expandedKeys = ref<(string | number)[]>([]);
const searchValue = ref<string>('');
const autoExpandParent = ref<boolean>(true);
const gData = ref<TreeProps['treeData']>(genData);
const onExpand = (keys: string[]) => {
expandedKeys.value = keys;
autoExpandParent.value = false;
};
watch(selectTreeDataValue, value => {
// 被选中的树节点
const onSelect = (selectedKeys: string[], info: any) => {
if(info.selected){
queryParams.value.energyType = info.node.id
getTableList()
}
};
watch(searchValue, value => {
const expanded = dataList
.map((item: TreeProps['treeData'][number]) => {
if (item.title.indexOf(value) > -1) {
@@ -265,273 +224,120 @@ import { log } from 'node:console';
})
.filter((item, i, self) => item && self.indexOf(item) === i);
expandedKeys.value = expanded;
selectTreeDataValue.value = value;
searchValue.value = value;
autoExpandParent.value = true;
});
// 筛选树结构中的数据
const onSearchTreeData = (selectTreeDataValue: string) => {
console.log('use value', selectTreeDataValue);
console.log('or use this.value', value.value);
// 查询因子分类树数据
const onSearchTreeData = () => {
};
// 点击数据点的复选框
const checkedIds = ref([])
const emissionType = ref()
const checkTreeNode = (checkedKeys, info) => {
checkedTreeNodeKeys.value = checkedKeys
checkedIds.value = []
info.checkedNodes.forEach(item=>{
checkedIds.value.push(item.id)
})
sessionStorage.setItem('checkedTreeNode', checkedIds.value);
emissionType.value = checkedIds.value.join(',')
mainRef.value?.nsTableRef.reload();
}
// 新增/编辑树节点点击确定
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) => {
// 获取因子分类树数据
const getTreeData = () => {
fetch(quickCalculation.carbonQuickTree).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]);
}
});
};
getTreeData()
// 列表数据
const total = ref<number>()
const queryParams = ref({
pageNum: 1,
pageSize: 10,
orgId: orgId.value,
})
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()
};
// 新增/编辑
const formRef = ref();
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' }],
};
// 点击新增按钮
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);
});
// 获取默认选中节点的所有id
getDefaultIds(selectedNodes)
};
// 删除数据
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 defaultIds = ref([])
const getDefaultIds = (selectedNodes) => {
selectedNodes.forEach(items => {
defaultIds.value.push(items.id)
if(items.children){
getDefaultIds(items.children)
}
})
emissionType.value = defaultIds.value.join(',')
checkedIds.value = defaultIds.value
sessionStorage.setItem('checkedTreeNode', checkedIds.value);
}
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');
tableConfig.value.params = {
...mainRef.value.params,
...params,
};
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 onClose = () => {
visible.value = false;
formData.value = {};
userAuthList.value.splice(0);
selectedRowKeys.value = [];
formRef.value.resetFields();
};
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 });
});
};
const tableConfig = ref({
title: '数据库',
api: carbonEmissionFactorLibrary.getTableList,
params: {
orgId,
emissionType
},
headerActions: [
{
label: '新增',
name: 'userAdd',
type: 'primary',
handle: () => {
opMap.value.type = 'add';
setTimeout(() => {
formData.value = {
carbonEmissionPrefix:'t',
numberOfReferences:'10'
};
userAuthList.value.splice(0);
});
opMap.value.fuc = (formData: any) => {
formData.emissionType = formData.emissionType[formData.emissionType.length - 1]
return http.post(carbonEmissionFactorLibrary.creatOrUpdate, formData).then(() => {
mainRef.value?.nsTableRef.reload();
visible.value = false;
NsMessage.success('操作成功');
});
};
visible.value = true;
},
},
{
label: '导入',
type: 'primary',
name: 'userImport',
handle: () => {},
},
{
label: '导出',
type: 'primary',
name: 'userExports',
},
{
label: '批量删除',
type: 'primary',
name: 'userBatchDel',
dynamicDisabled: (data: any) => {
return data.list.length === 0;
},
confirm: true,
isReload: true,
isClearCheck: true,
api: carbonEmissionFactorLibrary.del,
dynamicParams: { ids: 'id[]' },
},
],
columns: [
{
title: 'id',
customRender: (text: any) => {
return text.index + 1;
},
},
{
title: '排放源',
dataIndex: 'emissionSources',
},
{
title: '排放类型',
dataIndex: 'emissionTypeColumn',
},
{
title: '排放气体',
dataIndex: 'emissionGas',
},
{
title: '排放环节',
dataIndex: 'emissionProcess',
},
{
title: '排放因子',
dataIndex: 'emissionFactors',
},
{
title: '排放因子单位',
dataIndex: 'emissionFactorUnits',
},
{
title: '数据来源',
dataIndex: 'dataSources',
},
{
title: '数据库',
dataIndex: 'carbonDatabase',
},
{
title: '参考文献',
dataIndex: 'reference',
},
{
title: '引用数量',
dataIndex: 'numberOfReferences',
},
],
columnActions: {
title: '操作',
actions: [
{
label: '编辑',
name: 'userEdit',
handle: (record: any) => {
userAuthList.value.splice(0);
setTimeout(() => {
console.log(record.id);
http.post(carbonEmissionFactorLibrary.findById,{ id: record.id } ).then((res) => {
formData.value = res.data;
});
}, 10);
opMap.value.type = 'edit';
opMap.value.fuc = (formData: any) => {
return http.post(carbonEmissionFactorLibrary.creatOrUpdate, formData).then(() => {
mainRef.value?.nsTableRef.reload();
visible.value = false;
NsMessage.success('操作成功');
});
};
visible.value = true;
},
},
{
label: '删除',
name: 'userDelete',
dynamicParams: { ids: 'id[]' },
confirm: true,
isReload: true,
api: carbonEmissionFactorLibrary.del,
},
],
},
rowKey: 'id',
});
</script>
<style lang="less" scoped>
.main {
background-color: @ns-content-bg;
@@ -540,13 +346,10 @@ import { log } from 'node:console';
}
.left {
width: 300px;
// max-height: calc(100vh - 96px);
margin-right: @ns-gap;
min-width: fit-content;
> div {
border-radius: @ns-border-radius;
background-color: @white;
// box-shadow: @ns-content-box-shadow;
flex: 1;
}
@@ -565,12 +368,14 @@ import { log } from 'node:console';
.right {
flex: 1;
min-width: 0;
height: 100%;
background: #ffffff;
}
::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;
@@ -580,4 +385,24 @@ import { log } from 'node:console';
padding-bottom: 10px;
border-bottom: 1px solid #e9e9e9;
}
::v-deep .ant-table-title{
display: flex;
height: 100%;
align-items: center;
}
.ns-table-title{
font-weight: bold;
}
.buttonGroup{
margin-left: 1vw;
width: 5vw;
display: flex;
justify-content: space-around;
}
</style>
<style scoped>
th.column-money,
td.column-money {
text-align: right !important;
}
</style>

View File

@@ -0,0 +1,141 @@
.out-dialog {
position: fixed;
right: 496px;
width: 500px;
height: 100%;
top: 0;
bottom: 0;
margin: auto;
box-sizing: border-box;
color: rgb(255, 83, 0);
background: black;
display: flex;
padding: 25px;
flex-direction: column;
.content {
overflow-y: scroll;
.div-operation {
display: inline-block;
width: 3px;
height: 13px;
opacity: 1;
border-radius: 1px;
background: rgba(67, 136, 251, 1);
}
.text-operation {
display: inline-block;
color: rgba(255, 255, 255, 1);
font-size: 16px;
font-weight: 700;
margin-left: 5px;
}
.j-box {
background-color: #000;
opacity: 1;
z-index: 99999;
overflow-y: scroll;
.journal {
padding: 1% 3%;
width: 100%;
height: 150px;
background-color: rgba(0, 0, 0);
border-radius: 12px;
border: 2px solid transparent;
border-image: linear-gradient(to bottom, #0077ff, #00f6ff, #000000) 1;
}
.imgText {
display: flex;
align-items: center;
justify-content: space-between;
.ztzm {
display: flex;
align-items: center;
}
.cxbtn {
color: rgba(255, 255, 255, 1);
border: none;
border-radius: 6px;
width: 59.79px;
height: 32px;
opacity: 1;
background: linear-gradient(
180deg,
rgba(255, 187, 0, 1) 0%,
rgba(255, 112, 3, 1) 91.21%,
rgba(255, 129, 3, 1) 100%
);
}
}
.btn-box {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
grid-row-gap: 15px;
.btn-item {
text-align: center;
display: flex;
align-content: space-between;
.left {
width: 70px;
height: 35px;
line-height: 35px;
border-radius: 4px;
background: linear-gradient(
180deg,
rgba(1, 206, 255, 1) 0%,
rgba(0, 150, 229, 1) 100%
);
color: rgba(255, 255, 255, 1);
font-size: 14px;
font-weight: 400;
}
.right {
width: 140px;
height: 35px;
line-height: 35px;
span {
vertical-align: middle;
}
img {
padding: 0 5px;
}
}
}
}
}
}
.button-box {
width: 100%;
box-sizing: border-box;
padding: 10px;
height: 60px;
position: absolute;
background-color: transparent;
bottom: 0;
left: 0;
right: 0;
.execute, .cancel {
margin-right: 10px;
width: 74px;
height: 40px;
opacity: 1;
cursor: pointer;
border-radius: 4px;
font-size: 14px;
font-weight: 400;
border: 0;
margin-left: 10px;
}
.execute {
background: rgb(67, 136, 251);
color: white;
}
.cancel {
background: white;
color: black;
}
}
}

View File

@@ -1,156 +0,0 @@
// 页面容器
.lighting-box {
// width: 100%;
// height: 100%;
position: relative;
// background: linear-gradient(#badaff, #8cabeb, #7095de);
// 照明设备功能总容器
.lighting-img-box {
position: relative;
width: 1280px;
height: 720px;
user-select: none;
background-image: url(../image/bg.jpg);
// 由于背景是俯视图,会产生有交点的透视效果,故使用透视属性
perspective: 1000px;
perspective-origin: 850px -160px;
// 左上角区域切换功能
.btn-box {
width: 120px;
position: sticky;
top: 10px;
left: 10px;
display: flex;
flex-direction: column;
gap: 8px;
.btn-item {
cursor: pointer;
width: 100%;
height: 40px;
border-radius: 4px;
background: rgba(39, 120, 255, 1);
border: 1px solid rgba(51, 199, 255, 1);
box-shadow: 0px 10px 15px rgba(0, 54, 136, 0.3);
font-size: 18px;
color: white;
}
.btn-item:hover {
color: black;
}
}
// 大区分区
.area{
position: absolute;
bottom: 170px;
left: 240px;
width: 780px;
height: 240px;
transform: rotateX(79deg) rotateZ(-22deg) skew(29deg);
display: flex;
gap: 8px;
.area1 {
width: 170px;
background: rgba(0, 251, 91, 0.3);
border: 2px solid rgb(0, 251, 91);
display: flex;
}
.area2 {
width: 240px;
background: rgba(255, 165, 0, 0.3);
border: 2px solid rgb(255, 165, 0);
display: flex;
}
.area3 {
width: 110px;
background: rgba(255, 0, 0, 0.3);
border: 2px solid rgb(255, 0, 0);
}
.area4 {
flex: 1;
background: rgba(80, 236, 244, 0.3);
border: 2px solid rgb(80, 236, 244);
}
// .area-item:hover {
// transform: scale(1.05);
// }
.area-item {
cursor: pointer;
transition: all ease 0.2s;
>.light-group {
height: 100%;
flex: 1;
display:flex;
justify-content: center;
align-items: center;
.group-shadow1 {
width: 35px;
height: 150px;
border-radius: 20px;
background: rgba(0, 0, 0, 0.1);
}
.group-shadow2 {
width: 35px;
height: 180px;
border-radius: 20px;
background: rgba(0, 0, 0, 0.1);
}
.group-shadow3 {
width: 40px;
height: 180px;
border-radius: 20px;
background: rgba(0, 0, 0, 0.1);
}
.group-shadow4 {
width: 40px;
height: 160px;
border-radius: 20px;
background: rgba(0, 0, 0, 0.1);
}
}
// .group-shadow {
// transition: all ease 0.2s;
// }
// .group-shadow:hover {
// transform: scale(1.05);
// }
}
}
}
}
// 总容器与抽屉按钮
.ns-content-main {
position: relative;
// 抽屉打开按钮
.drawer-box-in {
width: 30px;
height: 40px;
border-radius: 2px;
position: fixed;
right: 0;
top: 0;
bottom: 0;
margin: auto;
background: rgba(0, 0 ,0 ,0.5);
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
// 抽屉关闭按钮
.drawer-box-out {
width: 30px;
height: 40px;
border-radius: 2px;
position: fixed;
right: 496px;
top: 0;
bottom: 0;
margin: auto;
background: rgba(0, 0 ,0 ,0.5);
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
}

View File

@@ -3,19 +3,19 @@
<div class="lighting-img-box">
<!-- 左上角区域切换 -->
<div class="btn-box">
<button class="btn-item">1F</button>
<button class="btn-item">2F</button>
<button class="btn-item">站台</button>
<button class="btn-item" @click=changeArea(1)>1F</button>
<button class="btn-item" @click=changeArea(2)>2F</button>
<button class="btn-item" @click=changeArea(3)>站台</button>
</div>
<!-- 楼层区域 -->
<div class="area">
<div
v-for="(item, index) in treeData"
:class="computedClass(item.id)"
@click="getArea(item.id)"
:class="computedClass(String(item.id))"
@click="getArea(item)"
:key="index">
<div v-for="(v, i) in item.children" :key="i" class="light-group">
<div class="group-shadow group-shadow1" :class="computedClass(v.id)" @click.stop="getArea(v.id)"></div>
<div class="group-shadow group-shadow1" :class="computedClass(v.id)" @click.stop="getArea(v)"></div>
</div>
</div>
</div>
@@ -40,16 +40,18 @@
placement="right"
:body-style="{ background: 'rgba(0, 0, 0)', opacity: 0.8 }"
:closable="false"
id="Odrawer"
id="drawer"
:maskStyle="{ 'background-color': 'rgba(0, 0, 0, 0)' }">
<a-tabs v-model:activeKey="activeKey">
<a-tab-pane key="1" tab="控制面板">
<tabs1 @changeArea="getArea" :treeData="treeData"></tabs1>
</a-tab-pane>
<a-tab-pane key="2" tab="计划列表" force-render>
<tabs2></tabs2>
</a-tab-pane>
<a-tab-pane key="3" tab="日志">
<tabs3></tabs3>
</a-tab-pane>
<a-tab-pane key="3" tab="日志"></a-tab-pane>
</a-tabs>
</a-drawer>
</div>
@@ -61,15 +63,17 @@ import { ref } from 'vue';
import { treeData } from './treeData'
import light from './light.vue';
import tabs1 from './tabs1.vue'
import tabs2 from './tabs2.vue'
import tabs3 from './tabs3.vue'
// ICON
import {
DoubleLeftOutlined,
DoubleRightOutlined
} from '@ant-design/icons-vue';
// 分区 - 当前选择的分区 - 默认选择一区
let area = ref(['1'])
// 分区 - 分区小灯泡
// 分区 - 当前选择的分区序号 - 默认选择一区
const area = ref(['1'])
// 分区 - 分区小灯泡 - 此处位置需前端写死
const bulbs = ref([
{
styleText: { left: '190px', bottom: '200px' },
@@ -121,6 +125,16 @@ const bulbs = ref([
},
])
// 分区 - 左上角分区切换
const changeArea = (area: number) => {
if (area == 1) {
console.log('1F')
} else if (area == 2) {
console.log('2F')
} else if (area == 3) {
console.log('站台')
}
}
// 分区 - 单个分区切换
const getArea = (result: any) => {
// 如果传入的值是数组
@@ -132,16 +146,14 @@ const getArea = (result: any) => {
area.value[0] = String(result)
}
}
// 分区 - 多个分区切换,只有照明回路能够触发多个分区
// 分区 - 样式函数
const computedClass = (number: number) => {
if (area.value.indexOf(number) != -1) {
return `isActive area-item area${number}`
const computedClass = (string: string) => {
if (area.value.indexOf(string) != -1) {
return `isActive area-item area${string}`
} else {
return `area-item area${number}`
return `area-item area${string}`
}
}
// 抽屉 - 当前选择的tab
let activeKey = ref('1');
// 抽屉 - 打开状态
@@ -153,7 +165,7 @@ const toggleDrawer = () => {
</script>
<style lang="less" scoped>
@import "./indexs.less";
@import "./index.less";
.isActive {
border: 3px solid white !important;
}

View File

@@ -1162,16 +1162,11 @@
selectedButton.value = null;
showControlMode.value = false;
showControlScene.value = false;
selectedButton3.value = null;
selectedButton4.value = null;
selectedButton3.value = '';
selectedButton4.value = '';
};
// 操作日志
const logModalVisible = ref(false);
const handlerefClick1 = () => {
console.log(1111);
executevisible.value = true;
};
let trindex = ref('-1');
const handleRowClick = (index: any) => {
@@ -1192,9 +1187,7 @@
};
// 添加模态框
const addvisible = ref<boolean>(false);
const addModal = () => {
addvisible.value = true;
};
// 穿梭框
interface MockData {
key: string;

View File

@@ -12,7 +12,7 @@
<div class="area">
<template v-if="!showAllButtonsArea">
<button v-for="(button, index) in limitedButtons1" :key="index"
:class="{ btn: true, selected: button.selected }" @click="selectButton(button, index)">
:class="{ btn: true, selected: button.selected }" @click="selectButton(button)">
{{ button.label }}
</button>
<div style="margin-top: 10px">
@@ -20,8 +20,8 @@
</div>
</template>
<template v-else>
<button v-for="(button, index) in props.treeData" :key="index"
:class="{ btn: true, selected: button.selected }" @click="selectButton(button)">
<button v-for="(button, index) in props.treeData" :key="index" :class="{ btn: true, selected: button.selected }"
@click="selectButton(button)">
{{ button.label }}
</button>
<div style="margin-top: 10px">
@@ -36,7 +36,7 @@
<div class="circuit-tab"></div>
<span class="circuit-text">照明回路</span>
<div class="btn2">
<button class="openplan" :class="{ enabled2: isPlanEnabled2, disabled2: !isPlanEnabled2 }" @click="togglePlan2">
<button class="openPlan" :class="{ enabled2: isPlanEnabled2, disabled2: !isPlanEnabled2 }" @click="togglePlan2">
{{ isPlanEnabled2 ? '启用面板' : '禁用面板' }}
</button>
<a-switch v-model:checked="selectAllCheckbox" :disabled="singleSelection" :class="{
@@ -49,7 +49,7 @@
</button>
</div>
</div>
<div class="btnarea" v-if="selectedButton">
<div class="btnArea" v-if="selectedButton">
<template v-if="!showAllButtons">
<button v-for="(button2, index) in limitedButtons2" :key="index"
:class="{ btn: true, selected: button2.selected }" class="zmhlbtn" @click="toggleSelection(button2)">
@@ -80,7 +80,7 @@
<!-- 控制模式按钮部分 -->
<div class="control-mode-btn-area" v-show="showControlMode">
<button v-for="(button3, index) in controlType" :key="index"
:class="{ btn: true, selected: button3.type === thisButtonType }" @click="selectButton3(button3)">
:class="{ btn: true, selected: button3.type == thisButton.type }" @click="selectButton3(button3)">
{{ button3.name }}
</button>
</div>
@@ -119,7 +119,7 @@
:style="{ height: '50px' }">
<td>{{ row.num }}</td>
<td>{{ row.light }}</td>
<td>{{ row.tempruter }}</td>
<td>{{ row.temperature }}</td>
</tr>
</tbody>
</table>
@@ -130,170 +130,71 @@
<button class="flushed" @click="refresh">刷新</button>
<button class="execute" @click="showModal">执行</button>
</div>
<!-- <a-modal :v-if="cxlist.length === 0" v-model:visible="executevisible" width="500px" height="792px" okText="执行"
:closable="false" @ok="handleOk2" :mask="false" :bodyStyle="{
opacity: 1,
background: ' rgba(0,0,0)',
color: 'rgba(255,83,0)',
boxSizing: 'borderBox',
display: 'flex',
flexDirection: 'column',
position: 'fixed',
right: '496px',
top: '0',
}">
<div :v-if="cxlist.length === 0" style="height: 792px">
<div class="out-dialog" v-if="executeVisible">
<div class="content" v-if="executeVisible">
<div>
<div class="div-operation"></div>
<span class="text-operation">变更内容 </span>
</div>
<div class="jbox" v-for="item in cxlist" :key="item.id">
<div class="j-box" v-for="item in cxList" :key="item.id">
<div class="journal" style="margin-top: 20px">
<div class="imgText">
<div class="zjzm">
<img class="titleimg" src="/asset/image//bulbLogo/21961.png" alt="" />&nbsp;
<span class="titletext" style="font-size: 20px; font-weight: 500; color: rgba(255, 255, 255, 1)">{{
item.name }}</span>
<img class="title-img" src="/asset/image//bulbLogo/21961.png" alt="" />&nbsp;
<span class="title-text" style="font-size: 20px; font-weight: 500; color: rgba(255, 255, 255, 1)">{{ item.name }}</span>
</div>
<button class="cxbtn" @click="delbtn(item.id)">撤销</button>
<button class="cxbtn" @click="delBtn(item.id)">撤销</button>
</div>
<div class="control-btn">
<button style="
width: 96px;
height: 40px;
border-radius: 4px;
background: linear-gradient(
180deg,
rgba(1, 206, 255, 1) 0%,
rgba(0, 150, 229, 1) 100%
);
border: 1px solid rgba(95, 154, 251, 1);
color: rgba(255, 255, 255, 1);
font-size: 14px;
font-weight: 400;
">
控制模式
</button>
<span style="
color: rgba(255, 255, 255, 1);
font-size: 14px;
font-weight: 400;
margin-left: 12px;
margin-right: 8px;
">手动</span>
<img src="/asset/image/bulbLogo/22406.png" alt="" />
<span style="
color: rgba(255, 255, 255, 1);
font-size: 14px;
font-weight: 400;
margin-left: 8px;
margin-right: 40px;
">自动</span>
</div>
<div class="light-btn">
<button style="
width: 68px;
height: 40px;
border-radius: 4px;
background: linear-gradient(
180deg,
rgba(1, 206, 255, 1) 0%,
rgba(0, 150, 229, 1) 100%
);
border: 1px solid rgba(95, 154, 251, 1);
color: rgba(255, 255, 255, 1);
font-size: 14px;
font-weight: 400;
">
亮度
</button>
<span style="
color: rgba(255, 255, 255, 1);
font-size: 14px;
font-weight: 400;
margin-left: 12px;
margin-right: 8px;
">100lux</span>
<img src="/asset/image/bulbLogo/22406.png" alt="" />
<span style="
color: rgba(243, 97, 99, 1);
font-size: 14px;
font-weight: 400;
margin-left: 8px;
">30lux</span>
</div>
<div class="control-area-btn">
<button style="
width: 96px;
height: 40px;
border-radius: 4px;
background: linear-gradient(
180deg,
rgba(1, 206, 255, 1) 0%,
rgba(0, 150, 229, 1) 100%
);
border: 1px solid rgba(95, 154, 251, 1);
color: rgba(255, 255, 255, 1);
font-size: 14px;
font-weight: 400;
">
控制场景
</button>
<span style="
color: rgba(255, 255, 255, 1);
font-size: 14px;
font-weight: 400;
margin-left: 12px;
margin-right: 8px;
">手动</span>
<img src="/asset/image/bulbLogo/22406.png" alt="" />
<span style="
color: rgba(255, 255, 255, 1);
font-size: 14px;
font-weight: 400;
margin-left: 8px;
margin-right: 40px;
">自动</span>
</div>
<div class="temp-btn">
<button style="
width: 68px;
height: 40px;
border-radius: 4px;
background: linear-gradient(
180deg,
rgba(1, 206, 255, 1) 0%,
rgba(0, 150, 229, 1) 100%
);
border: 1px solid rgba(95, 154, 251, 1);
color: rgba(255, 255, 255, 1);
font-size: 14px;
font-weight: 400;
">
色温
</button>
<span style="
color: rgba(255, 255, 255, 1);
font-size: 14px;
font-weight: 400;
margin-left: 12px;
margin-right: 8px;
">4000k</span>
<img src="/asset/image/bulbLogo/22406.png" alt="" />
<span style="
color: rgba(255, 255, 255, 1);
font-size: 14px;
font-weight: 400;
margin-left: 8px;
">3800k</span>
<div class="btn-box">
<div class="btn-item">
<div class="left">控制模式</div>
<div class="right">
<span>手动</span>
<img src="/asset/image/bulbLogo/22406.png" alt="" />
<span>自动</span>
</div>
</div>
<div class="btn-item">
<div class="left">
亮度
</div>
<div class="right">
<span>100lux</span>
<img src="/asset/image/bulbLogo/22406.png" alt="" />
<span>30lux</span>
</div>
</div>
<div class="btn-item">
<div class="left">
控制场景
</div>
<div class="right">
<span>手动</span>
<img src="/asset/image/bulbLogo/22406.png" alt="" />
<span>自动</span>
</div>
</div>
<div class="btn-item">
<div class="left">
色温
</div>
<div class="right">
<span>4000k</span>
<img src="/asset/image/bulbLogo/22406.png" alt="" />
<span>3800k</span>
</div>
</div>
</div>
</div>
</div>
</div>
</a-modal> -->
<div style="width: 100%; height: 60px;"></div>
<div class="button-box">
<button class="cancel" @click="executeVisible = false">取消</button>
<button class="execute">执行</button>
</div>
</div>
</template>
<script setup lang="ts">
@@ -307,19 +208,23 @@ import {
// 初始化
onMounted(() => {
const tree = props.treeData
const data = props.treeData[0]
// 默认选中第一个分区
tree[0].selected = true
data.selected = true
// 默认展示第一个分区的回路
buttons2.value = tree[0].children
buttons2.value = data.children
})
// 与父组件的交互 ===================================================================
const props = defineProps({
// 分区结构(照明区域 > 照明回路)
treeData: {
type: Array
type: Array,
default: []
},
line: {
type: Array
}
});
const emit = defineEmits(['changeArea']);
@@ -336,20 +241,13 @@ const togglePlan = () => {
const showAllButtonsArea = ref(false);
// 照明区域 - 分区 - 被选中的按钮 默认为1
const selectedButton = ref('1');
// 照明区域 - 区域切换(按钮点击)事件
const selectButton = (button: any, index: number) => {
// 照明区域 - 区域切换(按钮点击-单选)事件
const selectButton = (button: any) => {
// 当前选中按钮
selectedButton.value = button;
// 分区只能单选
props.treeData.forEach(item => {
item.selected = false
})
// 重置
initMenu(1)
button.selected = true
// 切换1级分区时重置二级分区
buttons2.value.forEach(item => {
item.selected = false
})
showControlMode.value = false
buttons2.value = button.children
// 反选area
emit('changeArea', []);
@@ -375,17 +273,8 @@ const togglePlan2 = () => {
isPlanEnabled2.value = !isPlanEnabled2.value;
// 禁用 - 则取消选中,增加禁止图标
if (isPlanEnabled2.value) {
item.selected = false;
item.stop = true
let level1 = String(selectedButton.value.id)
let arr = [level1]
buttons2.value.forEach(item => {
if (item.selected) {
arr.push(item.id)
}
})
emit('changeArea', arr)
// 启用 - 去除禁止图标
// 启用 - 去除禁止图标
} else {
item.stop = false
}
@@ -410,12 +299,10 @@ const toggleAllSelection = () => {
// 全选
if (selectAllCheckbox.value) {
buttons2.value.forEach((item) => {
if (!item.stop) {
item.selected = true;
arr.push(item.id)
}
item.selected = true;
arr.push(item.id)
});
// 全不选
// 全不选
} else {
buttons2.value.forEach((item) => {
item.selected = false;
@@ -431,7 +318,7 @@ const toggleSelection = (button: any) => {
zmhlid.value = button.id
// 如果已被锁定,则展示禁用/启用状态跳出
if (button.stop) {
return isPlanEnabled2.value = true
isPlanEnabled2.value = true
} else {
isPlanEnabled2.value = false
}
@@ -455,19 +342,24 @@ const toggleSelection = (button: any) => {
arr.push(item.id)
}
});
console.log(arr)
emit('changeArea', arr)
}
// 用于展示控制模式
if (button.selected) {
// 发生了选中事件
showControlMode.value = true
thisButtonType.value = button.type
thisButton.value = button
if (button.type == 3) {
showControlScene.value = true
} else {
showControlScene.value = false
}
} else {
// 未发生选中 或 多选被取消
showControlMode.value = false
thisButton.value = null
thisButton.value = { type: '0' }
}
};
// 照明回路 - 按钮区展开与收起状态
const showAllButtons = ref(false);
@@ -479,16 +371,12 @@ const buttons2 = ref([]);
// 控制模式 =======================================================================
// 控制模式 - 决定该区域是否显示
const showControlMode = ref(false);
const thisButtonType = ref(null)
const thisButton = ref(null)
// 控制模式 - 当前选择按钮
const selectedButton3 = ref('');
const thisButton = ref({ type: '0' })
// 控制模式 - 按钮切换
const selectButton3 = (button3) => {
thisButton.value.type = button3.type
thisButtonType.value = button3.type
showControlScene.value = button3.name === '手动';
selectedButton4.value = ''; // 清空选中的控制场景按钮
selectedButton4.value = null; // 清空选中的控制场景按钮
};
// 控制场景 =======================================================================
@@ -502,7 +390,7 @@ const controlSceneButtons = ref([
{ label: '客流高峰', selected: false },
]);
// 控制场景 - 当前选择按钮
const selectedButton4 = ref('');
const selectedButton4 = ref(null);
// 控制场景 - 按钮切换
const selectButton4 = (button4) => {
selectedButton4.value = button4.label;
@@ -510,33 +398,112 @@ const selectButton4 = (button4) => {
// 灯具参数 ========================================================================
// 灯具参数 - 表格数据
const lightSource = ref([{ num: '8/10', light: '100', tempruter: '4200' }]);
const lightSource = ref([{ num: '8/10', light: '100', temperature: '4200' }]);
let trIndex = ref('-1');
const handleRowClick = (index: any) => {
trindex.value = index;
if (index === trindex.value) {
console.log('tri');
}
// 显示模态框
logModalVisible.value = true;
};
trIndex.value = index;
if (index === trIndex.value) {
console.log('tri');
}
};
// 底部表格 ========================================================================
// 内侧弹窗 ========================================================================
const cxList = ref([
{
id: '1',
name: '站厅照明 1区',
manual: '手动',
automatic: '自动',
brightness: '100lux',
brightness2: '30lux',
manual2: '手动',
automatic2: '自动',
brightness3: '4000k',
brightness4: '3800k',
},
{
id: '2',
name: '站厅照明 2区',
manual: '手动',
automatic: '自动',
brightness: '100lux',
brightness2: '30lux',
manual2: '手动',
automatic2: '自动',
brightness3: '4000k',
brightness4: '3800k',
},
{
id: '3',
name: '站厅照明 3区',
manual: '手动',
automatic: '自动',
brightness: '100lux',
brightness2: '30lux',
manual2: '手动',
automatic2: '自动',
brightness3: '4000k',
brightness4: '3800k',
},
]);
// const cxList = cxList.value.concat(cxList.value)
//撤销
const delBtn = (id: any) => {
console.log(id);
cxList.value.pop(id);
console.log(cxList.value.length);
const refresh = () => {
selectedButton.value = {};
if (cxList.value.length === 0) {
executeVisible.value = false;
}
};
// 其他业务 ========================================================================
// 用于初始化5级联动的菜单
const initMenu = (tier: number) => {
// 1 = 照明区域 - 切换时,重置以下所有菜单
if (tier == 1) {
// 切换前,清除照明回路的选中状态
buttons2.value.forEach(item => {
item.selected = false
})
// 切换后,清空所有选中状态
props.treeData.forEach(item => {
item.selected = false
})
// 控制模式 隐藏
showControlMode.value = false;
// 控制场景 隐藏
showControlScene.value = false;
selectedButton3.value = null;
// 灯具参数 隐藏
selectedButton4.value = null;
} else if (tier == 2) {
// 控制场景 隐藏
showControlScene.value = false;
// 灯具参数 隐藏
selectedButton4.value = null;
}
}
// 刷新
const refresh = () => {
executeVisible.value = false
selectedButton.value = '1';
emit('changeArea', []);
emit('changeArea', [1]);
showControlMode.value = false;
showControlScene.value = false;
selectedButton4.value = null;
};
// 执行确认
const executevisible = ref<boolean>(false);
const showModal = () => {
executevisible.value = true;
};
const executeVisible = ref<boolean>(false);
const showModal = () => {
executeVisible.value = true;
};
</script>
<style lang="less" scoped>
@import "./dialogStyle.less";
// 抽屉
.drawer-item {
@@ -614,7 +581,7 @@ const executevisible = ref<boolean>(false);
cursor: not-allowed;
}
.openplan.enabled2 {
.openPlan.enabled2 {
border: none;
font-size: 14px;
font-weight: 400;
@@ -627,7 +594,7 @@ const executevisible = ref<boolean>(false);
color: white;
}
.openplan.disabled2 {
.openPlan.disabled2 {
border: none;
font-size: 14px;
font-weight: 400;
@@ -639,7 +606,7 @@ const executevisible = ref<boolean>(false);
background-color: red;
}
.openplan:disabled {
.openPlan:disabled {
cursor: not-allowed;
}
@@ -714,7 +681,7 @@ const executevisible = ref<boolean>(false);
}
.area,
.btnarea,
.btnArea,
.control-mode-btn-area,
.control-scene-btn-area {
margin-left: -17px;
@@ -828,7 +795,6 @@ const executevisible = ref<boolean>(false);
position: fixed;
bottom: 0;
right: 0;
margin-bottom: 10px;
}
.execute {
@@ -836,6 +802,7 @@ const executevisible = ref<boolean>(false);
width: 74px;
height: 40px;
opacity: 1;
cursor: pointer;
border-radius: 4px;
background: rgba(67, 136, 251, 1);
font-size: 14px;
@@ -848,6 +815,7 @@ const executevisible = ref<boolean>(false);
.flushed {
width: 74px;
height: 40px;
cursor: pointer;
opacity: 1;
border-radius: 4px;
font-size: 14px;
@@ -857,50 +825,6 @@ const executevisible = ref<boolean>(false);
border: 1px solid rgba(193, 197, 204, 1);
}
.tabreboot,
.tabdelete {
border: none;
background-color: rgba(0, 0, 0, 0);
font-size: 14px;
font-weight: 400;
letter-spacing: 0;
line-height: 20px;
color: rgba(67, 136, 251, 1);
}
.tabreboot {
margin-right: 8px;
}
.add {
width: 74px;
height: 40px;
opacity: 1;
border-radius: 4px;
background: rgba(67, 136, 251, 1);
border: rgba(67, 136, 251, 1);
font-size: 14px;
font-weight: 400;
color: white;
}
.divadd {
width: 100%;
height: 64px;
display: flex;
justify-content: flex-end;
align-items: center;
position: fixed;
bottom: 0;
right: 0;
margin-bottom: 10px;
margin-right: 20px;
}
.atable {
margin-top: 20px;
}
:deep(.ant-table-pagination) {
visibility: hidden;
}
@@ -1006,9 +930,12 @@ const executevisible = ref<boolean>(false);
display: flex;
align-items: center;
}
.zmhlbtn {
position: relative;
}
// 禁用图标
.anticon-stop {
position: absolute;
right: 3px;

View File

@@ -0,0 +1,216 @@
<template>
<div class="div-add">
<button class="add" @click="addModal">添加</button>
</div>
<table class="custom-table table1">
<thead>
<tr :style="{ background: 'rgba(35,45,69)' }">
<th>序号</th>
<th>执行时间</th>
<th>计划名称</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(row, index) in dataSource" :key="index">
<td>{{ row.key }}</td>
<td>{{ row.data }}</td>
<td>{{ row.planName }}</td>
<td v-if="row.status === '待执行'">
<button
style="
font-size: 12px;
background: rgba(57, 215, 187, 0.1);
color: rgb(57, 215, 187);
border: 1px solid rgb(57, 215, 187);
">
{{ row.status }}
</button>
</td>
<td v-if="row.status !== '待执行'">
<button
style="
font-size: 12px;
background: rgba(243, 97, 99, 0.1);
border: 1px solid rgba(243, 97, 99);
color: rgba(243, 97, 99);
">
{{ row.status }}
</button>
</td>
<td>
<button class="tabReboot" @click="handleRefClick1">重启</button>
<button class="tabDelete">删除</button>
</td>
</tr>
</tbody>
</table>
<div class="out-dialog" v-if="addVisible">
<div class="content" v-if="addVisible">
<div class="div-operation"></div>
<span class="text-operation">计划库</span>
</div>
<div style="margin-top: 20px">
<a-transfer
v-model:target-keys="targetKeys"
:data-source="mockData"
show-search
:filter-option="filterOption"
:render="(item) => item.title"
@change="handleChange"
:style="{ color: 'rgba(255,255,255,1)' }"
@search="handleSearch"
:listStyle="{ border: '2px solid rgba(25,74,125,1)', height: 'calc(100vh - 200px)' }" />
</div>
<div style="width: 100%; height: 60px;"></div>
<div class="button-box">
<button class="cancel" @click="addVisible = false">取消</button>
<button class="execute">确定</button>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
// 初始化
onMounted(() => {
})
// 表格数据
const dataSource = ref([
{
key: '1',
data: '2024-05-01',
planName: '劳动节',
status: '暂停中',
},
{
key: '2',
data: '2024-05-01',
planName: '国庆节',
status: '待执行',
},
{
key: '3',
data: '2024-05-01',
planName: '元旦',
status: '待执行',
},
]);
const addVisible = ref<boolean>(false);
// 操作日志
const handleRefClick1 = () => {
alert(111)
};
const addModal = () => {
addVisible.value = true;
};
const handleChange = (keys: string[], direction: string, moveKeys: string[]) => {
console.log(keys, direction, moveKeys);
};
const handleSearch = (dir: string, value: string) => {
console.log('search:', dir, value);
};
// 穿梭框 相关业务
interface MockData {
key: string;
title: string;
description: string;
chosen: boolean;
}
const mockData = ref([
{
key: '1',
title: '计划再开',
},
{
key: '2',
title: '检修模式',
},
{
key: '3',
title: '设备变更',
},
]);
const targetKeys = ref<string[]>([]);
const filterOption = (inputValue: string, option: MockData) => {
console.log(option.description);
return option.description.indexOf(inputValue) > -1;
};
</script>
<style lang="less" scoped>
@import "./dialogStyle.less";
// 右下角添加按钮
.div-add {
height: 64px;
display: flex;
justify-content: flex-end;
align-items: center;
position: fixed;
bottom: 0;
right: 0;
margin-right: 20px;
.add {
width: 74px;
height: 40px;
opacity: 1;
border-radius: 4px;
background: rgba(67, 136, 251, 1);
border: rgba(67, 136, 251, 1);
font-size: 14px;
font-weight: 400;
color: rgba(255, 255, 255, 1);
}
}
// 表格
.custom-table {
border-collapse: collapse;
width: 416px;
height: 60px;
color: rgba(255, 255, 255, 1);
}
.custom-table th,
.custom-table td {
border: 1px solid rgba(163, 192, 243, 1);
text-align: left;
padding: 8px;
text-align: center;
}
.table1 {
margin-top: 20px;
width: 100%;
border: 1px solid rgba(255, 255, 255);
border-radius: 5px;
background: rgba(255, 255, 255, 0.1);
// 表格中的操作按钮
.tabReboot,
.tabDelete {
border: none;
background-color: rgba(0, 0, 0, 0);
font-size: 14px;
font-weight: 400;
letter-spacing: 0;
line-height: 20px;
color: rgba(67, 136, 251, 1);
}
.tabReboot {
margin-right: 8px;
}
}
::v-deep(.ant-transfer) {
// 屏蔽自带的hover效果
.ant-transfer-list-content-item:hover {
background: black;
}
}
</style>

View File

@@ -0,0 +1,255 @@
<template>
<table class="custom-table table1">
<thead>
<tr :style="{ background: 'rgba(35,45,69)' }">
<th>序号</th>
<th>执行时间</th>
<th>操作内容</th>
<th>操作人</th>
</tr>
</thead>
<tbody>
<tr v-for="(row, index) in dataSource1" :key="index" @click="handleRowClick(row.key)"
:class="row.key === trIndex ? 'isTrIndex' : ''">
<td>{{ row.key }}</td>
<td>{{ row.data }}</td>
<td>{{ row.planName }}</td>
<td>{{ row.status }}</td>
</tr>
</tbody>
</table>
<div class="out-dialog" v-if="logModalVisible">
<div class="content" v-if="logModalVisible">
<div>
<div class="div-operation"></div>
<span class="text-operation">变更内容 </span>
</div>
<div class="jbox" v-for="item in cxList" :key="item.id">
<div class="journal" style="margin-top: 20px">
<div class="imgText">
<div class="zjzm">
<img class="title-img" src="/asset/image//bulbLogo/21961.png" alt="" />&nbsp;
<span class="title-text" style="font-size: 20px; font-weight: 500; color: rgba(255, 255, 255, 1)">{{
item.name }}</span>
</div>
</div>
<div class="btn-box">
<div class="btn-item">
<div class="left">控制模式</div>
<div class="right">
<span>手动</span>
<img src="/asset/image/bulbLogo/22406.png" alt="" />
<span>自动</span>
</div>
</div>
<div class="btn-item">
<div class="left">
亮度
</div>
<div class="right">
<span>100lux</span>
<img src="/asset/image/bulbLogo/22406.png" alt="" />
<span>30lux</span>
</div>
</div>
<div class="btn-item">
<div class="left">
控制场景
</div>
<div class="right">
<span>手动</span>
<img src="/asset/image/bulbLogo/22406.png" alt="" />
<span>自动</span>
</div>
</div>
<div class="btn-item">
<div class="left">
色温
</div>
<div class="right">
<span>4000k</span>
<img src="/asset/image/bulbLogo/22406.png" alt="" />
<span>3800k</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div style="height: 60px;"></div>
<div class="button-box">
<button class="cancel" @click="logModalVisible = false">取消</button>
</div>
</div>
<div class="div-add">
<button class="add">刷新</button>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
// 初始化
onMounted(() => {
})
// 与父组件的交互 ===================================================================
const props = defineProps({
// 分区结构(照明区域 > 照明回路)
treeData: {
type: Array
},
});
const emit = defineEmits(['changeArea']);
// 表格数据
const dataSource1 = ref([
{
key: '1',
data: '2024-05-01',
planName: '计划再开',
status: '张三111',
},
{
key: '2',
data: '2024-05-01',
planName: '检修模式',
status: '李四12',
},
{
key: '3',
data: '2024-05-01',
planName: '设备变更',
status: '王五33',
},
]);
const cxList = ref([
{
id: '1',
name: '站厅照明 1区',
manual: '手动',
automatic: '自动',
brightness: '100lux',
brightness2: '30lux',
manual2: '手动',
automatic2: '自动',
brightness3: '4000k',
brightness4: '3800k',
},
{
id: '2',
name: '站厅照明 2区',
manual: '手动',
automatic: '自动',
brightness: '100lux',
brightness2: '30lux',
manual2: '手动',
automatic2: '自动',
brightness3: '4000k',
brightness4: '3800k',
},
{
id: '3',
name: '站厅照明 3区',
manual: '手动',
automatic: '自动',
brightness: '100lux',
brightness2: '30lux',
manual2: '手动',
automatic2: '自动',
brightness3: '4000k',
brightness4: '3800k',
},
]);
let trIndex = ref('-1');
const logModalVisible = ref(false);
const handleRowClick = (index: any) => {
trIndex.value = index;
if (index === trIndex.value) {
console.log('tri');
}
// 显示模态框
logModalVisible.value = true;
};
</script>
<style lang="less" scoped>
@import "./dialogStyle.less";
// 右下角添加按钮
.div-add {
height: 64px;
display: flex;
justify-content: flex-end;
align-items: center;
position: fixed;
bottom: 0;
right: 0;
margin-right: 20px;
.add {
width: 74px;
height: 40px;
opacity: 1;
border-radius: 4px;
background: rgba(67, 136, 251, 1);
border: rgba(67, 136, 251, 1);
font-size: 14px;
font-weight: 400;
color: rgba(255, 255, 255, 1);
}
}
// 表格
.custom-table {
border-collapse: collapse;
width: 416px;
height: 60px;
color: rgba(255, 255, 255, 1);
}
.custom-table th,
.custom-table td {
border: 1px solid rgba(163, 192, 243, 1);
text-align: left;
padding: 8px;
text-align: center;
}
.table1 {
margin-top: 20px;
width: 100%;
border: 1px solid rgba(255, 255, 255);
border-radius: 5px;
background: rgba(255, 255, 255, 0.1);
.tabReboot,
.tabDelete {
border: none;
background-color: rgba(0, 0, 0, 0);
font-size: 14px;
font-weight: 400;
letter-spacing: 0;
line-height: 20px;
color: rgba(67, 136, 251, 1);
}
.tabReboot {
margin-right: 8px;
}
.isTrIndex {
background: rgba(67, 136, 251, 1);
}
}
::v-deep(.ant-transfer) {
// 屏蔽自带的hover效果
.ant-transfer-list-content-item:hover {
background: black;
}
}
</style>

View File

@@ -1,38 +1,46 @@
import { NsSelect } from './../../../../../lib/component/form/select/index';
import { dateUtil } from '/nerv-lib/util/date-util';
import data from './mock.json';
import { http } from '/nerv-lib/util';
import { ref } from 'vue';
import { group } from '/@/api/deviceManage';
import { device, group } from '/@/api/deviceManage';
import { dict } from '/@/api';
import { origanizemanage } from '/@/api/origanizemanage';
const tableCalKeyMap = [
{
title: '来源企业',
dataIndex: 'orgName',
// textEllipsis: true,
// textNumber: 4,
dataIndex: 'linkOrgName',
textEllipsis: true,
textNumber: 10,
},
{
title: '设备id',
textNumber: 10,
dataIndex: 'deviceCode',
},
{
title: '设备编号',
dataIndex: 'deviceName',
textNumber: 8,
textEllipsis: true,
},
{
title: '设备编号',
dataIndex: 'deviceNum',
textNumber: 10,
},
{
textNumber: 10,
title: '分组名称',
dataIndex: 'position',
dataIndex: 'groupName',
},
{
title: '设备品牌/型号',
dataIndex: 'position',
textNumber: 10,
dataIndex: 'deviceNameType',
},
{
textNumber: 10,
title: '设备状态',
dataIndex: 'position',
dataIndex: 'deviceStatus',
customRender: ({ value }) => {
return value === '0' ? '启用' : '停用';
},
},
];
const tableKeyMap = [
@@ -59,7 +67,6 @@ const doWnload = (url) => {
a.click();
};
const mockData = ref(data.listData);
export const formSchema = [
{
field: 'isCreate',
@@ -116,7 +123,7 @@ export const formSchema = [
immediate: true,
// resultField: 'data.COUNT_POINT',
labelField: 'cnValue',
valueField: 'cnValue',
valueField: 'dicKey',
},
rules: [
{
@@ -146,6 +153,26 @@ export const editTreeConfig = (orgId) => ({
],
},
});
export const editCalTreeConfig = (orgId) => ({
selectedKeys: ['0-0'],
defaultExpandAll: true,
api: group.queryEditCompute,
params: { orgId },
resultField: 'data.orgInfos',
fieldNames: { title: 'orgName', key: 'orgId' },
formConfig: {
schemas: [
{
field: 'orgName',
component: 'NsInput',
autoSubmit: true,
componentProps: {
placeholder: '请输入企业名称',
},
},
],
},
});
export const treeConfig = (orgId) => {
return {
defaultExpandAll: true,
@@ -172,7 +199,7 @@ export const treeConfig = (orgId) => {
immediate: true,
// resultField: 'data.ENERGY_TYPE',
labelField: 'cnValue',
valueField: 'cnValue',
valueField: 'dicKey',
placeholder: '请选择能耗种类',
autoSelectFirst: true,
},
@@ -200,6 +227,7 @@ export const tableConfig = (el, elGroup, elFormula, defaultParams) => {
label: '编辑',
name: 'groupEdit',
type: 'primary',
dynamicDisabled: () => !defaultParams.value?.id,
handle: (a, b) => {
el.value.toggle();
},
@@ -211,9 +239,131 @@ export const tableConfig = (el, elGroup, elFormula, defaultParams) => {
dynamicDisabled: (data: any) => {
return data.list.length === 0;
},
handle: () => {
mockData.value.splice(0, 2);
dynamicParams: { linkIds: 'linkId[]' },
confirm: true,
isClearCheck: true,
isReload: true,
api: group.delGroupList,
},
{
label: '批量导出',
name: 'groupExports',
type: 'primary',
dynamicDisabled: (data: any) => {
return data.list.length === 0;
},
extra: {
xlsxMap: tableKeyMap,
xlsxName: '分组信息YYYY-MM-DD',
},
},
{
label: '批量导入',
name: 'groupImport',
type: 'primary',
extra: {
// api: props.postImportApi, // 导入接口名
title: '设备信息', // 弹窗title
templateName: 'whiteListUser', // 所使用的文件名称
indexName: '设备id', // 匹配类型字段
message: [
{ label: '1、若必填项未填写则不能进行导入操作' },
{ label: `2、当重复时则更新数据。` },
{ label: '3、数据将从模版的第五行进行导入。' },
{ label: '4、文件导入勿超过5MB。' },
],
},
},
{
label: '模板下载',
name: 'groupTemDownload',
type: 'primary',
handle: () => {
// http.get('/asset/file/whiteListUser.xlsx');
doWnload('/hx-ai-intelligent/asset/file/whiteListUser.xlsx');
},
},
],
columns: tableKeyMap,
columnActions: {
title: '操作',
actions: [
{
label: '删除',
name: 'groupDelete',
dynamicParams: { linkIds: 'linkId[]' },
confirm: true,
isClearCheck: true,
isReload: true,
api: group.delGroupList,
},
],
},
formConfig: {
schemas: [
{
field: 'orgName',
component: 'NsSelectApi',
defaultParams: defaultParams.value,
componentProps: {
placeholder: '请选择公司',
mode: 'multiple',
api: group.dropGroupFilter,
resultField: 'data',
params: { filterField: 'ORG' },
labelField: 'orgName',
valueField: 'orgId',
filterOption: (input: string, option: any) => {
return option.deviceName.toLowerCase().indexOf(input.toLowerCase()) >= 0;
},
showSearch: true,
dropdownReload: true,
allowClear: true,
},
},
{
field: 'pointNum',
component: 'NsInput',
componentProps: {
placeholder: '请输入节点编号',
},
},
],
},
// pagination: { pageSizeOptions: false },
rowKey: 'id',
};
};
export const tableConfigCal = (el, elGroup, elFormula, defaultParams) => {
// 计算节点
return {
title: '点位信息',
api: group.queryGroupInfoPage,
params: defaultParams.value,
headerActions: [
{
label: '编辑',
name: 'groupEdit',
type: 'primary',
handle: (a, b) => {
el.value.toggle();
},
},
{
label: '批量删除',
name: 'groupTemDownload',
type: 'primary',
dynamicDisabled: (data: any) => {
return data.list.length === 0;
},
dynamicParams: { ids: 'id[]' },
confirm: true,
isReload: true,
isClearCheck: true,
api: group.delComputeList,
},
{
label: '批量导出',
@@ -259,7 +409,13 @@ export const tableConfig = (el, elGroup, elFormula, defaultParams) => {
label: '批量分组',
name: 'groupBatGroup',
type: 'primary',
handle: () => {
dynamicDisabled: (data: any) => {
return data.list.length === 0;
},
handle: ({ list }) => {
const ids = list.map(({ id }) => id);
defaultParams.value['saveDeviceInfoIds'] = ids;
elGroup.value.toggle();
},
},
@@ -272,156 +428,7 @@ export const tableConfig = (el, elGroup, elFormula, defaultParams) => {
},
},
],
columns: tableKeyMap,
columnActions: {
title: '操作',
actions: [
{
label: '删除',
name: 'groupDelete',
dynamicParams: ['uuid', 'appealType'],
confirm: true,
handle: () => {
mockData.value.splice(0, 1);
},
},
],
},
formConfig: {
schemas: [
{
field: 'name',
label: '设备名称',
component: 'NsInput',
componentProps: {
placeholder: '请输入',
},
},
{
field: 'provider',
label: '设备厂商',
component: 'NsInput',
componentProps: {
placeholder: '请输入',
},
},
{
field: 'payWay',
label: '设备区域',
component: 'NsSelect',
componentProps: {
placeholder: '请选择',
options: [
{
label: '全部',
value: '',
},
],
},
},
{
field: 'createTime',
label: '生产日期',
component: 'NsRangePicker',
fieldMap: ['queryStartDate', 'queryEndDate'],
componentProps: {
valueFormat: 'YYYY-MM-DD',
},
},
{
field: 'createTime1',
label: '采购日期',
component: 'NsRangePicker',
fieldMap: ['queryStartDate', 'queryEndDate'],
componentProps: {
valueFormat: 'YYYY-MM-DD',
},
},
{
field: 'createTime2',
label: '启用日期',
component: 'NsRangePicker',
fieldMap: ['queryStartDate', 'queryEndDate'],
componentProps: {
valueFormat: 'YYYY-MM-DD',
},
},
],
},
// pagination: { pageSizeOptions: false },
rowKey: 'id',
};
};
export const tableConfigCal = (el, elGroup, elFormula, defaultParams) => {
// 分组节点
return {
title: '点位信息',
// api: '/carbon_emission/device/getDeviceList',
value: mockData.value,
params: defaultParams,
headerActions: [
{
label: '编辑',
name: 'groupEdit',
type: 'primary',
handle: (a, b) => {
el.value.toggle();
},
},
{
label: '批量删除',
name: 'groupTemDownload',
type: 'primary',
dynamicDisabled: (data: any) => {
return data.list.length === 0;
},
handle: () => {
mockData.value.splice(0, 2);
},
},
{
label: '批量导出',
name: 'groupExports',
type: 'primary',
dynamicDisabled: (data: any) => {
return data.list.length === 0;
},
extra: {
xlsxMap: tableKeyMap,
xlsxName: '分组信息YYYY-MM-DD',
},
},
{
label: '批量导入',
name: 'groupImport',
type: 'primary',
extra: {
// api: props.postImportApi, // 导入接口名
title: '设备信息', // 弹窗title
templateName: 'whiteListUser', // 所使用的文件名称
indexName: '设备id', // 匹配类型字段
message: [
{ label: '1、若必填项未填写则不能进行导入操作' },
{ label: `2、当重复时则更新数据。` },
{ label: '3、数据将从模版的第五行进行导入。' },
{ label: '4、文件导入勿超过5MB。' },
],
},
},
{
label: '模板下载',
name: 'groupTemDownload',
type: 'primary',
handle: () => {
// http.get('/asset/file/whiteListUser.xlsx');
doWnload('/hx-ai-intelligent/asset/file/whiteListUser.xlsx');
},
},
],
scroll: { x: 1400 },
columns: tableCalKeyMap,
columnActions: {
title: '操作',
@@ -429,11 +436,11 @@ export const tableConfigCal = (el, elGroup, elFormula, defaultParams) => {
{
label: '删除',
name: 'groupDelete',
dynamicParams: 'id',
dynamicParams: { ids: 'id[]' },
confirm: true,
isReload: true,
isClearCheck: true,
api: group.delGroupList,
api: group.delComputeList,
},
],
},
@@ -441,18 +448,80 @@ export const tableConfigCal = (el, elGroup, elFormula, defaultParams) => {
formConfig: {
schemas: [
{
field: 'name',
label: '设备名称',
component: 'NsInput',
field: 'orgIds',
component: 'NsSelectApi',
defaultParams: defaultParams.value,
componentProps: {
placeholder: '请选择公司',
mode: 'multiple',
api: group.dropGroupInfoFilter,
resultField: 'data',
params: { filterField: 'ORG' },
labelField: 'orgName',
valueField: 'orgId',
filterOption: (input: string, option: any) => {
return option.deviceName.toLowerCase().indexOf(input.toLowerCase()) >= 0;
},
showSearch: true,
dropdownReload: true,
allowClear: true,
},
},
{
field: 'deviceCode',
component: 'NsInput',
componentProps: {
placeholder: '请输入设备id',
},
},
{
field: 'deviceNum',
component: 'NsInput',
componentProps: {
placeholder: '请输入设备编号',
},
},
{
field: 'deviceStatus',
component: 'NsSelectApi',
componentProps: {
placeholder: '请选择设备状态',
api: () => dict({ params: { dicKey: 'DEVICE_STATUS' } }),
immediate: true,
labelField: 'cnValue',
valueField: 'dicKey',
},
},
{
field: 'deviceNameType',
component: 'NsSelectApi',
defaultParams: defaultParams.value,
componentProps: {
placeholder: '请选择设备型号',
api: (params: any) => {
return http.post(group.dropGroupInfoFilter, params).then((res: any) => {
const result = [...new Set(res.data)];
return { data: result };
});
},
resultField: 'data',
params: { filterField: 'DEVICE_TYPE' },
// labelField: 'orgName',
// valueField: 'orgId',
filterOption: (input: string, option: any) => {
return option.deviceName.toLowerCase().indexOf(input.toLowerCase()) >= 0;
},
showSearch: true,
dropdownReload: true,
allowClear: true,
},
},
{
field: 'provider',
component: 'NsInput',
componentProps: {
placeholder: '请输入节点编号',
placeholder: '请输入分组名称',
},
},
],

View File

@@ -14,12 +14,10 @@
v-model:target-keys="targetKeys"
:data-source="dataSource"
style="height: 100%; width: 66%"
oneWay
:listStyle="listStyle"
show-search
:render="(item) => item.title"
:filter-option="filterOption"
@change="handleChange" />
:filter-option="filterOption" />
</div>
</ns-drawer>
</template>
@@ -29,12 +27,13 @@
import { editTreeConfig } from './config';
import { group } from '/@/api/deviceManage';
import { http } from '/nerv-lib/util/http';
const emit = defineEmits(['sure']);
const props = defineProps({ params: Object });
const result = JSON.parse(sessionStorage.getItem('ORGID')!);
const config = computed(() => {
return editTreeConfig(result);
});
const visible = ref(true);
const visible = ref(false);
const dataSource = ref([]);
const listStyle = {
height: '100%',
@@ -42,13 +41,16 @@
};
const targetKeys = ref([]);
const currentId = ref('');
const clearData = () => {
dataSource.value = [];
targetKeys.value = [];
currentId.value = '';
};
const toggle = () => {
visible.value = !visible.value;
};
const handleChange = (nextTargetKeys: string[], direction: string, moveKeys: string[]) => {
console.log('targetKeys: ', nextTargetKeys);
console.log('direction: ', direction);
console.log('moveKeys: ', moveKeys);
clearData();
visible.value && getData(currentId.value);
};
const filterOption = (inputValue: string, option: any) => {
@@ -57,7 +59,10 @@
const btnClick = () => {
// visible.value = false;
if (!currentId.value) {
NsMessage.warn('请先选择公司');
return;
}
http
.post(group.saveGroupList, {
...props.params,
@@ -65,7 +70,9 @@
saveGroupIds: targetKeys.value,
})
.then(() => {
emit('sure');
NsMessage.success('操作成功');
toggle();
});
};
function treeSelect(
@@ -98,8 +105,8 @@
item['key'] = item.id.toString();
return item;
});
targetKeys.value = res.data.linkGroups.map((item) => {
return item.id;
targetKeys.value = res.data.linkGroups?.map((item) => {
return item.id.toString();
});
});
};

View File

@@ -0,0 +1,126 @@
<template>
<ns-drawer
v-model:visible="visible"
:width="800"
class="custom-class"
title=" "
destroyOnClose
:ok="btnClick"
:cancel="() => (visible = false)"
placement="right">
<div class="drawerContainer">
<ns-tree-api v-bind="config" @select="treeSelect" />
<a-transfer
v-model:target-keys="targetKeys"
:data-source="dataSource"
style="height: 100%; width: 66%"
:listStyle="listStyle"
show-search
:render="(item) => item.title"
:filter-option="filterOption" />
</div>
</ns-drawer>
</template>
<script lang="ts" setup>
import { computed, onMounted, ref } from 'vue';
import { NsMessage } from '/nerv-lib/component';
import { editCalTreeConfig } from './config';
import { group } from '/@/api/deviceManage';
import { http } from '/nerv-lib/util/http';
const emit = defineEmits(['sure']);
const props = defineProps({ params: Object });
const result = JSON.parse(sessionStorage.getItem('ORGID')!);
const config = computed(() => {
return editCalTreeConfig(result);
});
const visible = ref(false);
const dataSource = ref([]);
const listStyle = {
height: '100%',
width: '100%',
};
const targetKeys = ref([]);
const currentId = ref('');
const clearData = () => {
dataSource.value = [];
targetKeys.value = [];
currentId.value = '';
};
const toggle = () => {
visible.value = !visible.value;
clearData();
visible.value && getData(currentId.value);
};
onMounted(() => {});
const filterOption = (inputValue: string, option: any) => {
return option?.title.toLowerCase().indexOf(inputValue.toLowerCase()) > -1;
};
const btnClick = () => {
if (!currentId.value) {
NsMessage.warn('请先选择公司');
return;
}
http
.post(group.saveComputeList, {
...props.params,
groupListId: props.params?.id,
saveOrgId: currentId.value,
saveDeviceInfoIds: targetKeys.value,
})
.then(() => {
emit('sure');
NsMessage.success('操作成功');
toggle();
});
};
function treeSelect(
selectedKeys: never[],
e: {
selected: boolean;
selectedNodes: { props: { dataRef: any } }[];
node: any;
event: any;
},
) {
console.log(selectedKeys, e);
const {
dataRef: { title },
} = e.node;
currentId.value = selectedKeys[0];
getData(currentId.value);
}
const getData = (id) => {
http
.post(group.queryEditCompute, {
orgId: result,
queryOrgId: id,
...props.params,
// energyType: props.params.energyType,
})
.then((res) => {
dataSource.value = res.data.deviceInfos?.map((item) => {
item['title'] = item.deviceName;
item['key'] = item.id.toString();
return item;
});
targetKeys.value = res.data.linkDeviceInfos?.map((item) => {
return item.id.toString();
});
});
};
defineExpose({
toggle,
});
</script>
<style scoped lang="less">
.drawerContainer {
height: 100%;
display: flex;
justify-content: space-between;
}
</style>

View File

@@ -2,34 +2,72 @@
<ns-drawer
v-model:visible="visible"
width="520"
title="公式编辑"
title=" "
:ok="btnClick"
:cancel="() => (visible = false)"
placement="right">
<ns-form :schemas="schemas" :model="model" formLayout="vertical" />
<div
style="
font-size: 16px;
font-weight: bold;
line-height: 24px;
padding: 16px 0;
padding-top: 0;
">
分组列表
</div>
<NsBasicTable v-model:dataSource="mockDataSource" v-bind="basicTableConfig" />
</ns-drawer>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { NsMessage } from '/nerv-lib/component';
import { group } from '/@/api/deviceManage';
import { http } from '/nerv-lib/util/http';
const emit = defineEmits(['sure']);
const props = defineProps({ params: Object });
const visible = ref(false);
const model = ref({});
const toggle = () => {
visible.value = !visible.value;
visible.value && getTableData();
visible.value && getFormula();
};
const mockDataSource = ref([
{
groupName: '1号厂区',
},
{
groupName: '2号厂区',
},
{
groupName: '3号厂区',
},
]);
const mockDataSource = ref([]);
const getFormula = () => {
http.post(group.queryFormula, props.params).then((res) => {
model.value.formula = res.data;
});
};
const getTableData = () => {
http.post(group.queryComputeGroup, props.params).then((res) => {
mockDataSource.value = res.data;
});
};
const basicTableConfig = ref({
bordered: true,
placeholder: '请输入',
pagination: false,
rowKey: (record) => record.id,
columns: [
{
title: '分组编号',
dataIndex: 'groupNum',
// customRender: ({ index }) => index + 1,
width: 80,
align: 'center',
},
{
title: '分组名称',
dataIndex: 'groupName',
align: 'center',
},
],
});
const schemas = [
{
field: 'basicInfo',
@@ -44,7 +82,6 @@
label: '',
field: 'formula',
component: 'NsTextarea',
defaultValue: '(A+B)*2',
formItemProps: {
wrapperCol: { span: 24 },
},
@@ -59,52 +96,64 @@
],
},
},
{
field: 'list',
label: '',
displayFormItem: false,
class: 'ns-form-item-full',
component: 'NsChildForm',
componentProps: {
title: '分组列表',
schemas: [
{
label: '',
field: 'NsBasicTable',
component: 'NsBasicTable',
formItemProps: {
wrapperCol: { span: 24 },
},
componentProps: {
disabled: true,
placeholder: '请输入',
dataSource: mockDataSource.value,
pagination: false,
rowKey: (record) => record.groupName,
columns: [
{
title: '序号',
dataIndex: 'name',
customRender: ({ index }) => index + 1,
width: 80,
align: 'center',
},
{
title: '分组名称',
dataIndex: 'groupName',
align: 'center',
},
],
},
},
],
},
},
// {
// field: 'list',
// label: '',
// displayFormItem: false,
// class: 'ns-form-item-full',
// component: 'NsChildForm',
// componentProps: {
// title: '分组列表',
// schemas: [
// {
// label: '',
// field: 'NsBasicTable',
// component: 'NsBasicTable',
// formItemProps: {
// wrapperCol: { span: 24 },
// },
// componentProps: {
// disabled: true,
// placeholder: '请输入',
// dataSource: mockDataSource.value,
// pagination: false,
// rowKey: (record) => record.groupName,
// columns: [
// {
// title: '序号',
// dataIndex: 'name',
// customRender: ({ index }) => index + 1,
// width: 80,
// align: 'center',
// },
// {
// title: '分组名称',
// dataIndex: 'groupName',
// align: 'center',
// },
// ],
// },
// },
// ],
// },
// },
];
const btnClick = () => {
visible.value = false;
NsMessage.success('操作成功');
if (!model.value?.formula) {
NsMessage.warn('请填写公式');
return;
}
http
.post(group.formula, {
...props.params,
...model.value,
})
.then(() => {
emit('sure');
toggle();
NsMessage.success('操作成功');
});
};
defineExpose({

View File

@@ -2,136 +2,285 @@
<ns-drawer
v-model:visible="visible"
width="520"
title="分组编辑"
title=" "
:ok="btnClick"
:cancel="() => (visible = false)"
placement="right">
<ns-form :schemas="schemas" :model="model" formLayout="vertical" />
<ns-form
ref="editGroupRef"
:schemas="schemas(inputDisabled)"
:model="model"
formLayout="vertical"
:wrapperCol="{ span: 20 }"
:labelCol="{ span: 4 }">
<template #addonAfter="data">
<template v-if="data.field === 'groupName'">
<div class="iconOP">
<EditOutlined title="编辑" v-if="inputDisabled" @click="editGroup" />
<CheckOutlined title="保存" v-else @click="add" />
</div>
</template>
</template>
</ns-form>
<div
style="
font-size: 16px;
font-weight: bold;
line-height: 24px;
padding: 16px 0;
padding-top: 0;
">
分组列表
<ns-button style="margin-left: 10px" type="primary" @click="addGroup">新增</ns-button>
</div>
<NsBasicTable
v-model:dataSource="mockDataSource"
v-bind="basicTableConfig"
:rowSelection="{
type: 'radio',
onChange: rowSelectChange,
selectedRowKeys,
}" />
</ns-drawer>
</template>
<script lang="ts" setup>
import { createVNode, onMounted, ref, unref } from 'vue';
import { NsMessage } from '/nerv-lib/component';
import { DeleteOutlined } from '@ant-design/icons-vue';
import { group } from '/@/api/deviceManage';
import { http } from '/nerv-lib/util/http';
import { EditOutlined, CheckOutlined } from '@ant-design/icons-vue';
import { Popconfirm } from 'ant-design-vue';
const emit = defineEmits(['sure']);
const props = defineProps({ params: Object });
const visible = ref(false);
const editGroupRef = ref();
const model = ref({});
const inputDisabled = ref(true);
const selectedRowKeys = ref([]);
let opType = true; // true新增false编辑
const toggle = () => {
visible.value = !visible.value;
visible.value && getTableData();
};
const deleteRow = (index) => {
console.log(index);
mockDataSource.value.splice(index, 1);
const startCararcter = 65;
// 点击新增按钮新增分组
const addGroup = () => {
opType = true;
getCode();
const code = startCararcter + mockDataSource.value?.length;
inputDisabled.value = false;
model.value = { groupName: '' };
// if(mockDataSource.value.length)
};
const addRow = () => {
console.log(model);
if (model.value?.groupName) mockDataSource.value.push(unref(model) as any);
const op = () => {
inputDisabled.value = !inputDisabled.value;
};
const mockDataSource = ref([
{
groupName: '1号厂区',
},
{
groupName: '2号厂区',
},
{
groupName: '3号厂区',
},
]);
const schemas = [
{
field: 'basicInfo',
label: '',
displayFormItem: false,
class: 'ns-form-item-full',
component: 'NsChildForm',
componentProps: {
title: '分组信息',
schemas: [
{
label: '分组编号',
field: 'groupCode',
component: 'NsInput',
defaultValue: 'WDIFHSUNGNDOR',
componentProps: {
disabled: true,
placeholder: '请输入',
},
},
{
label: '分组名称',
field: 'groupName',
component: 'NsInput',
componentProps: {
placeholder: '请输入',
addonAfter: createVNode(
'div',
{ style: { cursor: 'pointer' }, onclick: addRow },
'新增',
),
},
rules: [{ required: true }],
},
],
const clearData = () => {
model.value = {};
selectedRowKeys.value = [];
};
const editGroup = () => {
if (!selectedRowKeys.value?.length) {
NsMessage.warn('请先选择需要编辑的分组');
return;
}
inputDisabled.value = false;
};
//点击对钩按钮处理保存逻辑
const add = () => {
const finalParams = { ...props.params, ...model.value };
if (opType) {
delete finalParams.id;
}
editGroupRef.value.triggerSubmit().then(() => {
http.post(group.saveComputeGroup, finalParams).then(() => {
getTableData();
NsMessage.success('操作成功');
op();
});
});
};
const delGroup = (id) => {
http.post(group.delComputeGroup, { id }).then(() => {
getTableData();
NsMessage.success('操作成功');
clearData();
});
};
const rowSelectChange = (selected, selectedRows) => {
opType = false;
console.log(selectedRowKeys, selectedRows);
selectedRowKeys.value = selected;
model.value = { ...selectedRows[0] };
};
const mockDataSource = ref([]);
const getTableData = () => {
http.post(group.queryComputeGroup, props.params).then((res) => {
mockDataSource.value = res.data;
});
};
const getCode = () => {
http.post(group.computeGroupNum, props.params).then((res) => {
model.value.groupNum = res.data;
});
};
const basicTableConfig = ref({
bordered: true,
placeholder: '请输入',
pagination: false,
rowKey: (record) => record.id,
columns: [
{
title: '分组编号',
dataIndex: 'groupNum',
// customRender: ({ index }) => index + 1,
width: 80,
align: 'center',
},
},
{
field: 'list',
label: '',
displayFormItem: false,
class: 'ns-form-item-full',
component: 'NsChildForm',
componentProps: {
title: '分组列表',
schemas: [
{
label: '',
field: 'NsBasicTable',
component: 'NsBasicTable',
formItemProps: {
wrapperCol: { span: 24 },
},
componentProps: {
disabled: true,
placeholder: '请输入',
dataSource: mockDataSource.value,
rowSelection: { type: 'radio' },
pagination: false,
rowKey: (record) => record.groupName,
columns: [
{
title: '序号',
dataIndex: 'name',
customRender: ({ index }) => index + 1,
width: 80,
align: 'center',
},
{
title: '分组名称',
dataIndex: 'groupName',
align: 'center',
},
{
title: '删除',
dataIndex: 'delete',
width: 80,
align: 'center',
customRender: ({ index }) =>
createVNode(DeleteOutlined, {
style: { color: 'red', cursor: 'pointer' },
onClick: () => deleteRow(index),
}),
},
],
},
},
],
{
title: '分组名称',
dataIndex: 'groupName',
align: 'center',
},
},
];
{
title: '删除',
dataIndex: 'delete',
width: 80,
align: 'center',
customRender: ({ record }) =>
createVNode(
Popconfirm,
{ title: '确定删除吗?', placement: 'leftTop', onConfirm: () => delGroup(record.id) },
() => [
createVNode(DeleteOutlined, {
style: { color: 'red', cursor: 'pointer' },
title: '删除',
// onClick: () => delGroup(record.id),
}),
],
),
},
],
});
const schemas = (val) => {
return [
{
field: 'basicInfo',
label: '',
displayFormItem: false,
class: 'ns-form-item-full',
component: 'NsChildForm',
componentProps: {
title: '分组信息',
schemas: [
{
label: '分组id',
field: 'id',
component: 'NsInput',
show: false,
},
{
label: '分组编号',
field: 'groupNum',
component: 'NsInput',
componentProps: {
disabled: true,
placeholder: '请输入',
},
},
{
label: '分组名称',
field: 'groupName',
component: 'NsInput',
componentProps: {
placeholder: '请输入',
disabled: val,
},
rules: [{ required: true }],
},
],
},
},
// {
// field: 'list',
// label: '',
// displayFormItem: false,
// class: 'ns-form-item-full',
// component: 'NsChildForm',
// componentProps: {
// title: '分组列表',
// schemas: [
// {
// label: '',
// field: 'NsBasicTable',
// component: 'NsBasicTable',
// formItemProps: {
// wrapperCol: { span: 24 },
// },
// componentProps: {
// bordered: true,
// disabled: true,
// placeholder: '请输入',
// dataSource: mockDataSource.value,
// rowSelection: { type: 'radio', onChange: rowSelectChange },
// pagination: false,
// rowKey: (record) => record.groupName,
// columns: [
// {
// title: '序号',
// dataIndex: 'name',
// customRender: ({ index }) => index + 1,
// width: 80,
// align: 'center',
// },
// {
// title: '分组名称',
// dataIndex: 'groupName',
// align: 'center',
// },
// {
// title: '删除',
// dataIndex: 'delete',
// width: 80,
// align: 'center',
// customRender: ({ index }) =>
// createVNode(DeleteOutlined, {
// style: { color: 'red', cursor: 'pointer' },
// onClick: () => deleteRow(index),
// }),
// },
// ],
// },
// },
// ],
// },
// },
];
};
const btnClick = () => {
visible.value = false;
NsMessage.success('操作成功');
if (!selectedRowKeys.value[0]) {
NsMessage.warn('请选择分组');
return;
}
http
.post(group.saveComputeGroupInfo, {
...props.params,
groupListId: selectedRowKeys.value[0],
})
.then(() => {
emit('sure');
toggle();
NsMessage.success('操作成功');
});
};
defineExpose({
@@ -144,4 +293,8 @@
display: flex;
justify-content: space-between;
}
.iconOP {
cursor: pointer;
color: @primary-color;
}
</style>

View File

@@ -1,11 +1,9 @@
<template>
<editDrawer ref="editDrawerRef" :params="defaultParams" />
<editGroup ref="editGroupRef" />
<editFormula ref="editFormulaRef" />
<!-- <ns-modal ref="modalRef" title="新增" v-model:visible="visible">
<ns-form ref="formRef" :schemas="formSchema" :model="formData" formLayout="formVertical" />
</ns-modal> -->
<!-- 分组编辑按钮 -->
<editDrawer ref="editDrawerRef" :params="defaultParams" @sure="handleOk" />
<editCalDrawer ref="editDrawerCalRef" :params="defaultParams" @sure="handleOk" />
<editGroup ref="editGroupRef" :params="defaultParams" @sure="handleOk" />
<editFormula ref="editFormulaRef" :params="defaultParams" @sure="handleOk" />
<NsModalFrom ref="modalFormRef" v-bind="nsModalFormConfig" />
<div class="groupContainer">
@@ -14,7 +12,14 @@
<template #title="data">
<div class="treeRow">
<div>
<ns-icon :name="data.pointType !== '计算节点' ? 'fenzujiedian' : 'jisuanjiedian'" />
<ns-icon
:name="
data?.id === 'all'
? 'common'
: data.pointType === 'GROUPING_NODE'
? 'fenzujiedian'
: 'jisuanjiedian'
" />
<span style="padding-left: 8px">{{ data.pointName }}</span>
</div>
<a-dropdown>
@@ -22,7 +27,6 @@
<template #overlay>
<a-menu>
<template v-for="(item, index) in filterAction(actionList, data)" :key="index">
<!-- 全部节点只需要新增子节点 -->
<a-menu-item @click="item.func(data)">
<span>{{ item.title }}</span>
</a-menu-item>
@@ -34,8 +38,8 @@
</template>
</ns-tree-api>
</div>
<ns-view-list-table v-if="defaultType" class="table" v-bind="config" ref="tableRef" />
<ns-view-list-table v-else class="table" v-bind="configCal" ref="tableCalRef" />
<ns-view-list-table v-show="defaultType" class="table" v-bind="config" ref="tableRef" />
<ns-view-list-table v-show="!defaultType" class="table" v-bind="configCal" ref="tableCalRef" />
</div>
</template>
<script lang="ts" setup>
@@ -43,6 +47,7 @@
import { tableConfig, treeConfig, tableConfigCal, formSchema } from './config';
import { useParams } from '/nerv-lib/use';
import editDrawer from './edit.vue';
import editCalDrawer from './editCal.vue';
import editGroup from './editGroup.vue';
import editFormula from './editFormula.vue';
import { NsMessage, NsModal } from '/nerv-lib/component';
@@ -56,15 +61,21 @@
const tableRef = ref();
const tableCalRef = ref();
const editDrawerRef = ref();
const editDrawerCalRef = ref();
const editGroupRef = ref();
const editFormulaRef = ref();
const treeRef = ref();
const defaultType = ref(true);
const result = JSON.parse(sessionStorage.getItem('ORGID')!);
const defaultParams = ref({ orgId: result, energyType: '用电量', id: 19 });
const defaultParams = ref({
orgId: result,
energyType: 'ELECTRICITY_USAGE',
id: '',
hxDeviceGroupId: '',
});
const config = tableConfig(editDrawerRef, editGroupRef, editFormulaRef, defaultParams);
const configCal = tableConfigCal(editDrawerRef, editGroupRef, editFormulaRef, defaultParams);
const configCal = tableConfigCal(editDrawerCalRef, editGroupRef, editFormulaRef, defaultParams);
const tConfig = treeConfig(result);
const nsModalFormConfig = ref({
api: group.creatOrUpdate,
@@ -155,13 +166,22 @@
{ title: '删除', key: 'deleteNode', func: (data) => deleteNode(data) },
];
const handleSelect = (key, record) => {
console.log(record);
//清除选中行数据
tableRef.value?.nsTableRef.clearCheck();
tableCalRef.value?.nsTableRef.clearCheck();
const {
node: { pointType, id, energyType },
} = record;
defaultParams.value.energyType = energyType;
defaultParams.value.id = id;
defaultType.value = pointType === '分组节点';
defaultParams.value.hxDeviceGroupId = id;
defaultType.value = pointType === 'GROUPING_NODE';
defaultType.value
? tableRef.value?.nsTableRef.reload()
: tableCalRef.value?.nsTableRef.reload();
};
const handleOk = () => {
defaultType.value
? tableRef.value?.nsTableRef.reload()
: tableCalRef.value?.nsTableRef.reload();
@@ -205,9 +225,16 @@
}
}
.treeRow {
.common-style {
display: flex;
justify-content: space-between;
align-items: center;
}
.treeRow {
.common-style;
> div:first-child {
.common-style;
}
}
</style>

View File

@@ -1,121 +0,0 @@
{
"data":[
{
"title": "1号楼",
"key": "A001",
"children": [
{
"title": "1号楼空调用电",
"key": "A002"
},
{
"title": "1号楼照明用电",
"key": "A003"
}
]
},
{
"title": "2号楼(A005)",
"key": "A004",
"children": [
{
"title": "2号楼空调用电(A007)",
"key": "A006"
}
]
},
{
"title": "3号楼",
"key": "A008",
"children": [
{
"title": "3号楼空调用电",
"key": "A009"
},
{
"title": "3号楼照明用电",
"key": "A010"
}
]
}
],
"insertData":[
{
"title": "北京公司",
"key": "A001"
},
{
"title": "广州公司",
"key": "A002"
},
{
"title": "南京公司",
"key": "A004"
},
{
"title": "上海公司",
"key": "A008",
"children": [
{
"title": "上海长宁",
"key": "A009"
},
{
"title": "上海徐汇",
"key": "A010"
},
{
"title": "上海浦东",
"key": "A011"
}
]
}
],
"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 commodo",
"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
}
]
}

View File

@@ -138,9 +138,29 @@ export const tableConfig = (orgId) => {
{
field: 'deviceName',
label: '设备名称',
component: 'NsInput',
component: 'NsSelectApi',
componentProps: {
placeholder: '请输入设备名称',
placeholder: '请选择设备名称',
api: (params) => {
return http.post(device.dropArea, params).then((res) => {
const result = res.data?.reduce((pre, cur) => {
!pre.includes(cur.deviceName) && pre.push(cur.deviceName);
return pre;
}, []);
return { data: result };
});
},
resultField: 'data',
params: { orgId, filterField: 'DEVICE_NAME_FACTORY' },
// labelField: 'deviceName',
// valueField: 'deviceName',
filterOption: (input: string, option: any) => {
return option.deviceName.toLowerCase().indexOf(input.toLowerCase()) >= 0;
},
showSearch: true,
immediate: true,
dropdownReload: true,
allowClear: true,
},
},
{
@@ -166,7 +186,7 @@ export const tableConfig = (orgId) => {
loadData: (selectedOptions, options) => {
const targetOption = selectedOptions[selectedOptions.length - 1];
if (!selectedOptions.length) {
http.post(device.dropArea, { orgId }).then((res) => {
http.post(device.dropArea, { orgId, filterField: 'DEVICE_AREA' }).then((res) => {
options.value = res.data?.map((item) => {
return { label: item, value: item, children: [], isLeaf: false };
});
@@ -175,12 +195,14 @@ export const tableConfig = (orgId) => {
const value = targetOption?.value;
if (targetOption) {
targetOption.loading = true;
http.post(device.dropArea, { device1Area: value, orgId }).then((res) => {
targetOption.loading = false;
targetOption.children = res.data?.map((item) => {
return { label: item, value: item, children: [], isLeaf: true };
http
.post(device.dropArea, { device1Area: value, orgId, filterField: 'DEVICE_AREA' })
.then((res) => {
targetOption.loading = false;
targetOption.children = res.data?.map((item) => {
return { label: item, value: item, children: [], isLeaf: true };
});
});
});
}
},
},
@@ -188,15 +210,29 @@ export const tableConfig = (orgId) => {
{
field: 'manufacturer',
label: '设备厂商',
component: 'NsInput',
component: 'NsSelectApi',
componentProps: {
placeholder: '请输入设备厂商',
options: [
{
label: '全部',
value: '',
},
],
placeholder: '请选择设备厂商',
api: (params) => {
return http.post(device.dropArea, params).then((res) => {
const result = res.data?.reduce((pre, cur) => {
!pre.includes(cur.manufacturer) && pre.push(cur.manufacturer);
return pre;
}, []);
return { data: result };
});
},
resultField: 'data',
params: { orgId, filterField: 'DEVICE_NAME_FACTORY' },
// labelField: 'manufacturer',
// valueField: 'manufacturer',
filterOption: (input: string, option: any) => {
return option.manufacturer.toLowerCase().indexOf(input.toLowerCase()) >= 0;
},
showSearch: true,
immediate: true,
dropdownReload: true,
allowClear: true,
},
},
{

View File

@@ -1,506 +0,0 @@
{
"data":[
{
"title": "家居照明",
"key": "1",
"children": [
{
"title": "灯泡",
"key": "1-1",
"children": [
{
"title": "LED灯泡",
"key": "1-1-1",
"children": [
{
"title": "E27 LED灯泡",
"key": "1-1-1-1",
"attr": {
"瓦特": "7W",
"光通量": "500lm",
"色温": "2700K"
}
},
{
"title": "E14 小灯泡",
"key": "1-1-1-2",
"attr": {
"瓦特": "4W",
"光通量": "250lm",
"色温": "6500K"
}
}
]
},
{
"title": "节能灯",
"key": "1-1-2",
"children": [
{
"title": "E27 节能灯泡",
"key": "1-1-2-1",
"attr": {
"瓦特": "11W",
"光通量": "800lm",
"色温": "6500K"
}
}
]
}
]
},
{
"title": "灯具",
"key": "1-2",
"children": [
{
"title": "吊灯",
"key": "1-2-1",
"children": [
{
"title": "水晶吊灯",
"key": "1-2-1-1",
"attr": {
"尺寸": "Φ60cm",
"适用面积": "15-20㎡"
}
},
{
"title": "现代简约吊灯",
"key": "1-2-1-2",
"attr": {
"尺寸": "Φ52cm",
"适用面积": "10-15㎡"
}
}
]
},
{
"title": "台灯",
"key": "1-2-2",
"children": [
{
"title": "护眼台灯",
"key": "1-2-2-1",
"attr": {
"瓦特": "18W",
"调光调色": "是"
}
},
{
"title": "折叠臂台灯",
"key": "1-2-2-2",
"attr": {
"瓦特": "14W",
"调光调色": "否"
}
}
]
}
]
},
{
"title": "开关插座",
"key": "1-3",
"children": [
{
"title": "智能开关",
"key": "1-3-1",
"children": [
{
"title": "触控式智能开关",
"key": "1-3-1-1",
"attr": {
"控制方式": "触控/远程",
"兼容性": "ZigBee/WiFi"
}
}
]
},
{
"title": "插座",
"key": "1-3-2",
"children": [
{
"title": "多功能插座",
"key": "1-3-2-1",
"attr": {
"插孔类型": "2/3插",
"USB接口": "有"
}
}
]
}
]
}
]
},
{
"title": "电梯",
"key": "3",
"children": [
{
"title": "扶梯",
"key": "301"
},
{
"title": "直梯",
"key": "302"
}
]
},
{
"title": "冷源源",
"key": "4",
"children": [
{
"title": "通风及空调设备",
"key": "5",
"children": [
{
"title": "组合式空调机组",
"key": "501"
},
{
"title": "新风机组",
"key": "502"
},
{
"title": "精密空调",
"key": "503"
},
{
"title": "风机盘管",
"key": "504"
},
{
"title": "VAV",
"key": "505"
},
{
"title": "室外多联机",
"key": "506"
},
{
"title": "风幕机",
"key": "507"
},
{
"title": "球喷",
"key": "508"
},
{
"title": "送风机",
"key": "509"
},
{
"title": "排风机",
"key": "510"
},
{
"title": "排风兼排烟机",
"key": "511"
},
{
"title": "通风机",
"key": "512"
},
{
"title": "风阀",
"key": "513"
},
{
"title": "风柱式空调",
"key": "514"
}
]
}
]
},
{
"title": "照明",
"key": "6",
"children": [
{
"title": "多功能传感器",
"key": "701"
},
{
"title": "照度传感器",
"key": "702"
},
{
"title": "噪声传感器",
"key": "703"
}
]
}
],
"dataSource":[
{
"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 commodo",
"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
},
{
"id": "d1",
"isDel": "0",
"officesId": "84",
"deviceCode": "37430200144",
"deviceName": "地听测试2",
"category": "1",
"type": "1001",
"energyCount": "1",
"serialNumber": "69",
"pidCode": null,
"brand": "",
"types": "",
"manufacturer": "elit non in",
"contacts": "ad reprehenderit",
"phonenumber": "34",
"position": "in esse commodo",
"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": "802",
"ip": "10.5.36.0",
"port": "6000",
"com": "",
"slaveAddress": "123测试",
"dlt": "",
"conversionIdentifier": "48",
"multiplicationAdjustment": "1",
"accessMethod": "1",
"replacementFrequency": "0",
"dataDetail": "sit",
"insertTime": "2024-02-28 11:26:58",
"children": null,
"devicePointList": null,
"insertUser": null
},
{
"id": "d2",
"isDel": "0",
"officesId": "84",
"deviceCode": "1235623",
"deviceName": "测试设备2",
"category": "1",
"type": "1001",
"energyCount": "是",
"serialNumber": "69",
"pidCode": null,
"brand": "",
"types": "",
"manufacturer": "elit non in",
"contacts": "ad reprehenderit",
"phonenumber": "34",
"position": "in esse commodo",
"activeState": "1",
"measurementDirection": "1",
"deviceMagnification": 62,
"deviceAccuracy": "89",
"frequency": "anim consequat irure",
"standardFrequency": "ut elit",
"deviceHead": "pariatur ex velit",
"constructor": null,
"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": "2024-02-28 11:31:57",
"children": null,
"devicePointList": null,
"insertUser": null
},
{
"id": "d7",
"isDel": "0",
"officesId": "",
"deviceCode": "0213",
"deviceName": "测试",
"category": "1",
"type": "1001",
"energyCount": "1",
"serialNumber": "",
"pidCode": null,
"brand": "6da085e5-956d-4000-bd3c-ebb01a9c99a1",
"types": "d7a8aede-b821-4ff2-953d-601a20e5a948",
"manufacturer": "",
"contacts": "",
"phonenumber": null,
"position": "",
"activeState": "",
"measurementDirection": "",
"deviceMagnification": null,
"deviceAccuracy": null,
"frequency": "",
"standardFrequency": "",
"deviceHead": "",
"constructor": "",
"voltageType": "",
"pt": null,
"ct": null,
"communicationProtocol": "",
"ip": "",
"port": "",
"com": "",
"slaveAddress": "",
"dlt": "",
"conversionIdentifier": "1",
"multiplicationAdjustment": "1",
"accessMethod": "",
"replacementFrequency": "0",
"dataDetail": "",
"insertTime": "2024-03-14 20:01:53",
"children": null,
"devicePointList": null,
"insertUser": ""
},
{
"id": "d3",
"isDel": "0",
"officesId": "84",
"deviceCode": "81",
"deviceName": "设备名称1111",
"category": "1",
"type": "1001",
"energyCount": "1",
"serialNumber": "69",
"pidCode": null,
"brand": "6da085e5-956d-4000-bd3c-ebb01a9c99a1",
"types": "d7a8aede-b821-4ff2-953d-601a20e5a948",
"manufacturer": "elit non in",
"contacts": "ad reprehenderit",
"phonenumber": "34",
"position": "in esse commodo",
"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": "2024-03-15 17:34:24",
"children": null,
"devicePointList": null,
"insertUser": null
},
{
"id": "d43fdfff_02_0001",
"isDel": "0",
"officesId": "843fdffff213d2d3",
"deviceCode": "00037430200143",
"deviceName": "应感者酸严",
"category": "1",
"type": "1001",
"energyCount": "esse consequat",
"serialNumber": "69",
"pidCode": null,
"brand": "",
"types": "",
"manufacturer": "elit non in",
"contacts": "ad reprehenderit",
"phonenumber": "34",
"position": "in esse commodo",
"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": "2024-04-29 11:12:43",
"children": null,
"devicePointList": null,
"insertUser": null
}
]
}

View File

@@ -474,6 +474,7 @@
onMounted(() => {
getDianWeiList();
changeDeviceType(null, null);
getSelect();
});
return {

View File

@@ -1,22 +1,55 @@
<template>
<a-row type="flex" style="height: 92%">
<a-col :span="8">
<a-radio-group
v-model:value="mode"
@change="changeMode"
style="padding-bottom: 10px; width: 40%; height: 4%; padding-left: 30px; padding-top: 10px">
<a-radio-button value="1" style="width: 50%; text-align: center"> 同比 </a-radio-button>
<a-radio-button value="2" style="width: 50%; text-align: center"> 环比 </a-radio-button>
</a-radio-group>
<div ref="analysisGraphchart" style="width: 100%; height: 95%"></div>
<div
style="
box-shadow: 0 0 0 2px rgba(218, 218, 218, 0.5); /* 灰色阴影 */
width: 98%;
height: 96%;
margin: 2%;
">
<a-radio-group
v-model:value="mode"
@change="changeMode"
style="
padding-bottom: 10px;
width: 40%;
height: 4%;
padding-left: 30px;
padding-top: 10px;
">
<a-radio-button value="1" style="width: 50%; text-align: center"> 同比 </a-radio-button>
<a-radio-button value="2" style="width: 50%; text-align: center"> 环比 </a-radio-button>
</a-radio-group>
<div ref="analysisGraphchart" style="width: 100%; height: 95%"></div>
</div>
</a-col>
<a-col :span="16">
<div
ref="analysisGraphRingchart"
style="
width: 98%;
height: 38%;
box-shadow: 0 0 0 2px rgba(218, 218, 218, 0.5);
margin: 1%;
"></div>
<div
ref="analysisGraphBarchart"
style="
width: 98%;
height: 58%;
box-shadow: 0 0 0 2px rgba(218, 218, 218, 0.5);
margin: 1%;
"></div>
</a-col>
<a-col :span="16" />
</a-row>
</template>
<script lang="ts">
import { defineComponent, onMounted, ref, inject, watch } from 'vue';
import * as echarts from 'echarts';
import JSZip from 'jszip';
import { saveAs } from 'file-saver';
export default defineComponent({
name: 'AnalysisGraph',
@@ -52,11 +85,24 @@
);
const changeMode = () => {};
const analysisGraphchart = ref(null);
const analysisGraphRingchart = ref(null);
const analysisGraphBarchart = ref(null);
// 左侧柱状图
let chartInstance: echarts.ECharts | null = null;
// 圆环图
let chartRight1: echarts.ECharts | null = null;
// 右下角柱状图
let chartRight2: echarts.ECharts | null = null;
const draw = () => {
data.value = pageData.analysisGraphList;
// 绘制左侧图
drawLeft();
drawRight1();
};
const drawLeft = () => {
if (data.value && data.value.length > 0) {
if (chartInstance) {
chartInstance.dispose();
@@ -65,7 +111,6 @@
var seriesdata = [];
var dateX = [];
// var legendList: string | any[] = [];
for (let i = 0; i < data.value.length; i++) {
dateX.push(data.value[i].name);
@@ -81,26 +126,39 @@
show: true,
formatter: '{b}',
},
barWidth: '25%',
},
];
const option = {
// tooltip: {
// trigger: 'axis',
// formatter: (params: any) => {
// const date = params[0].name;
// const values = params
// .map((param: any) => {
// const unit = data.value.find((d) => d.name === date)?.unit || '';
// return `<tr>
// <td>${param.marker}${param.seriesName}</td>
// <td style="text-align: right;">${param.value} ${unit}</td>
// </tr>`;
// })
// .join('');
// return `<div>${date}</div><table style="width: 100%;">${values}</table>`;
// },
// },
grid: {
top: 60,
bottom: 20,
},
dataZoom: [
{
show: true,
type: 'slider',
zoomLock: true,
startValue: 0, // 从头开始。
endValue: 4,
showDetail: false,
width: 5,
yAxisIndex: [0, 1], // 控制y轴滚动对象
},
{
show: true,
type: 'inside',
// width: 0,
startValue: 0,
endValue: 10,
minValueSpan: 10,
yAxisIndex: [0],
zoomOnMouseWheel: false, // 关闭滚轮缩放
moveOnMouseWheel: true, // 开启滚轮平移
moveOnMouseMove: true, // 鼠标移动能触发数据窗口平移
},
],
yAxis: {
type: 'category',
axisLine: { show: false },
@@ -125,26 +183,283 @@
chartInstance.setOption(option);
}
};
const drawRight1 = () => {
if (data.value && data.value.length > 0) {
if (chartRight1) {
chartRight1.dispose();
}
chartRight1 = echarts.init(analysisGraphRingchart.value);
var seriesdata = [];
var dateX = [];
// var legendList: string | any[] = [];
for (let i = 0; i < data.value.length; i++) {
dateX.push(data.value[i].name);
seriesdata.push({ value: data.value[i].ringValue, name: data.value[i].name });
}
var seriesList = [
{
// name: data.value[0].energyType,
data: seriesdata,
type: 'pie',
// 圆环内径和外径
radius: ['70%', '90%'],
center: ['30%', '50%'], // 调整环形图的位置,百分比表示相对于容器的宽高
// 显示折线
labelLine: {
show: true,
length: 10, // 调整第一个折线段的长度
length2: 30, // 调整第二个折线段的长度
},
label: {
show: true,
// formatter: '{b}',
position: 'outside', // 确保标签在环形图外部
// alignTo: 'edge',
formatter: '{c}' + data.value[0].energyUnit + '\n{d}%',
alignTo: 'labelLine',
distanceToLabelLine: 5, // 调整标签和引导线之间的距离
distance: 10, // 调整标签距离图形的距离
},
itemStyle: {
normal: {
// 白色间距
borderWidth: 2,
borderColor: '#ffffff',
},
},
},
];
const option = {
tooltip: {
trigger: 'item',
},
// 图例
legend: {
top: 'center',
left: '60%',
// 排列方式 垂直
orient: 'vertical',
},
yAxis: {
type: 'category',
axisLine: { show: false },
axisLabel: { show: false },
axisTick: { show: false },
splitLine: { show: false },
data: dateX,
},
xAxis: {
type: 'value',
position: 'top',
splitLine: {
lineStyle: {
type: 'dashed',
},
},
},
series: seriesList,
};
chartRight1 = echarts.init(analysisGraphRingchart.value);
chartRight1.setOption(option);
// 默认点击第一个
if (seriesdata.length > 0) {
drawRight2(seriesdata[0]);
}
chartRight1.on('click', function (params) {
// 控制台输出数据的名称
console.log(params.name + ' 被点击了');
drawRight2(params);
});
}
};
// 右下角柱状图
// chartRight2
// analysisGraphBarchart
const drawRight2 = (auxiliary: any) => {
if (chartRight2) {
chartRight2.dispose();
}
// 辅助线
var compareData: any[] = [];
// 展示数据
var showData: any[] = [];
// X轴
var dateX: any[] = [];
data.value.forEach((item) => {
if (item.name !== auxiliary.name) {
dateX.push(item.name);
showData.push(item.ringValue);
compareData.push(auxiliary.value);
}
});
const option = {
// 图例
legend: {
data: [
{ name: '对比值', icon: 'rect' }, // 对比值使用矩形图标
{
name: '参考线',
icon: 'path://M234.666667 490.666667h-153.6a25.6 25.6 0 1 0 0 51.2h153.6a25.6 25.6 0 1 0 0-51.2zM473.6 490.666667h-153.6a25.6 25.6 0 1 0 0 51.2h153.6a25.6 25.6 0 1 0 0-51.2zM934.4 490.666667h-136.533333a25.6 25.6 0 1 0 0 51.2h136.533333a25.6 25.6 0 1 0 0-51.2zM712.533333 490.666667h-153.6a25.6 25.6 0 1 0 0 51.2h153.6a25.6 25.6 0 1 0 0-51.2z',
}, // 参考线使用自定义路径图标,只显示线条
],
orient: 'horizontal',
bottom: 10,
left: 60,
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
lineStyle: {
color: 'red', // 设置 tooltip 的线颜色
},
},
},
grid: {
top: 20,
bottom: 60,
},
xAxis: {
type: 'category',
axisLine: { show: false },
axisLabel: { show: true },
axisTick: { show: false },
splitLine: { show: false },
data: dateX,
},
yAxis: {
type: 'value',
position: 'top',
splitLine: {
lineStyle: {
type: 'dashed',
},
},
},
dataZoom: [
{
show: true,
type: 'slider',
zoomLock: true,
startValue: 0, // 从头开始。
endValue: 5,
bottom: '0%',
height: 10,
showDetail: false,
},
{
show: true,
type: 'inside',
xAxisIndex: 0,
zoomOnMouseWheel: false, // 滚轮是否触发缩放
moveOnMouseMove: true, // 鼠标滚轮触发滚动
moveOnMouseWheel: true,
},
],
series: [
{
name: '对比值',
type: 'bar',
stack: 'Total',
label: {
// show: true,
position: 'right',
formatter: '{b}',
},
data: showData,
barWidth: 30, // 设置柱状图的宽度
},
{
name: '参考线',
type: 'line',
data: compareData,
markLine: {
symbol: 'none',
label: {
show: false,
},
lineStyle: {
type: 'dashed',
color: 'red',
},
},
itemStyle: {
color: 'red', // 设置参考线的小圆点颜色
},
emphasis: {
itemStyle: {
opacity: 0, // 隐藏鼠标悬停时的节点
},
},
showSymbol: false, // 隐藏数据点
lineStyle: {
type: 'dashed', // 虚线样式
color: 'red',
},
},
],
};
chartRight2 = echarts.init(analysisGraphBarchart.value);
chartRight2.setOption(option);
};
onMounted(() => {
draw();
});
// 下载图表
const downloadChart = () => {
if (chartInstance) {
const base64 = chartInstance.getDataURL({
type: 'png',
backgroundColor: '#fff',
const downloadChart = async () => {
// if (chartInstance) {
// const base64 = chartInstance.getDataURL({
// type: 'png',
// backgroundColor: '#fff',
// });
// const link = document.createElement('a');
// link.href = base64;
// link.download = 'chart.png';
// link.click();
// }
const zip = new JSZip();
const chartInstances = [chartInstance, chartRight1, chartRight2];
const imagePromises = chartInstances.map((chart: any, index) => {
return new Promise((resolve) => {
const base64 = chart.getDataURL({
type: 'png',
backgroundColor: '#fff',
});
// 将 Base64 转换为二进制
const binary = atob(base64.split(',')[1]);
const array = [];
for (let i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
const uint8Array = new Uint8Array(array);
resolve({ name: `chart${index + 1}.png`, data: uint8Array });
});
const link = document.createElement('a');
link.href = base64;
link.download = 'chart.png';
link.click();
}
});
const images = await Promise.all(imagePromises);
images.forEach((image: any) => {
zip.file(image.name, image.data);
});
zip.generateAsync({ type: 'blob' }).then((content) => {
saveAs(content, 'charts.zip'); // 使用 FileSaver.js 保存 ZIP 文件
});
};
return {
analysisGraphchart,
analysisGraphRingchart,
analysisGraphBarchart,
downloadChart,
mode,
changeMode,

View File

@@ -24,7 +24,7 @@
<environment-table ref="tableRef" v-else />
</div>
<div v-else style="height: 90%">
<analysis-graph ref="graphRef" v-if="isGraph" />
<analysis-graph ref="analysisGraphRef" v-if="isGraph" />
<analysis-table ref="analysisTableRef" v-else />
</div>
</div>
@@ -44,6 +44,8 @@
const treeRef = ref();
const graphRef = ref();
const analysisGraphRef = ref();
const tableRef = ref();
const analysisTableRef = ref();
@@ -59,6 +61,10 @@
if (graphRef.value) {
graphRef.value.downloadChart();
}
} else {
if (analysisGraphRef.value) {
analysisGraphRef.value.downloadChart();
}
}
};

View File

@@ -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 | undefined>();
// 采集频率
const frequencyValue = ref<string | undefined>();
const selectedValue = ref<string | number | null | undefined>();
// 日期类型
const dateTypeValue = ref<string | undefined>();
// 时间
const dateRange = ref<[Dayjs, Dayjs] | undefined>();
const dateValue = ref<[Dayjs, Dayjs] | undefined>();
// 页面初始化参数
const getOptionsList = async () => {
@@ -107,25 +111,20 @@
(item.value = item.cnValue), (item.label = item.cnValue);
});
options1.value = options.data.data; // 根据返回数据的结构来更新 options1.value
if (options1.value) {
selectedValue.value = options1.value[0].value;
}
} catch (error) {
console.error('Failed to fetch options:', error);
}
options2.value = [
{
value: '1',
label: '5分钟',
value: 'month',
label: '',
},
{
value: '2',
label: '10分钟',
},
{
value: '3',
label: '30分钟',
},
{
value: '4',
label: '1小时',
value: 'year',
label: '',
},
];
};
@@ -148,7 +147,7 @@
// 选择能耗类型
const changeEnergyType = () => {
if (selectedValue.value == '8') {
if (selectedValue.value == '碳排量') {
shebei.value = true;
mode.value = '2';
} else {
@@ -337,7 +336,9 @@
{
name: 'AC_002暖通电表',
value: -21,
ringValue: 21,
energyType: selectedValue.value,
energyUnit: 'kWh',
unit: 'V',
labelRight: {
position: 'right',
@@ -346,6 +347,7 @@
{
name: 'AC_003照明电表',
value: 36,
ringValue: 36,
energyType: selectedValue.value,
unit: 'V',
labelRight: {
@@ -355,6 +357,67 @@
{
name: 'AC_004给排水电表',
value: -5,
ringValue: 5,
energyType: selectedValue.value,
unit: 'V',
labelRight: {
position: 'right',
},
},
{
name: 'AC_005给排水电表',
value: -25,
ringValue: 15,
energyType: selectedValue.value,
unit: 'V',
labelRight: {
position: 'right',
},
},
{
name: 'AC_006给排水电表',
value: 35,
ringValue: 30,
energyType: selectedValue.value,
unit: 'V',
labelRight: {
position: 'insideLeft',
},
},
{
name: 'AC_007给排水电表',
value: 15,
ringValue: 18,
energyType: selectedValue.value,
unit: 'V',
labelRight: {
position: 'insideLeft',
},
},
{
name: 'AC_008给排水电表',
value: -25,
ringValue: 41,
energyType: selectedValue.value,
unit: 'V',
labelRight: {
position: 'right',
},
},
{
name: 'AC_009给排水电表',
value: -5,
ringValue: 55,
energyType: selectedValue.value,
unit: 'V',
labelRight: {
position: 'right',
},
},
{
name: 'AC_0090给排水电表',
value: -5,
ringValue: 55,
energyType: selectedValue.value,
unit: 'V',
labelRight: {
@@ -624,9 +687,9 @@
}
};
const onChange = (val: RangeValue) => {
dateRange.value = val;
};
// const onChange = (val: RangeValue) => {
// dateRange.value = val;
// };
const onCalendarChange = (val: RangeValue) => {
dates.value = val;
@@ -634,6 +697,7 @@
onMounted(() => {
getOptionsList();
changeMode();
getSelect();
});
return {
@@ -648,8 +712,8 @@
options2,
mode,
selectedValue,
frequencyValue,
dateRange,
dateTypeValue,
dateValue,
getOptionsList,
getSelect,
getSelect11,
@@ -657,7 +721,7 @@
disabledDate,
onCalendarChange,
onOpenChange,
onChange,
// onChange,
hackValue,
treeLoading,
changeEnergyType,

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,24 @@
<template>
<a-tabs v-model:activeKey="activeKey" style="height: 5%">
<a-tab-pane key="1" tab="综合数据" />
<a-tab-pane key="2" tab="历史数据" force-render>Content of Tab Pane 2</a-tab-pane>
<a-tab-pane key="3" tab="平均数据">Content of Tab Pane 3</a-tab-pane>
</a-tabs>
<!-- <ns-view-list-table v-bind="tableConfig" v-if="activeKey == '1'" /> -->
<aggregate-data ref="aggregateDataRef" v-if="activeKey == '1'" style="height: 85%" />
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { tableConfig } from './config';
import aggregateData from './aggregateData/index.vue';
const aggregateDataRef = ref();
var activeKey = ref('1');
defineOptions({
name: 'EnvironmentMonitorIndex', // 与页面路由name一致缓存才可生效
});
</script>
<style lang="less" scoped></style>

View File

@@ -194,7 +194,9 @@
const selectRoleRef = ref();
const formSchema = formConfig(disabled as any);
const formSchema2 = formConfig2(roleDisabled as any);
const { orgName, projectId, orgId } = JSON.parse(sessionStorage.getItem(import.meta.env.VITE_PUBLIC_PATH));
const { orgName, projectId, orgId } = JSON.parse(
sessionStorage.getItem(import.meta.env.VITE_PUBLIC_PATH),
);
// const orgId = JSON.parse(sessionStorage.getItem('ORGID'));
const roleTreeData = ref([]);
const rolePermissionTreeData = ref([]);
@@ -340,7 +342,7 @@
const info = {
node: { key: '0-0-0', dataRef: { ...roleTreeData.value[0].children[0] } },
};
SelectUserTree([''], info);
// SelectUserTree([''], info);
});
}
});

View File

@@ -89,8 +89,8 @@ export const appConfig = {
// 修改密码配置
updatePassWordInfo: {
title: '修改密码',
subtitle: 'huaxing平台',
api: '/api/web/objs/User/changePassword',
subtitle: 'huaxing管理平台',
api: '/carbon-smart/api/user/update/password',
},
// headerBellInfo: {
// isShow: true,

View File

@@ -13,7 +13,7 @@
</template>
<component :is="schema.component" v-bind="formProps">
<template #[item]="data" v-for="item in Object.keys($slots)">
<slot :name="item" v-bind="data || {}"></slot>
<slot :name="item" v-bind="data || {}" :field="schema.field"></slot>
</template>
</component>
<!-- <div class="ns-tips">-->
@@ -47,6 +47,7 @@
mapKeys,
upperFirst,
get,
cloneDeep,
} from 'lodash-es';
import { isInputType } from '/nerv-lib/component/form/form-util';
import { useParams } from '/nerv-lib/use/use-params';
@@ -332,6 +333,7 @@
getFormItemClass,
getSlots,
formLayout,
cloneDeep,
};
},
beforeCreate() {

View File

@@ -275,6 +275,7 @@
.ant-empty-description {
color: rgba(0, 0, 0, 0.3);
margin-bottom: 0;
}
// 表头加粗

View File

@@ -19,7 +19,7 @@
<ns-form
style="width: 100%; margin: auto"
ref="formOneRef"
formLayout="修改"
formLayout="vertical"
:schemas="formSchema"
:model="data" />
<div class="step-box">
@@ -32,8 +32,6 @@
</div>
</div>
</a-layout-content>
<a class="toLogin" @click="toLogin" v-show="step === 0">登录已有豪恩账号 ></a>
<!-- <a-layout-footer>Copyright 2021 xu科技 All Rights Reserved</a-layout-footer> -->
</a-layout>
</div>
</template>
@@ -69,7 +67,7 @@
const { navigateBackV2: navigateBack } = useNavigate();
const formSchema = reactive([
{
field: 'oldPassword',
field: 'originPassword',
label: '原密码',
component: 'NsInputPassword',
componentProps: {
@@ -86,7 +84,7 @@
},
{
field: 'newPassword',
field: 'password',
label: '新密码',
component: 'NsInputPassword',
componentProps: {
@@ -147,7 +145,7 @@
if (!value) {
return;
}
if (value !== data.newPassword) {
if (value !== data.password) {
return Promise.reject('两次密码不一致');
}
},
@@ -166,14 +164,14 @@
async function update() {
try {
const res = await http.post(configStore.updatePassWordInfo?.api, data);
if (res.success) {
NsMessage.success('修改成功,需重新登陆', 1, () => {
Cookies.remove(`${import.meta.env.VITE_PUBLIC_PATH}-nervsid`);
sessionStorage.clear();
router.push('/login');
authorizationStore.clearAuthorization();
});
}
// if (res.success) {
NsMessage.success('修改成功,需重新登陆', 1, () => {
Cookies.remove(`${import.meta.env.VITE_PUBLIC_PATH}-nervsid`);
sessionStorage.clear();
router.replace('/login');
authorizationStore.clearAuthorization();
});
// }
loading.value = false;
} catch (err) {
loading.value = false;

View File

@@ -129,8 +129,10 @@
accountNo: userName.value.trim(),
password: password.value.trim(),
});
validator(null, value.code)
validator(null, value?.code)
.then(() => {
console.log('登录');
// 记住密码
rememberFunc(data);
loading.value = true;
@@ -257,13 +259,13 @@
created() {
const _this = this;
window.sessionStorage.clear();
document.onkeydown = function (e) {
const key = window.event === undefined ? e.keyCode : window.event.keyCode;
key === 13 ? _this.submit() : '';
};
// document.onkeydown = function (e) {
// const key = window.event === undefined ? e.keyCode : window.event.keyCode;
// key === 13 ? _this.submit() : '';
// };
},
beforeUnmount() {
document.onkeydown = function (e) {};
// document.onkeydown = function (e) {};
},
mounted() {