domainRequest.js 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. /**
  2. * 领域接口服务的共用底座(票 05)。
  3. *
  4. * 三个领域模块(`mapApi` / `detailApi` / `runtimeApi`)都做同一件事:
  5. * 拼查询串 → 走票 04 的 `requestCockpitJson` → 用 `sectionFromResult` 收成一个分区。
  6. * 这段样板收在这里,领域模块只留「路径 + 转换函数 + 空判据」。
  7. *
  8. * 分工不变(票 04 的票面):地址拼接、凭据、mock/real 切换全在 `cockpitApi.js`;
  9. * 本文件与领域模块**不出现** `Authorization`,也读不到令牌。
  10. */
  11. import { requestCockpitJson } from './cockpitApi.js'
  12. import { sectionFromResult } from '../domain/sectionState.js'
  13. /** 拼查询串;空值(undefined/null/'')跳过,数组按重复键展开。 */
  14. export function buildQuery(params) {
  15. const search = new URLSearchParams()
  16. for (const [key, value] of Object.entries(params || {})) {
  17. if (value === undefined || value === null || value === '') continue
  18. if (Array.isArray(value)) {
  19. for (const item of value) {
  20. if (item !== undefined && item !== null && item !== '') search.append(key, String(item))
  21. }
  22. continue
  23. }
  24. search.append(key, String(value))
  25. }
  26. const text = search.toString()
  27. return text ? `?${text}` : ''
  28. }
  29. /**
  30. * 取一个分区。
  31. * @param {string} path 领域路径
  32. * @param {object} [options]
  33. * @param {object} [options.params] 查询参数
  34. * @param {(raw: any) => any} [options.toData] 载荷 → 领域对象
  35. * @param {(raw: any) => boolean} [options.isEmpty] 空数据判据
  36. * @param {(raw: any) => string} [options.freshnessOf] 取新鲜度字符串
  37. * @param {object} [options.config] / [options.fetchImpl] 单测注入
  38. */
  39. export async function fetchSection(path, options = {}) {
  40. const result = await requestCockpitJson(`${path}${buildQuery(options.params)}`, {
  41. config: options.config,
  42. fetchImpl: options.fetchImpl,
  43. })
  44. return sectionFromResult(result, {
  45. toData: options.toData,
  46. isEmpty: options.isEmpty,
  47. freshnessOf: options.freshnessOf,
  48. })
  49. }
  50. /** 「列表长度为 0」这类通用空判据。 */
  51. export function isEmptyBy(predicate) {
  52. return (payload) => {
  53. try {
  54. return !!predicate(payload)
  55. } catch {
  56. // 载荷形状意外时不要当成空——交给转换层记 missing,别静默显示「无数据」。
  57. return false
  58. }
  59. }
  60. }