完成中介库导入改造
This commit is contained in:
@@ -178,14 +178,6 @@ export function importPersonTemplate() {
|
||||
})
|
||||
}
|
||||
|
||||
// 下载机构中介导入模板
|
||||
export function importEntityTemplate() {
|
||||
return request({
|
||||
url: '/ccdi/intermediary/importEntityTemplate',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
// 导入个人中介黑名单
|
||||
export function importPersonData(data, updateSupport) {
|
||||
return request({
|
||||
@@ -195,12 +187,11 @@ export function importPersonData(data, updateSupport) {
|
||||
})
|
||||
}
|
||||
|
||||
// 导入机构中介黑名单
|
||||
export function importEntityData(data, updateSupport) {
|
||||
// 下载中介实体关联关系导入模板
|
||||
export function importEnterpriseRelationTemplate() {
|
||||
return request({
|
||||
url: '/ccdi/intermediary/importEntityData?updateSupport=' + updateSupport,
|
||||
method: 'post',
|
||||
data: data
|
||||
url: '/ccdi/intermediary/importEnterpriseRelationTemplate',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -221,18 +212,27 @@ export function getPersonImportFailures(taskId, pageNum, pageSize) {
|
||||
})
|
||||
}
|
||||
|
||||
// 查询实体中介导入状态
|
||||
export function getEntityImportStatus(taskId) {
|
||||
// 导入中介实体关联关系
|
||||
export function importEnterpriseRelationData(data, updateSupport) {
|
||||
return request({
|
||||
url: `/ccdi/intermediary/importEntityStatus/${taskId}`,
|
||||
url: '/ccdi/intermediary/importEnterpriseRelationData?updateSupport=' + updateSupport,
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 查询中介实体关联关系导入状态
|
||||
export function getEnterpriseRelationImportStatus(taskId) {
|
||||
return request({
|
||||
url: `/ccdi/intermediary/importEnterpriseRelationStatus/${taskId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 查询实体中介导入失败记录
|
||||
export function getEntityImportFailures(taskId, pageNum, pageSize) {
|
||||
// 查询中介实体关联关系导入失败记录
|
||||
export function getEnterpriseRelationImportFailures(taskId, pageNum, pageSize) {
|
||||
return request({
|
||||
url: `/ccdi/intermediary/importEntityFailures/${taskId}`,
|
||||
url: `/ccdi/intermediary/importEnterpriseRelationFailures/${taskId}`,
|
||||
method: 'get',
|
||||
params: { pageNum, pageSize }
|
||||
})
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
<el-descriptions-item label="姓名">{{ detailData.name || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="证件号">{{ detailData.personId || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="人员类型">{{ detailData.personType || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="中介子类型">{{ detailData.personSubType || detailData.relationType || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="性别">{{ formatGender(detailData.gender) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="证件类型">{{ detailData.idType || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="职位">{{ detailData.position || '-' }}</el-descriptions-item>
|
||||
|
||||
@@ -26,6 +26,27 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<!-- v-model="form.personSubType" -->
|
||||
<el-form-item label="中介子类型">
|
||||
<el-select
|
||||
v-model="localForm.personSubType"
|
||||
placeholder="请选择中介子类型"
|
||||
clearable
|
||||
style="width: 100%"
|
||||
@change="handlePersonSubTypeChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in personSubTypeOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="证件类型">
|
||||
<el-select v-model="localForm.idType" placeholder="请选择证件类型" clearable style="width: 100%">
|
||||
@@ -131,6 +152,10 @@ export default {
|
||||
certTypeOptions: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
personSubTypeOptions: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@@ -162,6 +187,12 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handlePersonSubTypeChange(value) {
|
||||
const typeMappings = [
|
||||
{ label: '个人', value: '本人' }
|
||||
];
|
||||
return typeMappings.find(item => item.value === value) || null;
|
||||
},
|
||||
handleSubmit() {
|
||||
this.$refs.formRef.validate(valid => {
|
||||
if (valid) {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 导入对话框 -->
|
||||
<el-dialog
|
||||
:title="title"
|
||||
:visible.sync="visible"
|
||||
@@ -13,22 +12,18 @@
|
||||
:close-on-press-escape="false"
|
||||
custom-class="import-dialog-wrapper"
|
||||
>
|
||||
<!-- 全屏Loading遮罩层 -->
|
||||
<div v-show="isUploading" class="import-loading-overlay">
|
||||
<i class="el-icon-loading"></i>
|
||||
<p>正在导入中,请稍候...</p>
|
||||
</div>
|
||||
|
||||
<el-form :model="formData" label-position="top" size="medium">
|
||||
<!-- 导入类型 -->
|
||||
<el-form-item label="导入类型">
|
||||
<el-radio-group v-model="formData.importType" @change="handleImportTypeChange" style="width: 100%">
|
||||
<el-radio label="person" border>个人中介</el-radio>
|
||||
<el-radio label="entity" border>机构中介</el-radio>
|
||||
</el-radio-group>
|
||||
<el-form label-position="top" size="medium">
|
||||
<el-form-item label="导入说明">
|
||||
<div class="scene-tips">
|
||||
<p v-for="item in sceneTips" :key="item">{{ item }}</p>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 文件上传 -->
|
||||
<el-form-item label="选择文件">
|
||||
<el-upload
|
||||
ref="upload"
|
||||
@@ -53,7 +48,6 @@
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 下载模板 -->
|
||||
<el-form-item>
|
||||
<el-link type="primary" :underline="false" @click="handleDownloadTemplate">
|
||||
<i class="el-icon-download"></i>
|
||||
@@ -62,7 +56,6 @@
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<!-- 底部按钮 -->
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button
|
||||
type="primary"
|
||||
@@ -79,7 +72,6 @@
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 导入结果对话框 -->
|
||||
<import-result-dialog
|
||||
:visible.sync="importResultVisible"
|
||||
:content="importResultContent"
|
||||
@@ -90,10 +82,16 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {getToken} from "@/utils/auth";
|
||||
import {getEntityImportStatus, getPersonImportStatus} from "@/api/ccdiIntermediary";
|
||||
import { getToken } from "@/utils/auth";
|
||||
import {
|
||||
getEnterpriseRelationImportStatus,
|
||||
getPersonImportStatus
|
||||
} from "@/api/ccdiIntermediary";
|
||||
import ImportResultDialog from "@/components/ImportResultDialog.vue";
|
||||
|
||||
const PERSON_SCENE = "person";
|
||||
const ENTERPRISE_RELATION_SCENE = "enterpriseRelation";
|
||||
|
||||
export default {
|
||||
name: "ImportDialog",
|
||||
components: { ImportResultDialog },
|
||||
@@ -105,32 +103,55 @@ export default {
|
||||
title: {
|
||||
type: String,
|
||||
default: "数据导入"
|
||||
},
|
||||
scene: {
|
||||
type: String,
|
||||
default: PERSON_SCENE
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
formData: {
|
||||
importType: "person"
|
||||
},
|
||||
headers: { Authorization: "Bearer " + getToken() },
|
||||
isUploading: false,
|
||||
isFileSelected: false,
|
||||
// 导入结果弹窗
|
||||
importResultVisible: false,
|
||||
importResultContent: "",
|
||||
// 轮询状态
|
||||
pollingTimer: null,
|
||||
currentTaskId: null
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
sceneConfig() {
|
||||
if (this.scene === ENTERPRISE_RELATION_SCENE) {
|
||||
return {
|
||||
uploadPath: "/ccdi/intermediary/importEnterpriseRelationData",
|
||||
templatePath: "ccdi/intermediary/importEnterpriseRelationTemplate",
|
||||
templateName: "中介实体关联关系导入模板",
|
||||
statusApi: getEnterpriseRelationImportStatus,
|
||||
tips: [
|
||||
"只导入中介与机构关系;",
|
||||
"统一社会信用代码必须已存在于系统机构表。"
|
||||
]
|
||||
};
|
||||
}
|
||||
return {
|
||||
uploadPath: "/ccdi/intermediary/importPersonData",
|
||||
templatePath: "ccdi/intermediary/importPersonTemplate",
|
||||
templateName: "中介信息导入模板",
|
||||
statusApi: getPersonImportStatus,
|
||||
tips: [
|
||||
"personSubType 为字典下拉;",
|
||||
"本人行 relatedNumId 为空;",
|
||||
"亲属行 relatedNumId 填关联中介本人证件号码。"
|
||||
]
|
||||
};
|
||||
},
|
||||
uploadUrl() {
|
||||
const baseUrl = process.env.VUE_APP_BASE_API;
|
||||
if (this.formData.importType === 'person') {
|
||||
return `${baseUrl}/ccdi/intermediary/importPersonData`;
|
||||
} else {
|
||||
return `${baseUrl}/ccdi/intermediary/importEntityData`;
|
||||
}
|
||||
return `${baseUrl}${this.sceneConfig.uploadPath}`;
|
||||
},
|
||||
sceneTips() {
|
||||
return this.sceneConfig.tips;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -145,21 +166,14 @@ export default {
|
||||
this.$emit("close");
|
||||
},
|
||||
handleCancel() {
|
||||
// 通过 $emit 通知父组件更新 visible 状态,而不是直接修改 prop
|
||||
this.$emit('update:visible', false);
|
||||
},
|
||||
handleImportTypeChange() {
|
||||
if (this.$refs.upload) {
|
||||
this.$refs.upload.clearFiles();
|
||||
}
|
||||
this.isFileSelected = false;
|
||||
this.$emit("update:visible", false);
|
||||
},
|
||||
handleDownloadTemplate() {
|
||||
if (this.formData.importType === 'person') {
|
||||
this.download('ccdi/intermediary/importPersonTemplate', {}, `个人中介黑名单模板_${new Date().getTime()}.xlsx`);
|
||||
} else {
|
||||
this.download('ccdi/intermediary/importEntityTemplate', {}, `机构中介黑名单模板_${new Date().getTime()}.xlsx`);
|
||||
}
|
||||
this.download(
|
||||
this.sceneConfig.templatePath,
|
||||
{},
|
||||
`${this.sceneConfig.templateName}_${new Date().getTime()}.xlsx`
|
||||
);
|
||||
},
|
||||
handleFileUploadProgress() {
|
||||
this.isUploading = true;
|
||||
@@ -177,28 +191,30 @@ export default {
|
||||
const taskId = response.data.taskId;
|
||||
this.currentTaskId = taskId;
|
||||
|
||||
// 显示通知
|
||||
this.$notify({
|
||||
title: '导入任务已提交',
|
||||
message: '正在后台处理中,处理完成后将通知您',
|
||||
type: 'info',
|
||||
title: "导入任务已提交",
|
||||
message: "正在后台处理中,处理完成后将通知您",
|
||||
type: "info",
|
||||
duration: 3000
|
||||
});
|
||||
|
||||
// 关闭对话框 - 使用$emit更新父组件的visible
|
||||
this.$emit('update:visible', false);
|
||||
this.$refs.upload.clearFiles();
|
||||
this.$emit("task-created", {
|
||||
scene: this.scene,
|
||||
taskId,
|
||||
status: "PROCESSING"
|
||||
});
|
||||
this.$emit("update:visible", false);
|
||||
this.$emit("success", { scene: this.scene, taskId });
|
||||
|
||||
// 通知父组件刷新列表
|
||||
this.$emit("success");
|
||||
if (this.$refs.upload) {
|
||||
this.$refs.upload.clearFiles();
|
||||
}
|
||||
|
||||
// 开始轮询
|
||||
this.startImportStatusPolling(taskId);
|
||||
} else {
|
||||
this.$modal.msgError(response.msg || '导入失败');
|
||||
this.$modal.msgError(response.msg || "导入失败");
|
||||
}
|
||||
},
|
||||
// 导入结果弹窗关闭
|
||||
handleImportResultClose() {
|
||||
this.importResultVisible = false;
|
||||
this.importResultContent = "";
|
||||
@@ -206,77 +222,65 @@ export default {
|
||||
handleFileError() {
|
||||
this.isUploading = false;
|
||||
this.$modal.msgError("导入失败,请检查文件格式是否正确");
|
||||
this.$refs.upload.clearFiles();
|
||||
if (this.$refs.upload) {
|
||||
this.$refs.upload.clearFiles();
|
||||
}
|
||||
},
|
||||
handleSubmit() {
|
||||
// 触发清除历史记录事件
|
||||
this.$emit('clear-import-history', this.formData.importType);
|
||||
|
||||
// 提交文件上传
|
||||
this.$emit("clear-import-history", this.scene);
|
||||
this.$refs.upload.submit();
|
||||
},
|
||||
/** 开始轮询导入状态 */
|
||||
startImportStatusPolling(taskId) {
|
||||
let pollCount = 0;
|
||||
const maxPolls = 150; // 最多5分钟
|
||||
const maxPolls = 150;
|
||||
|
||||
this.pollingTimer = setInterval(async () => {
|
||||
try {
|
||||
pollCount++;
|
||||
|
||||
if (pollCount > maxPolls) {
|
||||
clearInterval(this.pollingTimer);
|
||||
this.$modal.msgWarning('导入任务处理超时,请联系管理员');
|
||||
this.$modal.msgWarning("导入任务处理超时,请联系管理员");
|
||||
return;
|
||||
}
|
||||
|
||||
// 根据导入类型调用不同的API
|
||||
const apiMethod = this.formData.importType === 'person'
|
||||
? getPersonImportStatus
|
||||
: getEntityImportStatus;
|
||||
|
||||
const response = await apiMethod(taskId);
|
||||
|
||||
if (response.data && response.data.status !== 'PROCESSING') {
|
||||
const response = await this.sceneConfig.statusApi(taskId);
|
||||
if (response.data && response.data.status !== "PROCESSING") {
|
||||
clearInterval(this.pollingTimer);
|
||||
this.handleImportComplete(response.data);
|
||||
}
|
||||
} catch (error) {
|
||||
clearInterval(this.pollingTimer);
|
||||
this.$modal.msgError('查询导入状态失败: ' + error.message);
|
||||
this.$modal.msgError("查询导入状态失败: " + error.message);
|
||||
}
|
||||
}, 2000); // 每2秒轮询一次
|
||||
}, 2000);
|
||||
},
|
||||
/** 处理导入完成 */
|
||||
handleImportComplete(statusResult) {
|
||||
if (statusResult.status === 'SUCCESS') {
|
||||
if (statusResult.status === "SUCCESS") {
|
||||
this.$notify({
|
||||
title: '导入完成',
|
||||
title: "导入完成",
|
||||
message: `全部成功!共导入${statusResult.totalCount}条数据`,
|
||||
type: 'success',
|
||||
type: "success",
|
||||
duration: 5000
|
||||
});
|
||||
} else if (statusResult.failureCount > 0) {
|
||||
this.$notify({
|
||||
title: '导入完成',
|
||||
title: "导入完成",
|
||||
message: `成功${statusResult.successCount}条,失败${statusResult.failureCount}条`,
|
||||
type: 'warning',
|
||||
type: "warning",
|
||||
duration: 5000
|
||||
});
|
||||
}
|
||||
|
||||
// 通知父组件更新失败记录状态
|
||||
this.$emit("import-complete", {
|
||||
scene: this.scene,
|
||||
taskId: statusResult.taskId,
|
||||
hasFailures: statusResult.failureCount > 0,
|
||||
importType: this.formData.importType,
|
||||
totalCount: statusResult.totalCount,
|
||||
successCount: statusResult.successCount,
|
||||
failureCount: statusResult.failureCount
|
||||
});
|
||||
}
|
||||
},
|
||||
/** 组件销毁时清除定时器 */
|
||||
beforeDestroy() {
|
||||
if (this.pollingTimer) {
|
||||
clearInterval(this.pollingTimer);
|
||||
@@ -292,35 +296,6 @@ export default {
|
||||
margin-bottom: 22px;
|
||||
}
|
||||
|
||||
.el-radio-group {
|
||||
display: flex;
|
||||
|
||||
.el-radio {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
margin-right: 0;
|
||||
|
||||
&:first-child {
|
||||
.el-radio__label {
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
.el-radio__label {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-bordered {
|
||||
padding: 10px 0;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-upload {
|
||||
width: 100%;
|
||||
|
||||
@@ -355,6 +330,18 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
.scene-tips {
|
||||
padding: 12px 14px;
|
||||
background: #f5f7fa;
|
||||
border-radius: 4px;
|
||||
color: #606266;
|
||||
line-height: 1.7;
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
text-align: center;
|
||||
padding: 5px 0 0;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user