217 lines
6.7 KiB
Markdown
217 lines
6.7 KiB
Markdown
|
|
# 身份证图片数据流验证
|
|||
|
|
|
|||
|
|
## 数据流概述
|
|||
|
|
身份证前后面的照片地址从前端表单 → 后端API → 数据库 `id_card` 字段,使用英文逗号分隔多个URL。
|
|||
|
|
|
|||
|
|
## 前端实现 ✅
|
|||
|
|
|
|||
|
|
### 1. 表单数据结构
|
|||
|
|
```javascript
|
|||
|
|
const ruleForm = reactive({
|
|||
|
|
username: '', // 司机姓名
|
|||
|
|
mobile: '', // 司机手机号
|
|||
|
|
status: '', // 账号状态
|
|||
|
|
carNumber: '', // 车牌号
|
|||
|
|
driverImg: [], // 驾驶证
|
|||
|
|
licenseImg: [], // 行驶证
|
|||
|
|
codeImg: [], // 牧运通备案码
|
|||
|
|
carImg: [], // 车头&车身照片
|
|||
|
|
idCardImg: [], // 身份证前后面 ✅
|
|||
|
|
remark: '', // 备注
|
|||
|
|
});
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 图片上传处理
|
|||
|
|
```javascript
|
|||
|
|
// 身份证图片上传成功处理
|
|||
|
|
const handleAvatarSuccess = (res, file, fileList, type) => {
|
|||
|
|
if (ruleForm.hasOwnProperty(type)) {
|
|||
|
|
// 解析图片URL并添加到对应数组
|
|||
|
|
ruleForm[type].push({ url: imageUrl });
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 数据提交处理
|
|||
|
|
```javascript
|
|||
|
|
// 保存时处理身份证图片
|
|||
|
|
params.idCard = ruleForm.idCardImg.length > 0
|
|||
|
|
? ruleForm.idCardImg.map((item) => item.url).join(',')
|
|||
|
|
: '';
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**示例数据**:
|
|||
|
|
```javascript
|
|||
|
|
// 前端发送的数据
|
|||
|
|
{
|
|||
|
|
username: '张三',
|
|||
|
|
mobile: '13800138000',
|
|||
|
|
carNumber: '京A12345',
|
|||
|
|
idCard: 'https://example.com/id_front.jpg,https://example.com/id_back.jpg'
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 后端实现 ✅
|
|||
|
|
|
|||
|
|
### 1. Controller 层
|
|||
|
|
```java
|
|||
|
|
@PostMapping("/addDriver")
|
|||
|
|
public AjaxResult addDriver(@RequestBody Map<String, Object> params) {
|
|||
|
|
String idCard = (String) params.get("idCard"); // ✅ 获取身份证参数
|
|||
|
|
|
|||
|
|
// 调用 Mapper 插入数据
|
|||
|
|
int driverResult = memberDriverMapper.insertDriver(
|
|||
|
|
memberId, username, carNumber, driverLicense,
|
|||
|
|
drivingLicense, carImg, recordCode, idCard, remark // ✅ 传递 idCard
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. Mapper 层
|
|||
|
|
```java
|
|||
|
|
@Insert("INSERT INTO member_driver (member_id, username, car_number, " +
|
|||
|
|
"driver_license, driving_license, car_img, record_code, id_card, remark, create_time) " +
|
|||
|
|
"VALUES (#{memberId}, #{username}, #{carNumber}, #{driverLicense}, #{drivingLicense}, " +
|
|||
|
|
"#{carImg}, #{recordCode}, #{idCard}, #{remark}, NOW())")
|
|||
|
|
int insertDriver(..., @Param("idCard") String idCard, ...); // ✅ 包含 idCard 参数
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 数据库存储 ✅
|
|||
|
|
|
|||
|
|
### 表结构
|
|||
|
|
```sql
|
|||
|
|
CREATE TABLE member_driver (
|
|||
|
|
id INT PRIMARY KEY AUTO_INCREMENT,
|
|||
|
|
member_id INT,
|
|||
|
|
username VARCHAR(100),
|
|||
|
|
car_number VARCHAR(20),
|
|||
|
|
driver_license TEXT,
|
|||
|
|
driving_license TEXT,
|
|||
|
|
car_img TEXT,
|
|||
|
|
record_code TEXT,
|
|||
|
|
id_card TEXT COMMENT '身份证前后面照片地址(多个URL用逗号分隔)', -- ✅ 新增字段
|
|||
|
|
remark TEXT,
|
|||
|
|
create_time DATETIME
|
|||
|
|
);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 存储示例
|
|||
|
|
```sql
|
|||
|
|
INSERT INTO member_driver (member_id, username, car_number, id_card, create_time)
|
|||
|
|
VALUES (1, '张三', '京A12345', 'https://example.com/id_front.jpg,https://example.com/id_back.jpg', NOW());
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 数据读取和显示 ✅
|
|||
|
|
|
|||
|
|
### 1. 后端查询
|
|||
|
|
```java
|
|||
|
|
@Select("SELECT md.id, md.member_id, md.username, md.car_number, " +
|
|||
|
|
"md.driving_license, md.driver_license, md.record_code, " +
|
|||
|
|
"md.car_img, md.id_card, md.remark, md.create_time, m.mobile " + // ✅ 包含 id_card
|
|||
|
|
"FROM member_driver md " +
|
|||
|
|
"LEFT JOIN member m ON md.member_id = m.id " +
|
|||
|
|
"WHERE md.id = #{driverId}")
|
|||
|
|
Map<String, Object> selectDriverById(@Param("driverId") Integer driverId);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 前端数据加载
|
|||
|
|
```javascript
|
|||
|
|
// 编辑时加载数据
|
|||
|
|
ruleForm.idCardImg = row.id_card
|
|||
|
|
? getImageList(row.id_card).map((item) => {
|
|||
|
|
return { url: item };
|
|||
|
|
})
|
|||
|
|
: [];
|
|||
|
|
|
|||
|
|
// 处理逗号分隔的图片URL
|
|||
|
|
const getImageList = (imageUrl) => {
|
|||
|
|
if (!imageUrl || imageUrl.trim() === '') {
|
|||
|
|
return [];
|
|||
|
|
}
|
|||
|
|
return imageUrl.split(',').map(url => url.trim()).filter(url => url !== '');
|
|||
|
|
};
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 详情页面显示
|
|||
|
|
```vue
|
|||
|
|
<el-col :span="12" style="display: flex">
|
|||
|
|
<div><span class="label">身份证前后面:</span></div>
|
|||
|
|
<template v-if="data.info.id_card">
|
|||
|
|
<el-image
|
|||
|
|
v-for="(item, index) in getImageList(data.info.id_card)"
|
|||
|
|
:key="index"
|
|||
|
|
:src="item"
|
|||
|
|
style="width: 80px; height: 80px; margin-right: 10px"
|
|||
|
|
fit="cover"
|
|||
|
|
:preview-src-list="getImageList(data.info.id_card)"
|
|||
|
|
preview-teleported
|
|||
|
|
>
|
|||
|
|
<template #error>
|
|||
|
|
<div style="width: 50px; height: 50px; display: flex; justify-content: center" class="image-slot">
|
|||
|
|
<el-icon :size="20"><Picture /></el-icon>
|
|||
|
|
</div>
|
|||
|
|
</template>
|
|||
|
|
</el-image>
|
|||
|
|
</template>
|
|||
|
|
<span v-else style="color: #999">暂无图片</span>
|
|||
|
|
</el-col>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 完整数据流示例
|
|||
|
|
|
|||
|
|
### 1. 新增司机流程
|
|||
|
|
```
|
|||
|
|
用户上传身份证照片
|
|||
|
|
→ 前端: ruleForm.idCardImg = [{url: 'url1'}, {url: 'url2'}]
|
|||
|
|
→ 前端: params.idCard = 'url1,url2'
|
|||
|
|
→ 后端: String idCard = params.get("idCard")
|
|||
|
|
→ 数据库: INSERT INTO member_driver (..., id_card, ...) VALUES (..., 'url1,url2', ...)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 编辑司机流程
|
|||
|
|
```
|
|||
|
|
用户点击编辑
|
|||
|
|
→ 后端: SELECT ..., id_card FROM member_driver WHERE id = ?
|
|||
|
|
→ 前端: row.id_card = 'url1,url2'
|
|||
|
|
→ 前端: ruleForm.idCardImg = [{url: 'url1'}, {url: 'url2'}]
|
|||
|
|
→ 用户修改后保存
|
|||
|
|
→ 前端: params.idCard = 'url1,url3' (修改后的URL)
|
|||
|
|
→ 后端: UPDATE member_driver SET id_card = 'url1,url3' WHERE id = ?
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 详情查看流程
|
|||
|
|
```
|
|||
|
|
用户点击详情
|
|||
|
|
→ 后端: SELECT ..., id_card FROM member_driver WHERE id = ?
|
|||
|
|
→ 前端: data.info.id_card = 'url1,url2'
|
|||
|
|
→ 前端: getImageList('url1,url2') = ['url1', 'url2']
|
|||
|
|
→ 页面: 显示两张身份证图片
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 验证要点
|
|||
|
|
|
|||
|
|
1. ✅ **字段存在**: `id_card` 字段已添加到 `member_driver` 表
|
|||
|
|
2. ✅ **数据格式**: 使用英文逗号分隔多个URL
|
|||
|
|
3. ✅ **前端处理**: 正确解析和显示逗号分隔的URL
|
|||
|
|
4. ✅ **后端处理**: 正确接收和存储 `idCard` 参数
|
|||
|
|
5. ✅ **数据库存储**: 正确存储到 `id_card` 字段
|
|||
|
|
6. ✅ **数据读取**: 正确从数据库读取并返回给前端
|
|||
|
|
|
|||
|
|
## 测试建议
|
|||
|
|
|
|||
|
|
1. **新增测试**: 上传身份证前后照片,检查数据库 `id_card` 字段
|
|||
|
|
2. **编辑测试**: 修改身份证照片,检查更新是否成功
|
|||
|
|
3. **详情测试**: 查看详情页面是否正确显示身份证图片
|
|||
|
|
4. **数据验证**: 确认URL格式正确,逗号分隔正常
|
|||
|
|
|
|||
|
|
## 总结
|
|||
|
|
|
|||
|
|
✅ **身份证前后照片地址已正确实现存储到 `id_card` 字段**
|
|||
|
|
✅ **使用英文逗号分隔多个URL地址**
|
|||
|
|
✅ **前端新增和编辑功能完整**
|
|||
|
|
✅ **后端API正确处理数据**
|
|||
|
|
✅ **数据库字段和查询已更新**
|
|||
|
|
✅ **详情页面正确显示身份证图片**
|
|||
|
|
|
|||
|
|
整个数据流已经完整实现,身份证前后面的照片地址会正确存储到数据库的 `id_card` 字段中,并用英文逗号分隔。
|