完成中介库导入改造

This commit is contained in:
wkc
2026-04-20 15:17:31 +08:00
parent 60a7906eb3
commit 6385778e4c
31 changed files with 1566 additions and 373 deletions

View File

@@ -17,6 +17,44 @@
v-hasPermi="['ccdi:intermediary:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-upload2"
size="mini"
@click="handleOpenPersonImport"
v-hasPermi="['ccdi:intermediary:import']"
>导入中介信息</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-connection"
size="mini"
@click="handleOpenEnterpriseRelationImport"
v-hasPermi="['ccdi:intermediary:import']"
>导入中介实体关联关系</el-button>
</el-col>
<el-col :span="1.5" v-if="personImportTask && personImportTask.failureCount > 0">
<el-button
type="warning"
plain
icon="el-icon-warning"
size="mini"
@click="viewPersonImportFailures"
>查看中介信息导入失败记录</el-button>
</el-col>
<el-col :span="1.5" v-if="enterpriseRelationImportTask && enterpriseRelationImportTask.failureCount > 0">
<el-button
type="warning"
plain
icon="el-icon-warning-outline"
size="mini"
@click="viewEnterpriseRelationImportFailures"
>查看中介实体关联关系导入失败记录</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList" />
</el-row>
@@ -36,6 +74,7 @@
:visible.sync="personDialogVisible"
:title="personDialogTitle"
:form="personForm"
:person-sub-type-options="relationTypeOptions"
:indiv-type-options="indivTypeOptions"
:gender-options="genderOptions"
:cert-type-options="certTypeOptions"
@@ -80,6 +119,87 @@
@edit-enterprise-relation="handleEditEnterpriseRelationFromDetail"
@delete-enterprise-relation="handleDelete"
/>
<import-dialog
:visible.sync="importDialogVisible"
:title="importDialogTitle"
:scene="importScene"
@task-created="handleImportTaskCreated"
@success="handleImportDialogSuccess"
@import-complete="handleImportComplete"
@clear-import-history="handleClearImportHistory"
/>
<el-dialog
title="中介信息导入失败记录"
:visible.sync="personFailureDialogVisible"
width="1200px"
append-to-body
>
<el-alert
v-if="personLastImportInfo"
:title="personLastImportInfo"
type="info"
:closable="false"
style="margin-bottom: 15px"
/>
<el-table :data="personFailureList" v-loading="personFailureLoading">
<el-table-column label="姓名" prop="name" align="center" />
<el-table-column label="人员子类型" prop="personSubType" align="center" />
<el-table-column label="证件号码" prop="personId" align="center" min-width="180" />
<el-table-column label="关联中介本人证件号码" prop="relatedNumId" align="center" min-width="180" />
<el-table-column label="失败原因" prop="errorMessage" align="center" min-width="220" :show-overflow-tooltip="true" />
</el-table>
<pagination
v-show="personFailureTotal > 0"
:total="personFailureTotal"
:page.sync="personFailureQueryParams.pageNum"
:limit.sync="personFailureQueryParams.pageSize"
@pagination="getPersonFailureList"
/>
<div slot="footer" class="dialog-footer">
<el-button @click="personFailureDialogVisible = false">关闭</el-button>
<el-button type="danger" plain @click="clearPersonImportHistory">清除历史记录</el-button>
</div>
</el-dialog>
<el-dialog
title="中介实体关联关系导入失败记录"
:visible.sync="enterpriseRelationFailureDialogVisible"
width="1200px"
append-to-body
>
<el-alert
v-if="enterpriseRelationLastImportInfo"
:title="enterpriseRelationLastImportInfo"
type="info"
:closable="false"
style="margin-bottom: 15px"
/>
<el-table :data="enterpriseRelationFailureList" v-loading="enterpriseRelationFailureLoading">
<el-table-column label="中介本人证件号码" prop="ownerPersonId" align="center" min-width="180" />
<el-table-column label="统一社会信用代码" prop="socialCreditCode" align="center" min-width="180" />
<el-table-column label="关联人职务" prop="relationPersonPost" align="center" />
<el-table-column label="失败原因" prop="errorMessage" align="center" min-width="220" :show-overflow-tooltip="true" />
</el-table>
<pagination
v-show="enterpriseRelationFailureTotal > 0"
:total="enterpriseRelationFailureTotal"
:page.sync="enterpriseRelationFailureQueryParams.pageNum"
:limit.sync="enterpriseRelationFailureQueryParams.pageSize"
@pagination="getEnterpriseRelationFailureList"
/>
<div slot="footer" class="dialog-footer">
<el-button @click="enterpriseRelationFailureDialogVisible = false">关闭</el-button>
<el-button type="danger" plain @click="clearEnterpriseRelationImportHistory">清除历史记录</el-button>
</div>
</el-dialog>
</div>
</template>
@@ -91,8 +211,12 @@ import {
delIntermediary,
delIntermediaryEnterpriseRelation,
delIntermediaryRelative,
getEnterpriseRelationImportFailures,
getEnterpriseRelationImportStatus,
getIntermediaryEnterpriseRelation,
getIntermediaryRelative,
getPersonImportFailures,
getPersonImportStatus,
getPersonIntermediary,
listIntermediary,
listIntermediaryEnterpriseRelations,
@@ -113,6 +237,10 @@ import EditDialog from "./components/EditDialog";
import DetailDialog from "./components/DetailDialog";
import RelativeEditDialog from "./components/RelativeEditDialog";
import EnterpriseRelationEditDialog from "./components/EnterpriseRelationEditDialog";
import ImportDialog from "./components/ImportDialog";
const PERSON_SCENE = "person";
const ENTERPRISE_RELATION_SCENE = "enterpriseRelation";
export default {
name: "Intermediary",
@@ -122,7 +250,8 @@ export default {
EditDialog,
DetailDialog,
RelativeEditDialog,
EnterpriseRelationEditDialog
EnterpriseRelationEditDialog,
ImportDialog
},
data() {
return {
@@ -159,7 +288,32 @@ export default {
relativeList: [],
enterpriseRelationList: [],
currentIntermediaryId: null,
currentOwnerName: ""
currentOwnerName: "",
importDialogVisible: false,
importDialogTitle: "",
importScene: PERSON_SCENE,
personImportTask: null,
enterpriseRelationImportTask: null,
personImportPollingTimer: null,
enterpriseRelationImportPollingTimer: null,
personFailureDialogVisible: false,
personFailureList: [],
personFailureLoading: false,
personFailureTotal: 0,
personFailureQueryParams: {
pageNum: 1,
pageSize: 10
},
personLastImportInfo: "",
enterpriseRelationFailureDialogVisible: false,
enterpriseRelationFailureList: [],
enterpriseRelationFailureLoading: false,
enterpriseRelationFailureTotal: 0,
enterpriseRelationFailureQueryParams: {
pageNum: 1,
pageSize: 10
},
enterpriseRelationLastImportInfo: ""
};
},
created() {
@@ -168,6 +322,11 @@ export default {
this.resetEnterpriseRelationForm();
this.getList();
this.loadEnumOptions();
this.restoreImportTasks();
},
beforeDestroy() {
this.clearImportPolling(PERSON_SCENE);
this.clearImportPolling(ENTERPRISE_RELATION_SCENE);
},
methods: {
loadEnumOptions() {
@@ -252,6 +411,206 @@ export default {
this.personDialogTitle = "新增中介本人";
this.personDialogVisible = true;
},
handleOpenPersonImport() {
this.importScene = PERSON_SCENE;
this.importDialogTitle = "导入中介信息";
this.importDialogVisible = true;
},
handleOpenEnterpriseRelationImport() {
this.importScene = ENTERPRISE_RELATION_SCENE;
this.importDialogTitle = "导入中介实体关联关系";
this.importDialogVisible = true;
},
handleImportDialogSuccess() {
// 导入任务创建后由任务轮询负责状态更新
},
handleImportTaskCreated(payload) {
const task = {
...payload,
failureCount: 0,
successCount: 0,
totalCount: 0,
saveTime: Date.now()
};
this.setImportTask(payload.scene, task);
this.saveImportTaskToStorage(payload.scene, task);
},
handleImportComplete(payload) {
const task = {
...payload,
status: payload.hasFailures ? "PARTIAL_SUCCESS" : "SUCCESS",
saveTime: Date.now()
};
this.setImportTask(payload.scene, task);
this.saveImportTaskToStorage(payload.scene, task);
if (payload.scene === PERSON_SCENE) {
this.personLastImportInfo = this.buildImportSummary(task);
} else {
this.enterpriseRelationLastImportInfo = this.buildImportSummary(task);
}
this.getList();
this.refreshCurrentDetail();
},
handleClearImportHistory(scene) {
this.clearImportTaskFromStorage(scene);
this.setImportTask(scene, null);
if (scene === PERSON_SCENE) {
this.personFailureList = [];
this.personFailureTotal = 0;
this.personLastImportInfo = "";
} else {
this.enterpriseRelationFailureList = [];
this.enterpriseRelationFailureTotal = 0;
this.enterpriseRelationLastImportInfo = "";
}
},
setImportTask(scene, task) {
if (scene === PERSON_SCENE) {
this.personImportTask = task;
return;
}
this.enterpriseRelationImportTask = task;
},
getImportTask(scene) {
return scene === PERSON_SCENE ? this.personImportTask : this.enterpriseRelationImportTask;
},
getImportStorageKey(scene) {
if (scene === PERSON_SCENE) {
return "ccdi_intermediary_person_import_task";
}
return "ccdi_intermediary_enterprise_relation_import_task";
},
saveImportTaskToStorage(scene, task) {
try {
localStorage.setItem(this.getImportStorageKey(scene), JSON.stringify(task));
} catch (error) {
console.error("保存中介导入任务状态失败:", error);
}
},
getImportTaskFromStorage(scene) {
try {
const raw = localStorage.getItem(this.getImportStorageKey(scene));
return raw ? JSON.parse(raw) : null;
} catch (error) {
console.error("读取中介导入任务状态失败:", error);
return null;
}
},
clearImportTaskFromStorage(scene) {
try {
localStorage.removeItem(this.getImportStorageKey(scene));
} catch (error) {
console.error("清除中介导入任务状态失败:", error);
}
this.clearImportPolling(scene);
},
restoreImportTasks() {
[PERSON_SCENE, ENTERPRISE_RELATION_SCENE].forEach((scene) => {
const task = this.getImportTaskFromStorage(scene);
if (!task) {
return;
}
this.setImportTask(scene, task);
if (scene === PERSON_SCENE) {
this.personLastImportInfo = this.buildImportSummary(task);
} else {
this.enterpriseRelationLastImportInfo = this.buildImportSummary(task);
}
if (task.status === "PROCESSING") {
this.resumeImportPolling(scene, task.taskId);
}
});
},
resumeImportPolling(scene, taskId) {
this.clearImportPolling(scene);
const timerKey = scene === PERSON_SCENE ? "personImportPollingTimer" : "enterpriseRelationImportPollingTimer";
const getStatus = scene === PERSON_SCENE ? getPersonImportStatus : getEnterpriseRelationImportStatus;
let pollCount = 0;
this[timerKey] = setInterval(async () => {
pollCount++;
if (pollCount > 150) {
this.clearImportPolling(scene);
return;
}
const response = await getStatus(taskId);
if (response.data && response.data.status !== "PROCESSING") {
this.clearImportPolling(scene);
this.handleImportComplete({
scene,
taskId: response.data.taskId,
hasFailures: response.data.failureCount > 0,
totalCount: response.data.totalCount,
successCount: response.data.successCount,
failureCount: response.data.failureCount
});
}
});
},
clearImportPolling(scene) {
const timerKey = scene === PERSON_SCENE ? "personImportPollingTimer" : "enterpriseRelationImportPollingTimer";
if (this[timerKey]) {
clearInterval(this[timerKey]);
this[timerKey] = null;
}
},
buildImportSummary(task) {
if (!task) {
return "";
}
return `任务ID: ${task.taskId},总数 ${task.totalCount || 0} 条,成功 ${task.successCount || 0} 条,失败 ${task.failureCount || 0}`;
},
viewPersonImportFailures() {
this.personFailureDialogVisible = true;
this.personFailureQueryParams.pageNum = 1;
this.personLastImportInfo = this.buildImportSummary(this.personImportTask);
this.getPersonFailureList();
},
getPersonFailureList() {
if (!this.personImportTask) {
return;
}
this.personFailureLoading = true;
getPersonImportFailures(
this.personImportTask.taskId,
this.personFailureQueryParams.pageNum,
this.personFailureQueryParams.pageSize
).then((response) => {
this.personFailureList = response.rows || [];
this.personFailureTotal = response.total || 0;
}).finally(() => {
this.personFailureLoading = false;
});
},
clearPersonImportHistory() {
this.personFailureDialogVisible = false;
this.handleClearImportHistory(PERSON_SCENE);
},
viewEnterpriseRelationImportFailures() {
this.enterpriseRelationFailureDialogVisible = true;
this.enterpriseRelationFailureQueryParams.pageNum = 1;
this.enterpriseRelationLastImportInfo = this.buildImportSummary(this.enterpriseRelationImportTask);
this.getEnterpriseRelationFailureList();
},
getEnterpriseRelationFailureList() {
if (!this.enterpriseRelationImportTask) {
return;
}
this.enterpriseRelationFailureLoading = true;
getEnterpriseRelationImportFailures(
this.enterpriseRelationImportTask.taskId,
this.enterpriseRelationFailureQueryParams.pageNum,
this.enterpriseRelationFailureQueryParams.pageSize
).then((response) => {
this.enterpriseRelationFailureList = response.rows || [];
this.enterpriseRelationFailureTotal = response.total || 0;
}).finally(() => {
this.enterpriseRelationFailureLoading = false;
});
},
clearEnterpriseRelationImportHistory() {
this.enterpriseRelationFailureDialogVisible = false;
this.handleClearImportHistory(ENTERPRISE_RELATION_SCENE);
},
handleDetail(row) {
if (row.recordType === "INTERMEDIARY") {
this.openIntermediaryDetail(row.recordId);