feat(credit): 添加历史被执行人功能模块

- 创建被执行人历史记录的数据模型和接口定义
- 实现被执行人历史记录的CRUD操作API方法
- 在被执行人页面添加导入历史被执行人的功能按钮
- 开发被执行人历史记录的管理页面和编辑弹窗组件
- 集成被执行人历史记录的搜索、分页、新增、修改、删除功能
- 添加导入历史被执行人数据的功能入口
This commit is contained in:
2026-01-12 09:14:44 +08:00
parent 4d9809197e
commit 7aa74c59a7
6 changed files with 209 additions and 146 deletions

View File

@@ -40,6 +40,9 @@ export interface CreditJudgmentDebtor {
createTime?: string; createTime?: string;
// 修改时间 // 修改时间
updateTime?: string; updateTime?: string;
// 历史ID
historyId?: number;
} }
/** /**

View File

@@ -103,3 +103,30 @@ export async function getCreditJudgmentDebtorHistory(id: number) {
} }
return Promise.reject(new Error(res.data.message)); return Promise.reject(new Error(res.data.message));
} }
/**
* 导入历史被执行人
*/
export async function importCreditJudgmentDebtorHistory(
file: File,
companyId?: number
) {
const formData = new FormData();
formData.append('file', file);
if (companyId != null) {
formData.append('companyId', String(companyId));
}
const res = await request.post<ApiResult<unknown>>(
'/credit/credit-judgment-debtor-history/import',
formData,
{
headers: {
'Content-Type': 'multipart/form-data'
}
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,96 @@
<!-- 历史被执行人导入弹窗 -->
<template>
<ele-modal
:width="520"
:footer="null"
title="历史被执行人批量导入"
:visible="visible"
@update:visible="updateVisible"
>
<a-spin :spinning="loading">
<a-upload-dragger
accept=".xls,.xlsx"
:show-upload-list="false"
:customRequest="doUpload"
style="padding: 24px 0; margin-bottom: 16px"
>
<p class="ant-upload-drag-icon">
<cloud-upload-outlined />
</p>
<p class="ant-upload-hint">将文件拖到此处或点击上传</p>
</a-upload-dragger>
</a-spin>
<div class="ele-text-center">
<span>只能上传xlsxlsx文件</span>
<a :href="templateUrl" download="历史被执行人导入模板.xlsx">
下载导入模板
</a>
</div>
</ele-modal>
</template>
<script lang="ts" setup>
import { computed, ref } from 'vue';
import { message } from 'ant-design-vue/es';
import { CloudUploadOutlined } from '@ant-design/icons-vue';
import { importCreditJudgmentDebtorHistory } from '@/api/credit/creditJudgmentDebtorHistory';
import { API_BASE_URL } from '@/config/setting';
const emit = defineEmits<{
(e: 'done'): void;
(e: 'update:visible', visible: boolean): void;
}>();
defineProps<{
// 是否打开弹窗
visible: boolean;
}>();
// 导入请求状态
const loading = ref(false);
// 模板下载地址,保持与当前接口域名一致
const templateUrl = computed(() => {
const base = (localStorage.getItem('ApiUrl') || API_BASE_URL || '').replace(
/\/$/,
''
);
return `${base}/credit/credit-judgment-debtor-history/import/template`;
});
/* 上传 */
const doUpload = ({ file }) => {
if (
![
'application/vnd.ms-excel',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
].includes(file.type)
) {
message.error('只能选择 excel 文件');
return false;
}
if (file.size / 1024 / 1024 > 10) {
message.error('大小不能超过 10MB');
return false;
}
loading.value = true;
importCreditJudgmentDebtorHistory(file)
.then((msg) => {
loading.value = false;
message.success(msg);
updateVisible(false);
emit('done');
})
.catch((e) => {
loading.value = false;
message.error(e.message);
});
return false;
};
/* 更新 visible */
const updateVisible = (value: boolean) => {
emit('update:visible', value);
};
</script>

View File

@@ -8,13 +8,14 @@
:title="isUpdate ? '编辑被执行人' : '添加被执行人'" :title="isUpdate ? '编辑被执行人' : '添加被执行人'"
:body-style="{ paddingBottom: '28px' }" :body-style="{ paddingBottom: '28px' }"
@update:visible="updateVisible" @update:visible="updateVisible"
:footer="null"
@ok="save" @ok="save"
> >
<a-form <a-form
ref="formRef" ref="formRef"
:model="form" :model="form"
:rules="rules" :rules="rules"
:label-col="styleResponsive ? { md: 4, sm: 5, xs: 24 } : { flex: '90px' }" :label-col="styleResponsive ? { md: 5, sm: 5, xs: 24 } : { flex: '90px' }"
:wrapper-col=" :wrapper-col="
styleResponsive ? { md: 19, sm: 19, xs: 24 } : { flex: '1' } styleResponsive ? { md: 19, sm: 19, xs: 24 } : { flex: '1' }
" "
@@ -68,57 +69,14 @@
v-model:value="form.dataStatus" v-model:value="form.dataStatus"
/> />
</a-form-item> </a-form-item>
<a-form-item label="备注" name="comments"> <!-- <a-form-item label="备注" name="comments">-->
<a-textarea <!-- <a-textarea-->
:rows="4" <!-- :rows="4"-->
:maxlength="200" <!-- :maxlength="200"-->
placeholder="请输入描述" <!-- placeholder="请输入描述"-->
v-model:value="form.comments" <!-- v-model:value="form.comments"-->
/> <!-- />-->
</a-form-item> <!-- </a-form-item>-->
<a-form-item label="是否推荐" name="recommend">
<a-input
allow-clear
placeholder="请输入是否推荐"
v-model:value="form.recommend"
/>
</a-form-item>
<a-form-item label="排序(数字越小越靠前)" name="sortNumber">
<a-input-number
:min="0"
:max="9999"
class="ele-fluid"
placeholder="请输入排序号"
v-model:value="form.sortNumber"
/>
</a-form-item>
<a-form-item label="状态, 0正常, 1冻结" name="status">
<a-radio-group v-model:value="form.status">
<a-radio :value="0">显示</a-radio>
<a-radio :value="1">隐藏</a-radio>
</a-radio-group>
</a-form-item>
<a-form-item label="是否删除, 0否, 1是" name="deleted">
<a-input
allow-clear
placeholder="请输入是否删除, 0否, 1是"
v-model:value="form.deleted"
/>
</a-form-item>
<a-form-item label="用户ID" name="userId">
<a-input
allow-clear
placeholder="请输入用户ID"
v-model:value="form.userId"
/>
</a-form-item>
<a-form-item label="修改时间" name="updateTime">
<a-input
allow-clear
placeholder="请输入修改时间"
v-model:value="form.updateTime"
/>
</a-form-item>
</a-form> </a-form>
</ele-modal> </ele-modal>
</template> </template>
@@ -174,18 +132,14 @@
dataStatus: undefined, dataStatus: undefined,
comments: undefined, comments: undefined,
recommend: undefined, recommend: undefined,
sortNumber: undefined,
status: undefined,
deleted: undefined, deleted: undefined,
userId: undefined, userId: undefined,
tenantId: undefined, tenantId: undefined,
createTime: undefined, createTime: undefined,
updateTime: undefined, updateTime: undefined,
creditJudgmentDebtorId: undefined,
creditJudgmentDebtorName: '',
status: 0, status: 0,
comments: '', sortNumber: 100,
sortNumber: 100 historyId: undefined
}); });
/* 更新visible */ /* 更新visible */

