mirror of
https://github.com/jeecgboot/JeecgBoot.git
synced 2025-12-30 00:32:26 +08:00
186 lines
4.6 KiB
Java
186 lines
4.6 KiB
Java
/*
|
||
* 省市区联动组件通用工具类。
|
||
* 列表翻译、组件反推、表单设计器组件反推等功能都可以用该工具类实现。
|
||
*
|
||
* 1. leafName字段的意义:
|
||
* AntdvUI和ElementUI的叶级节点名字是不一样的,
|
||
* AntdvUI的名字是 isLeaf,ElementUI是 leaf,
|
||
* 默认是AntdvUI的名字,在表单设计器那边需要手动 setLeafName
|
||
*/
|
||
|
||
import { pcaa } from 'area-data'
|
||
|
||
export { pcaa }
|
||
|
||
/** 根节点Code = 86 */
|
||
export const ROOT_CODE = '86'
|
||
|
||
/** 叶级节点的名字 */
|
||
let leafName = 'isLeaf'
|
||
|
||
/**
|
||
* set leafName
|
||
* @param $leafName
|
||
*/
|
||
export function setLeafName($leafName = 'isLeaf') {
|
||
leafName = $leafName
|
||
}
|
||
|
||
/**
|
||
* 将地区数据转换成下拉框等组件可识别的Options数组
|
||
* @param data 地区data
|
||
* @param labelName label标签名字
|
||
* @return
|
||
*/
|
||
export function transToOptions(data, labelName = 'label') {
|
||
if (data) {
|
||
return Object.keys(data).map(key => ({ value: key, [labelName]: data[key] }))
|
||
} else {
|
||
return []
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取子级Data对象
|
||
*
|
||
* @param code 父级地区Code
|
||
*/
|
||
export function getChildrenDataByCode(code) {
|
||
return pcaa[code]
|
||
}
|
||
|
||
/**
|
||
* 获取子级Options对象
|
||
*
|
||
* @param code 父级地区Code
|
||
* @return {Array} 返回的值一定是一个数组,如果数组length===0,则代表没有子级
|
||
*/
|
||
export function getChildrenOptionsByCode(code) {
|
||
let options = []
|
||
let data = getChildrenDataByCode(code)
|
||
if (data) {
|
||
for (let key in data) {
|
||
if (data.hasOwnProperty(key)) {
|
||
options.push({ value: key, label: data[key], })
|
||
}
|
||
}
|
||
return options
|
||
} else {
|
||
return []
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取兄弟Data对象
|
||
*
|
||
* @param code 地区Code
|
||
*/
|
||
export function getSiblingsDataByCode(code) {
|
||
if (typeof code === 'string' && code.length === 6) {
|
||
// 父级节点Code
|
||
let parentCode = `${code.substring(0, 4)}00`
|
||
return getChildrenDataByCode(parentCode)
|
||
} else {
|
||
console.warn('[getSiblingsByCode]: code不合法')
|
||
return null
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取对应的 Label
|
||
*
|
||
* @param code 地区Code
|
||
*/
|
||
export function getLabelByCode(code) {
|
||
if (code) {
|
||
// 获取当前code所有的兄弟节点
|
||
let siblingsData = getSiblingsDataByCode(code)
|
||
// 然后取出自己的值
|
||
return siblingsData[code]
|
||
} else {
|
||
return code
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取所有的 Label,包括自身和所有父级
|
||
*
|
||
* @param code 地区Code
|
||
* @param joinText 合并文本
|
||
*/
|
||
export function getAllLabelByCode(code, joinText = ' / ') {
|
||
if (code) {
|
||
let { labels } = getAllParentByCode(code)
|
||
return labels.join(joinText)
|
||
} else {
|
||
return code
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 通过子级 code 反推所有父级的 code
|
||
*
|
||
* @param code 子级地区Code
|
||
* @returns {Object} options: 所有父级的选项;codes: 所有父级的code;labels: 所有父级的显示名
|
||
*/
|
||
export function getAllParentByCode(code) {
|
||
code = (typeof code === 'string' ? code : '').trim()
|
||
if (code.length === 0) {
|
||
return { options: [], codes: [], labels: [] }
|
||
}
|
||
// 获取第一级数据
|
||
let rootOptions = getChildrenOptionsByCode(ROOT_CODE)
|
||
hasChildren(rootOptions)
|
||
// 父级code数组,code长度
|
||
let parentCodes = [code], length = code.length
|
||
// 父级label数组
|
||
let parentLabels = [getLabelByCode(code)]
|
||
// 级别,位数,是否继续循环
|
||
let level = 1, num = 2, flag = true
|
||
|
||
let options = rootOptions
|
||
do {
|
||
let endIndex = num * level++
|
||
// 末尾补零个数
|
||
let zeroPadding = [...new Array(length - endIndex)].map(i => '0').join('')
|
||
// 裁剪并补零(获取上级的方式就是将当前code的后两位变成 00)
|
||
let parentCode = code.substring(0, endIndex) + zeroPadding
|
||
// 是否找到在选项中的位置
|
||
let findIt = false
|
||
for (let option of options) {
|
||
if (option.value === parentCode) {
|
||
if (option[leafName]) {
|
||
flag = false
|
||
} else {
|
||
let children = getChildrenOptionsByCode(option.value)
|
||
hasChildren(children)
|
||
option.children = children
|
||
options = children
|
||
parentCodes.splice(parentCodes.length - 1, 0, option.value)
|
||
parentLabels.splice(parentLabels.length - 1, 0, option.label)
|
||
}
|
||
findIt = true
|
||
break
|
||
}
|
||
}
|
||
|
||
if (findIt) {
|
||
findIt = false
|
||
} else {
|
||
flag = false
|
||
}
|
||
} while (flag)
|
||
return { options: rootOptions, codes: parentCodes, labels: parentLabels }
|
||
}
|
||
|
||
/**
|
||
* 判断所有的项是否有子节点
|
||
*
|
||
* @param options
|
||
*/
|
||
export function hasChildren(options) {
|
||
options.forEach(option => {
|
||
option[leafName] = getChildrenOptionsByCode(option.value).length === 0
|
||
})
|
||
}
|