# Design: 同步前端以支持中介黑名单详细字段和类型化模板导入
## 前端架构设计
### 文件结构
```
ruoyi-ui/src/
├── api/
│ └── dpcIntermediary.js (修改 - 添加新接口)
├── views/
│ └── dpcIntermediary/
│ └── index.vue (修改 - 添加详情对话框和表单增强)
```
## API 接口层设计
### 新增接口函数
在 `ruoyi-ui/src/api/dpcIntermediary.js` 中添加:
```javascript
// 下载个人中介导入模板
export function importPersonTemplate() {
return request({
url: '/dpc/intermediary/importPersonTemplate',
method: 'post'
})
}
// 下载机构中介导入模板
export function importEntityTemplate() {
return request({
url: '/dpc/intermediary/importEntityTemplate',
method: 'post'
})
}
// 导入个人中介黑名单
export function importPersonData(data, updateSupport) {
return request({
url: '/dpc/intermediary/importPersonData?updateSupport=' + updateSupport,
method: 'post',
data: data
})
}
// 导入机构中介黑名单
export function importEntityData(data, updateSupport) {
return request({
url: '/dpc/intermediary/importEntityData?updateSupport=' + updateSupport,
method: 'post',
data: data
})
}
```
## 视图层设计
### 列表页面修改
#### 1. 操作列添加"查看详情"按钮
```vue
详情
修改
删除
```
#### 2. 导入对话框改造
支持选择导入类型,并根据类型下载对应模板:
```vue
个人中介
机构中介
将文件拖到此处,或点击上传
是否更新已经存在的数据
下载模板
仅允许导入"xls"或"xlsx"格式文件。
```
### 详情对话框设计
#### 对话框结构
```vue
{{ detailData.intermediaryId }}
{{ detailData.intermediaryTypeName }}
{{ detailData.name }}
{{ detailData.certificateNo }}
正常
停用
{{ detailData.dataSourceName }}
{{ detailData.indivType || '-' }}
{{ detailData.indivSubType || '-' }}
{{ detailData.indivGenderName || '-' }}
{{ detailData.indivCertType || '-' }}
{{ detailData.indivPhone || '-' }}
{{ detailData.indivWechat || '-' }}
{{ detailData.indivAddress || '-' }}
{{ detailData.indivCompany || '-' }}
{{ detailData.indivPosition || '-' }}
{{ detailData.indivRelatedId || '-' }}
{{ detailData.indivRelation || '-' }}
{{ detailData.corpCreditCode || '-' }}
{{ detailData.corpType || '-' }}
{{ detailData.corpNature || '-' }}
{{ detailData.corpIndustryCategory || '-' }}
{{ detailData.corpIndustry || '-' }}
{{ detailData.corpEstablishDate || '-' }}
{{ detailData.corpAddress || '-' }}
{{ detailData.corpLegalRep || '-' }}
{{ detailData.corpLegalCertType || '-' }}
{{ detailData.corpLegalCertNo || '-' }}
{{ detailData.corpShareholder1 || '-' }}
{{ detailData.corpShareholder2 || '-' }}
{{ detailData.corpShareholder3 || '-' }}
{{ detailData.corpShareholder4 || '-' }}
{{ detailData.corpShareholder5 || '-' }}
{{ detailData.remark || '-' }}
{{ detailData.createTime }}
{{ detailData.createBy }}
```
#### 数据属性
```javascript
data() {
return {
// ... 现有数据 ...
// 详情对话框
detailOpen: false,
detailData: {},
// 导入参数
upload: {
open: false,
title: "",
isUploading: false,
updateSupport: 0,
importType: "person", // person 或 entity
headers: { Authorization: "Bearer " + getToken() },
url: "" // 动态设置
}
}
}
```
#### 方法实现
```javascript
methods: {
/** 查看详情操作 */
handleDetail(row) {
const intermediaryId = row.intermediaryId;
getIntermediary(intermediaryId).then(response => {
this.detailData = response.data;
this.detailOpen = true;
});
},
/** 导入按钮操作 */
handleImport() {
this.upload.title = "中介黑名单数据导入";
this.upload.importType = "person"; // 默认个人
this.upload.updateSupport = 0;
this.upload.open = true;
},
/** 下载导入模板 */
downloadImportTemplate() {
if (this.upload.importType === 'person') {
this.download('dpc/intermediary/importPersonTemplate', {}, `个人中介黑名单模板_${new Date().getTime()}.xlsx`);
} else {
this.download('dpc/intermediary/importEntityTemplate', {}, `机构中介黑名单模板_${new Date().getTime()}.xlsx`);
}
},
// 文件上传中处理
handleFileUploadProgress(event, file, fileList) {
this.upload.isUploading = true;
},
// 文件上传成功处理
handleFileSuccess(response, file, fileList) {
this.upload.isUploading = false;
this.upload.open = false;
this.getList();
this.$alert("
" + response.msg + "
", "导入结果");
},
// 提交上传文件
submitFileForm() {
// 根据导入类型设置上传地址
if (this.upload.importType === 'person') {
this.upload.url = process.env.VUE_APP_BASE_API + "/dpc/intermediary/importPersonData?updateSupport=" + this.upload.updateSupport;
} else {
this.upload.url = process.env.VUE_APP_BASE_API + "/dpc/intermediary/importEntityData?updateSupport=" + this.upload.updateSupport;
}
this.$refs.upload.submit();
}
}
```
### 新增/编辑对话框增强
#### 使用 Tabs 分组展示字段
```vue
个人
机构
正常
停用
股东信息
```
#### 数据属性和方法
```javascript
data() {
return {
// ... 现有数据 ...
activeTab: 'basic'
}
},
methods: {
// 表单重置
reset() {
this.form = {
intermediaryId: null,
name: null,
certificateNo: null,
intermediaryType: "1",
status: "0",
remark: null,
// 个人字段
indivType: null,
indivSubType: null,
indivGender: null,
indivCertType: null,
indivPhone: null,
indivWechat: null,
indivAddress: null,
indivCompany: null,
indivPosition: null,
indivRelatedId: null,
indivRelation: null,
// 机构字段
corpCreditCode: null,
corpType: null,
corpNature: null,
corpIndustryCategory: null,
corpIndustry: null,
corpEstablishDate: null,
corpAddress: null,
corpLegalRep: null,
corpLegalCertType: null,
corpLegalCertNo: null,
corpShareholder1: null,
corpShareholder2: null,
corpShareholder3: null,
corpShareholder4: null,
corpShareholder5: null
};
this.activeTab = 'basic';
this.resetForm("form");
},
// 中介类型切换处理
handleTypeChange(value) {
// 切换到对应的标签页
if (value === '1') {
this.activeTab = 'person';
} else if (value === '2') {
this.activeTab = 'entity';
}
}
}
```
## 数据流设计
### 详情数据流
```
用户点击"详情"按钮
↓
调用 getIntermediary(id)
↓
后端根据 intermediaryType 返回不同的 VO
↓
前端接收响应并存储到 detailData
↓
详情对话框根据 detailData.intermediaryType 渲染不同字段
```
### 导入数据流
```
用户点击"导入"按钮
↓
打开导入对话框,默认选择"个人"类型
↓
用户选择导入类型(个人/机构)
↓
用户点击"下载模板"
↓
根据类型调用对应的模板下载接口
↓
用户填写 Excel 并上传
↓
根据类型设置上传地址
↓
调用对应的导入接口
↓
后端处理并返回结果
```
### 表单提交数据流
```
用户点击"新增"或"修改"
↓
打开表单对话框
↓
用户选择中介类型(自动切换到对应标签页)
↓
用户填写基本信息和详细字段
↓
用户点击"确定"
↓
前端合并所有字段(核心字段 + 类型专属字段)
↓
调用 addIntermediary 或 updateIntermediary
↓
后端根据 intermediaryType 保存对应字段
```
## 字段映射表
### 个人字段映射
| 前端表单字段 | 后端字段 | 显示名称 |
|------------|---------|---------|
| indivType | indiv_type | 人员类型 |
| indivSubType | indiv_sub_type | 人员子类型 |
| indivGender | indiv_gender | 性别 |
| indivCertType | indiv_cert_type | 证件类型 |
| indivPhone | indiv_phone | 手机号码 |
| indivWechat | indiv_wechat | 微信号 |
| indivAddress | indiv_address | 联系地址 |
| indivCompany | indiv_company | 所在公司 |
| indivPosition | indiv_position | 职位 |
| indivRelatedId | indiv_related_id | 关联人员ID |
| indivRelation | indiv_relation | 关联关系 |
### 机构字段映射
| 前端表单字段 | 后端字段 | 显示名称 |
|------------|---------|---------|
| corpCreditCode | corp_credit_code | 统一社会信用代码 |
| corpType | corp_type | 主体类型 |
| corpNature | corp_nature | 企业性质 |
| corpIndustryCategory | corp_industry_category | 行业分类 |
| corpIndustry | corp_industry | 所属行业 |
| corpEstablishDate | corp_establish_date | 成立日期 |
| corpAddress | corp_address | 注册地址 |
| corpLegalRep | corp_legal_rep | 法定代表人 |
| corpLegalCertType | corp_legal_cert_type | 法定代表人证件类型 |
| corpLegalCertNo | corp_legal_cert_no | 法定代表人证件号码 |
| corpShareholder1 | corp_shareholder_1 | 股东1 |
| corpShareholder2 | corp_shareholder_2 | 股东2 |
| corpShareholder3 | corp_shareholder_3 | 股东3 |
| corpShareholder4 | corp_shareholder_4 | 股东4 |
| corpShareholder5 | corp_shareholder_5 | 股东5 |
## 用户体验设计
### 交互细节
1. **类型切换自动跳转**
- 用户选择"个人"类型,自动跳转到"个人信息"标签页
- 用户选择"机构"类型,自动跳转到"机构信息"标签页
2. **导入类型提示**
- 导入对话框顶部显示当前选择的导入类型
- 下载模板链接根据类型变化
3. **详情字段空值处理**
- 字段值为空时显示 "-"
- 避免显示空白或 undefined
4. **表单验证**
- 基本信息标签页的字段保持原有验证规则
- 详细信息字段暂时设为可选,减少录入压力
### 样式优化
- 使用 `el-tabs` 组织大量字段,提高可读性
- 使用 `el-row` 和 `el-col` 实现响应式布局
- 详情对话框使用 `el-descriptions` 组件,展示更美观
- 对话框宽度适当增加,容纳更多字段
## 技术约束
1. **前端框架**:Vue 2.6.12
2. **UI 组件库**:Element UI 2.15.14
3. **HTTP 客户端**:Axios 0.28.1
4. **向后兼容**:保持现有功能不变,只做增强
## 测试要点
### 功能测试
- [ ] 详情对话框正确显示个人类型字段
- [ ] 详情对话框正确显示机构类型字段
- [ ] 新增/编辑对话框正确切换标签页
- [ ] 个人中介模板下载正常
- [ ] 机构中介模板下载正常
- [ ] 个人中介数据导入正常
- [ ] 机构中介数据导入正常
### 兼容性测试
- [ ] 旧数据详情显示正常(字段为空时显示"-")
- [ ] 现有列表查询功能正常
- [ ] 现有新增/编辑功能正常
- [ ] 现有删除功能正常
- [ ] 现有导出功能正常