View File

@@ -33,6 +33,14 @@
<template v-if="column.key === 'image'"> <template v-if="column.key === 'image'">
<a-image :src="record.image" :width="50" /> <a-image :src="record.image" :width="50" />
</template> </template>
<template v-if="column.key === 'caseNumber'">
<template v-if="record.historyId">
<span class="text-red-500 font-bold">{{ record.caseNumber }}</span>
</template>
<template v-else>
{{ record.caseNumber }}
</template>
</template>
<template v-if="column.key === 'name'"> <template v-if="column.key === 'name'">
<template v-if="record.url"> <template v-if="record.url">
<a :href="record.url" target="_blank">{{ record.name }}</a> <a :href="record.url" target="_blank">{{ record.name }}</a>
@@ -41,6 +49,9 @@
{{ record.name }} {{ record.name }}
</template> </template>
</template> </template>
<template v-if="column.key === 'dataStatus'">
<div v-if="record.historyId" class="text-red-500 font-bold">有效</div>
</template>
<template v-if="column.key === 'status'"> <template v-if="column.key === 'status'">
<a-tag v-if="record.status === 0" color="green">显示</a-tag> <a-tag v-if="record.status === 0" color="green">显示</a-tag>
<a-tag v-if="record.status === 1" color="red">隐藏</a-tag> <a-tag v-if="record.status === 1" color="red">隐藏</a-tag>
@@ -69,6 +80,17 @@
/> />
<!-- 导入弹窗 --> <!-- 导入弹窗 -->
<CreditJudgmentDebtorImport v-model:visible="showImport" @done="reload" /> <CreditJudgmentDebtorImport v-model:visible="showImport" @done="reload" />
<!-- 历史被执行人导入弹窗 -->
<CreditJudgmentDebtorHistoryImport
v-model:visible="showImport2"
@done="reload"
/>
<!-- 编辑弹窗 -->
<CreditJudgmentDebtorHistoryEdit
v-model:visible="showEdit2"
:data="current"
@done="reload"
/>
</a-page-header> </a-page-header>
</template> </template>
@@ -87,7 +109,9 @@
import { exportCreditData } from '../utils/export'; import { exportCreditData } from '../utils/export';
import { getPageTitle } from '@/utils/common'; import { getPageTitle } from '@/utils/common';
import CreditJudgmentDebtorEdit from './components/creditJudgmentDebtorEdit.vue'; import CreditJudgmentDebtorEdit from './components/creditJudgmentDebtorEdit.vue';
import CreditJudgmentDebtorHistoryEdit from '@/views/credit/creditJudgmentDebtorHistory/components/creditJudgmentDebtorHistoryEdit.vue';
import CreditJudgmentDebtorImport from './components/credit-judgment-debtor-import.vue'; import CreditJudgmentDebtorImport from './components/credit-judgment-debtor-import.vue';
import CreditJudgmentDebtorHistoryImport from './components/credit-judgment-debtor-history-import.vue';
import { import {
pageCreditJudgmentDebtor, pageCreditJudgmentDebtor,
listCreditJudgmentDebtor, listCreditJudgmentDebtor,
@@ -108,8 +132,12 @@
const current = ref<CreditJudgmentDebtor | null>(null); const current = ref<CreditJudgmentDebtor | null>(null);
// 是否显示编辑弹窗 // 是否显示编辑弹窗
const showEdit = ref(false); const showEdit = ref(false);
// 是否显示编辑弹窗2
const showEdit2 = ref(false);
// 是否显示导入弹窗 // 是否显示导入弹窗
const showImport = ref(false); const showImport = ref(false);
// 是否显示历史被执行人导入弹窗
const showImport2 = ref(false);
// 是否显示批量移动弹窗 // 是否显示批量移动弹窗
const showMove = ref(false); const showMove = ref(false);
// 加载状态 // 加载状态
@@ -184,12 +212,14 @@
key: 'courtName', key: 'courtName',
ellipsis: true ellipsis: true
}, },
// { {
// title: '数据状态', title: '状态',
// dataIndex: 'dataStatus', dataIndex: 'dataStatus',
// key: 'dataStatus', key: 'dataStatus',
// ellipsis: true ellipsis: true,
// }, align: 'center',
width: 90
},
{ {
title: '创建时间', title: '创建时间',
dataIndex: 'createTime', dataIndex: 'createTime',
@@ -235,6 +265,17 @@
showImport.value = true; showImport.value = true;
}; };
/* 打开历史被执行人导入弹窗 */
const openImport2 = () => {
showImport2.value = true;
};
/* 打开编辑弹窗 */
const openEdit2 = (row?: CreditJudgmentDebtor) => {
current.value = row ?? null;
showEdit2.value = true;
};
/* 导出 */ /* 导出 */
const exportData = () => { const exportData = () => {
exportCreditData<CreditJudgmentDebtor>({ exportCreditData<CreditJudgmentDebtor>({
@@ -320,7 +361,12 @@
}, },
// 行双击事件 // 行双击事件
onDblclick: () => { onDblclick: () => {
openEdit(record); if(!record.historyId){
openEdit(record);
}else {
openEdit2(record);
}
} }
}; };
}; };

