| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526 |
- /**
- * 预警处置模式的「事件 + 预警/报警切换」状态(票 13)。
- *
- * 职责边界,沿用票 05/11/17/18 已定的分工:
- * · 本 store 只做三件事:持有切换状态(`mode` 当前是预警还是报警)、
- * 调 `services/eventApi.js` 取跨设备当前事件(当 mode 变了就换族重取)、
- * 把结果收成一个 `currentEvents` 分区;
- * · 事件怎么画归 `domain/eventList.js`(纯函数,本文件不做字段改名);
- * · 路径拼接、凭据、mock/real 切换归 `services/`(本文件不出现 fetched、裸字段名)。
- *
- * 为什么「切换」在 store 而不是组件里:票 19 要求「四个面板均支持预警/报警切换」——
- * 切换是**共享**状态(当前预警/历史分析/预警效率/预警分析四块面板读同一个当前族),
- * 放组件里每块各存一份,切了一块其它三块不会跟着变。本票先把 store 状态落好,
- * 组件(`EventListPane.vue`)只消费它,票 19 的四块面板直接复用同一份。
- *
- * 竞态收口沿用票 10/11 的 token 纪律:快速连续切 预警→报警→预警 时,
- * 只让最后一次请求落进分区(迟到的响应丢弃),不会出现"显示报警却把预警数据挂上去"。
- *
- * 票 61(统一分页批次三)新增**服务端页码状态**:当前事件表与历史事件单窗范围都按
- * `page`+`pageSize=10` 发请求,页码是本 store 的视图状态(`currentPage`/`historyPage`)。
- * 纪律有三条:① 条件(mode/range/industry/level/status)变化 → 页码回第 1 页;
- * ② 定时刷新/同条件重取**不复位**(条文 6 的反面),越界由回显夹回最后一页;
- * ③ 翻一页只重取该分区(不牵连另外三块面板),并用同一 token 作废迟到的页响应。
- */
- import { computed, ref } from 'vue'
- import { defineStore } from 'pinia'
- import { SECTION_STATE, section } from '../domain/sectionState.js'
- import { REQUEST_REASON } from '../domain/requestReason.js'
- import { EVENT_FAMILY } from '../domain/events.js'
- import { currentEventsView, isKnownEventMode, refreshedEventSelection } from '../domain/eventList.js'
- import { fetchCurrentEvents } from '../services/eventApi.js'
- import { EVENT_DETAIL_RESULT, eventDetailView, planEventLocate } from '../domain/eventDetail.js'
- import { getCameraState, getAssociatedDeviceState, highlightMapObject, setCameraFocus } from '../services/mapService.js'
- import { useMapStore } from './mapStore.js'
- import { EVENT_RANGES } from '../domain/warningResponsePanels.js'
- import { eventTimeWindow, historyWindows } from '../domain/eventRange.js'
- import { fetchEventAnalysis, fetchEventHistory, fetchHandlingEfficiency } from '../services/warningResponseApi.js'
- import { fetchWorkOrderList } from '../services/detailApi.js'
- import { PAGE_SIZE, serverPageView } from '../domain/pagination.js'
- /**
- * 会触发「回第 1 页」的条件键(条文 5/6;定时刷新不经过这里)。
- *
- * 票 67 补 `scope`(当前范围)。它必须进这张表:片区现在真的会下发给预警分析端点
- * (`warningResponseApi.js` 的 `acceptsDistrict`),换片区就是换了一批数据,
- * 页码留在第 3 页会翻到一个在新范围里根本不存在的页。
- */
- const CONDITION_KEYS = ['mode', 'range', 'industry', 'level', 'status', 'scope']
- /**
- * 报警效率面板「当前工单列表」的页大小(票 65)。
- *
- * 与事件表的 `PAGE_SIZE`(10)**刻意分开**:两者是不同端点、不同翻页语义,
- * 共用一个常量会让「改事件页大小」意外改掉工单列表(票 61 变异 M1 记过同类教训)。
- */
- const WORK_ORDER_LIST_PAGE_SIZE = 5
- /** 未取数时的分区(与其它 store 同形,`loaded:false` 表示"还没请求过")。 */
- function pending() {
- return { state: SECTION_STATE.EMPTY, reason: '', mode: '', data: null, missing: [], freshness: '', retained: false, loaded: false }
- }
- function initialSections() {
- return {
- currentEvents: pending(),
- historyAnalysis: pending(),
- responseEfficiency: pending(),
- eventAnalysis: pending(),
- // 票 65:报警效率面板的「当前工单列表」(全量工单端点,与上面四块各自成败)。
- // 分区名刻意叫 `workOrderList`:store 只说领域词汇,不照抄后端字段名
- // (照抄会被 t13 的 I1 守卫判红,票 05 纪律)。
- workOrderList: pending(),
- }
- }
- export const useEventStore = defineStore('eventStore', () => {
- /** 当前切换状态:`WARNING`(预警)或 `ALARM`(报警)。默认预警(`/events/current` 的 mode 必填)。 */
- const mode = ref(EVENT_FAMILY.WARNING)
- /** 当前事件分区(`/events/current` 的整体响应;成败由内部事件分区状态表达)。 */
- const sections = ref(initialSections())
- /** 预警处置三块聚合面板共享的时间范围,默认近 7 天。 */
- const range = ref('7d')
- /** 正在取数(界面只做轻提示;分区成败仍由分区自己说)。 */
- const loading = ref(false)
- /** 当前事件表的服务端页码(1 起,`pageSize=PAGE_SIZE`)。 */
- const currentPage = ref(1)
- /** 历史事件**单窗范围**的服务端页码(多窗合并范围无全局页,渲染层自持页码)。 */
- const historyPage = ref(1)
- /**
- * 「当前工单列表」的服务端页码(票 65)。
- *
- * 与上面两个页码**互不牵连**:翻工单页只重取工单分区,不动事件表/历史/效率/分析
- * (与「翻一页只重取该分区」同一条纪律)。
- */
- const workOrderPage = ref(1)
- /** 最后一个「当前事件分区的领域对象」(视图层读它,避免每次都重解构 section)。 */
- const currentDomain = ref(null)
- /** 当前打开的事件详情与地图定位结果;返回时不重取列表,保留 mode/筛选/分页上下文。 */
- const selectedEvent = ref(null)
- const locate = ref({ result: '', deviceCode: '', pointCode: '', reasonText: '' })
- /** 请求序号:翻页/切族/切范围共用一个令牌,迟到的页响应整批丢弃(token 纪律)。 */
- let token = 0
- /**
- * 工单列表专用的令牌(票 65)。
- *
- * 为什么不共用 `token`:那份是全局面板的令牌,翻一个工单页就把它 +1,会把在途的
- * 四块面板响应整批作废(用户只是翻了个工单页,另外三块却停在旧数据上)。
- * 工单列表是**独立分区**,竞态也该独立收口。
- */
- let workOrderToken = 0
- /**
- * 工单列表当前钉住的时间窗(票 65,2026-10-22)。
- *
- * 由 `loadPanels` 在每次取数时写入,`setWorkOrderPage` 直接复用 —— 翻页期间窗口必须
- * 一个字节都不变。若每次翻页都重算 `eventTimeWindow()`,`endTime` 会毫秒级后移,
- * 边界工单就会在页与页之间重复或消失(P10 断言钉住这件事)。
- */
- let workOrderWindow = null
- /** 请求注入(config / fetchImpl / industry…):取一次让后续所有取数共用。 */
- let requestOptions = {}
- function configure(options = {}) {
- requestOptions = { ...requestOptions, ...options }
- }
- /** 直接写入分区(走查与单测注入用)。 */
- function setSection(name, value) {
- sections.value = { ...sections.value, [name]: { ...value, loaded: true } }
- }
- /** 条件的可比较快照(只取值,不按对象身份——视图计划每次重算都是新对象)。 */
- function conditionSnapshot() {
- return {
- mode: mode.value,
- range: range.value,
- industry: requestOptions.industry,
- level: requestOptions.level,
- status: requestOptions.status,
- scope: requestOptions.scope,
- }
- }
- function selectedRange() {
- return EVENT_RANGES.find((item) => item.key === range.value) || EVENT_RANGES[0]
- }
- /** 四块面板共享的请求条件(`/events/current` 与三块聚合接口同一份)。 */
- function activeConditions() {
- const active = selectedRange()
- return { ...requestOptions, ...eventTimeWindow(active.type), mode: mode.value, rangeType: active.type }
- }
- /** 该范围是否存在「全局页」(单窗才有;多窗合并范围只能对已加载集合分页)。 */
- function singleHistoryWindow() {
- const active = selectedRange()
- const window = eventTimeWindow(active.type)
- return historyWindows(window.startTime, window.endTime).length <= 1
- }
- /** 当前事件页的后端回显 → 控件视图(失败/无回显回 null,不夹、不猜)。 */
- function currentPageView(result) {
- if (!result || !result.data) return null
- const rows = result.data.sections && result.data.sections.events && result.data.sections.events.data
- return serverPageView(result.data.pagination, Array.isArray(rows) ? rows.length : 0)
- }
- /** 历史事件页的后端回显 → 控件视图(只有服务端分页形态才有全局页)。 */
- function historyPageView(result) {
- const paging = result && result.data && result.data.paging
- if (!paging || paging.mode !== 'server') return null
- return serverPageView(paging, Array.isArray(result.data.events) ? result.data.events.length : 0)
- }
- async function fetchCurrentAt(page, pageSize = PAGE_SIZE) {
- try {
- return await fetchCurrentEvents({ ...activeConditions(), page, pageSize })
- } catch (error) {
- return section(SECTION_STATE.FAILED, { reason: REQUEST_REASON.UNREACHABLE, data: null })
- }
- }
- async function fetchHistoryAt(page) {
- try {
- return await fetchEventHistory({ ...activeConditions(), page, pageSize: PAGE_SIZE })
- } catch (error) {
- return section(SECTION_STATE.FAILED, { reason: REQUEST_REASON.UNREACHABLE, data: null })
- }
- }
- /**
- * 取一页并做越界夹回(条文 6:数据变少时页码越界 ⇒ 夹回最后一页再取一次)。
- * 只在「后端回显的分页视图说当前页超过了最后一页」时补一次请求,不递归。
- * @returns {Promise<object|null>} `null` = 期间又发生了更新的请求(token 已变),调用方应放弃
- */
- async function loadPage(request, pageRef, pageViewOf, mine) {
- let result = await request(pageRef.value)
- if (mine !== token) return null
- const view = pageViewOf(result)
- if (view && view.page !== pageRef.value) {
- pageRef.value = view.page
- result = await request(pageRef.value)
- if (mine !== token) return null
- const clamped = pageViewOf(result)
- if (clamped) pageRef.value = clamped.page
- }
- return result
- }
- /** 当前「事件 + 切换」视图(领域层现算;组件与走查都读它)。 */
- const view = computed(() => {
- // 已取到数据:从领域对象读事件分区(行 + 内部状态)。
- if (currentDomain.value) return currentEventsView(currentDomain.value)
- // 还没取过 / 整体失败:用整个分区驱动占位措辞(pending → 正在取数;failed → 加载失败)。
- return currentEventsView(null, sections.value.currentEvents)
- })
- /**
- * 取预警处置四块面板。切换 mode/range/筛选时四块共享一次条件,迟到响应整批丢弃;
- * 条件变化同时把两个服务端页码回第 1 页(**定时刷新不带条件 ⇒ 页码保持**)。
- */
- async function loadPanels(options = {}) {
- const before = conditionSnapshot()
- if (options.mode !== undefined && isKnownEventMode(options.mode)) mode.value = options.mode
- if (options.range !== undefined && EVENT_RANGES.some((item) => item.key === options.range)) range.value = options.range
- if (Object.keys(options).some((key) => !['mode', 'range'].includes(key))) configure(options)
- const after = conditionSnapshot()
- if (CONDITION_KEYS.some((key) => before[key] !== after[key])) {
- currentPage.value = 1
- historyPage.value = 1
- // 票 65:条件变了,工单列表也回第 1 页(条文 5;定时刷新不带条件 ⇒ 页码保持)。
- workOrderPage.value = 1
- }
- const active = activeConditions()
- // 票 65:把窗口**钉**在这一次取数上。`eventTimeWindow()` 每次调用都按 `Date.now()`
- // 重算,首屏与翻页各算一次就会毫秒级漂移 —— 翻页时窗口在动,边界工单会重复或漏掉。
- workOrderWindow = { startTime: active.startTime, endTime: active.endTime }
- token += 1
- const mine = token
- loading.value = true
- const requests = await Promise.all([
- fetchCurrentEvents({ ...active, page: currentPage.value, pageSize: PAGE_SIZE }),
- fetchEventHistory({ ...active, page: historyPage.value, pageSize: PAGE_SIZE }),
- fetchHandlingEfficiency(active),
- fetchEventAnalysis(active),
- // 票 65:报警效率面板的「当前工单列表」走**全量工单**端点(另一个粒度:
- // handling-efficiency 只给状态计数、不返回工单实体)。预警族不画工单列表,
- // 但这里照取不误——切族时不必等一次新往返,且失败只影响那一块分区。
- // 页码取 `workOrderPage`(定时刷新保持当前页),时间窗用刚钉下的那一份。
- fetchWorkOrderList(
- { page: workOrderPage.value, pageSize: WORK_ORDER_LIST_PAGE_SIZE, startTime: workOrderWindow.startTime, endTime: workOrderWindow.endTime },
- requestOptions,
- ),
- ].map(async (request) => {
- try {
- return await request
- } catch (error) {
- return section(SECTION_STATE.FAILED, { reason: REQUEST_REASON.UNREACHABLE, data: null })
- }
- }))
- if (mine !== token) return sections.value
- const [current, history, efficiency, analysis, workOrderList] = requests
- const safeCurrent = await clampSettled(current, currentPage, currentPageView, fetchCurrentAt, mine)
- if (mine !== token) return sections.value
- const safeHistory = await clampSettled(history, historyPage, historyPageView, fetchHistoryAt, mine)
- if (mine !== token) return sections.value
- sections.value = {
- currentEvents: { ...safeCurrent, loaded: true },
- historyAnalysis: { ...safeHistory, loaded: true },
- responseEfficiency: { ...efficiency, loaded: true },
- eventAnalysis: { ...analysis, loaded: true },
- workOrderList: { ...workOrderList, loaded: true },
- }
- currentDomain.value = safeCurrent.data || null
- selectedEvent.value = refreshedEventSelection(selectedEvent.value, currentDomain.value)
- loading.value = false
- return sections.value
- }
- /**
- * 已落定的一页若越界则夹回并补取一次(与 `loadPage` 同一判据)。
- * 并发批次取数时不能在 `Promise.all` 里改页码,所以夹回发生在整批回包之后。
- */
- async function clampSettled(result, pageRef, pageViewOf, request, mine) {
- if (mine !== token) return result
- const view = pageViewOf(result)
- if (!view || view.page === pageRef.value) {
- if (view) pageRef.value = view.page
- return result
- }
- pageRef.value = view.page
- const clamped = await request(pageRef.value)
- if (mine !== token) return result
- const clampedView = pageViewOf(clamped)
- if (clampedView) pageRef.value = clampedView.page
- return clamped
- }
- function setRange(next) {
- if (!EVENT_RANGES.some((item) => item.key === next) || next === range.value) return sections.value
- return loadPanels({ range: next })
- }
- /**
- * 当前事件表翻页(服务端页码分页):只重取当前事件分区,其余三块不动。
- * 迟到的页响应由 token 作废;越界页码按回显夹回最后一页。
- * @param {number} next 目标页码(1 起)
- * @returns {Promise<object>} `sections.currentEvents`
- */
- async function setCurrentPage(next) {
- const page = Math.max(1, Math.trunc(Number(next) || 1))
- if (page === currentPage.value) return sections.value.currentEvents
- currentPage.value = page
- token += 1
- const mine = token
- // 翻页**不置 loading**:条文 8「翻页请求进行中保持旧内容,不闪空白」——
- // 整面板 loading 只用于换条件/首取(那才需要占位)。
- const result = await loadPage(fetchCurrentAt, currentPage, currentPageView, mine)
- if (!result) return sections.value.currentEvents
- sections.value = { ...sections.value, currentEvents: { ...result, loaded: true } }
- currentDomain.value = result.data || null
- // 翻页后保留已打开的详情与「当前列表未返回该事件」语义(票 13 既有行为)。
- selectedEvent.value = refreshedEventSelection(selectedEvent.value, currentDomain.value)
- return sections.value.currentEvents
- }
- /**
- * 历史事件单窗范围翻页(服务端页码分页):只重取历史分析分区。
- * 多窗合并范围没有全局页,本入口不适用(渲染层对已加载集合分页)。
- * @param {number} next 目标页码(1 起)
- * @returns {Promise<object>} `sections.historyAnalysis`
- */
- async function setHistoryPage(next) {
- const page = Math.max(1, Math.trunc(Number(next) || 1))
- if (!singleHistoryWindow() || page === historyPage.value) return sections.value.historyAnalysis
- historyPage.value = page
- token += 1
- const mine = token
- // 与当前事件表同一条纪律:翻页保持旧内容,不闪空白(条文 8)。
- const result = await loadPage(fetchHistoryAt, historyPage, historyPageView, mine)
- if (!result) return sections.value.historyAnalysis
- sections.value = { ...sections.value, historyAnalysis: { ...result, loaded: true } }
- return sections.value.historyAnalysis
- }
- /**
- * 「当前工单列表」翻页(服务端页码分页;票 65):只重取工单分区。
- *
- * 三条纪律与事件表翻页一致,只是竞态用**独立令牌**:
- * · 翻页保持旧内容、不闪空白(条文 8);
- * · 页码越界由后端回显夹回(`serverPageView` 同一判据),夹回后同步到 `workOrderPage`;
- * · 迟到的页响应整体丢弃(`workOrderToken` 变了就放弃)。
- *
- * @param {number} next 目标页码(1 起)
- * @returns {Promise<object>} `sections.workOrderList`
- */
- async function setWorkOrderPage(next) {
- const page = Math.max(1, Math.trunc(Number(next) || 1))
- if (page === workOrderPage.value) return sections.value.workOrderList
- workOrderPage.value = page
- workOrderToken += 1
- const mine = workOrderToken
- // 翻页必须用**首屏钉下的同一份时间窗**(不是现在重算一份):
- // 少了窗口,第 2 页会悄悄变回全库口径;每次重算窗口,`endTime` 会毫秒级后移,
- // 边界工单就会在页与页之间重复或消失。两种情况都是「看不出来」的错。
- const window = workOrderWindow || activeConditions()
- let result
- try {
- result = await fetchWorkOrderList(
- { page, pageSize: WORK_ORDER_LIST_PAGE_SIZE, startTime: window.startTime, endTime: window.endTime },
- requestOptions,
- )
- } catch (error) {
- result = section(SECTION_STATE.FAILED, { reason: REQUEST_REASON.UNREACHABLE, data: null })
- }
- // 迟到响应丢弃:期间又翻过页/切过条件,这一页不落分区。
- if (mine !== workOrderToken) return sections.value.workOrderList
- const view = serverPageView(
- result && result.data && result.data.pagination,
- result && result.data && Array.isArray(result.data.orders) ? result.data.orders.length : 0,
- )
- // 后端夹回(如数据变少后第 3 页不存在):以回显为准,不再补一次请求。
- if (view) workOrderPage.value = view.page
- sections.value = { ...sections.value, workOrderList: { ...result, loaded: true } }
- return sections.value.workOrderList
- }
- /**
- * 取当前事件列表(跨设备的 `/events/current`;票 13 的预警处置面板数据源)。
- *
- * `options.mode` 显式给(菜单面板里点别的族)时更新切换状态;没给就沿用当前族。
- * token 纪律:换族后旧的在途响应作废(迟到的预警不落进报警表)。
- * 票 61:`page`/`pageSize` 进请求;`page` 缺省回第 1 页(这是一次完整重取)。
- * @param {object} [options] `{ mode, industry, level, status, page, pageSize, config, fetchImpl }`
- * @returns {Promise<object>} `sections.currentEvents`
- */
- async function loadCurrentEvents(options = {}) {
- if (options.mode !== undefined && isKnownEventMode(options.mode)) mode.value = options.mode
- if (Object.keys(options).some((key) => !['mode', 'page', 'pageSize'].includes(key))) configure(options)
- const pageSize = Number.isInteger(options.pageSize) && options.pageSize > 0 ? options.pageSize : PAGE_SIZE
- currentPage.value = Number.isInteger(options.page) && options.page > 0 ? options.page : 1
- token += 1
- const mine = token
- loading.value = true
- const result = await loadPage((page) => fetchCurrentAt(page, pageSize), currentPage, currentPageView, mine)
- // 迟到的响应丢弃:mode/页码换过之后,旧请求的结果不得写进新分区。
- if (!result) return sections.value.currentEvents
- const next = { ...result, loaded: true }
- sections.value = { ...sections.value, currentEvents: next }
- currentDomain.value = result.data || null
- selectedEvent.value = refreshedEventSelection(selectedEvent.value, currentDomain.value)
- loading.value = false
- return next
- }
- /** 从当前列表打开详情;不改变当前列表数据或筛选上下文。 */
- function openEvent(event) {
- selectedEvent.value = event || null
- // 定位结果先清空:位置(设备码/点位码)由 `locateEvent` 按事件所在行的编码现算,
- // 这里只留一个"还没定位过"的空态,不预先冒充结果。
- locate.value = { result: '', code: (event && event.code) || '', deviceCode: '', pointCode: '', reasonText: '' }
- return selectedEvent.value
- }
- function closeEvent() {
- selectedEvent.value = null
- locate.value = { result: '', code: '', deviceCode: '', pointCode: '', reasonText: '' }
- // 收起详情时把强调还原(传空 = 全部回到常态),地图上不留上一轮的高亮。
- highlightMapObject([])
- }
- async function locateEvent(event = selectedEvent.value, deps = {}) {
- if (event) selectedEvent.value = event
- const current = selectedEvent.value
- const mapStore = useMapStore()
- const objects = deps.objects || [
- ...getAssociatedDeviceState().plan.filter((row) => row.placement === 'drawn').map((row) => ({ ...row, kind: 'monitoring-device' })),
- ...mapStore.summary.objects,
- ]
- const mapReady = deps.mapReady === undefined ? !!getCameraState() : !!deps.mapReady
- const plan = planEventLocate(current, objects, mapReady)
- locate.value = { result: plan.result, deviceCode: plan.deviceCode, pointCode: plan.pointCode, reasonText: plan.reasonText }
- if (plan.result !== EVENT_DETAIL_RESULT.OK) return locate.value
- const focus = deps.focus || setCameraFocus
- const highlight = deps.highlight || highlightMapObject
- if (!plan.target || focus(plan.target) !== true) {
- locate.value = { result: EVENT_DETAIL_RESULT.UNAVAILABLE, deviceCode: plan.deviceCode, pointCode: plan.pointCode, reasonText: '地图尚未就绪,稍后重试' }
- return locate.value
- }
- // 设备与关联管线一起高亮;一个都没高亮到 = 目标还没上图(如实说,不假装成功)。
- const matched = highlight(plan.codes)
- if (!matched) {
- locate.value = { result: EVENT_DETAIL_RESULT.UNAVAILABLE, deviceCode: plan.deviceCode, pointCode: plan.pointCode, reasonText: '关联设备尚未出现在地图上' }
- }
- return locate.value
- }
- /**
- * 切换预警/报警。唯一入口(组件与票 19 的面板都走它):
- * 改切换状态 + 换族重取 —— 切换与字段/状态标签同步是 `domain/eventList.js` 的
- * `eventListSwitchView` 结构保证的,这里只管状态与取数。
- * @param {string} next `WARNING`/`ALARM`;认不出不改
- * @returns {Promise<object>} 分区
- */
- async function setMode(next) {
- if (!isKnownEventMode(next) || next === mode.value) return sections.value.currentEvents
- return loadPanels({ mode: next })
- }
- /** 仅测试用:回到未加载状态。 */
- function reset() {
- token += 1
- mode.value = EVENT_FAMILY.WARNING
- sections.value = initialSections()
- currentDomain.value = null
- range.value = '7d'
- currentPage.value = 1
- historyPage.value = 1
- selectedEvent.value = null
- locate.value = { result: '', code: '', deviceCode: '', pointCode: '', reasonText: '' }
- loading.value = false
- requestOptions = {}
- }
- return {
- mode,
- range,
- sections,
- loading,
- currentPage,
- historyPage,
- workOrderPage,
- currentDomain,
- selectedEvent,
- locate,
- view,
- configure,
- setRange,
- loadPanels,
- openEvent,
- closeEvent,
- locateEvent,
- setSection,
- loadCurrentEvents,
- setCurrentPage,
- setHistoryPage,
- setWorkOrderPage,
- setMode,
- reset,
- }
- })
|