diff --git a/src/api/ems/dzjk.js b/src/api/ems/dzjk.js index 56a36b0..79b619f 100644 --- a/src/api/ems/dzjk.js +++ b/src/api/ems/dzjk.js @@ -8,6 +8,31 @@ export function getDzjkHomeView(siteId) { }) } +// 单站监控项目点位配置(供单站监控功能查询) +export function getProjectPointMapping(siteId) { + return request({ + url: `/ems/siteMonitor/getProjectPointMapping?siteId=${siteId}`, + method: 'get' + }) +} + +// 单站监控项目展示数据(字段配置 + 最新值) +export function getProjectDisplayData(siteId) { + return request({ + url: `/ems/siteMonitor/getProjectDisplayData?siteId=${siteId}`, + method: 'get' + }) +} + +// 单站监控项目展示数据写入(批量) +export function saveProjectDisplayData(data) { + return request({ + url: `/ems/siteMonitor/saveProjectDisplayData`, + method: 'post', + data + }) +} + //站点首页 冲放曲线 export function getSevenChargeData({siteId, startDate, endDate}) { return request({ diff --git a/src/api/ems/search.js b/src/api/ems/search.js index 32bd1ea..e1cf73d 100644 --- a/src/api/ems/search.js +++ b/src/api/ems/search.js @@ -29,4 +29,12 @@ export function getAllBatteryIdsBySites(data) { url: `/ems/generalQuery/getAllBatteryIdsBySites/${data}`, method: 'get', }) -} \ No newline at end of file +} + +// 综合查询-按站点获取配置设备列表 +export function getGeneralQueryDeviceList(siteId) { + return request({ + url: `/ems/siteConfig/getDeviceList?siteId=${siteId}`, + method: 'get', + }) +} diff --git a/src/api/ems/site.js b/src/api/ems/site.js index 2f25903..60233a5 100644 --- a/src/api/ems/site.js +++ b/src/api/ems/site.js @@ -8,6 +8,24 @@ export function getSiteInfoList({siteName, startTime, endTime, pageSize, pageNum }) } +// 新增站点 +export function addSite(data) { + return request({ + url: `/ems/siteConfig/addSite`, + method: 'post', + data + }) +} + +// 编辑站点 +export function updateSite(data) { + return request({ + url: `/ems/siteConfig/updateSite`, + method: 'post', + data + }) +} + // 设备列表 export function getDeviceInfoList(data) { return request({ @@ -102,6 +120,23 @@ export function getDeviceListBySiteAndCategory({siteId, deviceCategory}) { }) } +// 获取单站监控项目点位映射 +export function getSingleMonitorProjectPointMapping(siteId) { + return request({ + url: `/ems/siteConfig/getSingleMonitorProjectPointMapping?siteId=${siteId}`, + method: 'get', + }) +} + +// 保存单站监控项目点位映射 +export function saveSingleMonitorProjectPointMapping(data) { + return request({ + url: `/ems/siteConfig/saveSingleMonitorProjectPointMapping`, + method: 'post', + data + }) +} + //新增设备保护 export function addProtectPlan(data) { return request({ @@ -163,6 +198,130 @@ export function importPointList(data) { }) } +// 按站点导入模板点位配置 +export function importPointTemplateBySite(data) { + return request({ + url: `/ems/pointConfig/importTemplateBySite`, + method: 'post', + data + }) +} + +// CSV导入点位配置 +export function importPointConfigCsv(data) { + return request({ + url: `/ems/pointConfig/importCsv`, + method: 'post', + data, + headers: { + 'Content-Type': 'multipart/form-data' + } + }) +} + +// 点位配置列表 +export function getPointMatchList(params) { + return request({ + url: `/ems/pointConfig/list`, + method: 'get', + params + }) +} + +// 点位配置详情 +export function getPointMatchDetail(id) { + return request({ + url: `/ems/pointConfig/${id}`, + method: 'get', + }) +} + +// 新增点位配置 +export function addPointMatch(data) { + return request({ + url: `/ems/pointConfig`, + method: 'post', + data + }) +} + +// 编辑点位配置 +export function updatePointMatch(data) { + return request({ + url: `/ems/pointConfig`, + method: 'put', + data + }) +} + +// 删除点位配置 +export function deletePointMatch(ids) { + return request({ + url: `/ems/pointConfig/${ids}`, + method: 'delete', + }) +} + +// 点位配置-批量获取最新值(新接口) +export function getPointConfigLatestValues(data) { + return request({ + url: `/ems/pointConfig/latestValues`, + method: 'post', + data + }) +} + +// 点位配置-曲线数据(新接口) +export function getPointConfigCurve(data) { + return request({ + url: `/ems/pointConfig/curve`, + method: 'post', + data + }) +} + +// 计算点配置列表 +export function getPointCalcConfigList(params) { + return request({ + url: `/ems/pointCalcConfig/list`, + method: 'get', + params + }) +} + +// 计算点配置详情 +export function getPointCalcConfigDetail(id) { + return request({ + url: `/ems/pointCalcConfig/${id}`, + method: 'get', + }) +} + +// 新增计算点配置 +export function addPointCalcConfig(data) { + return request({ + url: `/ems/pointCalcConfig`, + method: 'post', + data + }) +} + +// 编辑计算点配置 +export function updatePointCalcConfig(data) { + return request({ + url: `/ems/pointCalcConfig`, + method: 'put', + data + }) +} + +// 删除计算点配置 +export function deletePointCalcConfig(ids) { + return request({ + url: `/ems/pointCalcConfig/${ids}`, + method: 'delete', + }) +} //mqtt export function getMqttList({pageSize, pageNum, mqttTopic, topicName, siteId}) { diff --git a/src/router/ems.js b/src/router/ems.js index f30c1e3..bda6551 100644 --- a/src/router/ems.js +++ b/src/router/ems.js @@ -9,13 +9,13 @@ export const dzjk = [ redirect: '/dzjk/home', meta: {title: '单站监控', icon: 'dashboard',}, alwaysShow: false, - name: 'Dzjk', + name: 'DzjkLocal', hidden: true, children: [ { path: '', component: () => import('@/views/ems/dzjk/index'), - name: 'Dzjk', + name: 'DzjkRoot', redirect: '/dzjk/home', hidden: true, children: [ @@ -301,5 +301,3 @@ export const dzjk = [ } ] - - diff --git a/src/router/index.js b/src/router/index.js index a3cf594..37d08b9 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -89,6 +89,19 @@ export const constantRoutes = [ } ] }, + { + path: '/ems/site/zdlb', + component: Layout, + hidden: true, + children: [ + { + path: 'monitor-point-mapping', + component: () => import('@/views/ems/site/zdlb/MonitorPointMapping.vue'), + name: 'MonitorPointMapping', + meta: { title: '单站监控项目点位配置', activeMenu: '/ems/site/zdlb' } + } + ] + }, // EMS管理系统routers ...dzjk ] diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 6484ed2..0265157 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -47,9 +47,12 @@ const permission = { const asyncRoutes = filterDynamicRoutes(dynamicRoutes) rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true }) router.addRoutes(asyncRoutes) - if(!hasDzjk){ + // 后端已下发 dzjk 菜单时,移除本地静态 dzjk 路由,避免重名/重复注册 + if (hasDzjk) { const index = constantRoutes.findIndex(i=>i.path.indexOf('dzjk')>-1) - constantRoutes.splice(index,1) + if (index > -1) { + constantRoutes.splice(index, 1) + } } commit('SET_ROUTES', rewriteRoutes) commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes)) @@ -121,11 +124,16 @@ export function filterDynamicRoutes(routes) { } export const loadView = (view) => { + const normalizedView = String(view || '') + .replace(/^\.\/+/, '') + .replace(/^\/+/, '') + .replace(/^@\/views\//, '') + if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'staging') { - return (resolve) => require([`@/views/${view}`], resolve) + return (resolve) => require([`@/views/${normalizedView}`], resolve) } else { // 使用 import 实现生产环境的路由懒加载 - return () => import(`@/views/${view}`) + return () => import(`@/views/${normalizedView}`) } } diff --git a/src/views/ems/search/index.vue b/src/views/ems/search/index.vue index 5938ede..f8f4d53 100644 --- a/src/views/ems/search/index.vue +++ b/src/views/ems/search/index.vue @@ -10,7 +10,7 @@ prop="siteIds" :rules="[{ required: true, message: '请选择站点' }]" > - + - - - - {{ item.name }} - - - +
+ + + + + + + +
+ + + +
+ 已选 {{ group.pointNames.length }} 个点位 +
+ + 刷新点位 + + + 清空选择 + +
+
+
+
+ +
+ + +
+
+ + @@ -50,22 +129,7 @@ @change="handleChildChange" > -
- - - -
+ 生成图表 @@ -98,8 +162,14 @@ import * as echarts from "echarts"; import resize from "@/mixins/ems/resize"; import {getAllSites} from "@/api/ems/zddt"; -import {getAllBatteryIdsBySites, getAllDeviceCategory, getPointValueList, pointFuzzyQuery,} from "@/api/ems/search"; +import { + getAllBatteryIdsBySites, + getGeneralQueryDeviceList, + getPointValueList, + pointFuzzyQuery, +} from "@/api/ems/search"; import DateTimeSelect from "./DateTimeSelect.vue"; +import {debounce} from "@/utils"; export default { name: "Search", @@ -107,13 +177,19 @@ export default { components: {DateTimeSelect}, computed: { isDtdc() { - return this.form.deviceCategory === "BATTERY"; + return this.form.queryGroups?.[0]?.deviceCategory === "BATTERY"; }, }, watch: { "form.siteIds": { handler(newVal) { - newVal && this.isDtdc && this.getChildList(); + this.form.queryGroups = [this.createEmptyQueryGroup()]; + this.form.child = []; + this.childOptions = []; + this.deviceList = []; + if (newVal) { + this.getDeviceListBySite(newVal); + } }, }, isDtdc: { @@ -123,8 +199,7 @@ export default { }, }, "form.dataUnit": { - handler(newVal, oldVal) { - console.log("wacth到了dataUnit的变化", newVal, oldVal); + handler() { this.$nextTick(() => { this.$refs.dateTimeSelect.init(); this.getDate(); @@ -135,24 +210,96 @@ export default { data() { return { chart: null, - deviceCategoryList: [], //设备列表 - siteList: [], //站点列表 - childOptions: [], //二级设备列表 + deviceList: [], + siteList: [], + childOptions: [], + maxQueryGroups: 10, + groupKeySeed: 0, form: { - dataRange: [], //时间选择范围 + dataRange: [], child: [], - siteIds: "", //当前选中的站点id 默认选中第一个站点 - deviceCategory: "", //设备 - pointName: "", //点位 - dataUnit: 1, //横坐标 + siteIds: "", + queryGroups: [], + dataUnit: 1, }, loading: false, + debouncedPointSearchMap: {}, }; }, + created() { + this.form.queryGroups = [this.createEmptyQueryGroup()]; + }, methods: { - changeSiteIds(val) { - console.log("切换站点或设备清空点位", val); - val && (this.form.pointName = ""); + createEmptyQueryGroup() { + this.groupKeySeed += 1; + return { + key: this.groupKeySeed, + deviceId: "", + deviceCategory: "", + pointNames: [], + pointOptions: [], + pointOptionsCache: {}, + pointRequestId: 0, + pointLoading: false, + }; + }, + getQueryGroup(index) { + return this.form.queryGroups[index]; + }, + addQueryGroup() { + if (this.form.queryGroups.length >= this.maxQueryGroups) { + this.$message.warning(`最多只能添加 ${this.maxQueryGroups} 组`); + return; + } + this.form.queryGroups.push(this.createEmptyQueryGroup()); + }, + removeQueryGroup(index) { + if (this.form.queryGroups.length <= 1) return; + this.form.queryGroups.splice(index, 1); + if (index === 0) { + this.form.child = []; + } + }, + canSelectPoint(group) { + return !!(this.form.siteIds && group && group.deviceId); + }, + pointSelectPlaceholder(group) { + return this.canSelectPoint(group) + ? "支持关键字搜索,展开可查看设备点位" + : "请先选择站点和设备"; + }, + pointNoDataText(group) { + return this.canSelectPoint(group) ? "暂无匹配点位" : "请先选择站点和设备"; + }, + getDeviceListBySite(siteId) { + if (!siteId) return Promise.resolve([]); + return getGeneralQueryDeviceList(siteId).then((response) => { + this.deviceList = response?.data || []; + return this.deviceList; + }); + }, + handleDeviceChange(groupIndex, deviceId) { + const group = this.getQueryGroup(groupIndex); + if (!group) return; + const selected = this.deviceList.find((item) => item.deviceId === deviceId); + group.deviceCategory = selected?.deviceCategory || ""; + group.pointNames = []; + group.pointOptions = []; + group.pointOptionsCache = {}; + group.pointRequestId = 0; + group.pointLoading = false; + + if (groupIndex === 0) { + this.form.child = []; + this.childOptions = []; + if (this.isDtdc) { + this.getChildList(); + } + } + + if (this.canSelectPoint(group)) { + this.fetchPointOptions(groupIndex, ""); + } }, getChildList() { this.childOptions = []; @@ -173,8 +320,8 @@ export default { const num = Math.ceil(length / base); if (num === 0) return; for (let i = 1; i <= num; i++) { - const start = (i - 1) * base + 1, - end = i * base; + const start = (i - 1) * base + 1; + const end = i * base; options[index].children.push({ value: i, label: `${start}-${end}`, @@ -188,12 +335,10 @@ export default { } } }); - console.log("二级设备options", options); this.childOptions = options; }); }, handleChildChange(data) { - console.log("选择二级设备", data); this.form.child = data; }, showLoading() { @@ -210,27 +355,22 @@ export default { this.getDate(); }, setOption(data) { - // 点位类型 dataType 1-瞬时值 2-累计值 仅当值为2展示差值 - // 图表类型 chartType 1-曲线图,2-箱线图 if (!this.chart) return; this.chart.clear(); - console.log("返回的数据", data); if (!data || data.length <= 0) { this.$message.warning("暂无数据"); + return; } - console.log('展示的图表类型chartType', data[0].chartType) if (data[0].chartType === 2) { - // 箱型图 - this.setBoxOption(data) + this.setBoxOption(data); } else { - //折线图 - this.setLineOption(data) + this.setLineOption(data); } }, setLineOption(data) { let dataset = []; - data.forEach((item, index) => { + data.forEach((item) => { item.deviceList.forEach((inner) => { dataset.push({ name: `${ @@ -242,44 +382,38 @@ export default { markPoint: { symbolSize: 30, emphasis: { - disabled: false//打开 鼠标高亮 + disabled: false, }, - data: [//最大值、最小值 + data: [ { - // type: 'max', - name: `最大值`, + name: "最大值", coord: [inner.maxDate, inner.maxValue], - relativeTo: 'coordinate', + relativeTo: "coordinate", label: { position: "top", - formatter: item.dataType === 2 ? ([ - `最大值:${inner.maxValue}`, - // `平均值:${inner.avgValue}`, - `差值:${inner.diffValue}`, - ]).join('\n') : ([ - `最大值:${inner.maxValue}`, - // `平均值:${inner.avgValue}`, - ]).join('\n'), + formatter: item.dataType === 2 + ? [ + `最大值:${inner.maxValue}`, + `差值:${inner.diffValue}`, + ].join("\n") + : [`最大值:${inner.maxValue}`].join("\n"), }, }, { - // type: 'min', - name: `最小值`, + name: "最小值", coord: [inner.minDate, inner.minValue], - relativeTo: 'coordinate', + relativeTo: "coordinate", label: { position: "top", - formatter: item.dataType === 2 ? ([ - `最小值:${inner.minValue}`, - // `平均值:${inner.avgValue}`, - `差值:${inner.diffValue}`, - ]).join('\n') : ([ - `最小值:${inner.minValue}`, - // `平均值:${inner.avgValue}`, - ]).join('\n'), - } - } - ] + formatter: item.dataType === 2 + ? [ + `最小值:${inner.minValue}`, + `差值:${inner.diffValue}`, + ].join("\n") + : [`最小值:${inner.minValue}`].join("\n"), + }, + }, + ], }, xdata: [], data: [], @@ -291,24 +425,17 @@ export default { }); }); }); - console.log("折线图图表数据", dataset); + this.chart.setOption({ - legend: { - // left: 'center', - // top: '10', - }, + legend: {}, grid: { containLabel: true, }, tooltip: { trigger: "axis", axisPointer: { - type: 'cross', + type: "cross", }, - // axisPointer: { - // // 坐标轴指示器,坐标轴触发有效 - // type: "shadow", // 默认为直线,可选为:'line' | 'shadow' - // }, }, textStyle: { color: "#333333", @@ -333,7 +460,7 @@ export default { }, setBoxOption(data) { let dataset = []; - data.forEach((item, index) => { + data.forEach((item) => { item.deviceList.forEach((inner) => { dataset.push({ name: `${ @@ -342,86 +469,33 @@ export default { : "" }${inner.deviceId}`, type: "boxplot", - // markPoint: { - // symbolSize: 30, - // emphasis: { - // disabled: false//打开 鼠标高亮 - // }, - // data: [//最大值、最小值 - // { - // // type: 'max', - // name: `最大值`, - // coord: [inner.maxDate, inner.maxValue], - // relativeTo: 'coordinate', - // label: { - // position: "top", - // formatter: item.dataType === 2 ? ([ - // `最大值:${inner.maxValue}`, - // // `平均值:${inner.avgValue}`, - // `差值:${inner.diffValue}`, - // ]).join('\n') : ([ - // `最大值:${inner.maxValue}`, - // // `平均值:${inner.avgValue}`, - // ]).join('\n'), - // }, - // }, - // { - // // type: 'min', - // name: `最小值`, - // coord: [inner.minDate, inner.minValue], - // relativeTo: 'coordinate', - // label: { - // position: "top", - // formatter: item.dataType === 2 ? ([ - // `最小值:${inner.minValue}`, - // // `平均值:${inner.avgValue}`, - // `差值:${inner.diffValue}`, - // ]).join('\n') : ([ - // `最小值:${inner.minValue}`, - // // `平均值:${inner.avgValue}`, - // ]).join('\n'), - // } - // } - // ] - // }, xdata: [], data: [], }); const length = dataset.length; inner.pointValueList.forEach((value) => { - const {valueDate, min, q1, median, q3, max} = value + const {valueDate, min, q1, median, q3, max} = value; dataset[length - 1].xdata.push(valueDate); dataset[length - 1].data.push([min, q1, median, q3, max]); }); }); }); - console.log("箱型图图表数据", dataset); + this.chart.setOption({ - legend: { - // left: 'center', - // top: '10', - }, + legend: {}, grid: { containLabel: true, }, tooltip: { - trigger: 'item', + trigger: "item", formatter: function (params) { - let data = params.data; - let result = params.marker + params.name + ' ' + params.seriesName + '
'; - result += '最小值: ' + data[1] + '
'; - result += '平均值: ' + data[3] + '
'; - result += '最大值: ' + data[5]; + let itemData = params.data; + let result = params.marker + params.name + " " + params.seriesName + "
"; + result += "最小值: " + itemData[1] + "
"; + result += "平均值: " + itemData[3] + "
"; + result += "最大值: " + itemData[5]; return result; - } - // trigger: "axis", - // axisPointer: { - // type: 'cross', - // }, - // axisPointer: { - // // 坐标轴指示器,坐标轴触发有效 - // type: "shadow", // 默认为直线,可选为:'line' | 'shadow' - // }, + }, }, textStyle: { color: "#333333", @@ -447,105 +521,189 @@ export default { submitForm() { this.getDate(); }, - handleSelect(data) { - this.form.pointName = data.value; + getPointCacheKey(group, query = "") { + return `${this.form.siteIds}_${group.deviceId}_${query.trim()}`; }, - querySearchAsync(query, cb) { - console.log("查询数据", query); - if (!this.form.siteIds || !this.form.deviceCategory) { - this.$message({ - type: "warning", - message: "请先选择站点和设备", - }); - return cb([]); + normalizePointOptions(data = []) { + return (data || []).map((item) => { + if (typeof item === "string") { + return {value: item, label: item, pointName: item, dataKey: "", pointDesc: ""}; + } + const pointName = item?.pointName || item?.value || ""; + const dataKey = item?.dataKey || ""; + const pointDesc = item?.pointDesc || ""; + const labelParts = [pointName]; + if (dataKey && dataKey !== pointName) { + labelParts.push(`key:${dataKey}`); + } + if (pointDesc) { + labelParts.push(pointDesc); + } + return { + value: pointName, + label: labelParts.join(" | "), + pointName, + dataKey, + pointDesc, + }; + }).filter((item) => item.value); + }, + setPointOptions(group, data = []) { + const selected = group.pointNames || []; + const selectedOptions = selected.map((value) => ({value, label: value, pointName: value})); + const normalized = this.normalizePointOptions(data); + const merged = [...selectedOptions, ...normalized]; + const seen = {}; + group.pointOptions = merged.filter((item) => { + if (!item?.value || seen[item.value]) { + return false; + } + seen[item.value] = true; + return true; + }); + }, + fetchPointOptions(groupIndex, query = "", {force = false} = {}) { + const group = this.getQueryGroup(groupIndex); + if (!group || !this.canSelectPoint(group)) return Promise.resolve([]); + const normalizedQuery = (query || "").trim(); + const cacheKey = this.getPointCacheKey(group, normalizedQuery); + if (!force && group.pointOptionsCache[cacheKey]) { + this.setPointOptions(group, group.pointOptionsCache[cacheKey]); + return Promise.resolve(group.pointOptionsCache[cacheKey]); } - pointFuzzyQuery({ + const requestId = ++group.pointRequestId; + group.pointLoading = true; + return pointFuzzyQuery({ siteIds: [this.form.siteIds], - deviceCategory: this.form.deviceCategory, - pointName: query, - }).then((response) => { - const data = response?.data || []; - cb( - data.map((item) => { - return {name: item, value: item}; - }) - ); - }); - }, - // 获取所有设备 - getDeviceCategory() { - return getAllDeviceCategory().then((response) => { - this.deviceCategoryList = response?.data || []; - }); - }, - getZdList() { - return getAllSites() + deviceCategory: group.deviceCategory, + deviceId: group.deviceId, + pointName: normalizedQuery, + }) .then((response) => { - this.siteList = response.data || []; + if (requestId !== group.pointRequestId) return []; + const data = this.normalizePointOptions(response?.data || []); + group.pointOptionsCache[cacheKey] = data; + this.setPointOptions(group, data); + return data; }) .finally(() => { + if (requestId === group.pointRequestId) { + group.pointLoading = false; + } }); }, + getDebouncedPointSearch(groupIndex) { + if (!this.debouncedPointSearchMap[groupIndex]) { + this.debouncedPointSearchMap[groupIndex] = debounce((query) => { + this.fetchPointOptions(groupIndex, query); + }, 260); + } + return this.debouncedPointSearchMap[groupIndex]; + }, + remotePointSearch(groupIndex, query) { + const group = this.getQueryGroup(groupIndex); + if (!group || !this.canSelectPoint(group)) return; + this.getDebouncedPointSearch(groupIndex)(query); + }, + handlePointDropdownVisible(groupIndex, visible) { + const group = this.getQueryGroup(groupIndex); + if (visible && group && this.canSelectPoint(group)) { + this.fetchPointOptions(groupIndex, ""); + } + }, + refreshPointOptions(groupIndex) { + const group = this.getQueryGroup(groupIndex); + if (!group || !this.canSelectPoint(group)) return; + this.fetchPointOptions(groupIndex, "", {force: true}); + }, + clearPointSelection(groupIndex) { + const group = this.getQueryGroup(groupIndex); + if (!group) return; + group.pointNames = []; + }, + getZdList() { + return getAllSites().then((response) => { + this.siteList = response.data || []; + }); + }, + buildSiteDeviceMap() { + let siteDeviceMap = {}; + this.form.child.forEach(([first, second, third]) => { + if (siteDeviceMap[first]) { + siteDeviceMap[first].push(third); + } else { + siteDeviceMap[first] = [third]; + } + }); + return siteDeviceMap; + }, getDate() { this.$refs.form.validate((valid) => { - if (valid) { - if (!this.form.pointName) { - return this.$message.error("请输入正确的点位"); - } - if ( - this.isDtdc && - (this.form.child.length === 0 || this.form.child.length > 5) - ) { - return this.$message.error("请选择单体电池且不能超过5个"); - } - const { - siteIds, - dataUnit, - deviceCategory, - pointName, - dataRange: [start = "", end = ""], - child, - } = this.form; - if (!start || !end) return this.$message.error("请选择时间"); - let siteDeviceMap = {}; - child.forEach(([first, second, third]) => { - if (siteDeviceMap[first]) { - siteDeviceMap[first].push(third); - } else { - siteDeviceMap[first] = []; - siteDeviceMap[first].push(third); - } - }); - let startDate, endDate; - if (start && dataUnit === 3) { - // startDate= start + `${dataUnit === 2 ? ':00' : ' 00:00:00'}` - startDate = start + " 00:00:00"; - } else { - startDate = start; - } - if (end && dataUnit === 3) { - // endDate= end + `${dataUnit === 2 ? ':00' : ' 00:00:00'}` - endDate = end + " 00:00:00"; - } else { - endDate = end; - } - this.loading = true; - getPointValueList({ + if (!valid) { + return; + } + + const activeGroups = this.form.queryGroups + .map((group, index) => ({group, index})) + .filter(({group}) => group.deviceId && group.pointNames && group.pointNames.length > 0); + + if (activeGroups.length === 0) { + return this.$message.error("请至少选择1组设备和点位"); + } + + const invalidGroupIndex = this.form.queryGroups.findIndex( + (group) => group.deviceId && (!group.pointNames || group.pointNames.length === 0) + ); + if (invalidGroupIndex !== -1) { + return this.$message.error(`第 ${invalidGroupIndex + 1} 组请至少选择1个点位`); + } + + if (this.isDtdc && (this.form.child.length === 0 || this.form.child.length > 5)) { + return this.$message.error("请选择单体电池且不能超过5个"); + } + + const { + siteIds, + dataUnit, + dataRange: [start = "", end = ""], + } = this.form; + + if (!start || !end) return this.$message.error("请选择时间"); + + let startDate = start; + let endDate = end; + if (start && dataUnit === 3) { + startDate = start + " 00:00:00"; + } + if (end && dataUnit === 3) { + endDate = end + " 00:00:00"; + } + + this.loading = true; + + const requests = activeGroups.map(({group, index}) => { + const useChildMap = index === 0 && group.deviceCategory === "BATTERY"; + return getPointValueList({ siteIds: [siteIds], dataUnit, - deviceCategory, - pointName, + deviceId: group.deviceId, + deviceCategory: group.deviceCategory, + pointNames: group.pointNames, + pointName: group.pointNames.join(","), startDate, endDate, - siteDeviceMap, - }) - .then((response) => { - this.setOption(response?.data || []); - }) - .finally(() => { - this.loading = false; - }); - } + siteDeviceMap: useChildMap ? this.buildSiteDeviceMap() : {}, + }).then((response) => response?.data || []); + }); + + Promise.all(requests) + .then((groupResults) => { + const merged = groupResults.flat(); + this.setOption(merged); + }) + .finally(() => { + this.loading = false; + }); }); }, }, @@ -561,12 +719,58 @@ export default { this.$nextTick(() => { this.initChart(); this.$refs.dateTimeSelect.init(); - Promise.all([this.getDeviceCategory(), this.getZdList()]).finally( - () => (this.loading = false) - ); + Promise.all([this.getZdList()]).finally(() => (this.loading = false)); }); }, }; - + diff --git a/src/views/ems/site/pointConfig/index.vue b/src/views/ems/site/pointConfig/index.vue new file mode 100644 index 0000000..6297739 --- /dev/null +++ b/src/views/ems/site/pointConfig/index.vue @@ -0,0 +1,1235 @@ + + + + + diff --git a/src/views/ems/site/sblb/index.vue b/src/views/ems/site/sblb/index.vue index 9424372..b3c6d07 100644 --- a/src/views/ems/site/sblb/index.vue +++ b/src/views/ems/site/sblb/index.vue @@ -95,19 +95,6 @@ label="操作" width="250"> @@ -177,14 +163,13 @@ import {deleteService, getDeviceDetailInfo, getDeviceInfoList} from '@/api/ems/s import {getAllSites} from '@/api/ems/zddt' import {formatNumber} from "@/filters/ems"; import {getAllDeviceCategory} from '@/api/ems/search' -import PointTable from './PointTable.vue' import AddDevice from "./AddDevice.vue"; import PointUpload from "./PointUpload.vue"; // import PcsSwitch from "./PcsSwitch.vue"; export default { name: "Sblb", - components: {AddDevice, PointTable, PointUpload}, + components: {AddDevice, PointUpload}, data() { return { loading: false, @@ -230,10 +215,6 @@ export default { this.deviceCategoryList = response?.data || [] }) }, - // 查看设备电位表格 - pointDetail(row, dataType) { - this.$refs.pointTable.showTable(row, dataType) - }, // 下载点位清单 downloadPointDetail(command, isDetail = false) { const siteId = isDetail ? command.siteId : this.siteId diff --git a/src/views/ems/site/zdlb/MonitorPointMapping.vue b/src/views/ems/site/zdlb/MonitorPointMapping.vue new file mode 100644 index 0000000..bcdb7db --- /dev/null +++ b/src/views/ems/site/zdlb/MonitorPointMapping.vue @@ -0,0 +1,217 @@ + + + + + diff --git a/src/views/ems/site/zdlb/index.vue b/src/views/ems/site/zdlb/index.vue index c4c3f27..e832e1d 100644 --- a/src/views/ems/site/zdlb/index.vue +++ b/src/views/ems/site/zdlb/index.vue @@ -1,4 +1,3 @@ -