import { getByTypeKey } from '@/api/dictionaryManage' import { getProvinces, getCityListByPid, getByCode, getDistrictTree, } from '@/api/dictionaryManage' import { getCatalogList } from '@/api/catalogManage' // 数据字典 export const dictMixin = { data() { return {} }, created() { this.getDictType() }, methods: { async getDictType() { if (!this.dictData) this.dictData = {} const keys = Object.keys(this.dictData) // 为每个请求添加类型标识,确保能区分不同请求返回的数据 const requests = keys.map((key) => getByTypeKey({ typeKey: key }).then((response) => ({ typeKey: key, data: response, })) ) const results = await Promise.all(requests) // 使用类型标识来处理数据,检查response是否为数组 results.forEach(({ typeKey, data }) => { this.dictData[typeKey] = Array.isArray(data) ? data : [] }) }, getDictName(typeKey, key) { const dictData = this.dictData[typeKey] if (!dictData || !key) return '' // 检查key是否包含逗号分隔的多个值 if (key.includes(',')) { // 分割成key数组并去除首尾空格 const keys = key.split(',').map((k) => k.trim()) // 为每个key查找对应的名称 const names = keys.map((k) => { const item = dictData.find((item) => item.key === k) return item ? item.name : k // 找不到对应名称时返回原key }) // 用逗号连接所有名称返回 return names.join(', ') } else { // 单个key的处理逻辑保持不变 const item = dictData.find((item) => item.key === key) return item ? item.name : key // 找不到对应名称时返回原key } }, // 根据字典 value 获取字典 name getDictNameByValue(typeKey, value) { const dictData = this.dictData[typeKey] if (!dictData || dictData.length === 0) return '' if (value === null || value === undefined || value === '') return '' // 辅助函数:在字典数据中根据 value 查找对应的 item const findDictItemByValue = (searchValue) => { if ( searchValue === null || searchValue === undefined || searchValue === '' ) return null // 尝试多种类型的匹配 const strValue = String(searchValue) const numValue = Number(searchValue) // 1. 严格匹配(原始类型) let item = dictData.find((item) => item.value === searchValue) if (item) return item // 2. 字符串匹配 item = dictData.find((item) => { return String(item.value) === strValue }) if (item) return item // 3. 数字匹配(如果 value 可以转换为数字) if (!isNaN(numValue) && !isNaN(searchValue)) { item = dictData.find((item) => { const itemNum = Number(item.value) return !isNaN(itemNum) && itemNum === numValue }) if (item) return item } return null } // 检查 value 是否包含逗号分隔的多个值 const valueStr = String(value) if (valueStr.includes(',')) { // 处理多个值 const values = valueStr .split(',') .map((v) => v.trim()) .filter(Boolean) const names = values.map((v) => { const item = findDictItemByValue(v) return item ? item.name : v // 找不到对应名称时返回原 value }) return names.join(', ') } else { // 处理单个值 const item = findDictItemByValue(value) return item ? item.name : valueStr // 找不到对应名称时返回原 value } }, }, } // 区域 export const regionMixin = { data() { return { districtTree: [], // 省市区数据 districtTreeData: [], // 省市区数据 provinces: [], // 省份城市数据 regionNameMap: {}, // 存储区域代码和名称 districtTreeCascaderProps: { checkStrictly: true, label: 'name', value: 'code', children: 'children', // lazy: true, // 启用懒加载 // lazyLoad: (node, resolve) => { // // node为当前点击的节点,resolve为数据加载完成的回调函数 // if (node.level > 0) { // const pid = node?.data?.id // getCityListByPid({ pid: pid }) // .then((res) => { // // 确保响应数据存在 // const childNodes = res.value || [] // // 格式化子节点数据 // const children = childNodes.map((item) => { // const isLastLevel = node.level >= 2 // 假设节点级别从0开始,0=省,1=市,2=区 // return { // ...item, // // 动态设置hasChildren属性 // // 如果是最后一级,则设为false,否则设为true // hasChildren: !isLastLevel, // } // }) // resolve(children) // }) // .catch((error) => { // console.error('获取子节点数据失败:', error) // resolve([]) // 出错时返回空数组 // }) // } // }, }, } }, created() { this.getDistrictTreeData() }, methods: { getDistrictTreeData() { getDistrictTree().then((res) => { this.districtTreeData = res.value this.districtTree = this.districtTreeData if (this.$permission.isAdminOrProvince()) { // 管理员或省级权限,显示所有数据 this.districtTree = this.districtTreeData } else { // 非管理员且数据范围为区域时,筛选出当前用户区域下的市区数据 let user = this.$permission.getUserInfo() if (user.dataScope === 1) { let arr = [] this.districtTreeData.forEach((item) => { if (item.children) { item.children.forEach((child) => { if (child.code === user.cityCode) { arr.push(child) } }) } }) this.districtTreeData = arr } else if (user.dataScope === 2) { // 只返回当前县的 let arr = [] this.districtTreeData.forEach((item) => { if (item.children) { item.children.forEach((child) => { if (child.code === user.cityCode) { if (child.children) { child.children = child.children.filter( (c) => c.code === user.countyCode ) } arr.push(child) } }) } }) this.districtTreeData = arr } this.districtTree = this.districtTreeData } }) }, // 获取所有省份 getProvincesData() { getProvinces().then((res) => { this.provinces = res.value.map((province) => ({ ...province, hasChildren: true, })) }) }, // 批量获取区域名称 async fetchRegionNames(tableData, regionCode) { for (const row of tableData) { if (!row[regionCode]) continue if (!this.regionNameMap[row[regionCode]]) { try { const res = await getByCode({ code: row[regionCode] }) if (res.value && res.value.name) { this.$set(this.regionNameMap, row[regionCode], res.value.name) } } catch (error) { console.error('获取区域名称失败:', error) } } } }, // }, } // 监审目录 export const catalogMixin = { data() { return { catalogListOptions: [], catalogProps: { filterable: true, placeholder: '请选择关联监审项目', style: 'width: 100%', showAllLevels: false, props: { multiple: true, children: 'children', checkStrictly: true, label: 'catalogName', value: 'id', }, }, } }, created() { this.getCatalogListOptions() }, methods: { getCatalogListOptions() { getCatalogList({}).then((res) => { this.catalogListOptions = res.value // 使用函数式方法直接生成新的tableData this.catalogListOptions = this.catalogListOptions .filter((item) => item.children && item.parentId === '0') .flatMap((item) => item.children) // 递归过滤出status == 1(启用状态)的数据 this.catalogListOptions = this.filterEnabledCatalogsStrict( this.catalogListOptions ) }) }, /** * 递归过滤出状态为启用(status == 1)的目录数据(严格模式) * @param {Array} catalogs - 目录数据数组 * @returns {Array} 过滤后的目录数据 */ filterEnabledCatalogsStrict(catalogs) { if (!Array.isArray(catalogs) || catalogs.length === 0) { return [] } const result = [] for (const catalog of catalogs) { // 检查当前节点是否为启用状态 if (catalog.status == 1) { // 创建当前节点的副本 const filteredCatalog = { ...catalog } // 如果有子目录,递归过滤子目录 if ( filteredCatalog.children && Array.isArray(filteredCatalog.children) ) { filteredCatalog.children = this.filterEnabledCatalogsStrict( filteredCatalog.children ) } result.push(filteredCatalog) } else if (catalog.children && Array.isArray(catalog.children)) { // 如果当前节点不是启用状态,但子节点中可能有启用的节点 const filteredChildren = this.filterEnabledCatalogsStrict( catalog.children ) // 如果有过滤后的子节点,将它们添加到结果中 result.push(...filteredChildren) } } return result }, }, } // 通用方法 export const commonMixin = { data() { return {} }, methods: { /** * 处理级联选择器多选提交数据 * @param {Object} config - 需要处理的字段名和选中的数据,格式为 { name: [['1','2], ['1','2] } * @returns {Object} 处理后的数据对象 */ extractLastLevelValues(config) { const result = {} for (const fieldName in config) { if (config.hasOwnProperty(fieldName)) { const fieldValue = config[fieldName] if (Array.isArray(fieldValue)) { // 获取每个选项的最后一级值 const lastLevelValues = fieldValue.map((item) => { // 如果是数组,取最后一个元素 if (Array.isArray(item)) { return item[item.length - 1] } // 如果是字符串,直接返回 return item }) // 转换为逗号分隔的字符串 result[fieldName] = lastLevelValues.join(',') } else { result[fieldName] = fieldValue } } } return result }, /** * 处理级联选择器多选回显数据 * @param {Object} config - 需要处理的字段名和选中的数据,格式为 { name: [['1','2], ['1','2] } * @param {Array} options - 级联选择器选项数据 * @returns {Object} 处理后的数据对象 * */ formatRelatedItemsForDisplay(config) { const result = {} for (const fieldName in config) { if (config.hasOwnProperty(fieldName)) { const fieldValue = config[fieldName].value // 如果是空字符串或null,返回空数组 if (!fieldValue || fieldValue.trim() === '') { return [] } // 将逗号分隔的字符串转换为数组 const itemsArray = fieldValue.split(',').map((item) => { // 返回选中值的完整路径(包括所有父级节点)一级一级查找 // 递归查找当前项的父级项 return this.getFullPath( item, config[fieldName].options, config[fieldName].id, config[fieldName].parentId ) }) // 将一维数组转换为二维数组(每个元素是一个包含一个编码的数组) result[fieldName] = itemsArray } } return result }, /** * 在选项树中递归查找指定ID的项 * @param {String} id - 要查找的ID * @param {Array} options - 选项数组 * @param {String} idKey - ID字段名,默认值为'id' * @returns {Object|null} 找到的项或null */ findItemById(id, options, idKey = 'id') { if (!Array.isArray(options)) { return null } for (const option of options) { if (option[idKey] === id) { return option } if (option.children && Array.isArray(option.children)) { const foundInChildren = this.findItemById(id, option.children, idKey) if (foundInChildren) { return foundInChildren } } } return null }, /** * 返回选中值的完整路径(包括所有父级节点) * @param {String} currentItem - 选中的值 * @param {Array} options - 级联选择器选项数据 * @param {String} idKey - 选中值的id的key,默认值为'id' * @param {String} parentIdKey - 选中值的父级id的key,默认值为'parentId' * @returns {Array} 选中值的完整路径(包括所有父级节点) */ getFullPath(currentItem, options, idKey = 'id', parentIdKey = 'parentId') { // 如果options不是数组,直接返回空数组 if (!Array.isArray(options)) { return [] } // 参数校验 if (!currentItem) { return [] } // 返回选中值的完整路径(包括所有父级节点) const path = [] let currentId = currentItem // 循环查找所有父级节点 while (currentId) { // 使用findItemById方法查找当前ID对应的节点 const foundItem = this.findItemById(currentId, options, idKey) if (foundItem) { // 将找到的节点ID添加到路径开头 path.unshift(foundItem[idKey]) // 继续查找父级节点 currentId = foundItem[parentIdKey] // 防止死循环:如果父ID与当前ID相同,说明达到了根节点或数据有问题 if (currentId === foundItem[idKey]) { break } } else { // 如果未找到当前ID对应的节点,结束循环 break } } return path }, // 生成UUID generateUUID() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace( /[xy]/g, function (c) { const r = (Math.random() * 16) | 0 const v = c === 'x' ? r : (r & 0x3) | 0x8 return v.toString(16) } ) }, }, }