View File

@@ -5,16 +5,17 @@
:visible="visible" :visible="visible"
:maskClosable="false" :maskClosable="false"
:maxable="maxable" :maxable="maxable"
:title="isUpdate ? '编辑被执行人' : '添加被执行人'" :title="isUpdate ? '历史被执行人' : '历史被执行人'"
:body-style="{ paddingBottom: '28px' }" :body-style="{ paddingBottom: '28px' }"
@update:visible="updateVisible" @update:visible="updateVisible"
:footer="null"
@ok="save" @ok="save"
> >
<a-form <a-form
ref="formRef" ref="formRef"
:model="form" :model="form"
:rules="rules" :rules="rules"
:label-col="styleResponsive ? { md: 4, sm: 5, xs: 24 } : { flex: '90px' }" :label-col="styleResponsive ? { md: 5, sm: 5, xs: 24 } : { flex: '90px' }"
:wrapper-col=" :wrapper-col="
styleResponsive ? { md: 19, sm: 19, xs: 24 } : { flex: '1' } styleResponsive ? { md: 19, sm: 19, xs: 24 } : { flex: '1' }
" "
@@ -33,13 +34,13 @@
v-model:value="form.name" v-model:value="form.name"
/> />
</a-form-item> </a-form-item>
<a-form-item label="被执行人" name="name1"> <!-- <a-form-item label="被执行人" name="name1">-->
<a-input <!-- <a-input-->
allow-clear <!-- allow-clear-->
placeholder="请输入被执行人" <!-- placeholder="请输入被执行人"-->
v-model:value="form.name1" <!-- v-model:value="form.name1"-->
/> <!-- />-->
</a-form-item> <!-- </a-form-item>-->
<a-form-item label="证件号/组织机构代码" name="code"> <a-form-item label="证件号/组织机构代码" name="code">
<a-input <a-input
allow-clear allow-clear
@@ -47,20 +48,6 @@
v-model:value="form.code" v-model:value="form.code"
/> />
</a-form-item> </a-form-item>
<a-form-item label="链接" name="url">
<a-input
allow-clear
placeholder="请输入链接"
v-model:value="form.url"
/>
</a-form-item>
<a-form-item label="是否多企业" name="type">
<a-input
allow-clear
placeholder="请输入是否多企业"
v-model:value="form.type"
/>
</a-form-item>
<a-form-item label="立案日期" name="occurrenceTime"> <a-form-item label="立案日期" name="occurrenceTime">
<a-input <a-input
allow-clear allow-clear
@@ -89,64 +76,14 @@
v-model:value="form.dataStatus" v-model:value="form.dataStatus"
/> />
</a-form-item> </a-form-item>
<a-form-item label="企业ID" name="companyId"> <!-- <a-form-item label="备注" name="comments">-->
<a-input <!-- <a-textarea-->
allow-clear <!-- :rows="4"-->
placeholder="请输入企业ID" <!-- :maxlength="200"-->
v-model:value="form.companyId" <!-- placeholder="请输入描述"-->
/> <!-- v-model:value="form.comments"-->
</a-form-item> <!-- />-->
<a-form-item label="备注" name="comments"> <!-- </a-form-item>-->
<a-textarea
:rows="4"
:maxlength="200"
placeholder="请输入描述"
v-model:value="form.comments"
/>
</a-form-item>
<a-form-item label="是否推荐" name="recommend">
<a-input
allow-clear
placeholder="请输入是否推荐"
v-model:value="form.recommend"
/>
</a-form-item>
<a-form-item label="排序(数字越小越靠前)" name="sortNumber">
<a-input-number
:min="0"
:max="9999"
class="ele-fluid"
placeholder="请输入排序号"
v-model:value="form.sortNumber"
/>
</a-form-item>
<a-form-item label="状态, 0正常, 1冻结" name="status">
<a-radio-group v-model:value="form.status">
<a-radio :value="0">显示</a-radio>
<a-radio :value="1">隐藏</a-radio>
</a-radio-group>
</a-form-item>
<a-form-item label="是否删除, 0否, 1是" name="deleted">
<a-input
allow-clear
placeholder="请输入是否删除, 0否, 1是"
v-model:value="form.deleted"
/>
</a-form-item>
<a-form-item label="用户ID" name="userId">
<a-input
allow-clear
placeholder="请输入用户ID"
v-model:value="form.userId"
/>
</a-form-item>
<a-form-item label="修改时间" name="updateTime">
<a-input
allow-clear
placeholder="请输入修改时间"
v-model:value="form.updateTime"
/>
</a-form-item>
</a-form> </a-form>
</ele-modal> </ele-modal>
</template> </template>