|
@@ -22,6 +22,7 @@
|
|
|
filterable
|
|
filterable
|
|
|
style="width: 100%;"
|
|
style="width: 100%;"
|
|
|
@change="handleBrandChange"
|
|
@change="handleBrandChange"
|
|
|
|
|
+ @clear="handleBrandClear"
|
|
|
>
|
|
>
|
|
|
<el-option
|
|
<el-option
|
|
|
v-for="brand in brandList"
|
|
v-for="brand in brandList"
|
|
@@ -40,6 +41,11 @@
|
|
|
/>
|
|
/>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-col>
|
|
</el-col>
|
|
|
|
|
+ <el-col :span="8">
|
|
|
|
|
+ <el-form-item label="商标注册人:">
|
|
|
|
|
+ <el-input v-model="formData.brandRegistrant" readonly style="width: 100%;" placeholder="商标注册人" class="readonly-input readonly-not-allowed" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
<el-col :span="8">
|
|
<el-col :span="8">
|
|
|
<el-form-item label="授权类型:">
|
|
<el-form-item label="授权类型:">
|
|
|
<el-select
|
|
<el-select
|
|
@@ -58,6 +64,7 @@
|
|
|
</el-select>
|
|
</el-select>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-col>
|
|
</el-col>
|
|
|
|
|
+
|
|
|
</el-row>
|
|
</el-row>
|
|
|
|
|
|
|
|
<!-- 第一行:三个分类下拉框 -->
|
|
<!-- 第一行:三个分类下拉框 -->
|
|
@@ -204,16 +211,23 @@
|
|
|
<!-- 授权链路 -->
|
|
<!-- 授权链路 -->
|
|
|
<el-form-item label="授权链路:">
|
|
<el-form-item label="授权链路:">
|
|
|
<div class="auth-chain-container">
|
|
<div class="auth-chain-container">
|
|
|
- <!-- 授权链路表格 -->
|
|
|
|
|
- <el-table :data="authChainTableData" border style="width: 100%; margin-bottom: 16px;">
|
|
|
|
|
- <el-table-column
|
|
|
|
|
- v-for="(level, index) in authChainLevels"
|
|
|
|
|
- :key="index"
|
|
|
|
|
- :label="level.label"
|
|
|
|
|
- align="center"
|
|
|
|
|
- min-width="200"
|
|
|
|
|
- >
|
|
|
|
|
- <template #default>
|
|
|
|
|
|
|
+ <!-- 授权链路自定义表格 -->
|
|
|
|
|
+ <div class="auth-chain-custom-table">
|
|
|
|
|
+ <div class="auth-chain-header">
|
|
|
|
|
+ <div
|
|
|
|
|
+ v-for="level in authChainLevels"
|
|
|
|
|
+ :key="'h-' + level.id"
|
|
|
|
|
+ class="auth-chain-cell header-cell"
|
|
|
|
|
+ >
|
|
|
|
|
+ {{ level.label }}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="auth-chain-row">
|
|
|
|
|
+ <div
|
|
|
|
|
+ v-for="level in authChainLevels"
|
|
|
|
|
+ :key="'c-' + level.id"
|
|
|
|
|
+ class="auth-chain-cell"
|
|
|
|
|
+ >
|
|
|
<el-input
|
|
<el-input
|
|
|
v-if="level.editable"
|
|
v-if="level.editable"
|
|
|
v-model="level.value"
|
|
v-model="level.value"
|
|
@@ -221,13 +235,13 @@
|
|
|
clearable
|
|
clearable
|
|
|
/>
|
|
/>
|
|
|
<span v-else>{{ level.value }}</span>
|
|
<span v-else>{{ level.value }}</span>
|
|
|
- </template>
|
|
|
|
|
- </el-table-column>
|
|
|
|
|
- </el-table>
|
|
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
|
|
|
<!-- 操作按钮 -->
|
|
<!-- 操作按钮 -->
|
|
|
<div class="auth-chain-actions">
|
|
<div class="auth-chain-actions">
|
|
|
- <el-button type="primary" @click="handleAddAuthLevel">添加品牌授权人</el-button>
|
|
|
|
|
|
|
+ <el-button type="primary" @click="handleAddAuthLevel" :disabled="authChainLevels.length >= 5">添加品牌授权人</el-button>
|
|
|
<el-button type="danger" @click="handleDeleteAuthLevel" :disabled="authChainLevels.length <= 2">删除</el-button>
|
|
<el-button type="danger" @click="handleDeleteAuthLevel" :disabled="authChainLevels.length <= 2">删除</el-button>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
@@ -357,7 +371,6 @@ import { ElMessage, ElMessageBox } from 'element-plus';
|
|
|
import { listBrand } from '@/api/product/brand';
|
|
import { listBrand } from '@/api/product/brand';
|
|
|
import { listCategory } from '@/api/product/category';
|
|
import { listCategory } from '@/api/product/category';
|
|
|
import type { CategoryVO } from '@/api/product/category/types';
|
|
import type { CategoryVO } from '@/api/product/category/types';
|
|
|
-import { chinaAreaList } from '@/api/system/addressarea';
|
|
|
|
|
import { listByIds } from '@/api/system/oss';
|
|
import { listByIds } from '@/api/system/oss';
|
|
|
import { addSupplierauthorize, getBrandAuthorizeDetail, updateSupplierauthorize } from '@/api/supplier/supplierauthorize';
|
|
import { addSupplierauthorize, getBrandAuthorizeDetail, updateSupplierauthorize } from '@/api/supplier/supplierauthorize';
|
|
|
import type { SupplierauthorizeForm } from '@/api/supplier/supplierauthorize/types';
|
|
import type { SupplierauthorizeForm } from '@/api/supplier/supplierauthorize/types';
|
|
@@ -366,6 +379,7 @@ import { listAuthorizetypeLevel } from '@/api/supplier/authorizetypeLevel';
|
|
|
import type { AuthorizetypeLevelVO } from '@/api/supplier/authorizetypeLevel/types';
|
|
import type { AuthorizetypeLevelVO } from '@/api/supplier/authorizetypeLevel/types';
|
|
|
import { useUserStore } from '@/store/modules/user';
|
|
import { useUserStore } from '@/store/modules/user';
|
|
|
import FileUpload from '@/components/FileUpload/index.vue';
|
|
import FileUpload from '@/components/FileUpload/index.vue';
|
|
|
|
|
+import { regionData } from 'element-china-area-data';
|
|
|
|
|
|
|
|
const router = useRouter();
|
|
const router = useRouter();
|
|
|
const route = useRoute();
|
|
const route = useRoute();
|
|
@@ -387,6 +401,7 @@ const formData = ref({
|
|
|
brandId: '',
|
|
brandId: '',
|
|
|
brandName: '',
|
|
brandName: '',
|
|
|
brandLogo: '', // 品牌LOGO
|
|
brandLogo: '', // 品牌LOGO
|
|
|
|
|
+ brandRegistrant: '', // 商标注册人
|
|
|
authorizeTypeId: '', // 授权类型ID
|
|
authorizeTypeId: '', // 授权类型ID
|
|
|
authorizeLevel: '', // 授权等级
|
|
authorizeLevel: '', // 授权等级
|
|
|
category1: '', // 第一行的一级分类
|
|
category1: '', // 第一行的一级分类
|
|
@@ -403,20 +418,25 @@ const authorizeTypeList = ref<AuthorizetypeLevelVO[]>([]);
|
|
|
|
|
|
|
|
// 授权链路
|
|
// 授权链路
|
|
|
interface AuthChainLevel {
|
|
interface AuthChainLevel {
|
|
|
|
|
+ id: number; // 唯一标识
|
|
|
label: string; // 列标题(0级授权、1级授权...)
|
|
label: string; // 列标题(0级授权、1级授权...)
|
|
|
value: string; // 授权人名称
|
|
value: string; // 授权人名称
|
|
|
editable: boolean; // 是否可编辑
|
|
editable: boolean; // 是否可编辑
|
|
|
placeholder: string; // 输入框提示
|
|
placeholder: string; // 输入框提示
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+let authLevelIdCounter = 0;
|
|
|
|
|
+
|
|
|
const authChainLevels = ref<AuthChainLevel[]>([
|
|
const authChainLevels = ref<AuthChainLevel[]>([
|
|
|
{
|
|
{
|
|
|
|
|
+ id: authLevelIdCounter++,
|
|
|
label: '0级授权',
|
|
label: '0级授权',
|
|
|
value: '',
|
|
value: '',
|
|
|
editable: true,
|
|
editable: true,
|
|
|
placeholder: '请输入授权人'
|
|
placeholder: '请输入授权人'
|
|
|
},
|
|
},
|
|
|
{
|
|
{
|
|
|
|
|
+ id: authLevelIdCounter++,
|
|
|
label: '1级授权',
|
|
label: '1级授权',
|
|
|
value: '优易达(武汉)有限公司',
|
|
value: '优易达(武汉)有限公司',
|
|
|
editable: false,
|
|
editable: false,
|
|
@@ -424,8 +444,12 @@ const authChainLevels = ref<AuthChainLevel[]>([
|
|
|
}
|
|
}
|
|
|
]);
|
|
]);
|
|
|
|
|
|
|
|
-// 表格数据(只有一行,用于显示)
|
|
|
|
|
-const authChainTableData = ref([{}]);
|
|
|
|
|
|
|
+const refreshAuthChainEditable = () => {
|
|
|
|
|
+ if (!authChainLevels.value?.length) return;
|
|
|
|
|
+ authChainLevels.value.forEach((lvl, idx) => (lvl.editable = idx !== authChainLevels.value.length - 1));
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+refreshAuthChainEditable();
|
|
|
|
|
|
|
|
// 第一行的分类列表
|
|
// 第一行的分类列表
|
|
|
const category1List = ref<CategoryVO[]>([]); // 一级分类
|
|
const category1List = ref<CategoryVO[]>([]); // 一级分类
|
|
@@ -488,13 +512,41 @@ const selectedAreaIds = ref<string[]>([]); // 选中的区域ID列表(用于
|
|
|
|
|
|
|
|
const cascaderProps = {
|
|
const cascaderProps = {
|
|
|
multiple: true,
|
|
multiple: true,
|
|
|
- value: 'id', // 使用id而不是areaCode
|
|
|
|
|
- label: 'areaName',
|
|
|
|
|
|
|
+ value: 'value', // 使用 component 自带的 value(即行政区划代码如 110000)
|
|
|
|
|
+ label: 'label',
|
|
|
children: 'children',
|
|
children: 'children',
|
|
|
checkStrictly: false,
|
|
checkStrictly: false,
|
|
|
emitPath: true
|
|
emitPath: true
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+const toProvinceCityOptions = (options: any[]) => {
|
|
|
|
|
+ return (options || []).map((province) => {
|
|
|
|
|
+ const provinceValue6 = String(province.value ?? '');
|
|
|
|
|
+ const provinceValue = provinceValue6.length >= 2 ? provinceValue6.slice(0, 2) : provinceValue6;
|
|
|
|
|
+
|
|
|
|
|
+ const cities = (province.children || []).map((city: any) => {
|
|
|
|
|
+ const cityValue6 = String(city.value ?? '');
|
|
|
|
|
+ const cityValue = cityValue6.length >= 4 ? cityValue6.slice(0, 4) : cityValue6;
|
|
|
|
|
+ const { children, ...rest } = city;
|
|
|
|
|
+ return {
|
|
|
|
|
+ ...rest,
|
|
|
|
|
+ value: cityValue
|
|
|
|
|
+ };
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ return {
|
|
|
|
|
+ ...province,
|
|
|
|
|
+ value: provinceValue,
|
|
|
|
|
+ children: cities
|
|
|
|
|
+ };
|
|
|
|
|
+ });
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const isCityCode = (val: any) => {
|
|
|
|
|
+ const s = String(val ?? '').trim();
|
|
|
|
|
+ return /^\d{4}$/.test(s);
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
/** 返回 */
|
|
/** 返回 */
|
|
|
const goBack = () => {
|
|
const goBack = () => {
|
|
|
router.back();
|
|
router.back();
|
|
@@ -514,6 +566,7 @@ const loadDetailData = async () => {
|
|
|
// 回显基本信息
|
|
// 回显基本信息
|
|
|
formData.value.brandName = data.brandName || '';
|
|
formData.value.brandName = data.brandName || '';
|
|
|
formData.value.brandLogo = data.brandLogo || '';
|
|
formData.value.brandLogo = data.brandLogo || '';
|
|
|
|
|
+ formData.value.brandRegistrant = data.brandRegistrant || (data as any).registrationCertificate || '';
|
|
|
formData.value.authorizeTypeId = Number(data.authorizeType) || '';
|
|
formData.value.authorizeTypeId = Number(data.authorizeType) || '';
|
|
|
formData.value.authorizeLevel = data.authorizeLevel || '';
|
|
formData.value.authorizeLevel = data.authorizeLevel || '';
|
|
|
|
|
|
|
@@ -582,9 +635,10 @@ const loadDetailData = async () => {
|
|
|
|
|
|
|
|
licensors.forEach((licensor, index) => {
|
|
licensors.forEach((licensor, index) => {
|
|
|
authChainLevels.value.push({
|
|
authChainLevels.value.push({
|
|
|
|
|
+ id: authLevelIdCounter++,
|
|
|
label: `${index}级授权`,
|
|
label: `${index}级授权`,
|
|
|
value: licensor.trim(),
|
|
value: licensor.trim(),
|
|
|
- editable: licensor.trim() !== '优易达(武汉)有限公司',
|
|
|
|
|
|
|
+ editable: index !== licensors.length - 1,
|
|
|
placeholder: '请输入授权人'
|
|
placeholder: '请输入授权人'
|
|
|
});
|
|
});
|
|
|
});
|
|
});
|
|
@@ -600,16 +654,11 @@ const loadDetailData = async () => {
|
|
|
// 需要根据区域ID在 areaOptions 中找到对应的省市关系
|
|
// 需要根据区域ID在 areaOptions 中找到对应的省市关系
|
|
|
selectedAreas.value = await buildCascaderValues(areaIds);
|
|
selectedAreas.value = await buildCascaderValues(areaIds);
|
|
|
|
|
|
|
|
- // 显示区域名称
|
|
|
|
|
- areaList.value = [{
|
|
|
|
|
- province: data.province || '',
|
|
|
|
|
- city: data.city || ''
|
|
|
|
|
- }];
|
|
|
|
|
|
|
+ areaList.value = buildAreaRows(selectedAreas.value);
|
|
|
console.log('授权区域回显:', {
|
|
console.log('授权区域回显:', {
|
|
|
areaIds,
|
|
areaIds,
|
|
|
selectedAreas: selectedAreas.value,
|
|
selectedAreas: selectedAreas.value,
|
|
|
- province: data.province,
|
|
|
|
|
- city: data.city
|
|
|
|
|
|
|
+ rows: areaList.value
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -672,6 +721,13 @@ const loadDetailData = async () => {
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+const handleBrandClear = () => {
|
|
|
|
|
+ formData.value.brandId = '';
|
|
|
|
|
+ formData.value.brandName = '';
|
|
|
|
|
+ formData.value.brandLogo = '';
|
|
|
|
|
+ formData.value.brandRegistrant = '';
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
|
|
|
|
|
|
|
|
/** 根据三级分类ID加载分类信息 */
|
|
/** 根据三级分类ID加载分类信息 */
|
|
@@ -724,15 +780,24 @@ const handleAuthorizeTypeChange = (id: string | number) => {
|
|
|
|
|
|
|
|
/** 品牌选择改变 */
|
|
/** 品牌选择改变 */
|
|
|
const handleBrandChange = (brandName: string) => {
|
|
const handleBrandChange = (brandName: string) => {
|
|
|
|
|
+ if (!brandName) {
|
|
|
|
|
+ formData.value.brandId = '';
|
|
|
|
|
+ formData.value.brandName = '';
|
|
|
|
|
+ formData.value.brandLogo = '';
|
|
|
|
|
+ formData.value.brandRegistrant = '';
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
const selectedBrand = brandList.value.find(b => b.brandName === brandName);
|
|
const selectedBrand = brandList.value.find(b => b.brandName === brandName);
|
|
|
if (selectedBrand) {
|
|
if (selectedBrand) {
|
|
|
formData.value.brandId = selectedBrand.id;
|
|
formData.value.brandId = selectedBrand.id;
|
|
|
formData.value.brandName = selectedBrand.brandName;
|
|
formData.value.brandName = selectedBrand.brandName;
|
|
|
formData.value.brandLogo = selectedBrand.brandLogo || ''; // 保存品牌LOGO
|
|
formData.value.brandLogo = selectedBrand.brandLogo || ''; // 保存品牌LOGO
|
|
|
|
|
+ formData.value.brandRegistrant = selectedBrand.registrationCertificate || selectedBrand.brandRegistrant || '';
|
|
|
console.log('选择品牌:', {
|
|
console.log('选择品牌:', {
|
|
|
brandId: formData.value.brandId,
|
|
brandId: formData.value.brandId,
|
|
|
brandName: formData.value.brandName,
|
|
brandName: formData.value.brandName,
|
|
|
- brandLogo: formData.value.brandLogo
|
|
|
|
|
|
|
+ brandLogo: formData.value.brandLogo,
|
|
|
|
|
+ brandRegistrant: formData.value.brandRegistrant
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
@@ -940,10 +1005,15 @@ const handleDeletePerson = () => {
|
|
|
|
|
|
|
|
/** 添加授权级别 */
|
|
/** 添加授权级别 */
|
|
|
const handleAddAuthLevel = () => {
|
|
const handleAddAuthLevel = () => {
|
|
|
|
|
+ if (authChainLevels.value.length >= 5) {
|
|
|
|
|
+ ElMessage.warning('授权链路最多支持5个级别');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
// 在最前面插入新的0级授权
|
|
// 在最前面插入新的0级授权
|
|
|
// 所有现有级别的标签都要+1
|
|
// 所有现有级别的标签都要+1
|
|
|
const newLevels: AuthChainLevel[] = [
|
|
const newLevels: AuthChainLevel[] = [
|
|
|
{
|
|
{
|
|
|
|
|
+ id: authLevelIdCounter++,
|
|
|
label: '0级授权',
|
|
label: '0级授权',
|
|
|
value: '',
|
|
value: '',
|
|
|
editable: true,
|
|
editable: true,
|
|
@@ -954,13 +1024,18 @@ const handleAddAuthLevel = () => {
|
|
|
// 将现有的级别标签都+1
|
|
// 将现有的级别标签都+1
|
|
|
authChainLevels.value.forEach((level, index) => {
|
|
authChainLevels.value.forEach((level, index) => {
|
|
|
newLevels.push({
|
|
newLevels.push({
|
|
|
|
|
+ id: level.id, // 保持唯一身份标识避免页面组件渲染错误
|
|
|
label: `${index + 1}级授权`,
|
|
label: `${index + 1}级授权`,
|
|
|
value: level.value,
|
|
value: level.value,
|
|
|
- editable: level.editable && level.value !== '优易达(武汉)有限公司', // 优易达始终不可编辑
|
|
|
|
|
|
|
+ editable: true,
|
|
|
placeholder: level.placeholder
|
|
placeholder: level.placeholder
|
|
|
});
|
|
});
|
|
|
});
|
|
});
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // 仅最后一级不可编辑
|
|
|
|
|
+ if (newLevels.length) {
|
|
|
|
|
+ newLevels.forEach((lvl, idx) => (lvl.editable = idx !== newLevels.length - 1));
|
|
|
|
|
+ }
|
|
|
authChainLevels.value = newLevels;
|
|
authChainLevels.value = newLevels;
|
|
|
ElMessage.success('添加成功');
|
|
ElMessage.success('添加成功');
|
|
|
};
|
|
};
|
|
@@ -978,8 +1053,14 @@ const handleDeleteAuthLevel = () => {
|
|
|
// 重新调整所有级别的标签
|
|
// 重新调整所有级别的标签
|
|
|
authChainLevels.value = authChainLevels.value.map((level, index) => ({
|
|
authChainLevels.value = authChainLevels.value.map((level, index) => ({
|
|
|
...level,
|
|
...level,
|
|
|
- label: `${index}级授权`
|
|
|
|
|
|
|
+ label: `${index}级授权`,
|
|
|
|
|
+ editable: true
|
|
|
}));
|
|
}));
|
|
|
|
|
+
|
|
|
|
|
+ // 仅最后一级不可编辑
|
|
|
|
|
+ if (authChainLevels.value.length) {
|
|
|
|
|
+ authChainLevels.value.forEach((lvl, idx) => (lvl.editable = idx !== authChainLevels.value.length - 1));
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
ElMessage.success('删除成功');
|
|
ElMessage.success('删除成功');
|
|
|
};
|
|
};
|
|
@@ -1111,30 +1192,35 @@ const handleDeleteFile = (row: any) => {
|
|
|
const buildCascaderValues = async (areaIds: string[]): Promise<any[]> => {
|
|
const buildCascaderValues = async (areaIds: string[]): Promise<any[]> => {
|
|
|
const cascaderValues: any[] = [];
|
|
const cascaderValues: any[] = [];
|
|
|
|
|
|
|
|
- // 遍历所有区域ID,找到它们在区域树中的位置
|
|
|
|
|
- areaIds.forEach(areaId => {
|
|
|
|
|
- const numId = Number(areaId);
|
|
|
|
|
-
|
|
|
|
|
- // 在省级数据中查找
|
|
|
|
|
- for (const province of areaOptions.value) {
|
|
|
|
|
- if (province.id === numId) {
|
|
|
|
|
- // 这是一个省级ID
|
|
|
|
|
- cascaderValues.push([numId]);
|
|
|
|
|
- return;
|
|
|
|
|
|
|
+ // 递归寻找属于叶子节点的路径
|
|
|
|
|
+ const findLeafPath = (options: any[], targetId: string, currentPath: string[]): boolean => {
|
|
|
|
|
+ for (const option of options) {
|
|
|
|
|
+ const path = [...currentPath, option.value];
|
|
|
|
|
+ if (option.value === targetId) {
|
|
|
|
|
+ // 找到了对应的ID,判断是否为叶子节点
|
|
|
|
|
+ // 因为 Cascader 的 checkStrictly: false, 父节点的显式勾选会导致级联其下所有节点
|
|
|
|
|
+ // 只有是叶子节点(即没有 children),我们才作为有效路径提供给 Cascader 回显
|
|
|
|
|
+ if (!option.children || option.children.length === 0) {
|
|
|
|
|
+ cascaderValues.push(path);
|
|
|
|
|
+ }
|
|
|
|
|
+ return true;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- // 在市级数据中查找
|
|
|
|
|
- if (province.children) {
|
|
|
|
|
- for (const city of province.children) {
|
|
|
|
|
- if (city.id === numId) {
|
|
|
|
|
- // 这是一个市级ID,需要包含省级ID
|
|
|
|
|
- cascaderValues.push([province.id, numId]);
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (option.children && option.children.length > 0) {
|
|
|
|
|
+ if (findLeafPath(option.children, targetId, path)) {
|
|
|
|
|
+ return true;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- });
|
|
|
|
|
|
|
+ return false;
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // 遍历所有区域ID,仅当它代表叶子节点时才添加路径去激活回显
|
|
|
|
|
+ areaIds
|
|
|
|
|
+ .map((areaId) => String(areaId).trim())
|
|
|
|
|
+ .filter((strId) => strId && isCityCode(strId))
|
|
|
|
|
+ .forEach((cityId) => {
|
|
|
|
|
+ findLeafPath(areaOptions.value, cityId, []);
|
|
|
|
|
+ });
|
|
|
|
|
|
|
|
console.log('构建级联选择器值:', { areaIds, cascaderValues });
|
|
console.log('构建级联选择器值:', { areaIds, cascaderValues });
|
|
|
return cascaderValues;
|
|
return cascaderValues;
|
|
@@ -1148,9 +1234,8 @@ const handleSelectArea = () => {
|
|
|
/** 初始化授权区域选项数据 */
|
|
/** 初始化授权区域选项数据 */
|
|
|
const initAreaOptions = async () => {
|
|
const initAreaOptions = async () => {
|
|
|
try {
|
|
try {
|
|
|
- const res = await chinaAreaList();
|
|
|
|
|
- areaOptions.value = res.data || [];
|
|
|
|
|
- console.log('授权区域选项数据加载完成:', areaOptions.value.length);
|
|
|
|
|
|
|
+ areaOptions.value = toProvinceCityOptions(regionData as any);
|
|
|
|
|
+ console.log('授权区域选项数据加载完成(使用 element-china-area-data):', areaOptions.value.length);
|
|
|
} catch (e) {
|
|
} catch (e) {
|
|
|
console.error('获取授权区域数据失败:', e);
|
|
console.error('获取授权区域数据失败:', e);
|
|
|
}
|
|
}
|
|
@@ -1164,10 +1249,9 @@ const handleAreaSubmit = async () => {
|
|
|
console.log('=== 授权区域提交 ===');
|
|
console.log('=== 授权区域提交 ===');
|
|
|
console.log('selectedAreas.value:', selectedAreas.value);
|
|
console.log('selectedAreas.value:', selectedAreas.value);
|
|
|
|
|
|
|
|
- // 从选中的路径中提取区域信息(用于显示)
|
|
|
|
|
- const regionData = extractRegionData(selectedAreas.value);
|
|
|
|
|
|
|
+ const areaRows = buildAreaRows(selectedAreas.value);
|
|
|
|
|
|
|
|
- // 提取所有选中的区域ID(包括省和市的ID)
|
|
|
|
|
|
|
+ // 提取所有选中的区域ID(包括省和市的ID),使用后端短编码格式(11、1101)
|
|
|
const areaIds: string[] = [];
|
|
const areaIds: string[] = [];
|
|
|
selectedAreas.value.forEach(path => {
|
|
selectedAreas.value.forEach(path => {
|
|
|
if (Array.isArray(path)) {
|
|
if (Array.isArray(path)) {
|
|
@@ -1175,8 +1259,9 @@ const handleAreaSubmit = async () => {
|
|
|
console.log('处理路径:', path);
|
|
console.log('处理路径:', path);
|
|
|
path.forEach(id => {
|
|
path.forEach(id => {
|
|
|
console.log('提取ID:', id, '类型:', typeof id);
|
|
console.log('提取ID:', id, '类型:', typeof id);
|
|
|
- if (id && !areaIds.includes(String(id))) {
|
|
|
|
|
- areaIds.push(String(id));
|
|
|
|
|
|
|
+ const strId = String(id).trim();
|
|
|
|
|
+ if (strId && !areaIds.includes(strId)) {
|
|
|
|
|
+ areaIds.push(strId);
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
@@ -1185,12 +1270,9 @@ const handleAreaSubmit = async () => {
|
|
|
selectedAreaIds.value = areaIds;
|
|
selectedAreaIds.value = areaIds;
|
|
|
|
|
|
|
|
// 更新授权区域列表显示
|
|
// 更新授权区域列表显示
|
|
|
- areaList.value = [{
|
|
|
|
|
- province: regionData.provinces,
|
|
|
|
|
- city: regionData.cities
|
|
|
|
|
- }];
|
|
|
|
|
|
|
+ areaList.value = areaRows;
|
|
|
|
|
|
|
|
- console.log('选中的授权区域名称:', regionData);
|
|
|
|
|
|
|
+ console.log('选中的授权区域名称:', areaRows);
|
|
|
console.log('选中的区域ID列表(用于提交):', selectedAreaIds.value);
|
|
console.log('选中的区域ID列表(用于提交):', selectedAreaIds.value);
|
|
|
console.log('=== 授权区域提交完成 ===');
|
|
console.log('=== 授权区域提交完成 ===');
|
|
|
ElMessage.success('授权区域设置成功');
|
|
ElMessage.success('授权区域设置成功');
|
|
@@ -1203,6 +1285,45 @@ const handleAreaSubmit = async () => {
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+const buildAreaRows = (selectedPaths: any[]) => {
|
|
|
|
|
+ const provinceMap = new Map<string, Set<string>>();
|
|
|
|
|
+
|
|
|
|
|
+ const normalizeCityDisplayName = (provinceName: string, cityName: string) => {
|
|
|
|
|
+ const p = String(provinceName || '');
|
|
|
|
|
+ const c = String(cityName || '');
|
|
|
|
|
+ if (!c) return '';
|
|
|
|
|
+ if (c === '市辖区') {
|
|
|
|
|
+ return p.endsWith('市') ? p : `${p}市`;
|
|
|
|
|
+ }
|
|
|
|
|
+ return c;
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ selectedPaths.forEach((path) => {
|
|
|
|
|
+ if (Array.isArray(path) && path.length >= 2) {
|
|
|
|
|
+ const [provinceId, cityId] = path;
|
|
|
|
|
+ const provinceName = findRegionNameById(provinceId, areaOptions.value);
|
|
|
|
|
+ const province = areaOptions.value.find((p) => p.value === String(provinceId));
|
|
|
|
|
+ const cityName = province && cityId ? findRegionNameById(cityId, province.children || []) : '';
|
|
|
|
|
+
|
|
|
|
|
+ if (!provinceName) return;
|
|
|
|
|
+ if (!provinceMap.has(provinceName)) {
|
|
|
|
|
+ provinceMap.set(provinceName, new Set());
|
|
|
|
|
+ }
|
|
|
|
|
+ const displayCityName = normalizeCityDisplayName(provinceName, cityName);
|
|
|
|
|
+ if (displayCityName) {
|
|
|
|
|
+ provinceMap.get(provinceName)!.add(displayCityName);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ return Array.from(provinceMap.entries()).map(([province, cities]) => {
|
|
|
|
|
+ return {
|
|
|
|
|
+ province,
|
|
|
|
|
+ city: Array.from(cities).join(',')
|
|
|
|
|
+ };
|
|
|
|
|
+ });
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
/** 从级联选择器的值中提取区域数据 */
|
|
/** 从级联选择器的值中提取区域数据 */
|
|
|
const extractRegionData = (selectedPaths: any[]) => {
|
|
const extractRegionData = (selectedPaths: any[]) => {
|
|
|
// 用于存储省-市的映射关系
|
|
// 用于存储省-市的映射关系
|
|
@@ -1212,9 +1333,9 @@ const extractRegionData = (selectedPaths: any[]) => {
|
|
|
if (Array.isArray(path) && path.length >= 2) {
|
|
if (Array.isArray(path) && path.length >= 2) {
|
|
|
const [provinceId, cityId] = path;
|
|
const [provinceId, cityId] = path;
|
|
|
|
|
|
|
|
- // 查找对应的名称(通过id查找)
|
|
|
|
|
|
|
+ // 查找对应的名称(通过value查找)
|
|
|
const provinceName = findRegionNameById(provinceId, areaOptions.value);
|
|
const provinceName = findRegionNameById(provinceId, areaOptions.value);
|
|
|
- const province = areaOptions.value.find(p => p.id === provinceId);
|
|
|
|
|
|
|
+ const province = areaOptions.value.find(p => p.value === provinceId);
|
|
|
const cityName = province && cityId ? findRegionNameById(cityId, province.children || []) : '';
|
|
const cityName = province && cityId ? findRegionNameById(cityId, province.children || []) : '';
|
|
|
|
|
|
|
|
if (provinceName) {
|
|
if (provinceName) {
|
|
@@ -1222,8 +1343,11 @@ const extractRegionData = (selectedPaths: any[]) => {
|
|
|
provinceMap.set(provinceName, new Set());
|
|
provinceMap.set(provinceName, new Set());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (cityName) {
|
|
|
|
|
|
|
+ // 直辖市的处理(市辖区转为原来的名称)
|
|
|
|
|
+ if (cityName && cityName !== '市辖区') {
|
|
|
provinceMap.get(provinceName)!.add(cityName);
|
|
provinceMap.get(provinceName)!.add(cityName);
|
|
|
|
|
+ } else if (cityName === '市辖区') {
|
|
|
|
|
+ provinceMap.get(provinceName)!.add(provinceName);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -1244,10 +1368,11 @@ const extractRegionData = (selectedPaths: any[]) => {
|
|
|
};
|
|
};
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-/** 根据id查找区域名称 */
|
|
|
|
|
|
|
+/** 根据value查找区域名称 */
|
|
|
const findRegionNameById = (id: string | number, regions: any[]): string => {
|
|
const findRegionNameById = (id: string | number, regions: any[]): string => {
|
|
|
- const region = regions.find(r => r.id === id);
|
|
|
|
|
- return region ? region.areaName : '';
|
|
|
|
|
|
|
+ const targetId = String(id);
|
|
|
|
|
+ const region = regions.find(r => r.value === targetId);
|
|
|
|
|
+ return region ? region.label : '';
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
/** 提交 */
|
|
/** 提交 */
|
|
@@ -1339,6 +1464,7 @@ const handleSubmit = async () => {
|
|
|
brandId: formData.value.brandId,
|
|
brandId: formData.value.brandId,
|
|
|
brandName: formData.value.brandName,
|
|
brandName: formData.value.brandName,
|
|
|
brandLogo: formData.value.brandLogo,
|
|
brandLogo: formData.value.brandLogo,
|
|
|
|
|
+ brandRegistrant: formData.value.brandRegistrant,
|
|
|
authorizeType: formData.value.authorizeTypeId, // 授权类型ID
|
|
authorizeType: formData.value.authorizeTypeId, // 授权类型ID
|
|
|
authorizeLevel: formData.value.authorizeLevel, // 授权等级
|
|
authorizeLevel: formData.value.authorizeLevel, // 授权等级
|
|
|
categoryIds: categoryIds, // 三级分类ID列表
|
|
categoryIds: categoryIds, // 三级分类ID列表
|
|
@@ -1518,30 +1644,82 @@ onMounted(async () => {
|
|
|
gap: 12px;
|
|
gap: 12px;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+.auth-chain-custom-table {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ margin-bottom: 16px;
|
|
|
|
|
+ border: 1px solid #ebeef5;
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+ overflow-x: auto;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.auth-chain-header {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ background-color: #f5f7fa;
|
|
|
|
|
+ border-bottom: 1px solid #ebeef5;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.auth-chain-row {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.auth-chain-cell {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ min-width: 200px;
|
|
|
|
|
+ padding: 12px;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ border-right: 1px solid #ebeef5;
|
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.auth-chain-cell:last-child {
|
|
|
|
|
+ border-right: none;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.header-cell {
|
|
|
|
|
+ font-weight: bold;
|
|
|
|
|
+ color: #909399;
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
/* 只读输入框样式 - 更美观的设计 */
|
|
/* 只读输入框样式 - 更美观的设计 */
|
|
|
.readonly-input :deep(.el-input__wrapper) {
|
|
.readonly-input :deep(.el-input__wrapper) {
|
|
|
- background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%) !important;
|
|
|
|
|
- border: 1px solid #dee2e6 !important;
|
|
|
|
|
- box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1) !important;
|
|
|
|
|
- cursor: not-allowed !important;
|
|
|
|
|
|
|
+ background: var(--el-input-bg-color) !important;
|
|
|
|
|
+ border: 1px solid var(--el-border-color) !important;
|
|
|
|
|
+ box-shadow: none !important;
|
|
|
|
|
+ cursor: default !important;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.readonly-input :deep(.el-input__inner) {
|
|
.readonly-input :deep(.el-input__inner) {
|
|
|
background: transparent !important;
|
|
background: transparent !important;
|
|
|
- color: #495057 !important;
|
|
|
|
|
- font-weight: 500 !important;
|
|
|
|
|
- cursor: not-allowed !important;
|
|
|
|
|
- text-align: center !important;
|
|
|
|
|
|
|
+ color: var(--el-text-color-regular) !important;
|
|
|
|
|
+ font-weight: 400 !important;
|
|
|
|
|
+
|
|
|
|
|
+ /* 文字居中显示 */
|
|
|
|
|
+ text-align: left !important;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.readonly-input :deep(.el-input__wrapper):hover {
|
|
.readonly-input :deep(.el-input__wrapper):hover {
|
|
|
- border-color: #adb5bd !important;
|
|
|
|
|
- box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.15) !important;
|
|
|
|
|
|
|
+ border-color: var(--el-border-color) !important;
|
|
|
|
|
+ box-shadow: none !important;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.readonly-input :deep(.el-input__wrapper):focus-within {
|
|
.readonly-input :deep(.el-input__wrapper):focus-within {
|
|
|
- border-color: #6c757d !important;
|
|
|
|
|
- box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.15), 0 0 0 2px rgba(108, 117, 125, 0.1) !important;
|
|
|
|
|
|
|
+ border-color: var(--el-border-color) !important;
|
|
|
|
|
+ box-shadow: none !important;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.auth-form :deep(.el-input.is-disabled .el-input__wrapper),
|
|
|
|
|
+.auth-form :deep(.el-select .el-input.is-disabled .el-input__wrapper) {
|
|
|
|
|
+ cursor: default;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.readonly-not-allowed :deep(.el-input__wrapper) {
|
|
|
|
|
+ cursor: not-allowed !important;
|
|
|
|
|
+ pointer-events: auto;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.readonly-not-allowed :deep(.el-input__inner) {
|
|
|
|
|
+ cursor: default !important;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* 分类区域样式 */
|
|
/* 分类区域样式 */
|