Compare commits

...

38 Commits

Author SHA1 Message Date
wangyan a94531bd57 Merge branch 'temp' into deploy-dev 4 months ago
xuziqiang b06c9ddc84 Merge branch 'temp' of http://123.60.103.97:3000/xuziqiang/SaaS-lib into temp 4 months ago
xuziqiang 40021ba5d0 fix: bug修改 4 months ago
zhaohy 1401d3611f Merge branch 'temp' of http://123.60.103.97:3000/xuziqiang/SaaS-lib into temp 4 months ago
zhaohy d29c724920 fix:联系方式 4 months ago
fks-xuxinyue 5eba9a35a0 taskid:084 remark:'commit' 4 months ago
fks-yangshouda 6278e3ff17 1.监控中心 - 环境监测 环境指数分析添加查询部分 4 months ago
xuziqiang 0b619fe937 fix: 补充相关限制 4 months ago
xuziqiang 48569345aa feat: 修改密码 4 months ago
xuziqiang dc0f2a164b fix: 修改登录多重submit 4 months ago
xuziqiang 1aa294b998 fix: 设备型号取消关联 4 months ago
xuziqiang ef20fa58de Merge branch 'temp' of http://123.60.103.97:3000/xuziqiang/SaaS-lib into temp 4 months ago
xuziqiang dac2e095e1 fix:分组管理逻辑补充 4 months ago
zhaohy c68dc4deb7 Merge branch 'temp' of http://123.60.103.97:3000/xuziqiang/SaaS-lib into temp 4 months ago
zhaohy 0e9743f598 fix:换成枚举 4 months ago
xuziqiang 2fe6bb6d81 Merge branch 'temp' of http://123.60.103.97:3000/xuziqiang/SaaS-lib into temp 4 months ago
xuziqiang 58300c60e2 fix:设备台账补充筛选项去重逻辑 4 months ago
zhaohy 3bf19ba70d Merge branch 'temp' of http://123.60.103.97:3000/xuziqiang/SaaS-lib into temp 4 months ago
zhaohy de0ce4ec2d fix: 添加联系人 4 months ago
zhaohy 8091bc10cc fix:能源告警换枚举 4 months ago
xuziqiang e90efdb08d Merge branch 'temp' of http://123.60.103.97:3000/xuziqiang/SaaS-lib into temp 4 months ago
xuziqiang 86e0b30e81 fix: 分组逻辑调整 4 months ago
zhaohy 0214356cbb Merge branch 'temp' of http://123.60.103.97:3000/xuziqiang/SaaS-lib into temp 4 months ago
zhaohy 098b4f29fd fix:配置设备告警 联系方式 4 months ago
chenpingsen 3598e3d887 add:增加照明系统前端交互 4 months ago
fks-xuxinyue 4869fd4d16 Merge branch 'temp' of http://123.60.103.97:3000/xuziqiang/SaaS-lib into temp 4 months ago
fks-xuxinyue b41caf9320 taskid:084 remark:'commit' 4 months ago
xuziqiang 8603732377 Merge branch 'temp' of http://123.60.103.97:3000/xuziqiang/SaaS-lib into temp 4 months ago
xuziqiang 32d1a633b1 feat: 查询补充 4 months ago
fks-yangshouda 5deff41679 1.能耗监测 - 分析 下载图表 4 months ago
xuziqiang 0681836c02 fix: 设备台账调整搜索 4 months ago
xuziqiang 4526da936e fix: 代码逻辑调整 5 months ago
xuziqiang c31b5468c7 Merge branch 'temp' of http://123.60.103.97:3000/xuziqiang/SaaS-lib into temp 5 months ago
xuziqiang e0206a228b feat: 分组管理批量分组,公式编辑 5 months ago
fks-xuxinyue 47614e12ed Merge branch 'temp' of http://123.60.103.97:3000/xuziqiang/SaaS-lib into temp 5 months ago
fks-xuxinyue d8cc8293bc taskid:083 remark:'commit' 5 months ago
fks-yangshouda 141f2a3e6f Merge branch 'temp' of http://123.60.103.97:3000/xuziqiang/SaaS-lib into temp 5 months ago
fks-yangshouda 4fcdae08de 能耗监测 分析 右侧图 5 months ago
  1. 8
      hx-ai-intelligent/src/api/alarmSettings/energyAlarm.ts
  2. 14
      hx-ai-intelligent/src/api/carbonEmissionFactorLibrary.ts
  3. 13
      hx-ai-intelligent/src/api/deviceManage.ts
  4. 3
      hx-ai-intelligent/src/config/app.config.ts
  5. 4
      hx-ai-intelligent/src/icon/common.svg
  6. 20
      hx-ai-intelligent/src/router/alarmManagement.ts
  7. 38
      hx-ai-intelligent/src/router/monitor.ts
  8. 109
      hx-ai-intelligent/src/view/alarmManagement/alarmOverview/index.vue
  9. 165
      hx-ai-intelligent/src/view/alarmManagement/alarmSettings/energyAlarm/configureEnergyAlarms.vue
  10. 151
      hx-ai-intelligent/src/view/alarmManagement/alarmSettings/energyAlarm/editConfigureEnergyAlarm.vue
  11. 12
      hx-ai-intelligent/src/view/alarmManagement/alarmSettings/equipmentAlarm/configureDeviceAlarms.vue
  12. 16
      hx-ai-intelligent/src/view/alarmManagement/alarmSettings/equipmentAlarm/editConfigureDeviceAlarm.vue
  13. 19
      hx-ai-intelligent/src/view/alarmManagement/alarmSettings/index.vue
  14. 255
      hx-ai-intelligent/src/view/alarmManagement/alarmSettings/notificationManagement/index.vue
  15. 22
      hx-ai-intelligent/src/view/alarmManagement/alarmSettings/notificationManagement/linkPeople/config.ts
  16. 341
      hx-ai-intelligent/src/view/alarmManagement/alarmSettings/notificationManagement/linkPeople/index.vue
  17. 10
      hx-ai-intelligent/src/view/alarmManagement/alarmSettings/ts/energyAlarmConfig.ts
  18. 8
      hx-ai-intelligent/src/view/alarmManagement/alarmSettings/ts/equipmentAlarmConfig.ts
  19. 28
      hx-ai-intelligent/src/view/alarmManagement/equipmentAlarm/index.vue
  20. 283
      hx-ai-intelligent/src/view/alarmManagement/equipmentAlarm/look.vue
  21. 108
      hx-ai-intelligent/src/view/alarmManagement/equipmentAlarm/notificationManagementMock.json
  22. 39
      hx-ai-intelligent/src/view/alarmManagement/equipmentAlarm/status.vue
  23. 164
      hx-ai-intelligent/src/view/alarmManagement/equipmentAlarm/ts/config.ts
  24. 346
      hx-ai-intelligent/src/view/carbonEmissionManage/carbonEmissionFactorLibrary/index.vue
  25. 62
      hx-ai-intelligent/src/view/carbonEmissionManage/carbonEmissionStatistics/config.ts
  26. 1
      hx-ai-intelligent/src/view/carbonEmissionManage/carbonEmissionStatistics/energyConsumption/index.vue
  27. 649
      hx-ai-intelligent/src/view/carbonEmissionManage/carbonEmissionStatistics/quickCalculation/index.vue
  28. 141
      hx-ai-intelligent/src/view/equipmentControl/lightingManage/dialogStyle.less
  29. 1108
      hx-ai-intelligent/src/view/equipmentControl/lightingManage/index.less
  30. 156
      hx-ai-intelligent/src/view/equipmentControl/lightingManage/indexs.less
  31. 50
      hx-ai-intelligent/src/view/equipmentControl/lightingManage/indexs.vue
  32. 15
      hx-ai-intelligent/src/view/equipmentControl/lightingManage/indexs1.vue
  33. 457
      hx-ai-intelligent/src/view/equipmentControl/lightingManage/tabs1.vue
  34. 216
      hx-ai-intelligent/src/view/equipmentControl/lightingManage/tabs2.vue
  35. 255
      hx-ai-intelligent/src/view/equipmentControl/lightingManage/tabs3.vue
  36. 267
      hx-ai-intelligent/src/view/equipmentManage/group/config.ts
  37. 31
      hx-ai-intelligent/src/view/equipmentManage/group/edit.vue
  38. 126
      hx-ai-intelligent/src/view/equipmentManage/group/editCal.vue
  39. 163
      hx-ai-intelligent/src/view/equipmentManage/group/editFormula.vue
  40. 369
      hx-ai-intelligent/src/view/equipmentManage/group/editGroup.vue
  41. 59
      hx-ai-intelligent/src/view/equipmentManage/group/index.vue
  42. 121
      hx-ai-intelligent/src/view/equipmentManage/group/mock.json
  43. 68
      hx-ai-intelligent/src/view/equipmentManage/ledger/config.ts
  44. 506
      hx-ai-intelligent/src/view/equipmentManage/ledger/mock.json
  45. 1
      hx-ai-intelligent/src/view/monitor/deviceMonitor/tree/index.vue
  46. 387
      hx-ai-intelligent/src/view/monitor/energyMonitor/analysisGraph/index.vue
  47. 8
      hx-ai-intelligent/src/view/monitor/energyMonitor/page.vue
  48. 120
      hx-ai-intelligent/src/view/monitor/energyMonitor/tree/index.vue
  49. 779
      hx-ai-intelligent/src/view/monitor/environmentMonitor/aggregateData/index.vue
  50. 24
      hx-ai-intelligent/src/view/monitor/environmentMonitor/index.vue
  51. 6
      hx-ai-intelligent/src/view/organizationManage/departmentManage/index.vue
  52. 4
      hx-op/src/config/app.config.ts
  53. 4
      lib/component/form/form/form-item.vue
  54. 1
      lib/saas/theme/global-antd.less
  55. 26
      lib/saas/view/service/updatePassWord.vue
  56. 14
      lib/saas/view/system/login.vue

8
hx-ai-intelligent/src/api/alarmSettings/energyAlarm.ts

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

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

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

13
hx-ai-intelligent/src/api/deviceManage.ts

@ -15,4 +15,17 @@ export enum group {
queryGroupPage = `${BASE_URL}/deviceGroup/queryGroupPage`, // 分组列表 queryGroupPage = `${BASE_URL}/deviceGroup/queryGroupPage`, // 分组列表
saveGroupList = `${BASE_URL}/deviceGroup/saveGroupList`, // 分组保存 saveGroupList = `${BASE_URL}/deviceGroup/saveGroupList`, // 分组保存
delGroupList = `${BASE_URL}/deviceGroup/delGroupList`, // 分组删除 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`, // 计算列表查询
} }

3
hx-ai-intelligent/src/config/app.config.ts

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

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

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

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

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

38
hx-ai-intelligent/src/router/monitor.ts

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

109
hx-ai-intelligent/src/view/alarmManagement/alarmOverview/index.vue

