pipeNetworkStore.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /**
  2. * 设施点位与管线图层状态(票 24)。
  3. *
  4. * 与监测点摘要(`mapStore`)**分开持有**:两者是不同业务对象、不同读取路径、不同统计口径
  5. * (管线不进地图摘要总数,监测点也不当管线渲染)。合并成一个 store 会让两种口径互相污染。
  6. *
  7. * 失败纪律沿用全舱:几何取不到只让**设施/管线图层**降级,不牵连监测点、设备与面板,
  8. * 也绝不回退 mock(票 04 的 real 纪律)。
  9. */
  10. import { computed, ref } from 'vue'
  11. import { defineStore } from 'pinia'
  12. import { SECTION_STATE, section } from '../domain/sectionState.js'
  13. import { REQUEST_REASON } from '../domain/requestReason.js'
  14. import { filterPipeNetwork } from '../domain/pipeNetwork.js'
  15. import { fetchPipeNetwork } from '../services/pipeLayerService.js'
  16. /** 未取数时的分区(与其它 store 同形,`loaded:false` 表示"还没请求过")。 */
  17. function pending() {
  18. return { state: SECTION_STATE.EMPTY, reason: '', mode: '', data: null, missing: [], freshness: '', retained: false, loaded: false }
  19. }
  20. const EMPTY_LAYER = { pipes: [], components: [], blocked: [], coverage: {}, counts: {}, districtApplied: false, districtUnresolvedCount: 0 }
  21. export const usePipeNetworkStore = defineStore('pipeNetworkStore', () => {
  22. const layer = ref(pending())
  23. const industry = ref('all')
  24. /**
  25. * 当前生效的片区筛选(前端键;票 67 更正)。
  26. *
  27. * 与行业同层、同一套纪律:几何是**全量取回、本地裁剪**,所以切片区只改本地筛选条件、
  28. * 不重新发请求(切换必须即时)。片区的来源是**设施编码前缀**(片区+行业+时间编码),
  29. * 见 `domain/pipeNetwork.js` 的 `pipeDistrictOf`。
  30. */
  31. const scope = ref('all')
  32. let requestOptions = {}
  33. /** 请求注入(config / fetchImpl):取一次让后续取数共用。 */
  34. function configure(options = {}) {
  35. requestOptions = { ...requestOptions, ...options }
  36. }
  37. /** 只读写入分区(走查与单测注入用)。 */
  38. function setLayer(value) {
  39. layer.value = { ...value, loaded: true }
  40. }
  41. /** 当前行业 + 片区筛选下的图层(图层过滤只此一处,引擎与组件都不做第二次过滤)。 */
  42. const filtered = computed(() =>
  43. filterPipeNetwork(layer.value.data || EMPTY_LAYER, { industry: industry.value, scope: scope.value }),
  44. )
  45. /** 取数成功(含真实为空)才交数组;**失败或还没取过一律交 `null`**。 */
  46. function layerOrNull(list) {
  47. const current = layer.value
  48. const settled = current.loaded === true
  49. && [SECTION_STATE.SUCCESS, SECTION_STATE.EMPTY, SECTION_STATE.STALE].includes(current.state)
  50. return settled ? list : null
  51. }
  52. /** 给 `modeLayerPlan` 的两段(与计划里的 `facilities`/`pipelines` 同形)。 */
  53. const facilities = computed(() => layerOrNull(filtered.value.components))
  54. const pipelines = computed(() => layerOrNull(filtered.value.pipes))
  55. /** 被拦下的对象(「无地图位置」清单的来源,带中文原因)。 */
  56. const blocked = computed(() => filtered.value.blocked)
  57. /** 行业覆盖:哪个行业有几何、哪个没有,由后端 `coverage` 表达,前端只转述。 */
  58. const coverage = computed(() => filtered.value.coverage)
  59. const loaded = computed(() => layer.value.loaded === true)
  60. const state = computed(() => layer.value.state)
  61. const reason = computed(() => layer.value.reason)
  62. /** 只改行业筛选(几何已全量取回,切行业不重新发请求)。 */
  63. function setIndustry(next) {
  64. industry.value = typeof next === 'string' && next ? next : 'all'
  65. return industry.value
  66. }
  67. /** 只改片区筛选(同上:本地裁剪,不重新发请求)。 */
  68. function setScope(next) {
  69. scope.value = typeof next === 'string' && next ? next : 'all'
  70. return scope.value
  71. }
  72. async function load(options = {}) {
  73. if (options.industry !== undefined) industry.value = options.industry
  74. if (options.scope !== undefined) scope.value = options.scope
  75. if (Object.keys(options).some((key) => !['industry', 'scope'].includes(key))) configure(options)
  76. let result = null
  77. try {
  78. result = await fetchPipeNetwork(requestOptions)
  79. } catch {
  80. // 适配层不抛;真抛了也要收成失败分区,不能让一次几何失败掀掉整个外壳。
  81. result = section(SECTION_STATE.FAILED, { reason: REQUEST_REASON.UNREACHABLE, data: null })
  82. }
  83. layer.value = { ...result, loaded: true }
  84. return layer.value
  85. }
  86. return { layer, loaded, state, reason, industry, scope, filtered, facilities, pipelines, blocked, coverage, load, setIndustry, setScope, configure, setLayer }
  87. })