diff --git a/src/api/inspectionDataManage/inspectionReporter.js b/src/api/inspectionDataManage/inspectionReporter.js
index 60c3271..25b107a 100644
--- a/src/api/inspectionDataManage/inspectionReporter.js
+++ b/src/api/inspectionDataManage/inspectionReporter.js
@@ -20,10 +20,12 @@ export function getPatrolReport(lineId,filter) {
});
}
-export function getPatrolReportShaoxing(url, lineId, filter) {
+export function getPatrolReportShaoxing(url, lineId, filter, stationCode) {
+ // 汇聚态:走聚合代理,stationCode 取点击的报告所属站
+ const prefix = stationCode ? "/agg/proxy" : "";
return request({
- url: `/patrol/insreport/shaoxing/${url}/${lineId}/${filter}`,
+ url: `${prefix}/patrol/insreport/shaoxing/${url}/${lineId}/${filter}`,
method: "get",
- params: {},
+ params: stationCode ? { stationCode } : {},
});
}
diff --git a/src/api/portal/index.js b/src/api/portal/index.js
index 62a544b..60c12f1 100644
--- a/src/api/portal/index.js
+++ b/src/api/portal/index.js
@@ -84,3 +84,46 @@ export function stopRealtimeVideo(query) {
noAlert: true
});
}
+
+// 汇聚侧云台控制:按摄像头所属站点代理转发
+// stationCode 取当前控制摄像头所在站(而非顶部站名筛选),以查询串方式传递
+export function aggPtzControl(payload) {
+ const { stationCode, ...data } = payload || {};
+ return request({
+ url: "/agg/proxy/patrol/preset/ptzControl",
+ method: "post",
+ params: { stationCode },
+ data,
+ noAlert: true
+ });
+}
+
+// 汇聚侧预置位列表:路径与单站一致(cameraCode 按 # 拆成 device/domain 放路径上),仅追加 ?stationCode
+export function aggPresetList(payload) {
+ const { stationCode, cameraCode } = payload || {};
+ const value = String(cameraCode || "");
+ const separatorIndex = value.indexOf("#");
+ if (separatorIndex <= 0 || separatorIndex === value.length - 1) {
+ return Promise.reject(new Error("摄像机编码格式不正确"));
+ }
+ const device = encodeURIComponent(value.slice(0, separatorIndex));
+ const domain = encodeURIComponent(value.slice(separatorIndex + 1));
+ return request({
+ url: `/agg/proxy/patrol/preset/presetList/${device}/${domain}`,
+ method: "get",
+ params: { stationCode },
+ noAlert: true
+ });
+}
+
+// 汇聚侧预置位保存:按摄像头所属站点代理转发
+export function aggPresetCreate(payload) {
+ const { stationCode, ...data } = payload || {};
+ return request({
+ url: "/agg/proxy/patrol/preset/presetCreate",
+ method: "post",
+ params: { stationCode },
+ data,
+ noAlert: true
+ });
+}
diff --git a/src/api/videosMonitor/index.js b/src/api/videosMonitor/index.js
index 406161f..e0b1cd0 100644
--- a/src/api/videosMonitor/index.js
+++ b/src/api/videosMonitor/index.js
@@ -1,4 +1,5 @@
import request from "@/utils/request";
+import store from "@/store";
import { defectList } from "../home/index";
/**
@@ -229,11 +230,13 @@ export function analysisDefectList(params) {
* @param {*} data
* @returns
*/
- export function analysisDefectListShaoxing(params) {
+ export function analysisDefectListShaoxing(params, stationCode) {
+ // 汇聚态:走聚合代理,stationCode 取点击的任务所属站
+ const prefix = stationCode ? "/agg/proxy" : "";
return request({
- url: `/patrol/analysis/list_v2_ex`,
+ url: `${prefix}/patrol/analysis/list_v2_ex`,
method: "get",
- params,
+ params: stationCode ? { ...params, stationCode } : params,
});
}
@@ -317,14 +320,27 @@ export function getDefectAlarmList(params = {}) {
});
}
/**
- * 缺陷记录卡片的列表
+ * 缺陷记录卡片的列表(支持 pageNum/pageSize/desc/pointName 等服务端筛选)
* @param {*} data
* @returns
*/
export function defectRecordList(params) {
+ // 汇聚态由拦截器映射改写为 /agg/patrol/analysis/defect/list;单站保持原路径(服务端 algName 筛选)
return request({
url: `/patrol/analysis/defect/list`,
method: "get",
params,
});
}
+
+/**
+ * 缺陷类型下拉选项:汇聚态 descOptions;单站 algNameOptions(算法名称)
+ * @returns
+ */
+export function defectDescOptions() {
+ const isAgg = store.getters.fromPortal;
+ return request({
+ url: isAgg ? `/agg/analysis/defect/algNameOptions` : `/patrol/analysis/defect/algNameOptions`,
+ method: "get",
+ });
+}
diff --git a/src/layout/components/AppMain.vue b/src/layout/components/AppMain.vue
index 2746d6e..54f69ed 100644
--- a/src/layout/components/AppMain.vue
+++ b/src/layout/components/AppMain.vue
@@ -20,7 +20,9 @@ export default {
return this.$store.state.tagsView.cachedViews
},
key() {
- return this.$route.path
+ // 拼上工作台选中的站名编码:切换站名时仅重建当前页面(重新拉取数据),导航栏不整页刷新
+ const stationCode = this.$store.getters.workspaceStationCode || ''
+ return this.$route.path + (stationCode ? '||' + stationCode : '')
}
},
watch: {
diff --git a/src/layout/components/Sidebar/index.vue b/src/layout/components/Sidebar/index.vue
index aa64f8c..8b52730 100644
--- a/src/layout/components/Sidebar/index.vue
+++ b/src/layout/components/Sidebar/index.vue
@@ -50,7 +50,7 @@ export default {
},
computed: {
...mapState(["settings"]),
- ...mapGetters(["sidebarRouters", "sidebar", "roles"]),
+ ...mapGetters(["sidebarRouters", "sidebar", "roles", "fromPortal"]),
// admin 账号显示全部导航,其余账号只显示默认菜单
isAdminAccount() {
if ((this.roles || []).indexOf("admin") !== -1) return true;
@@ -80,7 +80,10 @@ export default {
const isTaskManagement = ["巡检任务管理", "巡视任务管理"].includes(title);
const isImplementationPoints = !this.isAdminAccount && isImplementationPointsMenu(route);
const isTemporarilyHiddenRootMenu = depth === 0 && temporarilyHiddenRootMenus.has(title);
- if (isTaskManagement || isImplementationPoints || isTemporarilyHiddenRootMenu) return result;
+ // 汇聚门户进入的会话:历史回放暂时隐藏
+ const isHistoryPlaybackHidden = this.fromPortal &&
+ ["/video-playback", "/inspection-workspace/video-playback"].includes(route.path);
+ if (isTaskManagement || isImplementationPoints || isTemporarilyHiddenRootMenu || isHistoryPlaybackHidden) return result;
result.push({
...route,
diff --git a/src/layout/index.vue b/src/layout/index.vue
index e6c6eaf..b849b38 100644
--- a/src/layout/index.vue
+++ b/src/layout/index.vue
@@ -23,7 +23,23 @@
@click="goModule(item.path)"
>{{ item.label }}
-
+
+
+
+
+
@@ -41,6 +57,7 @@ import { AppMain, Navbar, Settings, Sidebar, TagsView } from './components'
import ResizeMixin from './mixin/ResizeHandler'
import { mapState, mapGetters } from 'vuex'
import variables from '@/assets/styles/variables.scss'
+import { getStationList } from '@/api/portal'
export default {
name: 'Layout',
@@ -55,7 +72,9 @@ export default {
data() {
return {
// 侧边栏宽度档位:0=160px,1=200px,2=240px,3=280px,随子菜单展开层级加深
- sidebarWidthLevel: 0
+ sidebarWidthLevel: 0,
+ // 汇聚态站名筛选选项
+ stationOptions: []
}
},
mixins: [ResizeMixin],
@@ -83,7 +102,20 @@ export default {
isPatrolWorkspace() {
return this.$route.matched.some(route => route.meta && route.meta.patrolWorkspace)
},
- ...mapGetters(['fromPortal']),
+ // 侧边栏宽度档位 ≥1 时给侧边栏容器加宽(修复模板引用未定义属性的告警)
+ sidebarWide() {
+ return this.sidebarWidthLevel >= 1
+ },
+ ...mapGetters(['fromPortal', 'workspaceStationCode']),
+ // 选中值存于 store(sessionStorage 持久化),跨页面保持
+ stationCode: {
+ get() {
+ return this.workspaceStationCode || ''
+ },
+ set(value) {
+ this.$store.dispatch('siteContext/setWorkspaceStation', value)
+ }
+ },
// 从门户跳转进入时展示:首页回门户,动环巡检为当前单站系统
moduleLinks() {
if (!this.fromPortal) return []
@@ -103,7 +135,18 @@ export default {
return variables;
}
},
+ mounted() {
+ if (this.fromPortal) this.loadStationOptions()
+ },
methods: {
+ // 站名下拉选项:与汇聚首页同款接口
+ loadStationOptions() {
+ getStationList({}).then(response => {
+ this.stationOptions = Array.isArray(response && response.data) ? response.data : []
+ }).catch(() => {
+ this.stationOptions = []
+ })
+ },
goModule(path) {
if (this.$route.path !== path) this.$router.push({ path }).catch(() => undefined)
},
@@ -186,6 +229,34 @@ export default {
align-items: stretch;
}
+ /* 汇聚态站名筛选:靠行最右 */
+ .module-station-select {
+ width: 150px;
+
+ ::v-deep .el-input__inner {
+ height: 28px;
+ line-height: 28px;
+ background: rgba(16, 30, 84, 0.65);
+ border-color: rgba(84, 130, 255, 0.35);
+ color: #eef4ff;
+ font-size: 12px;
+
+ &::placeholder {
+ color: rgba(159, 180, 232, 0.65);
+ }
+ }
+
+ ::v-deep .el-input__suffix {
+ display: flex;
+ align-items: center;
+ height: 28px;
+ }
+
+ ::v-deep .el-input__icon {
+ line-height: 28px;
+ }
+ }
+
.module-link {
position: relative;
min-width: 90px;
diff --git a/src/store/getters.js b/src/store/getters.js
index 87a5f27..1e045ea 100644
--- a/src/store/getters.js
+++ b/src/store/getters.js
@@ -21,5 +21,6 @@ const getters = {
siteName: state => state.siteContext.siteName,
inSite: state => state.siteContext.siteId !== undefined && state.siteContext.siteId !== null,
fromPortal: state => state.siteContext.fromPortal,
+ workspaceStationCode: state => state.siteContext.workspaceStationCode,
}
export default getters
diff --git a/src/store/modules/siteContext.js b/src/store/modules/siteContext.js
index eb13058..50c224a 100644
--- a/src/store/modules/siteContext.js
+++ b/src/store/modules/siteContext.js
@@ -5,6 +5,8 @@
const SITE_KEY = "portal_site";
// 是否从汇聚门户跳转进入单站视图(会话级标记,直接输地址打开时不带)
const FROM_KEY = "portal_from";
+// 汇聚门户工作台顶部"站名"下拉选中的站(会话级)
+const WORKSPACE_STATION_KEY = "portal_ws_station";
function readSite() {
try {
@@ -22,7 +24,8 @@ const siteContext = {
return {
siteId: site ? site.id : undefined,
siteName: site ? site.name : "",
- fromPortal: sessionStorage.getItem(FROM_KEY) === "1"
+ fromPortal: sessionStorage.getItem(FROM_KEY) === "1",
+ workspaceStationCode: sessionStorage.getItem(WORKSPACE_STATION_KEY) || ""
};
},
mutations: {
@@ -42,6 +45,14 @@ const siteContext = {
} else {
sessionStorage.removeItem(SITE_KEY);
}
+ },
+ SET_WORKSPACE_STATION(state, code) {
+ state.workspaceStationCode = code || "";
+ if (code) {
+ sessionStorage.setItem(WORKSPACE_STATION_KEY, code);
+ } else {
+ sessionStorage.removeItem(WORKSPACE_STATION_KEY);
+ }
}
},
actions: {
@@ -49,6 +60,10 @@ const siteContext = {
markFromPortal({ commit }) {
commit("SET_FROM_PORTAL", true);
},
+ // 工作台顶部站名下拉选择
+ setWorkspaceStation({ commit }, code) {
+ commit("SET_WORKSPACE_STATION", code);
+ },
// 进入单站视图
enterSite({ commit }, site) {
commit("SET_SITE", site);
@@ -62,6 +77,7 @@ const siteContext = {
fromPortal: state => state.fromPortal,
siteId: state => state.siteId,
siteName: state => state.siteName,
+ workspaceStationCode: state => state.workspaceStationCode,
// 是否处于单站视图
inSite: state => state.siteId !== undefined && state.siteId !== null
}
diff --git a/src/utils/request.js b/src/utils/request.js
index e5a56aa..5719f45 100644
--- a/src/utils/request.js
+++ b/src/utils/request.js
@@ -18,6 +18,39 @@ let downloadLoadingInstance;
export let isRelogin = { show: false };
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
+
+// 汇聚门户(动环巡检)只读会话的接口改写映射:
+// 从门户进入且未进入单站视图时,动环业务查询统一走后端聚合接口(agg)。
+// key/value 不含查询参数,按 url(忽略首部斜杠)全等匹配,
+// 因此 /relation/right、/patrol/insreport/{id}/{filter} 等衍生接口不会被误改。
+const AGG_API_MAP = {
+ 'patrol/taskstatus/list': 'agg/taskstatus/list',
+ 'patrol/task/taskInfo_v2': 'agg/proxy/patrol/task/taskInfo_v2',
+ 'patrol/task/getPatrolPointName': 'agg/proxy/patrol/task/getPatrolPointName',
+ 'patrol/task/list': 'agg/task/list',
+ 'basedata/prodevmnt/device/treeAreaDeviceSelectFilterByPreset/relation': 'patrol/agg/tree/device',
+ 'basedata/patrolpointmnt/patrolpoint/list/monitor/relation': 'agg/patrolpoint/list/monitor',
+ 'patrol/insreport/list': 'agg/insreport/list',
+ 'patrol/calender/year': 'agg/calender/year',
+ 'patrol/calender/month': 'agg/calender/month',
+ 'patrol/calender/day': 'agg/calender/day',
+ 'patrol/analysis/defect/list': 'agg/analysis/defect/list'
+}
+
+// 汇聚门户工作台顶部"站名"下拉:选中站后,下列查询接口统一携带 stationCode
+// (前缀匹配;缺陷类型下拉选项 algNameOptions 也按选中站过滤)
+const AGG_STATION_CODE_PATHS = [
+ '/agg/taskstatus/list',
+ '/agg/task/list',
+ '/agg/insreport/list',
+ '/agg/calender/',
+ '/agg/tree/channel',
+ '/patrol/agg/tree/device',
+ '/agg/patrolpoint/list/monitor',
+ '/agg/analysis/defect/list',
+ '/agg/analysis/defect/algNameOptions'
+]
+
// 创建axios实例
const service = axios.create({
// axios中请求配置有baseURL选项,表示请求URL公共部分
@@ -28,6 +61,16 @@ const service = axios.create({
// request拦截器
service.interceptors.request.use(config => {
+ // 汇聚门户只读会话:动环业务接口改写为聚合接口(单站/嵌入会话不受影响)
+ if (store.getters.fromPortal && !store.getters.inSite && typeof config.url === "string") {
+ const mapped = AGG_API_MAP[config.url.replace(/^\/+/, "")]
+ if (mapped) config.url = "/" + mapped
+ // 工作台顶部站名下拉:选中站后给列表/树查询带上 stationCode("全部场站"不传)
+ const wsCode = store.getters.workspaceStationCode
+ if (wsCode && config.method === "get" && AGG_STATION_CODE_PATHS.some(p => config.url.indexOf(p) === 0)) {
+ config.params = Object.assign({}, config.params, { stationCode: wsCode })
+ }
+ }
// 是否需要设置 token
const isToken = (config.headers || {}).isToken === false
// 是否需要防止数据重复提交
@@ -89,7 +132,7 @@ service.interceptors.request.use(config => {
function LoginEntity() {
let username;
- let password;
+ let password;
}
diff --git a/src/views/cards/defectRecord/index.vue b/src/views/cards/defectRecord/index.vue
index 7ed887f..6311547 100644
--- a/src/views/cards/defectRecord/index.vue
+++ b/src/views/cards/defectRecord/index.vue
@@ -11,13 +11,11 @@
{{ total }}
+
+
+
+
@@ -128,7 +143,7 @@