巴青农资商城

region.js 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. import cityCodeJson from '@/utils/json/cityCode.json'
  2. /** 与平台 ruoyi-ui `utils/region.js` 逻辑一致 */
  3. export function normalizeRegionTree(nodes) {
  4. if (!nodes || !nodes.length) {
  5. return []
  6. }
  7. return nodes.map((node) => {
  8. const hasChildren = node.children && node.children.length > 0
  9. const children = hasChildren ? normalizeRegionTree(node.children) : undefined
  10. const isDistrict = node.type === 3
  11. const item = {
  12. code: node.code,
  13. name: node.name,
  14. type: node.type
  15. }
  16. if (children && children.length) {
  17. item.children = children
  18. }
  19. return item
  20. })
  21. }
  22. export function findRegionPath(nodes, targetCode, path) {
  23. if (!nodes || !nodes.length || targetCode == null || targetCode === '') {
  24. return null
  25. }
  26. const target = String(targetCode)
  27. for (let i = 0; i < nodes.length; i++) {
  28. const node = nodes[i]
  29. const nextPath = (path || []).concat(node.code)
  30. if (String(node.code) === target) {
  31. return nextPath
  32. }
  33. if (node.children && node.children.length) {
  34. const found = findRegionPath(node.children, target, nextPath)
  35. if (found) {
  36. return found
  37. }
  38. }
  39. }
  40. return null
  41. }
  42. export function getRegionNamesByCodes(regionTree, codes) {
  43. const names = []
  44. let nodes = regionTree
  45. for (let i = 0; i < codes.length; i++) {
  46. const code = codes[i]
  47. const node = (nodes || []).find((item) => String(item.code) === String(code))
  48. if (!node) {
  49. break
  50. }
  51. names.push(node.name)
  52. nodes = node.children || []
  53. }
  54. return names
  55. }
  56. export function findRegionNodeByCodes(regionTree, codes) {
  57. let nodes = regionTree
  58. let node = null
  59. for (let i = 0; i < codes.length; i++) {
  60. node = (nodes || []).find((item) => String(item.code) === String(codes[i]))
  61. if (!node) {
  62. return null
  63. }
  64. nodes = node.children || []
  65. }
  66. return node
  67. }
  68. /**
  69. * 解析级联选择结果(须选至区县 type=3)
  70. * @returns {{ valid: boolean, code?: string, name?: string }}
  71. */
  72. export function parseRegionSelection(regionTree, codes) {
  73. if (!codes || !codes.length) {
  74. return { valid: false }
  75. }
  76. const lastNode = findRegionNodeByCodes(regionTree, codes)
  77. if (!lastNode || lastNode.type !== 3) {
  78. return { valid: false }
  79. }
  80. const names = getRegionNamesByCodes(regionTree, codes)
  81. return {
  82. valid: true,
  83. code: String(codes[codes.length - 1]),
  84. name: names.join('/')
  85. }
  86. }
  87. /** 展示用:省/市/区 → 空格分隔 */
  88. export function formatRegionDisplay(regionName) {
  89. return (regionName || '').replace(/\//g, ' ')
  90. }
  91. /**
  92. * 将 cityCode.json 转为三级树(与后端 RegionTreeVO 结构一致)
  93. */
  94. export function convertCityCodeToRegionTree(cityCodeList) {
  95. return (cityCodeList || []).map((province) => {
  96. const provinceCode = String(province.code)
  97. const cities = (province.cityList || []).map((city) => {
  98. const cityCode = String(city.code)
  99. const areas = (city.areaList || []).map((area) => ({
  100. code: String(area.code),
  101. name: area.name,
  102. type: 3
  103. }))
  104. const cityNode = {
  105. code: cityCode,
  106. name: city.name,
  107. type: 2
  108. }
  109. if (areas.length) {
  110. cityNode.children = areas
  111. }
  112. return cityNode
  113. })
  114. const provinceNode = {
  115. code: provinceCode,
  116. name: province.name,
  117. type: 1
  118. }
  119. if (cities.length) {
  120. provinceNode.children = cities
  121. }
  122. return provinceNode
  123. })
  124. }
  125. let cachedRawTree = null
  126. let cachedCascaderTree = null
  127. function getRegionTreeFromCityCode() {
  128. if (!cachedRawTree) {
  129. cachedRawTree = convertCityCodeToRegionTree(cityCodeJson)
  130. }
  131. return cachedRawTree
  132. }
  133. /** 加载并缓存级联树(本地 cityCode.json,normalize 后供 up-cascader) */
  134. export function loadRegionCascaderTree(force = false) {
  135. if (!force && cachedCascaderTree) {
  136. return Promise.resolve({ raw: cachedRawTree, cascader: cachedCascaderTree })
  137. }
  138. cachedRawTree = getRegionTreeFromCityCode()
  139. cachedCascaderTree = normalizeRegionTree(cachedRawTree)
  140. return Promise.resolve({ raw: cachedRawTree, cascader: cachedCascaderTree })
  141. }