实现身份证文件自动解析与拉取提交流程

This commit is contained in:
wkc
2026-03-11 17:58:39 +08:00
parent efebd4f76c
commit bd09d483e0

View File

@@ -225,12 +225,18 @@
:auto-upload="false"
:limit="1"
:file-list="idCardFileList"
accept=".xls,.xlsx"
:on-change="handleIdCardFileChange"
:on-remove="handleIdCardFileRemove"
>
<el-button size="small" type="primary">选择文件</el-button>
<div slot="tip" class="el-upload__tip">
支持 .xls.xlsx 文件
</div>
</el-upload>
<div v-if="parsingIdCardFile" class="parse-tip">
正在解析身份证文件...
</div>
</el-form-item>
<el-form-item label="时间跨度">
<el-date-picker
@@ -246,7 +252,11 @@
</el-form>
<span slot="footer">
<el-button @click="pullBankInfoDialogVisible = false">取消</el-button>
<el-button type="primary" :loading="pullBankInfoLoading">
<el-button
type="primary"
:loading="pullBankInfoLoading"
@click="handleConfirmPullBankInfo"
>
确认拉取
</el-button>
</span>
@@ -758,6 +768,123 @@ export default {
this.parsingIdCardFile = false;
this.pullBankInfoLoading = false;
},
parseIdCardText(text) {
return Array.from(
new Set(
(text || "")
.split(/[\n,]+/)
.map((item) => item.trim())
.filter(Boolean)
)
);
},
mergeIdCards(currentText, parsedIdCards) {
const merged = [
...this.parseIdCardText(currentText),
...((parsedIdCards || [])
.map((item) => String(item || "").trim())
.filter(Boolean)),
];
return Array.from(new Set(merged)).join(", ");
},
async handleIdCardFileChange(file, fileList) {
const latestFile = (fileList || []).slice(-1);
const currentFile = latestFile[0] || file;
const fileName = (currentFile && currentFile.name) || "";
const isExcel = /\.(xls|xlsx)$/i.test(fileName);
if (!isExcel) {
this.idCardFileList = [];
this.$message.error("仅支持上传 .xls 或 .xlsx 文件");
return;
}
if (!currentFile || !currentFile.raw) {
this.idCardFileList = [];
this.$message.error("未获取到有效文件");
return;
}
this.idCardFileList = latestFile;
this.parsingIdCardFile = true;
try {
const res = await parseIdCardFile(currentFile.raw);
const parsedIdCards =
(res && res.data && Array.isArray(res.data.idCards) && res.data.idCards) ||
[];
this.pullBankInfoForm.idCardText = this.mergeIdCards(
this.pullBankInfoForm.idCardText,
parsedIdCards
);
this.$message.success(
`身份证文件解析成功,共 ${parsedIdCards.length} 条有效身份证`
);
} catch (error) {
this.idCardFileList = [];
this.$message.error(
"身份证文件解析失败:" +
((error && error.message) || "未知错误")
);
} finally {
this.parsingIdCardFile = false;
}
},
handleIdCardFileRemove() {
this.idCardFileList = [];
this.parsingIdCardFile = false;
},
buildFinalIdCardList() {
return this.parseIdCardText(this.pullBankInfoForm.idCardText);
},
async handleConfirmPullBankInfo() {
const idCards = this.buildFinalIdCardList();
const [startDate, endDate] = this.pullBankInfoForm.dateRange || [];
if (idCards.length === 0) {
this.$message.warning("请至少输入一个身份证号");
return;
}
if (!startDate || !endDate) {
this.$message.warning("请选择完整的时间跨度");
return;
}
this.pullBankInfoLoading = true;
try {
const payload = {
projectId: this.projectId,
idCards,
startDate,
endDate,
};
const res = await pullBankInfo(payload);
this.pullBankInfoDialogVisible = false;
this.resetPullBankInfoForm();
this.$message.success((res && res.msg) || "拉取任务已提交");
await Promise.all([this.loadStatistics(), this.loadFileList()]);
const hasPollingRecords =
this.statistics.uploading > 0 ||
this.statistics.parsing > 0 ||
this.fileUploadList.some((item) =>
["uploading", "parsing"].includes(item.fileStatus)
);
if (hasPollingRecords) {
this.startPolling();
}
} catch (error) {
this.pullBankInfoLoading = false;
this.$message.error(
"拉取本行信息失败:" + ((error && error.message) || "未知错误")
);
}
},
/** 拉取本行信息 */
handleFetchBankInfo() {
this.resetPullBankInfoForm();
@@ -1412,6 +1539,12 @@ export default {
}
}
.parse-tip {
margin-top: 8px;
font-size: 12px;
color: #909399;
}
// 响应式
@media (max-width: 1200px) {
.upload-section .upload-cards {