@ -30,7 +30,9 @@
style="flex: 1; height: 100%; background-color: white; border-radius: 4px; padding: 12px"> style="flex: 1; height: 100%; background-color: white; border-radius: 4px; padding: 12px">
<div ref="echartPieOne" style="width: 100%; height: 100%"></div> <div ref="echartPieOne" style="width: 100%; height: 100%"></div>
</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> </div>
<!-- 告警矩形 echarts --> <!-- 告警矩形 echarts -->
<div style="flex: 4; width: 100%; background-color: white; border-radius: 4px; padding: 12px"> <div style="flex: 4; width: 100%; background-color: white; border-radius: 4px; padding: 12px">
@ -49,8 +51,10 @@
const info = ref({}); const info = ref({});
let chartInstance: echarts.ECharts | null = null; let chartInstance: echarts.ECharts | null = null;
let chartInstanceOne: echarts.ECharts | null = null; let chartInstanceOne: echarts.ECharts | null = null;
let chartInstanceTow: echarts.ECharts | null = null;
const graphChart = ref(null); const graphChart = ref(null);
const echartPieOne = ref(null); const echartPieOne = ref(null);
const echartPieTow = ref(null);
const getGraphChart = () => { const getGraphChart = () => {
let dayData = []; let dayData = [];
let energyAlarm = []; let energyAlarm = [];
@ -294,7 +298,7 @@
}, },
textAlign: 'center', textAlign: 'center',
x: '44.3%', x: '44.3%',
y: '46%', y: '43%',
}, },
], ],
tooltip: { tooltip: {
@ -327,9 +331,10 @@
clockwise: false, // clockwise: false, //
avoidLabelOverlap: false, avoidLabelOverlap: false,
label: { label: {
show: true,
normal: { normal: {
show: true, show: true,
position: 'outter', position: 'outside',
textStyle: { textStyle: {
fontSize: 14, fontSize: 14,
fontWeight: 'bold', fontWeight: 'bold',
@ -342,7 +347,7 @@
labelLine: { labelLine: {
show: true, // 线 show: true, // 线
length: 10, // 线 length: 10, // 线
length2: 20, // 线 length2: 0, // 线
// lineStyle // lineStyle
}, },
data: m2R2Data, data: m2R2Data,
@ -352,11 +357,107 @@
chartInstanceOne = echarts.init(echartPieOne.value); chartInstanceOne = echarts.init(echartPieOne.value);
chartInstanceOne.setOption(option); 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(() => { onMounted(() => {
// //
getGraphChart(); getGraphChart();
// //
getEchartPieOne(); getEchartPieOne();
getEchartPieTow();
}); });
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>

165
hx-ai-intelligent/src/view/alarmManagement/alarmSettings/energyAlarm/configureEnergyAlarms.vue

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

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

@ -27,9 +27,9 @@
}" }"
tree-node-filter-prop="orgName" /> tree-node-filter-prop="orgName" />
</a-form-item> </a-form-item>
<a-form-item label="数据来源" name="sbtype"> <a-form-item label="数据来源" name="dataSources">
<a-cascader <a-cascader
v-model:value="infoObject.sbtype" v-model:value="infoObject.dataSources"
:options="deviceTypeTreeData" :options="deviceTypeTreeData"
:field-names="{ :field-names="{
children: 'children', children: 'children',
@ -45,16 +45,19 @@
v-model:value="infoObject.deviceNode" v-model:value="infoObject.deviceNode"
style="width: 100%" style="width: 100%"
placeholder="请选择设备节点" placeholder="请选择设备节点"
:disabled="!infoObject.sbtype" :disabled="!infoObject.dataSources"
:tree-line="true && { showLeafIcon: false }" :tree-line="true && { showLeafIcon: false }"
:tree-data="jdTreeData" :tree-data="jdTreeData"
:field-names="{ :field-names="{
children: 'children', children: 'children',
label: infoObject.sbtype && infoObject.sbtype[1] === 1 ? 'deviceName' : 'pointName', label:
infoObject.dataSources && infoObject.dataSources[1] === 1
? 'deviceName'
: 'pointName',
value: 'id', value: 'id',
}" /> }" />
</a-form-item> </a-form-item>
<a-form-item label="启用规则" name="enableRules"> <a-form-item label="启用规则">
<a-switch <a-switch
:checked="infoObject.enableRules === 1 ? true : false" :checked="infoObject.enableRules === 1 ? true : false"
:class="{ :class="{
@ -67,6 +70,7 @@
<a-textarea <a-textarea
v-model:value="infoObject.abnormalDescription" v-model:value="infoObject.abnormalDescription"
style="height: 32px" style="height: 32px"
placeholder="请输入异常描述"
:autoSize="{ minRows: 1, maxRows: 1 }" :autoSize="{ minRows: 1, maxRows: 1 }"
show-count show-count
:maxlength="30" /> :maxlength="30" />
@ -152,10 +156,11 @@
deviceNode: null, deviceNode: null,
ruleType: null, ruleType: null,
abnormalDescription: null, abnormalDescription: null,
sbtype: null, dataSources: null,
enableRules: 0, enableRules: 0,
alarmList: [{ id: null, logic: null, num: null, isDelete: 0 }], alarmList: [{ id: null, logic: null, num: null, isDelete: 0 }],
}); });
const emit = defineEmits(['editObject']);
// //
const delAlarmList = ref([]); const delAlarmList = ref([]);
// //
@ -224,7 +229,7 @@
.post(device.queryDevicePage, { .post(device.queryDevicePage, {
pageNum: 1, pageNum: 1,
pageSize: 999, pageSize: 999,
energyType: selectedOptions[0].cnValue, energyType: selectedOptions[0].dicKey,
orgId: orgId.value, orgId: orgId.value,
}) })
.then((res) => { .then((res) => {
@ -236,7 +241,7 @@
.post(group.queryDeviceGroupTree, { .post(group.queryDeviceGroupTree, {
pageNum: 1, pageNum: 1,
pageSize: 999, pageSize: 999,
energyType: selectedOptions[0].cnValue, energyType: selectedOptions[0].dicKey,
orgId: orgId.value, orgId: orgId.value,
}) })
.then((res) => { .then((res) => {
@ -271,19 +276,24 @@
const toggle = async (value: any, info: any) => { const toggle = async (value: any, info: any) => {
// //
let energyType = await dict({ params: { dicKey: 'ENERGY_TYPE' } }); let energyType = await dict({ params: { dicKey: 'ENERGY_TYPE' } });
energyType.data.data.forEach((item: any) => { if (energyType.data.data) {
item.children = [ energyType.data.data.forEach((item: any) => {
{ item.children = [
id: 1, {
cnValue: '设备', id: 1,
}, cnValue: '设备',
{ },
id: 2, {
cnValue: '节点', id: 2,
}, cnValue: '节点',
]; },
}); ];
deviceTypeTreeData.value = energyType.data.data; });
deviceTypeTreeData.value = energyType.data.data;
} else {
deviceTypeTreeData.value = [];
}
// //
energyAlarm.value = info; energyAlarm.value = info;
// //
@ -294,16 +304,38 @@
}); });
// //
if (value) { if (value) {
value.ruleType = value.ruleType + ''; await http.post(energyAlarms.configFindById, { id: value.id }).then((res) => {
value.comparisonType = value.comparisonType.split(','); if (res.msg === 'success') {
value.sbtype = [value.dataSourcesType, value.dataSourcesWay]; infoObject.value = res.data;
delete value.dataSourcesType; //
delete value.dataSourcesWay; infoObject.value.dataSources = [
infoObject.value = value; infoObject.value.dataSourcesType,
/// infoObject.value.dataSourcesWay,
deviceTypeTreeData.value.forEach((item: any) => { ];
if (item.id === infoObject.value.sbtype[0]) { delete infoObject.value.dataSourcesType;
selectDeviceType(infoObject.value.sbtype, [{ ...item }]); 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 { } else {
@ -313,7 +345,7 @@
deviceNode: null, deviceNode: null,
ruleType: null, ruleType: null,
abnormalDescription: null, abnormalDescription: null,
sbtype: null, dataSources: null,
enableRules: 0, enableRules: 0,
alarmList: [{ id: null, logic: null, num: null, isDelete: 0 }], alarmList: [{ id: null, logic: null, num: null, isDelete: 0 }],
}; };
@ -324,8 +356,7 @@
// //
const rules = { const rules = {
site: [{ required: true, message: '请选择站点', trigger: 'change' }], site: [{ required: true, message: '请选择站点', trigger: 'change' }],
sbtype: [{ required: true, message: '请选择设备类型', trigger: 'change' }], dataSources: [{ required: true, message: '请选择设备类型', trigger: 'change' }],
enableRules: [{ required: true, message: '请选择启用规则', trigger: 'change' }],
deviceNode: [{ required: true, message: '请选择设备名称', trigger: 'change' }], deviceNode: [{ required: true, message: '请选择设备名称', trigger: 'change' }],
sbAdress: [{ required: true, message: '请选择设备点位', trigger: 'change' }], sbAdress: [{ required: true, message: '请选择设备点位', trigger: 'change' }],
comparisonType: [{ 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 = () => { const btnClick = () => {
console.log(infoObject.value, '数据');
infoObject.value.alarmList.forEach((item) => { infoObject.value.alarmList.forEach((item) => {
if (item.logic === null || item.num === null) { if (item.logic === null || item.num === null) {
return; return;
@ -361,17 +389,16 @@
} }
// //
formRef.value.validate().then(() => { formRef.value.validate().then(() => {
console.log(energyAlarm.value, '数据');
// //
let data = { ...infoObject.value }; let data = { ...infoObject.value };
//id //id
data.equipmentAlarmId = energyAlarm.value.id; data.equipmentAlarmId = energyAlarm.value.id;
data.errorCode = energyAlarm.value.errorCode; data.errorCode = energyAlarm.value.errorCode;
data.dataSourcesType = data.sbtype[0]; data.dataSourcesType = data.dataSources[0];
data.dataSourcesWay = data.sbtype[1]; data.dataSourcesWay = data.dataSources[1];
delete data.dataSources;
data.hxAlarmRuleLogicList = [...infoObject.value.alarmList, ...delAlarmList.value]; data.hxAlarmRuleLogicList = [...infoObject.value.alarmList, ...delAlarmList.value];
data.comparisonType = data.comparisonType.toString; data.comparisonType = data.comparisonType.toString();
data.hxAlarmRuleLogicList.forEach((item) => { data.hxAlarmRuleLogicList.forEach((item) => {
const num = Number(item.num); const num = Number(item.num);
if (!isNaN(num)) { if (!isNaN(num)) {
@ -382,24 +409,24 @@
}); });
data.ruleType = Number(data.ruleType); data.ruleType = Number(data.ruleType);
delete data.alarmList; delete data.alarmList;
// http http
// .post(energyAlarms.configAddOrUpNewData, data) .post(energyAlarms.configAddOrUpNewData, data)
// .then((res) => { .then((res) => {
// if (res.msg === 'success') { if (res.msg === 'success') {
// // //
// if (data.id) { if (data.id) {
// NsMessage.success(''); NsMessage.success('告警规则编辑成功');
// } else { } else {
// NsMessage.success(''); NsMessage.success('告警规则新增成功');
// } }
// emit('editObject', null); emit('editObject', null);
// handleClose(); handleClose();
// } }
// }) })
// .catch((error) => { .catch((error) => {
// // //
// console.error('', error); console.error('请求失败:', error);
// }); });
}); });
}; };
// //
@ -413,7 +440,7 @@
ruleType: null, ruleType: null,
deviceNode: null, deviceNode: null,
abnormalDescription: null, abnormalDescription: null,
sbtype: null, dataSources: null,
enableRules: 0, enableRules: 0,
alarmList: [{ id: null, logic: null, num: null, isDelete: 0 }], alarmList: [{ id: null, logic: null, num: null, isDelete: 0 }],
}; };
@ -475,7 +502,7 @@
.grey-background.ant-switch .ant-switch-handle { .grey-background.ant-switch .ant-switch-handle {
background-color: grey !important; background-color: grey !important;
} }
/deep/ .ant-form-item-label { :deep(.ant-form-item-label) {
z-index: 20; z-index: 20;
text-align: right; text-align: right;
width: 23%; width: 23%;

12
hx-ai-intelligent/src/view/alarmManagement/alarmSettings/equipmentAlarm/configureDeviceAlarms.vue

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

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

@ -85,6 +85,7 @@
<a-textarea <a-textarea
v-model:value="infoObject.abnormalDescription" v-model:value="infoObject.abnormalDescription"
style="height: 32px" style="height: 32px"
placeholder="请输入异常描述"
:autoSize="{ minRows: 1, maxRows: 1 }" :autoSize="{ minRows: 1, maxRows: 1 }"
show-count show-count
:maxlength="30" /> :maxlength="30" />
@ -145,7 +146,7 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { NsMessage } from '/nerv-lib/component'; import { NsMessage } from '/nerv-lib/component';
import { ref, toRaw } from 'vue'; import { ref } from 'vue';
import type { SelectProps } from 'ant-design-vue'; import type { SelectProps } from 'ant-design-vue';
import type { ShowSearchType } from 'ant-design-vue/es/cascader'; import type { ShowSearchType } from 'ant-design-vue/es/cascader';
import { device } from '/@/api/deviceManage'; import { device } from '/@/api/deviceManage';
@ -153,7 +154,6 @@
import { http } from '/nerv-lib/util'; import { http } from '/nerv-lib/util';
import type { Rule } from 'ant-design-vue/es/form';
import { async } from '@antv/x6/lib/registry/marker/async'; import { async } from '@antv/x6/lib/registry/marker/async';
const visible = ref(false); const visible = ref(false);
@ -319,11 +319,19 @@
getDevicePoint({ id: infoObject.value.deviceName }); getDevicePoint({ id: infoObject.value.deviceName });
// //
findParentIds(deviceTypeTreeData.value, infoObject.value.deviceType, selectDevice.value); 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 || []; infoObject.value.alarmList = infoObject.value.hxAlarmRuleLogicList || [];
delete infoObject.value.hxAlarmRuleLogicList; delete infoObject.value.hxAlarmRuleLogicList;
infoObject.value.deviceType = selectDevice; infoObject.value.deviceType = selectDevice;
infoObject.value.ruleType = infoObject.value.ruleType + ''; infoObject.value.ruleType = infoObject.value.ruleType + '';
console.log(infoObject.value, '数据');
} }
}); });
} else { } else {
@ -496,7 +504,7 @@
.grey-background.ant-switch .ant-switch-handle { .grey-background.ant-switch .ant-switch-handle {
background-color: grey !important; background-color: grey !important;
} }
/deep/ .ant-form-item-label { :deep(.ant-form-item-label) {
z-index: 20; z-index: 20;
text-align: right; text-align: right;
width: 23%; width: 23%;

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

@ -40,11 +40,17 @@
</template> </template>
<template v-if="column.dataIndex === 'monitor'"> <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>
<template v-if="column.dataIndex === 'repetition'">
{{ record.repetitions.label }}
</template>
<template v-if="column.dataIndex === 'prioritys'">
{{ record.priority.label }}
</template>
</template> </template>
</ns-view-list-table> </ns-view-list-table>
<a-button <a-button
@ -77,6 +83,15 @@
clickSwitch({ type: 3, enableRules: record.enableRules, record: record }) clickSwitch({ type: 3, enableRules: record.enableRules, record: record })
" /> " />
</template> </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> </template>
</ns-view-list-table> </ns-view-list-table>
<a-button <a-button

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

@ -1,15 +1,15 @@
<template> <template>
<ns-drawer <ns-drawer
v-model:visible="visible" v-model:visible="visible"
width="520" width="600"
:title="' '" :title="'设置通知联系人'"
:ok="btnClick" :ok="btnClick"
:cancel="handleClose" :cancel="handleClose"
placement="right" placement="right"
:footer-style="{ textAlign: 'right' }" :footer-style="{ textAlign: 'right' }"
@close="handleClose"> @close="handleClose">
<div style="padding: 18px; width: 100%; overflow: hidden"> <div style="width: 100%; overflow: hidden; overflow-y: hidden; height: 100%">
<a-form ref="formRef" :model="infoObject" :rules="rules"> <a-form ref="formRef" :model="infoObject" :rules="rules" style="width: 80%">
<a-form-item ref="notification" label="通知方式" name="notification"> <a-form-item ref="notification" label="通知方式" name="notification">
<a-select <a-select
ref="select" ref="select"
@ -22,7 +22,7 @@
placeholder="请选择通知方式" placeholder="请选择通知方式"
:filter-option="filterDevicePoint" /> :filter-option="filterDevicePoint" />
</a-form-item> </a-form-item>
<a-form-item label="启用规则" name="enableRules"> <a-form-item label="启用规则">
<a-switch <a-switch
:checked="infoObject.enableRules === 1 ? true : false" :checked="infoObject.enableRules === 1 ? true : false"
:class="{ :class="{
@ -31,28 +31,61 @@
}" }"
@click="clickSwitch" /> @click="clickSwitch" />
</a-form-item> </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-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> </div>
<linkPeople
v-show="visibleModel"
ref="linkPeoples"
@handleCancel="handleCancel"
@handleOk="handleOk" />
</ns-drawer> </ns-drawer>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref } from 'vue'; 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 { number } from 'vue-types';
import { http } from '/nerv-lib/util'; import linkPeople from './linkPeople/index.vue';
// import { deviceAlarms } from '/@/api/alarmSettings/deviceAlarms'; // import { deviceAlarms } from '/@/api/alarmSettings/deviceAlarms';
@ -61,25 +94,80 @@
{ {
title: '序号', title: '序号',
dataIndex: 'address', dataIndex: 'address',
width: 80,
fixed: 'left',
customRender: (text: any) => { customRender: (text: any) => {
return text.index + 1; return text.index + 1;
}, },
}, },
{ {
title: '通知名单', title: '姓名',
dataIndex: 'name', dataIndex: 'deviceName',
key: 'name', width: 80,
fixed: 'left',
key: 'deviceName',
},
{
title: '性别',
dataIndex: 'sex',
width: 80,
key: 'sex',
},
{
title: '组织关系',
dataIndex: 'site',
key: 'site',
}, },
];
const dataSource = [
{ {
name: '运维>运维1部>张三', title: '部门',
dataIndex: 'department',
key: 'department',
}, },
{ {
name: '运维>运维1部>李四', title: '操作',
width: 80,
dataIndex: 'operation',
fixed: 'right',
}, },
]; ];
const visibleModel = ref(false);
const dataSource = ref([]);
const visible = ref(false); 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({ const infoObject = ref({
enableRules: 0, enableRules: 0,
@ -101,71 +189,30 @@
{ label: '站内信息', value: 1 }, { label: '站内信息', value: 1 },
{ label: '邮件', value: 2 }, { 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 = { const rules = {
notification: [{ required: true, message: '请选择站点', trigger: 'change' }], notification: [{ required: true, message: '请选择通知方式', trigger: 'change' }],
enableRules: [{ required: true, message: '请选择启用规则', trigger: 'change' }],
user: [{ 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 formRef = ref();
const emit = defineEmits(['editObject']); const emit = defineEmits(['editObject']);
const toggle = (value: any) => { const toggle = (value: any) => {
// //
if (value) { 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 { } else {
infoObject.value = { infoObject.value = {
enableRules: 0, enableRules: 0,
@ -173,9 +220,26 @@
} }
visible.value = !visible.value; 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 = () => { const btnClick = () => {
console.log(infoObject.value); 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(() => { formRef.value.validate().then(() => {
// //
@ -190,22 +254,13 @@
// //
formRef.value.resetFields(); formRef.value.resetFields();
visible.value = false; visible.value = false;
options.value = [ visibleModel.value = false;
{
value: 'zhejiang',
label: 'Zhejiang',
isLeaf: false,
},
{
value: 'jiangsu',
label: 'Jiangsu',
isLeaf: false,
},
];
}; };
defineExpose({ defineExpose({
toggle, toggle,
handleClose, handleClose,
handleCancel,
handleChangePage,
formRef, formRef,
}); });
</script> </script>
@ -238,9 +293,9 @@
.grey-background.ant-switch .ant-switch-handle { .grey-background.ant-switch .ant-switch-handle {
background-color: grey !important; background-color: grey !important;
} }
/deep/ .ant-form-item-label { :deep(.ant-form-item-label) {
z-index: 20; z-index: 20;
text-align: right; text-align: left;
width: 23%; width: 20%;
} }
</style> </style>

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

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

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

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

10
hx-ai-intelligent/src/view/alarmManagement/alarmSettings/ts/energyAlarmConfig.ts

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

8
hx-ai-intelligent/src/view/alarmManagement/alarmSettings/ts/equipmentAlarmConfig.ts

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

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

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

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

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

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

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

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

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

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

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

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

@ -36,27 +36,31 @@
:expanded-keys="expandedKeys" :expanded-keys="expandedKeys"
:auto-expand-parent="autoExpandParent" :auto-expand-parent="autoExpandParent"
@expand="onExpand"> @expand="onExpand">
<template #title="{ emissionName }"> <template #title="data">
<span v-if="emissionName && selectTreeDataValue && emissionName.indexOf(selectTreeDataValue) > -1"> <div class="treeRow">
{{ emissionName.substring(0, emissionName.indexOf(selectTreeDataValue)) }} <div>
<span style="color: #f50">{{ selectTreeDataValue }}</span> <span v-if="data.emissionName && selectTreeDataValue && data.emissionName.indexOf(selectTreeDataValue) > -1">
{{ emissionName.substring(emissionName.indexOf(selectTreeDataValue) + selectTreeDataValue.length) }} {{ data.emissionName.substring(0, data.emissionName.indexOf(selectTreeDataValue)) }}
</span> <span style="color: #f50" >{{ selectTreeDataValue }}</span>
<span v-else>{{ emissionName }}</span> {{ data.emissionName.substring(data.emissionName.indexOf(selectTreeDataValue) + selectTreeDataValue.length) }}
</template> </span>
</a-tree> <span v-else>{{ data.emissionName }}</span>
<a-popover v-if="showOperation" placement="rightTop" trigger="focus"> </div>
<template #content> <a-dropdown>
<div style="display: flex;flex-direction: column;"> <ns-icon name="actionMore" size="14" class="actionMore" />
<a-button type="text" @click="editTreeNodeData">编辑</a-button> <template #overlay>
<a-button type="text" @click="addTreeNodeData">新增子节点</a-button> <a-menu>
<a-button type="text">上移</a-button> <a-menu-item @click="editTreeNodeData">编辑</a-menu-item>
<a-button type="text">下移</a-button> <a-menu-item @click="addTreeNodeData">新增子节点</a-menu-item>
<a-button type="text" @click="deleteTreeNode">删除</a-button> <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> </div>
</template> </template>
<MoreOutlined style="position: absolute;right: 0;top: 16%;font-size: 25px;cursor: pointer;" /> </a-tree>
</a-popover>
<div class="addTreeNode"> <div class="addTreeNode">
<a-button type="primary" style="width:100%;" @click="addTreeNodeData">新增</a-button> <a-button type="primary" style="width:100%;" @click="addTreeNodeData">新增</a-button>
</div> </div>
@ -82,6 +86,7 @@
@close="onClose"> @close="onClose">
<ns-form <ns-form
ref="formRef" ref="formRef"
:schemas="formSchema"
:model="formData" :model="formData"
class="form" class="form"
:wrapperCol="{ span: 20 }" :wrapperCol="{ span: 20 }"
@ -91,12 +96,100 @@
<a-button type="primary" @click="onEdit">确定</a-button> <a-button type="primary" @click="onEdit">确定</a-button>
</template> </template>
</a-drawer> </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> </div>
</template> </template>
<script lang="ts" setup> <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 { 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 { http } from '/nerv-lib/util/http';
import { NsMessage, NsModal } from '/nerv-lib/component'; import { NsMessage, NsModal } from '/nerv-lib/component';
import { formConfig, formConfig2 } from './config'; import { formConfig, formConfig2 } from './config';
@ -106,7 +199,7 @@
AntTreeNodeDropEvent, AntTreeNodeDropEvent,
TreeProps, TreeProps,
} from 'ant-design-vue/es/tree'; } from 'ant-design-vue/es/tree';
import { log } from 'node:console'; import { log } from 'node:console';
defineOptions({ name: 'OrderListIndex' }); defineOptions({ name: 'OrderListIndex' });
const selectTreeDataValue = ref<string>(''); const selectTreeDataValue = ref<string>('');
@ -115,6 +208,7 @@ import { log } from 'node:console';
let formData = ref({}); let formData = ref({});
const formRef = ref(); const formRef = ref();
const visible = ref(false); const visible = ref(false);
const unitManagement = ref(false);
const searchValue = ref<string>(''); const searchValue = ref<string>('');
const searchValue2 = ref<string>(''); const searchValue2 = ref<string>('');
const disabled = ref(false); const disabled = ref(false);
@ -149,7 +243,7 @@ import { log } from 'node:console';
const y = 2; const y = 2;
const z = 1; const z = 1;
const genData: TreeProps['treeData'] = []; const genData: TreeProps['treeData'] = [];
const checkedTreeNodeKeys = ref<string[]>(['0-0']); const checkedTreeNodeKeys = ref<string[]>();
const generateData = (_level: number, _preKey?: string, _tns?: TreeProps['treeData']) => { const generateData = (_level: number, _preKey?: string, _tns?: TreeProps['treeData']) => {
const preKey = _preKey || '0'; const preKey = _preKey || '0';
@ -357,15 +451,15 @@ import { log } from 'node:console';
fetch(carbonEmissionFactorLibrary.getCarbonFactorTree, params).then((res) => { fetch(carbonEmissionFactorLibrary.getCarbonFactorTree, params).then((res) => {
gData.value = res.data gData.value = res.data
// //
const selectedNodes = []; // const selectedNodes = [];
checkedTreeNodeKeys.value.forEach(key => { // checkedTreeNodeKeys.value.forEach(key => {
const [parentId, childId] = key.split('-').map(Number); // const [parentId, childId] = key.split('-').map(Number);
if (parentId >= 0 && childId >= 0 && gData.value[parentId]?.children?.[childId]) { // if (parentId >= 0 && childId >= 0 && gData.value[parentId]?.children?.[childId]) {
selectedNodes.push(gData.value[parentId]); // selectedNodes.push(gData.value[parentId]);
} // }
}); // });
// id // id
getDefaultIds(selectedNodes) // getDefaultIds(selectedNodes)
}); });
}; };
const defaultIds = ref([]) const defaultIds = ref([])
@ -427,7 +521,12 @@ import { log } from 'node:console';
formData.value = {}; formData.value = {};
userAuthList.value.splice(0); userAuthList.value.splice(0);
}; };
const closeUnitManag = () => {
unitTreeParams.value = {
grp: 'MEASUREMENT_UNIT'
}
unitManagement.value = false;
};
const onEdit = () => { const onEdit = () => {
formRef.value?.triggerSubmit().then(() => { formRef.value?.triggerSubmit().then(() => {
console.log(formData.value, 'formData.value'); console.log(formData.value, 'formData.value');
@ -496,6 +595,18 @@ import { log } from 'node:console';
api: carbonEmissionFactorLibrary.del, api: carbonEmissionFactorLibrary.del,
dynamicParams: { ids: 'id[]' }, dynamicParams: { ids: 'id[]' },
}, },
{
label: '单位管理',
type: 'primary',
name: 'userAdd',
handle: () => {
unitManagement.value = true,
fetch(carbonEmissionFactorLibrary.findOutermost).then((res) => {
groupData.value = res.data
});
getUnitTree()
},
},
], ],
columns: [ columns: [
{ {
@ -678,6 +789,146 @@ import { log } from 'node:console';
// pagination: { defaultPageSize: 10 }, // pagination: { defaultPageSize: 10 },
rowKey: 'id', 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> </script>
<style lang="less" scoped> <style lang="less" scoped>
.main { .main {
@ -695,7 +946,6 @@ import { log } from 'node:console';
// box-shadow: @ns-content-box-shadow; // box-shadow: @ns-content-box-shadow;
flex: 1; flex: 1;
} }
display: flex; display: flex;
flex-direction: column; flex-direction: column;
.top{ .top{
@ -726,4 +976,34 @@ import { log } from 'node:console';
padding-bottom: 10px; padding-bottom: 10px;
border-bottom: 1px solid #e9e9e9; 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> </style>

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

@ -77,4 +77,66 @@ export const tableColumns = [
key: 'action', key: 'action',
width: 130 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',
},
]; ];

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

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

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

@ -1,16 +1,14 @@
<!-- @format -->
<template> <template>
<div class="main"> <div class="main">
<div class="left"> <div class="left">
<div class="top"> <div class="top">
<a-form style="width: 100%;margin: 0 auto;"> <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%;"> <div style="padding: 0 16px !important;width: 100%;">
<a-row> <a-row>
<a-col :span="24" style="margin-bottom: 16px;"> <a-col :span="24" style="margin-bottom: 16px;">
<a-input-search <a-input-search
v-model:value="selectTreeDataValue" v-model:value="searchValue"
placeholder="请输入关键词" placeholder="请输入关键词"
@search="onSearchTreeData" @search="onSearchTreeData"
/> />
@ -20,117 +18,131 @@
</a-form> </a-form>
<a-tree <a-tree
v-if="gData && gData.length > 0" 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" :expanded-keys="expandedKeys"
:auto-expand-parent="autoExpandParent" :auto-expand-parent="autoExpandParent"
@expand="onExpand"> :tree-data="gData"
<template #title="{ emissionName }"> show-line
<span v-if="emissionName && selectTreeDataValue && emissionName.indexOf(selectTreeDataValue) > -1"> @expand="onExpand"
{{ emissionName.substring(0, emissionName.indexOf(selectTreeDataValue)) }} @select="onSelect"
<span style="color: #f50">{{ selectTreeDataValue }}</span> style="padding: 0 16px !important;"
{{ emissionName.substring(emissionName.indexOf(selectTreeDataValue) + selectTreeDataValue.length) }} >
<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>
<span v-else>{{ emissionName }}</span> <span v-else>{{ data.energyType }}</span>
</template> </template>
</a-tree> </a-tree>
</div> </div>
</div> </div>
<div class="right"> <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> </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> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { Modal } from 'ant-design-vue'; import { ref, watch, toRaw } from 'vue';
import { computed, createVNode, defineComponent, reactive, ref, watchEffect,watch } 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 { http } from '/nerv-lib/util/http';
import { NsMessage, NsModal } from '/nerv-lib/component'; import { quickCalculation,carbonEmissionFactorLibrary } from '/@/api/carbonEmissionFactorLibrary';
import { carbonEmissionFactorLibrary } from '/@/api/carbonEmissionFactorLibrary'; defineOptions({
import type { energyType: 'quickCalculation', // name
AntTreeNodeDragEnterEvent, components: {
AntTreeNodeDropEvent, 'a-pagination': Pagination,
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: {},
});
watchEffect(() => {
disabled.value = opMap.value.type === 'edit';
}); });
const casData = ref([]);
const treeData = ref([]);
const userAuthList = ref([]);
const orgId = ref(''); const orgId = ref('');
const result = JSON.parse(sessionStorage.getItem('ORGID')!); const result = JSON.parse(sessionStorage.getItem('ORGID')!);
orgId.value = result; orgId.value = result;
const dynamicDisabled = computed(() => { const fetch = (api, params = { orgId } ) => {
return formRef.value?.validateResult && userAuthList.value?.length;
});
const fetch = (api, params = { orgId }) => {
return http.post(api, params); return http.post(api, params);
}; };
//
//
const x = 3; const x = 3;
const y = 2; const y = 2;
const z = 1; const z = 1;
const genData: TreeProps['treeData'] = []; const genData: TreeProps['treeData'] = [];
const checkedTreeNodeKeys = ref<string[]>(['0-0']);
const generateData = (_level: number, _preKey?: string, _tns?: TreeProps['treeData']) => { const generateData = (_level: number, _preKey?: string, _tns?: TreeProps['treeData']) => {
const preKey = _preKey || '0'; const preKey = _preKey || '0';
@ -154,70 +166,7 @@ import { log } from 'node:console';
}); });
}; };
generateData(z); 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 dataList: TreeProps['treeData'] = [];
const generateList = (data: TreeProps['treeData']) => { const generateList = (data: TreeProps['treeData']) => {
for (let i = 0; i < data.length; i++) { for (let i = 0; i < data.length; i++) {
@ -249,13 +198,23 @@ import { log } from 'node:console';
return parentKey; return parentKey;
}; };
const expandedKeys = ref<(string | number)[]>([]); const expandedKeys = ref<(string | number)[]>([]);
const searchValue = ref<string>('');
const autoExpandParent = ref<boolean>(true); const autoExpandParent = ref<boolean>(true);
const gData = ref<TreeProps['treeData']>(genData);
const onExpand = (keys: string[]) => { const onExpand = (keys: string[]) => {
expandedKeys.value = keys; expandedKeys.value = keys;
autoExpandParent.value = false; 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 const expanded = dataList
.map((item: TreeProps['treeData'][number]) => { .map((item: TreeProps['treeData'][number]) => {
if (item.title.indexOf(value) > -1) { if (item.title.indexOf(value) > -1) {
@ -265,273 +224,120 @@ import { log } from 'node:console';
}) })
.filter((item, i, self) => item && self.indexOf(item) === i); .filter((item, i, self) => item && self.indexOf(item) === i);
expandedKeys.value = expanded; expandedKeys.value = expanded;
selectTreeDataValue.value = value; searchValue.value = value;
autoExpandParent.value = true; autoExpandParent.value = true;
}); });
// //
const onSearchTreeData = (selectTreeDataValue: string) => { const onSearchTreeData = () => {
console.log('use value', selectTreeDataValue);
console.log('or use this.value', value.value);
}; };
// //
const checkedIds = ref([]) const getTreeData = () => {
const emissionType = ref() fetch(quickCalculation.carbonQuickTree).then((res) => {
const checkTreeNode = (checkedKeys, info) => { gData.value = res.data
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 = () => { getTreeData()
addTreeNode.value = '' //
treeNodeAdd.value = false; const total = ref<number>()
}; const queryParams = ref({
// pageNum: 1,
const getOrgTree = (params?) => { pageSize: 10,
fetch(carbonEmissionFactorLibrary.getCarbonFactorTree, params).then((res) => { orgId: orgId.value,
gData.value = res.data })
// const tableData = ref([]);
const selectedNodes = []; //
checkedTreeNodeKeys.value.forEach(key => { const getTableList = () => {
const [parentId, childId] = key.split('-').map(Number); fetch(quickCalculation.queryCarbonEmissionPage,queryParams.value).then((res) => {
if (parentId >= 0 && childId >= 0 && gData.value[parentId]?.children?.[childId]) { tableData.value = res.data.records
selectedNodes.push(gData.value[parentId]); total.value = res.data.total
}
});
// id
getDefaultIds(selectedNodes)
}); });
}; };
const defaultIds = ref([]) getTableList()
const getDefaultIds = (selectedNodes) => { //
selectedNodes.forEach(items => { const onChange = (pageNumber: number,size: number) => {
defaultIds.value.push(items.id) queryParams.value.pageNum = pageNumber;
if(items.children){ queryParams.value.pageSize = size;
getDefaultIds(items.children) getTableList()
}
})
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 = () => { const formRef = ref();
console.log(searchValue.value); const labelCol = { span: 6 };
getOrgTree({ orgName: searchValue.value, orgId }); const wrapperCol = { span: 18 };
const formState = ref({})
const visible = ref(false);
// form
const rules: Record<string, Rule[]> = {
energyType: [{ required: true, message: '请输入能源种类', trigger: 'change' }],
}; };
//
const tableFetch = (params) => { const addNewData = () => {
console.log(params, 'sdfasfasdfasdfasdf'); visible.value = true
getNewTable()
tableConfig.value.params = {
...mainRef.value.params,
...params,
};
setTimeout(() => {
mainRef.value?.nsTableRef.reload();
}, 100);
}; };
//
const handleSelect = (selectedKeys: any, info: any) => { const selectedRowKeys = ref([]);
fetch(carbonEmissionFactorLibrary.queryDeptTree, { orgId: info.node?.orgInfo.orgId }).then((res) => { const onSelectionChange = (selectedKeys, selectedRows) => {
treeData2.value = res.data; 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
}); });
tableFetch({ orgId: info.node?.orgInfo.orgId });
}; };
//
const editData = (record) =>{
const onClose = () => { visible.value = true
visible.value = false;
formData.value = {};
userAuthList.value.splice(0);
}; };
//
const onEdit = () => { const onSubmit = () => {
formRef.value?.triggerSubmit().then(() => { formRef.value
console.log(formData.value, 'formData.value'); .validate()
// if (!userAuthList.value.length) { .then(() => {
// NsMessage.error(''); console.log('values', formState, toRaw(formState));
// return; fetch(quickCalculation.creat,formState.value).then((res) => {
// } console.log(res);
opMap.value.fuc && });
opMap.value.fuc({ ...formData.value }); })
}); .catch(error => {
console.log('error', error);
});
}; };
const tableConfig = ref({ //
title: '数据库', const delData = (record) => {
api: carbonEmissionFactorLibrary.getTableList, Modal.confirm({
params: { title: '警告',
orgId, content: '确定要删除吗?',
emissionType okText: '确定',
}, okType: 'primary',
headerActions: [ cancelText: '取消',
{ onOk() {
label: '新增', fetch(quickCalculation.del , {id : record.id }).then((res) => {
name: 'userAdd', message.success('操作成功!');
type: 'primary', getTableList()
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',
}, },
{ onCancel() {
title: '排放类型', console.log('Cancel');
dataIndex: 'emissionTypeColumn',
}, },
{ });
title: '排放气体', };
dataIndex: 'emissionGas', //
}, const onClose = () => {
{ visible.value = false;
title: '排放环节', selectedRowKeys.value = [];
dataIndex: 'emissionProcess', formRef.value.resetFields();
}, };
{
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> </script>
<style lang="less" scoped> <style lang="less" scoped>
.main { .main {
background-color: @ns-content-bg; background-color: @ns-content-bg;
@ -540,13 +346,10 @@ import { log } from 'node:console';
} }
.left { .left {
width: 300px; width: 300px;
// max-height: calc(100vh - 96px);
margin-right: @ns-gap; margin-right: @ns-gap;
min-width: fit-content; min-width: fit-content;
> div { > div {
border-radius: @ns-border-radius;
background-color: @white; background-color: @white;
// box-shadow: @ns-content-box-shadow;
flex: 1; flex: 1;
} }
@ -565,12 +368,14 @@ import { log } from 'node:console';
.right { .right {
flex: 1; flex: 1;
min-width: 0; min-width: 0;
height: 100%;
background: #ffffff;
}
::v-deep .ant-table-container{
padding: 0px 16px;
} }
.top { .top {
overflow: auto; overflow: auto;
// height: 50%;
// border-bottom: 5px solid rgb(229, 235, 240);
// overflow-y: auto;
} }
.ns-form-title{ .ns-form-title{
font-weight: bold; font-weight: bold;
@ -580,4 +385,24 @@ import { log } from 'node:console';
padding-bottom: 10px; padding-bottom: 10px;
border-bottom: 1px solid #e9e9e9; 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>
<style scoped>
th.column-money,
td.column-money {
text-align: right !important;
}
</style>

141
hx-ai-intelligent/src/view/equipmentControl/lightingManage/dialogStyle.less

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

1108
hx-ai-intelligent/src/view/equipmentControl/lightingManage/index.less

File diff suppressed because it is too large

156
hx-ai-intelligent/src/view/equipmentControl/lightingManage/indexs.less

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

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

@ -3,19 +3,19 @@
<div class="lighting-img-box"> <div class="lighting-img-box">
<!-- 左上角区域切换 --> <!-- 左上角区域切换 -->
<div class="btn-box"> <div class="btn-box">
<button class="btn-item">1F</button> <button class="btn-item" @click=changeArea(1)>1F</button>
<button class="btn-item">2F</button> <button class="btn-item" @click=changeArea(2)>2F</button>
<button class="btn-item">站台</button> <button class="btn-item" @click=changeArea(3)>站台</button>
</div> </div>
<!-- 楼层区域 --> <!-- 楼层区域 -->
<div class="area"> <div class="area">
<div <div
v-for="(item, index) in treeData" v-for="(item, index) in treeData"
:class="computedClass(item.id)" :class="computedClass(String(item.id))"
@click="getArea(item.id)" @click="getArea(item)"
:key="index"> :key="index">
<div v-for="(v, i) in item.children" :key="i" class="light-group"> <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> </div>
</div> </div>
@ -40,16 +40,18 @@
placement="right" placement="right"
:body-style="{ background: 'rgba(0, 0, 0)', opacity: 0.8 }" :body-style="{ background: 'rgba(0, 0, 0)', opacity: 0.8 }"
:closable="false" :closable="false"
id="Odrawer" id="drawer"
:maskStyle="{ 'background-color': 'rgba(0, 0, 0, 0)' }"> :maskStyle="{ 'background-color': 'rgba(0, 0, 0, 0)' }">
<a-tabs v-model:activeKey="activeKey"> <a-tabs v-model:activeKey="activeKey">
<a-tab-pane key="1" tab="控制面板"> <a-tab-pane key="1" tab="控制面板">
<tabs1 @changeArea="getArea" :treeData="treeData"></tabs1> <tabs1 @changeArea="getArea" :treeData="treeData"></tabs1>
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="2" tab="计划列表" force-render> <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>
<a-tab-pane key="3" tab="日志"></a-tab-pane>
</a-tabs> </a-tabs>
</a-drawer> </a-drawer>
</div> </div>
@ -61,15 +63,17 @@ import { ref } from 'vue';
import { treeData } from './treeData' import { treeData } from './treeData'
import light from './light.vue'; import light from './light.vue';
import tabs1 from './tabs1.vue' import tabs1 from './tabs1.vue'
import tabs2 from './tabs2.vue'
import tabs3 from './tabs3.vue'
// ICON // ICON
import { import {
DoubleLeftOutlined, DoubleLeftOutlined,
DoubleRightOutlined DoubleRightOutlined
} from '@ant-design/icons-vue'; } from '@ant-design/icons-vue';
// - - // - -
let area = ref(['1']) const area = ref(['1'])
// - // - -
const bulbs = ref([ const bulbs = ref([
{ {
styleText: { left: '190px', bottom: '200px' }, 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) => { const getArea = (result: any) => {
// //
@ -132,16 +146,14 @@ const getArea = (result: any) => {
area.value[0] = String(result) area.value[0] = String(result)
} }
} }
// -
// - // -
const computedClass = (number: number) => { const computedClass = (string: string) => {
if (area.value.indexOf(number) != -1) { if (area.value.indexOf(string) != -1) {
return `isActive area-item area${number}` return `isActive area-item area${string}`
} else { } else {
return `area-item area${number}` return `area-item area${string}`
} }
} }
// - tab // - tab
let activeKey = ref('1'); let activeKey = ref('1');
// - // -
@ -153,7 +165,7 @@ const toggleDrawer = () => {
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
@import "./indexs.less"; @import "./index.less";
.isActive { .isActive {
border: 3px solid white !important; border: 3px solid white !important;
} }

15
hx-ai-intelligent/src/view/equipmentControl/lightingManage/indexs1.vue

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

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

@ -12,7 +12,7 @@
<div class="area"> <div class="area">
<template v-if="!showAllButtonsArea"> <template v-if="!showAllButtonsArea">
<button v-for="(button, index) in limitedButtons1" :key="index" <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.label }}
</button> </button>
<div style="margin-top: 10px"> <div style="margin-top: 10px">
@ -20,8 +20,8 @@
</div> </div>
</template> </template>
<template v-else> <template v-else>
<button v-for="(button, index) in props.treeData" :key="index" <button v-for="(button, index) in props.treeData" :key="index" :class="{ btn: true, selected: button.selected }"
:class="{ btn: true, selected: button.selected }" @click="selectButton(button)"> @click="selectButton(button)">
{{ button.label }} {{ button.label }}
</button> </button>
<div style="margin-top: 10px"> <div style="margin-top: 10px">
@ -36,7 +36,7 @@
<div class="circuit-tab"></div> <div class="circuit-tab"></div>
<span class="circuit-text">照明回路</span> <span class="circuit-text">照明回路</span>
<div class="btn2"> <div class="btn2">
<button class="openplan" :class="{ enabled2: isPlanEnabled2, disabled2: !isPlanEnabled2 }" @click="togglePlan2"> <button class="openPlan" :class="{ enabled2: isPlanEnabled2, disabled2: !isPlanEnabled2 }" @click="togglePlan2">
{{ isPlanEnabled2 ? '启用面板' : '禁用面板' }} {{ isPlanEnabled2 ? '启用面板' : '禁用面板' }}
</button> </button>
<a-switch v-model:checked="selectAllCheckbox" :disabled="singleSelection" :class="{ <a-switch v-model:checked="selectAllCheckbox" :disabled="singleSelection" :class="{
@ -49,7 +49,7 @@
</button> </button>
</div> </div>
</div> </div>
<div class="btnarea" v-if="selectedButton"> <div class="btnArea" v-if="selectedButton">
<template v-if="!showAllButtons"> <template v-if="!showAllButtons">
<button v-for="(button2, index) in limitedButtons2" :key="index" <button v-for="(button2, index) in limitedButtons2" :key="index"
:class="{ btn: true, selected: button2.selected }" class="zmhlbtn" @click="toggleSelection(button2)"> :class="{ btn: true, selected: button2.selected }" class="zmhlbtn" @click="toggleSelection(button2)">
@ -80,7 +80,7 @@
<!-- 控制模式按钮部分 --> <!-- 控制模式按钮部分 -->
<div class="control-mode-btn-area" v-show="showControlMode"> <div class="control-mode-btn-area" v-show="showControlMode">
<button v-for="(button3, index) in controlType" :key="index" <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 }} {{ button3.name }}
</button> </button>
</div> </div>
@ -119,7 +119,7 @@
:style="{ height: '50px' }"> :style="{ height: '50px' }">
<td>{{ row.num }}</td> <td>{{ row.num }}</td>
<td>{{ row.light }}</td> <td>{{ row.light }}</td>
<td>{{ row.tempruter }}</td> <td>{{ row.temperature }}</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@ -130,170 +130,71 @@
<button class="flushed" @click="refresh">刷新</button> <button class="flushed" @click="refresh">刷新</button>
<button class="execute" @click="showModal">执行</button> <button class="execute" @click="showModal">执行</button>
</div> </div>
<!-- <a-modal :v-if="cxlist.length === 0" v-model:visible="executevisible" width="500px" height="792px" okText="执行"
:closable="false" @ok="handleOk2" :mask="false" :bodyStyle="{ <div class="out-dialog" v-if="executeVisible">
opacity: 1, <div class="content" v-if="executeVisible">
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> <div>
<div class="div-operation"></div> <div class="div-operation"></div>
<span class="text-operation">变更内容 </span> <span class="text-operation">变更内容 </span>
</div> </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="journal" style="margin-top: 20px">
<div class="imgText"> <div class="imgText">
<div class="zjzm"> <div class="zjzm">
<img class="titleimg" src="/asset/image//bulbLogo/21961.png" alt="" />&nbsp; <img class="title-img" src="/asset/image//bulbLogo/21961.png" alt="" />&nbsp;
<span class="titletext" style="font-size: 20px; font-weight: 500; color: rgba(255, 255, 255, 1)">{{ <span class="title-text" style="font-size: 20px; font-weight: 500; color: rgba(255, 255, 255, 1)">{{ item.name }}</span>
item.name }}</span>
</div> </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>
<div class="temp-btn"> <div class="btn-box">
<button style=" <div class="btn-item">
width: 68px; <div class="left">控制模式</div>
height: 40px; <div class="right">
border-radius: 4px; <span>手动</span>
background: linear-gradient( <img src="/asset/image/bulbLogo/22406.png" alt="" />
180deg, <span>自动</span>
rgba(1, 206, 255, 1) 0%, </div>
rgba(0, 150, 229, 1) 100% </div>
); <div class="btn-item">
border: 1px solid rgba(95, 154, 251, 1); <div class="left">
color: rgba(255, 255, 255, 1); 亮度
font-size: 14px; </div>
font-weight: 400; <div class="right">
"> <span>100lux</span>
色温 <img src="/asset/image/bulbLogo/22406.png" alt="" />
</button> <span>30lux</span>
<span style=" </div>
color: rgba(255, 255, 255, 1); </div>
font-size: 14px; <div class="btn-item">
font-weight: 400; <div class="left">
margin-left: 12px; 控制场景
margin-right: 8px; </div>
">4000k</span> <div class="right">
<img src="/asset/image/bulbLogo/22406.png" alt="" /> <span>手动</span>
<span style=" <img src="/asset/image/bulbLogo/22406.png" alt="" />
color: rgba(255, 255, 255, 1); <span>自动</span>
font-size: 14px; </div>
font-weight: 400; </div>
margin-left: 8px; <div class="btn-item">
">3800k</span> <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> </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> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -307,19 +208,23 @@ import {
// //
onMounted(() => { 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({ const props = defineProps({
// > // >
treeData: { treeData: {
type: Array type: Array,
default: []
}, },
line: {
type: Array
}
}); });
const emit = defineEmits(['changeArea']); const emit = defineEmits(['changeArea']);
@ -336,20 +241,13 @@ const togglePlan = () => {
const showAllButtonsArea = ref(false); const showAllButtonsArea = ref(false);
// - - 1 // - - 1
const selectedButton = ref('1'); const selectedButton = ref('1');
// - // - -
const selectButton = (button: any, index: number) => { const selectButton = (button: any) => {
// //
selectedButton.value = button; selectedButton.value = button;
// //
props.treeData.forEach(item => { initMenu(1)
item.selected = false
})
button.selected = true button.selected = true
// 1
buttons2.value.forEach(item => {
item.selected = false
})
showControlMode.value = false
buttons2.value = button.children buttons2.value = button.children
// area // area
emit('changeArea', []); emit('changeArea', []);
@ -375,17 +273,8 @@ const togglePlan2 = () => {
isPlanEnabled2.value = !isPlanEnabled2.value; isPlanEnabled2.value = !isPlanEnabled2.value;
// - // -
if (isPlanEnabled2.value) { if (isPlanEnabled2.value) {
item.selected = false;
item.stop = true 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 { } else {
item.stop = false item.stop = false
} }
@ -410,12 +299,10 @@ const toggleAllSelection = () => {
// //
if (selectAllCheckbox.value) { if (selectAllCheckbox.value) {
buttons2.value.forEach((item) => { buttons2.value.forEach((item) => {
if (!item.stop) { item.selected = true;
item.selected = true; arr.push(item.id)
arr.push(item.id)
}
}); });
// //
} else { } else {
buttons2.value.forEach((item) => { buttons2.value.forEach((item) => {
item.selected = false; item.selected = false;
@ -431,7 +318,7 @@ const toggleSelection = (button: any) => {
zmhlid.value = button.id zmhlid.value = button.id
// / // /
if (button.stop) { if (button.stop) {
return isPlanEnabled2.value = true isPlanEnabled2.value = true
} else { } else {
isPlanEnabled2.value = false isPlanEnabled2.value = false
} }
@ -455,19 +342,24 @@ const toggleSelection = (button: any) => {
arr.push(item.id) arr.push(item.id)
} }
}); });
console.log(arr)
emit('changeArea', arr) emit('changeArea', arr)
} }
// //
if (button.selected) { if (button.selected) {
//
showControlMode.value = true showControlMode.value = true
thisButtonType.value = button.type
thisButton.value = button thisButton.value = button
if (button.type == 3) {
showControlScene.value = true
} else {
showControlScene.value = false
}
} else { } else {
//
showControlMode.value = false showControlMode.value = false
thisButton.value = null thisButton.value = { type: '0' }
} }
}; };
// - // -
const showAllButtons = ref(false); const showAllButtons = ref(false);
@ -479,16 +371,12 @@ const buttons2 = ref([]);
// ======================================================================= // =======================================================================
// - // -
const showControlMode = ref(false); const showControlMode = ref(false);
const thisButtonType = ref(null) const thisButton = ref({ type: '0' })
const thisButton = ref(null)
// -
const selectedButton3 = ref('');
// - // -
const selectButton3 = (button3) => { const selectButton3 = (button3) => {
thisButton.value.type = button3.type thisButton.value.type = button3.type
thisButtonType.value = button3.type
showControlScene.value = button3.name === '手动'; showControlScene.value = button3.name === '手动';
selectedButton4.value = ''; // selectedButton4.value = null; //
}; };
// ======================================================================= // =======================================================================
@ -502,7 +390,7 @@ const controlSceneButtons = ref([
{ label: '客流高峰', selected: false }, { label: '客流高峰', selected: false },
]); ]);
// - // -
const selectedButton4 = ref(''); const selectedButton4 = ref(null);
// - // -
const selectButton4 = (button4) => { const selectButton4 = (button4) => {
selectedButton4.value = button4.label; 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) => { const handleRowClick = (index: any) => {
trindex.value = index; trIndex.value = index;
if (index === trindex.value) { if (index === trIndex.value) {
console.log('tri'); console.log('tri');
} }
// };
logModalVisible.value = true;
};
// ======================================================================== // ========================================================================
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 = () => { if (cxList.value.length === 0) {
selectedButton.value = {}; 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; showControlMode.value = false;
//
showControlScene.value = false; showControlScene.value = false;
selectedButton3.value = null; //
selectedButton4.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 executeVisible = ref<boolean>(false);
const showModal = () => { const showModal = () => {
executevisible.value = true; executeVisible.value = true;
}; };
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
@import "./dialogStyle.less";
// //
.drawer-item { .drawer-item {
@ -614,7 +581,7 @@ const executevisible = ref<boolean>(false);
cursor: not-allowed; cursor: not-allowed;
} }
.openplan.enabled2 { .openPlan.enabled2 {
border: none; border: none;
font-size: 14px; font-size: 14px;
font-weight: 400; font-weight: 400;
@ -627,7 +594,7 @@ const executevisible = ref<boolean>(false);
color: white; color: white;
} }
.openplan.disabled2 { .openPlan.disabled2 {
border: none; border: none;
font-size: 14px; font-size: 14px;
font-weight: 400; font-weight: 400;
@ -639,7 +606,7 @@ const executevisible = ref<boolean>(false);
background-color: red; background-color: red;
} }
.openplan:disabled { .openPlan:disabled {
cursor: not-allowed; cursor: not-allowed;
} }
@ -714,7 +681,7 @@ const executevisible = ref<boolean>(false);
} }
.area, .area,
.btnarea, .btnArea,
.control-mode-btn-area, .control-mode-btn-area,
.control-scene-btn-area { .control-scene-btn-area {
margin-left: -17px; margin-left: -17px;
@ -828,7 +795,6 @@ const executevisible = ref<boolean>(false);
position: fixed; position: fixed;
bottom: 0; bottom: 0;
right: 0; right: 0;
margin-bottom: 10px;
} }
.execute { .execute {
@ -836,6 +802,7 @@ const executevisible = ref<boolean>(false);
width: 74px; width: 74px;
height: 40px; height: 40px;
opacity: 1; opacity: 1;
cursor: pointer;
border-radius: 4px; border-radius: 4px;
background: rgba(67, 136, 251, 1); background: rgba(67, 136, 251, 1);
font-size: 14px; font-size: 14px;
@ -848,6 +815,7 @@ const executevisible = ref<boolean>(false);
.flushed { .flushed {
width: 74px; width: 74px;
height: 40px; height: 40px;
cursor: pointer;
opacity: 1; opacity: 1;
border-radius: 4px; border-radius: 4px;
font-size: 14px; font-size: 14px;
@ -857,50 +825,6 @@ const executevisible = ref<boolean>(false);
border: 1px solid rgba(193, 197, 204, 1); 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) { :deep(.ant-table-pagination) {
visibility: hidden; visibility: hidden;
} }
@ -1006,9 +930,12 @@ const executevisible = ref<boolean>(false);
display: flex; display: flex;
align-items: center; align-items: center;
} }
.zmhlbtn { .zmhlbtn {
position: relative; position: relative;
} }
//
.anticon-stop { .anticon-stop {
position: absolute; position: absolute;
right: 3px; right: 3px;

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

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

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

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

267
hx-ai-intelligent/src/view/equipmentManage/group/config.ts

@ -1,38 +1,46 @@
import { NsSelect } from './../../../../../lib/component/form/select/index';
import { dateUtil } from '/nerv-lib/util/date-util'; import { dateUtil } from '/nerv-lib/util/date-util';
import data from './mock.json'; import data from './mock.json';
import { http } from '/nerv-lib/util'; import { http } from '/nerv-lib/util';
import { ref } from 'vue'; import { ref } from 'vue';
import { group } from '/@/api/deviceManage'; import { device, group } from '/@/api/deviceManage';
import { dict } from '/@/api'; import { dict } from '/@/api';
import { origanizemanage } from '/@/api/origanizemanage'; import { origanizemanage } from '/@/api/origanizemanage';
const tableCalKeyMap = [ const tableCalKeyMap = [
{ {
title: '来源企业', title: '来源企业',
dataIndex: 'orgName', dataIndex: 'linkOrgName',
// textEllipsis: true, textEllipsis: true,
// textNumber: 4, textNumber: 10,
}, },
{ {
title: '设备id', title: '设备id',
textNumber: 10,
dataIndex: 'deviceCode', dataIndex: 'deviceCode',
textEllipsis: true,
}, },
{ {
title: '设备编号', title: '设备编号',
dataIndex: 'deviceName', dataIndex: 'deviceNum',
textNumber: 8, textNumber: 10,
textEllipsis: true,
}, },
{ {
textNumber: 10,
title: '分组名称', title: '分组名称',
dataIndex: 'position', dataIndex: 'groupName',
}, },
{ {
title: '设备品牌/型号', title: '设备品牌/型号',
dataIndex: 'position', textNumber: 10,
dataIndex: 'deviceNameType',
}, },
{ {
textNumber: 10,
title: '设备状态', title: '设备状态',
dataIndex: 'position', dataIndex: 'deviceStatus',
customRender: ({ value }) => {
return value === '0' ? '启用' : '停用';
},
}, },
]; ];
const tableKeyMap = [ const tableKeyMap = [
@ -59,7 +67,6 @@ const doWnload = (url) => {
a.click(); a.click();
}; };
const mockData = ref(data.listData);
export const formSchema = [ export const formSchema = [
{ {
field: 'isCreate', field: 'isCreate',
@ -116,7 +123,7 @@ export const formSchema = [
immediate: true, immediate: true,
// resultField: 'data.COUNT_POINT', // resultField: 'data.COUNT_POINT',
labelField: 'cnValue', labelField: 'cnValue',
valueField: 'cnValue', valueField: 'dicKey',
}, },
rules: [ 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) => { export const treeConfig = (orgId) => {
return { return {
defaultExpandAll: true, defaultExpandAll: true,
@ -172,7 +199,7 @@ export const treeConfig = (orgId) => {
immediate: true, immediate: true,
// resultField: 'data.ENERGY_TYPE', // resultField: 'data.ENERGY_TYPE',
labelField: 'cnValue', labelField: 'cnValue',
valueField: 'cnValue', valueField: 'dicKey',
placeholder: '请选择能耗种类', placeholder: '请选择能耗种类',
autoSelectFirst: true, autoSelectFirst: true,
}, },
@ -200,6 +227,7 @@ export const tableConfig = (el, elGroup, elFormula, defaultParams) => {
label: '编辑', label: '编辑',
name: 'groupEdit', name: 'groupEdit',
type: 'primary', type: 'primary',
dynamicDisabled: () => !defaultParams.value?.id,
handle: (a, b) => { handle: (a, b) => {
el.value.toggle(); el.value.toggle();
}, },
@ -211,9 +239,11 @@ export const tableConfig = (el, elGroup, elFormula, defaultParams) => {
dynamicDisabled: (data: any) => { dynamicDisabled: (data: any) => {
return data.list.length === 0; return data.list.length === 0;
}, },
handle: () => { dynamicParams: { linkIds: 'linkId[]' },
mockData.value.splice(0, 2); confirm: true,
}, isClearCheck: true,
isReload: true,
api: group.delGroupList,
}, },
{ {
label: '批量导出', label: '批量导出',
@ -254,23 +284,6 @@ export const tableConfig = (el, elGroup, elFormula, defaultParams) => {
doWnload('/hx-ai-intelligent/asset/file/whiteListUser.xlsx'); doWnload('/hx-ai-intelligent/asset/file/whiteListUser.xlsx');
}, },
}, },
{
label: '批量分组',
name: 'groupBatGroup',
type: 'primary',
handle: () => {
elGroup.value.toggle();
},
},
{
label: '公式编辑',
name: 'groupFormulaEdit',
type: 'primary',
handle: () => {
elFormula.value.toggle();
},
},
], ],
columns: tableKeyMap, columns: tableKeyMap,
columnActions: { columnActions: {
@ -279,11 +292,11 @@ export const tableConfig = (el, elGroup, elFormula, defaultParams) => {
{ {
label: '删除', label: '删除',
name: 'groupDelete', name: 'groupDelete',
dynamicParams: ['uuid', 'appealType'], dynamicParams: { linkIds: 'linkId[]' },
confirm: true, confirm: true,
handle: () => { isClearCheck: true,
mockData.value.splice(0, 1); isReload: true,
}, api: group.delGroupList,
}, },
], ],
}, },
@ -291,60 +304,30 @@ export const tableConfig = (el, elGroup, elFormula, defaultParams) => {
formConfig: { formConfig: {
schemas: [ schemas: [
{ {
field: 'name', field: 'orgName',
label: '设备名称', component: 'NsSelectApi',
component: 'NsInput', defaultParams: defaultParams.value,
componentProps: { componentProps: {
placeholder: '请输入', 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: 'provider', field: 'pointNum',
label: '设备厂商',
component: 'NsInput', component: 'NsInput',
componentProps: { componentProps: {
placeholder: '请输入', 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',
}, },
}, },
], ],
@ -355,13 +338,11 @@ export const tableConfig = (el, elGroup, elFormula, defaultParams) => {
}; };
export const tableConfigCal = (el, elGroup, elFormula, defaultParams) => { export const tableConfigCal = (el, elGroup, elFormula, defaultParams) => {
// 分组节点 // 计算节点
return { return {
title: '点位信息', title: '点位信息',
// api: '/carbon_emission/device/getDeviceList', api: group.queryGroupInfoPage,
value: mockData.value, params: defaultParams.value,
params: defaultParams,
headerActions: [ headerActions: [
{ {
label: '编辑', label: '编辑',
@ -378,9 +359,11 @@ export const tableConfigCal = (el, elGroup, elFormula, defaultParams) => {
dynamicDisabled: (data: any) => { dynamicDisabled: (data: any) => {
return data.list.length === 0; return data.list.length === 0;
}, },
handle: () => { dynamicParams: { ids: 'id[]' },
mockData.value.splice(0, 2); confirm: true,
}, isReload: true,
isClearCheck: true,
api: group.delComputeList,
}, },
{ {
label: '批量导出', label: '批量导出',
@ -421,7 +404,31 @@ export const tableConfigCal = (el, elGroup, elFormula, defaultParams) => {
doWnload('/hx-ai-intelligent/asset/file/whiteListUser.xlsx'); doWnload('/hx-ai-intelligent/asset/file/whiteListUser.xlsx');
}, },
}, },
{
label: '批量分组',
name: 'groupBatGroup',
type: 'primary',
dynamicDisabled: (data: any) => {
return data.list.length === 0;
},
handle: ({ list }) => {
const ids = list.map(({ id }) => id);
defaultParams.value['saveDeviceInfoIds'] = ids;
elGroup.value.toggle();
},
},
{
label: '公式编辑',
name: 'groupFormulaEdit',
type: 'primary',
handle: () => {
elFormula.value.toggle();
},
},
], ],
scroll: { x: 1400 },
columns: tableCalKeyMap, columns: tableCalKeyMap,
columnActions: { columnActions: {
title: '操作', title: '操作',
@ -429,11 +436,11 @@ export const tableConfigCal = (el, elGroup, elFormula, defaultParams) => {
{ {
label: '删除', label: '删除',
name: 'groupDelete', name: 'groupDelete',
dynamicParams: 'id', dynamicParams: { ids: 'id[]' },
confirm: true, confirm: true,
isReload: true, isReload: true,
isClearCheck: true, isClearCheck: true,
api: group.delGroupList, api: group.delComputeList,
}, },
], ],
}, },
@ -441,18 +448,80 @@ export const tableConfigCal = (el, elGroup, elFormula, defaultParams) => {
formConfig: { formConfig: {
schemas: [ schemas: [
{ {
field: 'name', field: 'orgIds',
label: '设备名称', component: 'NsSelectApi',
component: 'NsInput', defaultParams: defaultParams.value,
componentProps: { componentProps: {
placeholder: '请选择公司', 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', field: 'provider',
component: 'NsInput', component: 'NsInput',
componentProps: { componentProps: {
placeholder: '请输入节点编号', placeholder: '请输入分组名称',
}, },
}, },
], ],

31
hx-ai-intelligent/src/view/equipmentManage/group/edit.vue

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

126
hx-ai-intelligent/src/view/equipmentManage/group/editCal.vue

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

163
hx-ai-intelligent/src/view/equipmentManage/group/editFormula.vue

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

369
hx-ai-intelligent/src/view/equipmentManage/group/editGroup.vue

@ -2,136 +2,285 @@
<ns-drawer <ns-drawer
v-model:visible="visible" v-model:visible="visible"
width="520" width="520"
title="分组编辑" title=" "
:ok="btnClick" :ok="btnClick"
:cancel="() => (visible = false)" :cancel="() => (visible = false)"
placement="right"> 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> </ns-drawer>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { createVNode, onMounted, ref, unref } from 'vue'; import { createVNode, onMounted, ref, unref } from 'vue';
import { NsMessage } from '/nerv-lib/component'; import { NsMessage } from '/nerv-lib/component';
import { DeleteOutlined } from '@ant-design/icons-vue'; 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 visible = ref(false);
const editGroupRef = ref();
const model = ref({}); const model = ref({});
const inputDisabled = ref(true);
const selectedRowKeys = ref([]);
let opType = true; // truefalse
const toggle = () => { const toggle = () => {
visible.value = !visible.value; visible.value = !visible.value;
visible.value && getTableData();
}; };
const deleteRow = (index) => {
console.log(index); const startCararcter = 65;
mockDataSource.value.splice(index, 1); //
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); const op = () => {
if (model.value?.groupName) mockDataSource.value.push(unref(model) as any); inputDisabled.value = !inputDisabled.value;
}; };
const mockDataSource = ref([
{ const clearData = () => {
groupName: '1号厂区', model.value = {};
}, selectedRowKeys.value = [];
{ };
groupName: '2号厂区',
}, const editGroup = () => {
{ if (!selectedRowKeys.value?.length) {
groupName: '3号厂区', NsMessage.warn('请先选择需要编辑的分组');
}, return;
]); }
const schemas = [ inputDisabled.value = false;
{ };
field: 'basicInfo', //
label: '', const add = () => {
displayFormItem: false, const finalParams = { ...props.params, ...model.value };
class: 'ns-form-item-full', if (opType) {
component: 'NsChildForm', delete finalParams.id;
componentProps: { }
title: '分组信息', editGroupRef.value.triggerSubmit().then(() => {
schemas: [ http.post(group.saveComputeGroup, finalParams).then(() => {
{ getTableData();
label: '分组编号', NsMessage.success('操作成功');
field: 'groupCode', op();
component: 'NsInput', });
defaultValue: 'WDIFHSUNGNDOR', });
componentProps: { };
disabled: true,
placeholder: '请输入', const delGroup = (id) => {
}, http.post(group.delComputeGroup, { id }).then(() => {
}, getTableData();
{ NsMessage.success('操作成功');
label: '分组名称', clearData();
field: 'groupName', });
component: 'NsInput', };
componentProps: { const rowSelectChange = (selected, selectedRows) => {
placeholder: '请输入', opType = false;
addonAfter: createVNode( console.log(selectedRowKeys, selectedRows);
'div', selectedRowKeys.value = selected;
{ style: { cursor: 'pointer' }, onclick: addRow }, model.value = { ...selectedRows[0] };
'新增', };
), const mockDataSource = ref([]);
}, const getTableData = () => {
rules: [{ required: true }], 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',
},
{
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),
}),
],
),
}, },
}, ],
{ });
field: 'list',
label: '', const schemas = (val) => {
displayFormItem: false, return [
class: 'ns-form-item-full', {
component: 'NsChildForm', field: 'basicInfo',
componentProps: { label: '',
title: '分组列表', displayFormItem: false,
schemas: [ class: 'ns-form-item-full',
{ component: 'NsChildForm',
label: '', componentProps: {
field: 'NsBasicTable', title: '分组信息',
component: 'NsBasicTable', schemas: [
formItemProps: { {
wrapperCol: { span: 24 }, label: '分组id',
field: 'id',
component: 'NsInput',
show: false,
},
{
label: '分组编号',
field: 'groupNum',
component: 'NsInput',
componentProps: {
disabled: true,
placeholder: '请输入',
},
}, },
componentProps: { {
disabled: true, label: '分组名称',
placeholder: '请输入', field: 'groupName',
dataSource: mockDataSource.value, component: 'NsInput',
rowSelection: { type: 'radio' }, componentProps: {
pagination: false, placeholder: '请输入',
rowKey: (record) => record.groupName, disabled: val,
columns: [ },
{ rules: [{ required: true }],
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),
}),
},
],
}, },
}, ],
], },
}, },
}, // {
]; // 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 = () => { const btnClick = () => {
visible.value = false; if (!selectedRowKeys.value[0]) {
NsMessage.success('操作成功'); NsMessage.warn('请选择分组');
return;
}
http
.post(group.saveComputeGroupInfo, {
...props.params,
groupListId: selectedRowKeys.value[0],
})
.then(() => {
emit('sure');
toggle();
NsMessage.success('操作成功');
});
}; };
defineExpose({ defineExpose({
@ -144,4 +293,8 @@
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
} }
.iconOP {
cursor: pointer;
color: @primary-color;
}
</style> </style>

59
hx-ai-intelligent/src/view/equipmentManage/group/index.vue

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

121
hx-ai-intelligent/src/view/equipmentManage/group/mock.json

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

68
hx-ai-intelligent/src/view/equipmentManage/ledger/config.ts

@ -138,9 +138,29 @@ export const tableConfig = (orgId) => {
{ {
field: 'deviceName', field: 'deviceName',
label: '设备名称', label: '设备名称',
component: 'NsInput', component: 'NsSelectApi',
componentProps: { 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) => { loadData: (selectedOptions, options) => {
const targetOption = selectedOptions[selectedOptions.length - 1]; const targetOption = selectedOptions[selectedOptions.length - 1];
if (!selectedOptions.length) { 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) => { options.value = res.data?.map((item) => {
return { label: item, value: item, children: [], isLeaf: false }; return { label: item, value: item, children: [], isLeaf: false };
}); });
@ -175,12 +195,14 @@ export const tableConfig = (orgId) => {
const value = targetOption?.value; const value = targetOption?.value;
if (targetOption) { if (targetOption) {
targetOption.loading = true; targetOption.loading = true;
http.post(device.dropArea, { device1Area: value, orgId }).then((res) => { http
targetOption.loading = false; .post(device.dropArea, { device1Area: value, orgId, filterField: 'DEVICE_AREA' })
targetOption.children = res.data?.map((item) => { .then((res) => {
return { label: item, value: item, children: [], isLeaf: true }; 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', field: 'manufacturer',
label: '设备厂商', label: '设备厂商',
component: 'NsInput', component: 'NsSelectApi',
componentProps: { componentProps: {
placeholder: '请输入设备厂商', placeholder: '请选择设备厂商',
options: [ api: (params) => {
{ return http.post(device.dropArea, params).then((res) => {
label: '全部', const result = res.data?.reduce((pre, cur) => {
value: '', !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,
}, },
}, },
{ {

506
hx-ai-intelligent/src/view/equipmentManage/ledger/mock.json

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

1
hx-ai-intelligent/src/view/monitor/deviceMonitor/tree/index.vue

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

387
hx-ai-intelligent/src/view/monitor/energyMonitor/analysisGraph/index.vue

@ -1,22 +1,55 @@
<template> <template>
<a-row type="flex" style="height: 92%"> <a-row type="flex" style="height: 92%">
<a-col :span="8"> <a-col :span="8">
<a-radio-group <div
v-model:value="mode" style="
@change="changeMode" box-shadow: 0 0 0 2px rgba(218, 218, 218, 0.5); /* 灰色阴影 */
style="padding-bottom: 10px; width: 40%; height: 4%; padding-left: 30px; padding-top: 10px"> width: 98%;
<a-radio-button value="1" style="width: 50%; text-align: center"> 同比 </a-radio-button> height: 96%;
<a-radio-button value="2" style="width: 50%; text-align: center"> 环比 </a-radio-button> margin: 2%;
</a-radio-group> ">
<div ref="analysisGraphchart" style="width: 100%; height: 95%"></div> <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>
<a-col :span="16" />
</a-row> </a-row>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, onMounted, ref, inject, watch } from 'vue'; import { defineComponent, onMounted, ref, inject, watch } from 'vue';
import * as echarts from 'echarts'; import * as echarts from 'echarts';
import JSZip from 'jszip';
import { saveAs } from 'file-saver';
export default defineComponent({ export default defineComponent({
name: 'AnalysisGraph', name: 'AnalysisGraph',
@ -52,11 +85,24 @@
); );
const changeMode = () => {}; const changeMode = () => {};
const analysisGraphchart = ref(null); const analysisGraphchart = ref(null);
const analysisGraphRingchart = ref(null);
const analysisGraphBarchart = ref(null);
//
let chartInstance: echarts.ECharts | null = null; let chartInstance: echarts.ECharts | null = null;
//
let chartRight1: echarts.ECharts | null = null;
//
let chartRight2: echarts.ECharts | null = null;
const draw = () => { const draw = () => {
data.value = pageData.analysisGraphList; data.value = pageData.analysisGraphList;
//
drawLeft();
drawRight1();
};
const drawLeft = () => {
if (data.value && data.value.length > 0) { if (data.value && data.value.length > 0) {
if (chartInstance) { if (chartInstance) {
chartInstance.dispose(); chartInstance.dispose();
@ -65,7 +111,6 @@
var seriesdata = []; var seriesdata = [];
var dateX = []; var dateX = [];
// var legendList: string | any[] = [];
for (let i = 0; i < data.value.length; i++) { for (let i = 0; i < data.value.length; i++) {
dateX.push(data.value[i].name); dateX.push(data.value[i].name);
@ -81,26 +126,39 @@
show: true, show: true,
formatter: '{b}', formatter: '{b}',
}, },
barWidth: '25%',
}, },
]; ];
const option = { const option = {
// tooltip: { grid: {
// trigger: 'axis', top: 60,
// formatter: (params: any) => { bottom: 20,
// const date = params[0].name; },
// const values = params dataZoom: [
// .map((param: any) => { {
// const unit = data.value.find((d) => d.name === date)?.unit || ''; show: true,
// return `<tr> type: 'slider',
// <td>${param.marker}${param.seriesName}</td> zoomLock: true,
// <td style="text-align: right;">${param.value} ${unit}</td> startValue: 0, //
// </tr>`; endValue: 4,
// }) showDetail: false,
// .join(''); width: 5,
// return `<div>${date}</div><table style="width: 100%;">${values}</table>`; 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: { yAxis: {
type: 'category', type: 'category',
axisLine: { show: false }, axisLine: { show: false },
@ -125,26 +183,283 @@
chartInstance.setOption(option); 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(() => { onMounted(() => {
draw(); draw();
}); });
// //
const downloadChart = () => { const downloadChart = async () => {
if (chartInstance) { // if (chartInstance) {
const base64 = chartInstance.getDataURL({ // const base64 = chartInstance.getDataURL({
type: 'png', // type: 'png',
backgroundColor: '#fff', // 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'; const images = await Promise.all(imagePromises);
link.click();
} images.forEach((image: any) => {
zip.file(image.name, image.data);
});
zip.generateAsync({ type: 'blob' }).then((content) => {
saveAs(content, 'charts.zip'); // 使 FileSaver.js ZIP
});
}; };
return { return {
analysisGraphchart, analysisGraphchart,
analysisGraphRingchart,
analysisGraphBarchart,
downloadChart, downloadChart,
mode, mode,
changeMode, changeMode,

8
hx-ai-intelligent/src/view/monitor/energyMonitor/page.vue

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

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

@ -40,18 +40,22 @@
<div class="fixed-bottom"> <div class="fixed-bottom">
<a-divider /> <a-divider />
<a-select <a-select
v-model:value="frequencyValue" v-model:value="dateTypeValue"
placeholder="请选择采集频率" placeholder="请选择日期类型"
style="width: 100%; margin-bottom: 10px" style="width: 100%; margin-bottom: 10px"
:options="options2" /> :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" :value="hackValue || dateRange"
:disabled-date="disabledDate" :disabled-date="disabledDate"
@change="onChange" @change="onChange"
@openChange="onOpenChange" @openChange="onOpenChange"
@calendarChange="onCalendarChange" @calendarChange="onCalendarChange"
style="width: 100%; margin-bottom: 10px" style="width: 100%; margin-bottom: 10px"
:placeholder="['请选择日期', '请选择日期']" /> :placeholder="['请选择日期', '请选择日期']" /> -->
<a-button type="primary" style="width: 100%; margin-bottom: 10px" @click="getSelect"> <a-button type="primary" style="width: 100%; margin-bottom: 10px" @click="getSelect">
查询 查询
</a-button> </a-button>
@ -89,15 +93,15 @@
// list // list
const options1 = ref<SelectProps['options']>([]); const options1 = ref<SelectProps['options']>([]);
// list // list
const options2 = ref<SelectProps['options']>([]); const options2 = ref<SelectProps['options']>([]);
const mode = ref<String>('1'); const mode = ref<String>('1');
// //
const selectedValue = ref<string | undefined>(); const selectedValue = ref<string | number | null | undefined>();
// //
const frequencyValue = ref<string | undefined>(); const dateTypeValue = ref<string | undefined>();
// //
const dateRange = ref<[Dayjs, Dayjs] | undefined>(); const dateValue = ref<[Dayjs, Dayjs] | undefined>();
// //
const getOptionsList = async () => { const getOptionsList = async () => {
@ -107,25 +111,20 @@
(item.value = item.cnValue), (item.label = item.cnValue); (item.value = item.cnValue), (item.label = item.cnValue);
}); });
options1.value = options.data.data; // options1.value options1.value = options.data.data; // options1.value
if (options1.value) {
selectedValue.value = options1.value[0].value;
}
} catch (error) { } catch (error) {
console.error('Failed to fetch options:', error); console.error('Failed to fetch options:', error);
} }
options2.value = [ options2.value = [
{ {
value: '1', value: 'month',
label: '5分钟', label: '月',
},
{
value: '2',
label: '10分钟',
}, },
{ {
value: '3', value: 'year',
label: '30分钟', label: '年',
},
{
value: '4',
label: '1小时',
}, },
]; ];
}; };
@ -148,7 +147,7 @@
// //
const changeEnergyType = () => { const changeEnergyType = () => {
if (selectedValue.value == '8') { if (selectedValue.value == '碳排量') {
shebei.value = true; shebei.value = true;
mode.value = '2'; mode.value = '2';
} else { } else {
@ -337,7 +336,9 @@
{ {
name: 'AC_002(暖通电表)', name: 'AC_002(暖通电表)',
value: -21, value: -21,
ringValue: 21,
energyType: selectedValue.value, energyType: selectedValue.value,
energyUnit: 'kWh',
unit: 'V', unit: 'V',
labelRight: { labelRight: {
position: 'right', position: 'right',
@ -346,6 +347,7 @@
{ {
name: 'AC_003(照明电表)', name: 'AC_003(照明电表)',
value: 36, value: 36,
ringValue: 36,
energyType: selectedValue.value, energyType: selectedValue.value,
unit: 'V', unit: 'V',
labelRight: { labelRight: {
@ -355,6 +357,67 @@
{ {
name: 'AC_004(给排水电表)', name: 'AC_004(给排水电表)',
value: -5, 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, energyType: selectedValue.value,
unit: 'V', unit: 'V',
labelRight: { labelRight: {
@ -624,9 +687,9 @@
} }
}; };
const onChange = (val: RangeValue) => { // const onChange = (val: RangeValue) => {
dateRange.value = val; // dateRange.value = val;
}; // };
const onCalendarChange = (val: RangeValue) => { const onCalendarChange = (val: RangeValue) => {
dates.value = val; dates.value = val;
@ -634,6 +697,7 @@
onMounted(() => { onMounted(() => {
getOptionsList(); getOptionsList();
changeMode(); changeMode();
getSelect();
}); });
return { return {
@ -648,8 +712,8 @@
options2, options2,
mode, mode,
selectedValue, selectedValue,
frequencyValue, dateTypeValue,
dateRange, dateValue,
getOptionsList, getOptionsList,
getSelect, getSelect,
getSelect11, getSelect11,
@ -657,7 +721,7 @@
disabledDate, disabledDate,
onCalendarChange, onCalendarChange,
onOpenChange, onOpenChange,
onChange, // onChange,
hackValue, hackValue,
treeLoading, treeLoading,
changeEnergyType, changeEnergyType,

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

File diff suppressed because one or more lines are too long

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

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

6
hx-ai-intelligent/src/view/organizationManage/departmentManage/index.vue

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

4
hx-op/src/config/app.config.ts

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

4
lib/component/form/form/form-item.vue

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

1
lib/saas/theme/global-antd.less

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

26
lib/saas/view/service/updatePassWord.vue

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

14
lib/saas/view/system/login.vue

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

Loading…
Cancel
Save