feat(客户信息): 增强地址显示功能并修复文档格式

添加地址格式化工具函数,支持标准地址和自定义地址的组合显示
修复行政区划代码文档中的多余冒号
This commit is contained in:
砂糖
2025-12-22 17:08:41 +08:00
parent 3c6919013d
commit 4ad9caf5c6
3 changed files with 97 additions and 2 deletions

View File

@@ -3,7 +3,7 @@
// 行政区划的层级与一个国家的中央地方关系模式、国土面积的大小、政府与公众的关系状况等因素有关。 // 行政区划的层级与一个国家的中央地方关系模式、国土面积的大小、政府与公众的关系状况等因素有关。
// 行政区划代码,也称行政代码,它是国家行政机关的识别符号,一般执行两项国家标准 // 行政区划代码,也称行政代码,它是国家行政机关的识别符号,一般执行两项国家标准
// 《中华人民共和国行政区划代码》GB/T2260-2007)和《县以下行政区划代码编制规则》GB/T10114-2003)。 // 《中华人民共和国行政区划代码》GB/T2260-2007)和《县以下行政区划代码编制规则》GB/T10114-2003)。
// 由9位阿拉伯数字组成相当于机关单位的身份号码。按照国务院《行政区划管理条例》规定行政区划代码由民政部门确定、发布。 // 由9位阿拉伯数字组成相当于机关单位的身份号码。按照国务院《行政区划管理条例》规定行政区划代码由民政部门确定、发布。
// 该标准对我国县以上行政区划的代码做了规定,用六位阿拉伯数字分层次代表我国的省(自治区、直辖市)、地区(市、州、盟)、县(区、市、旗)的名称。 // 该标准对我国县以上行政区划的代码做了规定,用六位阿拉伯数字分层次代表我国的省(自治区、直辖市)、地区(市、州、盟)、县(区、市、旗)的名称。

View File

@@ -0,0 +1,85 @@
import areaData from './data.js';
/**
* 辅助函数将code数组/字符串转为name字符串
* @param {String|Array} codeVal - 如 "110000/110101" 或 ["110000", "110101"]
* @returns {String} 如 "北京市/东城区"
*/
function convertCodeToName(codeVal) {
if (!codeVal) return '';
const codeArr = Array.isArray(codeVal) ? codeVal : codeVal.split('/').filter(Boolean);
return codeArr.map(code => areaData[code] || '').filter(Boolean).join('/');
}
/**
* 格式化/解析区域地址文本(兼容「[标准地址](自定义地址)」格式)
* @param {String|Object} value - 输入值:
* - 字符串:如 "[北京市/东城区](XX街道1号)"、"北京市/东城区"、"" 等
* - 对象:{ standard: '北京市/东城区', custom: 'XX街道1号' }
* @returns {Object|String} 输出规则:
* - 输入为字符串 → 返回结构化对象 { standard: '', custom: '' }
* - 输入为对象 → 返回格式化后的组合字符串 "[标准地址](自定义地址)"
* - 输入为空/非预期类型 → 返回空字符串(对象模式)或空结构(字符串模式)
*/
function formatAreaText(value) {
// 核心正则:匹配「[标准地址](自定义地址)」格式,分组提取标准地址和自定义地址
const areaReg = /^\[([^\]]*)\]\(([^)]*)\)$/;
// ========== 场景1输入为空/非预期类型 → 容错返回 ==========
if (!value || (typeof value !== 'string' && typeof value !== 'object')) {
// 输入非字符串/对象 → 按类型返回默认值
return typeof value === 'object' ? '' : { standard: '', custom: '' };
}
// ========== 场景2输入是字符串 → 解析为结构化对象 ==========
if (typeof value === 'string') {
// 去除首尾空格
const trimVal = value.trim();
// 空字符串 → 返回空结构
if (!trimVal) return { standard: '', custom: '' };
// 匹配「[标准地址](自定义地址)」格式
const matchResult = trimVal.match(areaReg);
if (matchResult) {
// 提取分组值并去空格
const standard = matchResult[1]?.trim() || '';
const custom = matchResult[2]?.trim() || '';
return { standard, custom };
}
// 非组合格式(纯标准地址/纯自定义地址)→ 默认归为standard
return { standard: trimVal, custom: '' };
}
// ========== 场景3输入是对象 → 格式化为组合字符串 ==========
if (typeof value === 'object' && !Array.isArray(value)) {
const { standard = '', custom = '' } = value;
// 转字符串并去空格
const standardStr = String(standard).trim();
const customStr = String(custom).trim();
// 组合为「[标准地址](自定义地址)」格式
return `[${standardStr}](${customStr})`;
}
// 兜底:其他情况返回空(如数组输入)
return typeof value === 'object' ? '' : { standard: '', custom: '' };
}
/**
* 增强版支持code自动转name的格式化函数
*/
function formatAreaTextEnhanced(value, keyType = 'name') {
// 先调用基础版解析/格式化
const result = formatAreaText(value);
// 如果是解析模式返回对象且keyType为name转换code为name
if (typeof result === 'object' && keyType === 'name') {
result.standard = convertCodeToName(result.standard);
}
return result;
}
// 输出:{ standard: "北京市/东城区", custom: "XX街道1号" }
export { formatAreaTextEnhanced };

View File

@@ -16,11 +16,15 @@
<el-descriptions-item label="客户等级"> <el-descriptions-item label="客户等级">
<dict-tag :value="customer.customerLevel" :options="dict.type.customer_level"></dict-tag> <dict-tag :value="customer.customerLevel" :options="dict.type.customer_level"></dict-tag>
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="客户地址" v-hasPermi="['crm:customer:address']">{{ customer.address || '-' }}</el-descriptions-item> <el-descriptions-item label="客户地址" v-hasPermi="['crm:customer:address']">
{{ formattedAddress || '-' }}
</el-descriptions-item>
</el-descriptions> </el-descriptions>
</template> </template>
<script> <script>
import { formatAreaTextEnhanced } from '@/components/ChinaAreaSelect/index.js'
export default { export default {
name: 'CustomerDetail', name: 'CustomerDetail',
props: { props: {
@@ -36,6 +40,12 @@ export default {
required: true, required: true,
default: () => ({ type: {} }) default: () => ({ type: {} })
} }
},
computed: {
formattedAddress() {
const address = formatAreaTextEnhanced(this.customer.address || '-')
return address.standard + ' (' + address.custom + ')'
}
} }
} }
</script> </script>