feat(credit): 添加客户管理模块

- 新增客户数据模型定义
- 实现客户分页查询、列表查询、新增、修改、删除等API接口
- 创建客户管理页面,包含表格展示、编辑弹窗、搜索功能
- 添加客户编辑表单,支持客户信息的录入与修改
- 实现客户数据的状态管理与操作功能
- 优化开庭公告等模块的字段命名与代码结构
- 统一导入导出功能组件的使用方式
- 修复被告/被上诉人字段绑定错误的问题
This commit is contained in:
2025-12-21 21:22:11 +08:00
parent f87103119a
commit ebdc9b5933
37 changed files with 2691 additions and 858 deletions

View File

@@ -0,0 +1,105 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CreditCustomer, CreditCustomerParam } from './model';
/**
* 分页查询客户
*/
export async function pageCreditCustomer(params: CreditCustomerParam) {
const res = await request.get<ApiResult<PageResult<CreditCustomer>>>(
'/credit/credit-customer/page',
{
params
}
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 查询客户列表
*/
export async function listCreditCustomer(params?: CreditCustomerParam) {
const res = await request.get<ApiResult<CreditCustomer[]>>(
'/credit/credit-customer',
{
params
}
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 添加客户
*/
export async function addCreditCustomer(data: CreditCustomer) {
const res = await request.post<ApiResult<unknown>>(
'/credit/credit-customer',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 修改客户
*/
export async function updateCreditCustomer(data: CreditCustomer) {
const res = await request.put<ApiResult<unknown>>(
'/credit/credit-customer',
data
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 删除客户
*/
export async function removeCreditCustomer(id?: number) {
const res = await request.delete<ApiResult<unknown>>(
'/credit/credit-customer/' + id
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 批量删除客户
*/
export async function removeBatchCreditCustomer(data: (number | undefined)[]) {
const res = await request.delete<ApiResult<unknown>>(
'/credit/credit-customer/batch',
{
data
}
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 根据id查询客户
*/
export async function getCreditCustomer(id: number) {
const res = await request.get<ApiResult<CreditCustomer>>(
'/credit/credit-customer/' + id
);
if (res.data.code === 0 && res.data.data) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}

View File

@@ -0,0 +1,45 @@
import type { PageParam } from '@/api';
/**
* 客户
*/
export interface CreditCustomer {
// ID
id?: number;
// 客户
name?: string;
// 状态
statusTxt?: string;
// 销售金额(万元)
price?: string;
// 公开日期
publicDate?: string;
// 数据来源
dataSource?: string;
// 备注
comments?: string;
// 是否推荐
recommend?: number;
// 排序(数字越小越靠前)
sortNumber?: number;
// 状态, 0正常, 1冻结
status?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 用户ID
userId?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
// 修改时间
updateTime?: string;
}
/**
* 客户搜索条件
*/
export interface CreditCustomerParam extends PageParam {
id?: number;
keywords?: string;
}

View File

@@ -37,7 +37,7 @@
<a-input
allow-clear
placeholder="请输入被告/被上诉人"
v-model:value="form.defendant appellee"
v-model:value="form.appellee"
/>
</a-form-item>
<a-form-item label="其他当事人/第三人" name="otherPartiesThirdParty">
@@ -188,7 +188,7 @@
id: undefined,
dataType: undefined,
plaintiffAppellant: undefined,
defendant appellee: undefined,
appellee: undefined,
otherPartiesThirdParty: undefined,
occurrenceTime: undefined,
caseNumber: undefined,

View File

@@ -1,57 +1,58 @@
<template>
<a-page-header :title="getPageTitle()" @back="() => $router.go(-1)">
<a-card :bordered="false" :body-style="{ padding: '16px' }">
<ele-pro-table
ref="tableRef"
row-key="id"
:columns="columns"
:datasource="datasource"
:customRow="customRow"
tool-class="ele-toolbar-form"
class="sys-org-table"
>
<template #toolbar>
<search
@search="reload"
:selection="selection"
@add="openEdit"
@remove="removeBatch"
@batchMove="openMove"
@importData="openImport"
@exportData="exportData"
/>
<a-card :bordered="false" :body-style="{ padding: '16px' }">
<ele-pro-table
ref="tableRef"
row-key="id"
:columns="columns"
:datasource="datasource"
:customRow="customRow"
tool-class="ele-toolbar-form"
class="sys-org-table"
>
<template #toolbar>
<search
@search="reload"
:selection="selection"
@add="openEdit"
@remove="removeBatch"
@batchMove="openMove"
@importData="openImport"
@exportData="exportData"
/>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'image'">
<a-image :src="record.image" :width="50" />
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'image'">
<a-image :src="record.image" :width="50" />
</template>
<template v-if="column.key === 'status'">
<a-tag v-if="record.status === 0" color="green">显示</a-tag>
<a-tag v-if="record.status === 1" color="red">隐藏</a-tag>
</template>
<template v-if="column.key === 'action'">
<a-space>
<a @click="openEdit(record)">修改</a>
<a-divider type="vertical" />
<a-popconfirm
title="确定要删除此记录吗?"
@confirm="remove(record)"
>
<a class="ele-text-danger">删除</a>
</a-popconfirm>
</a-space>
</template>
<template v-if="column.key === 'status'">
<a-tag v-if="record.status === 0" color="green">显示</a-tag>
<a-tag v-if="record.status === 1" color="red">隐藏</a-tag>
</template>
</ele-pro-table>
</a-card>
<template v-if="column.key === 'action'">
<a-space>
<a @click="openEdit(record)">修改</a>
<a-divider type="vertical" />
<a-popconfirm
title="确定要删除此记录吗?"
@confirm="remove(record)"
>
<a class="ele-text-danger">删除</a>
</a-popconfirm>
</a-space>
</template>
</template>
</ele-pro-table>
</a-card>
<!-- 编辑弹窗 -->
<CreditBreachOfTrustEdit v-model:visible="showEdit" :data="current" @done="reload" />
<!-- 导入弹窗 -->
<CreditBreachOfTrustImport
v-model:visible="showImport"
@done="reload"
/>
<!-- 编辑弹窗 -->
<CreditBreachOfTrustEdit
v-model:visible="showEdit"
:data="current"
@done="reload"
/>
<!-- 导入弹窗 -->
<CreditBreachOfTrustImport v-model:visible="showImport" @done="reload" />
</a-page-header>
</template>
@@ -185,8 +186,7 @@
width: 180,
align: 'center',
ellipsis: true,
customRender: ({ text }) =>
toDateString(text, 'yyyy-MM-dd HH:mm:ss')
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd HH:mm:ss')
},
{
title: '操作',

View File

@@ -37,7 +37,7 @@
<a-input
allow-clear
placeholder="请输入被告/被上诉人"
v-model:value="form.defendant appellee"
v-model:value="form.appellee"
/>
</a-form-item>
<a-form-item label="其他当事人/第三人" name="otherPartiesThirdParty">
@@ -188,7 +188,7 @@
id: undefined,
dataType: undefined,
plaintiffAppellant: undefined,
defendant appellee: undefined,
appellee: undefined,
otherPartiesThirdParty: undefined,
occurrenceTime: undefined,
caseNumber: undefined,

View File

@@ -37,7 +37,7 @@
<a-input
allow-clear
placeholder="请输入被告/被上诉人"
v-model:value="form.defendant appellee"
v-model:value="form.appellee"
/>
</a-form-item>
<a-form-item label="其他当事人/第三人" name="otherPartiesThirdParty">
@@ -188,7 +188,7 @@
id: undefined,
dataType: undefined,
plaintiffAppellant: undefined,
defendant appellee: undefined,
appellee: undefined,
otherPartiesThirdParty: undefined,
occurrenceTime: undefined,
caseNumber: undefined,

View File

@@ -37,7 +37,7 @@
<a-input
allow-clear
placeholder="请输入被告/被上诉人"
v-model:value="form.defendant appellee"
v-model:value="form.appellee"
/>
</a-form-item>
<a-form-item label="其他当事人/第三人" name="otherPartiesThirdParty">
@@ -148,7 +148,10 @@
import { ref, reactive, watch } from 'vue';
import { Form, message } from 'ant-design-vue';
import { assignObject, uuid } from 'ele-admin-pro';
import { addCreditCourtSession, updateCreditCourtSession } from '@/api/credit/creditCourtSession';
import {
addCreditCourtSession,
updateCreditCourtSession
} from '@/api/credit/creditCourtSession';
import { CreditCourtSession } from '@/api/credit/creditCourtSession/model';
import { useThemeStore } from '@/store/modules/theme';
import { storeToRefs } from 'pinia';
@@ -188,7 +191,7 @@
id: undefined,
dataType: undefined,
plaintiffAppellant: undefined,
defendant appellee: undefined,
appellee: undefined,
otherPartiesThirdParty: undefined,
occurrenceTime: undefined,
caseNumber: undefined,
@@ -196,20 +199,15 @@
involvedAmount: undefined,
courtName: undefined,
dataStatus: undefined,
comments: undefined,
recommend: undefined,
sortNumber: undefined,
status: undefined,
deleted: undefined,
userId: undefined,
tenantId: undefined,
createTime: undefined,
updateTime: undefined,
creditCourtSessionId: undefined,
creditCourtSessionName: '',
status: 0,
comments: '',
sortNumber: 100
comments: ''
});
/* 更新visible */
@@ -257,7 +255,9 @@
const formData = {
...form
};
const saveOrUpdate = isUpdate.value ? updateCreditCourtSession : addCreditCourtSession;
const saveOrUpdate = isUpdate.value
? updateCreditCourtSession
: addCreditCourtSession;
saveOrUpdate(formData)
.then((msg) => {
loading.value = false;
@@ -280,12 +280,12 @@
images.value = [];
if (props.data) {
assignObject(form, props.data);
if(props.data.image){
if (props.data.image) {
images.value.push({
uid: uuid(),
url: props.data.image,
status: 'done'
})
});
}
isUpdate.value = true;
} else {

View File

@@ -1,55 +1,63 @@
<template>
<a-page-header :title="getPageTitle()" @back="() => $router.go(-1)">
<a-card :bordered="false" :body-style="{ padding: '16px' }">
<ele-pro-table
ref="tableRef"
row-key="id"
:columns="columns"
:datasource="datasource"
:customRow="customRow"
tool-class="ele-toolbar-form"
class="sys-org-table"
>
<template #toolbar>
<search
@search="reload"
:selection="selection"
@add="openEdit"
@remove="removeBatch"
@batchMove="openMove"
/>
<a-card :bordered="false" :body-style="{ padding: '16px' }">
<ele-pro-table
ref="tableRef"
row-key="id"
:columns="columns"
:datasource="datasource"
:customRow="customRow"
tool-class="ele-toolbar-form"
class="sys-org-table"
>
<template #toolbar>
<search
@search="reload"
:selection="selection"
@add="openEdit"
@remove="removeBatch"
@batchMove="openMove"
@importData="openImport"
@exportData="exportData"
/>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'image'">
<a-image :src="record.image" :width="50" />
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'image'">
<a-image :src="record.image" :width="50" />
</template>
<template v-if="column.key === 'status'">
<a-tag v-if="record.status === 0" color="green">显示</a-tag>
<a-tag v-if="record.status === 1" color="red">隐藏</a-tag>
</template>
<template v-if="column.key === 'action'">
<a-space>
<a @click="openEdit(record)">修改</a>
<a-divider type="vertical" />
<a-popconfirm
title="确定要删除此记录吗?"
@confirm="remove(record)"
>
<a class="ele-text-danger">删除</a>
</a-popconfirm>
</a-space>
</template>
<template v-if="column.key === 'status'">
<a-tag v-if="record.status === 0" color="green">显示</a-tag>
<a-tag v-if="record.status === 1" color="red">隐藏</a-tag>
</template>
</ele-pro-table>
</a-card>
<template v-if="column.key === 'action'">
<a-space>
<a @click="openEdit(record)">修改</a>
<a-divider type="vertical" />
<a-popconfirm
title="确定要删除此记录吗?"
@confirm="remove(record)"
>
<a class="ele-text-danger">删除</a>
</a-popconfirm>
</a-space>
</template>
</template>
</ele-pro-table>
</a-card>
<!-- 编辑弹窗 -->
<CreditCourtSessionEdit v-model:visible="showEdit" :data="current" @done="reload" />
<!-- 编辑弹窗 -->
<CreditCourtSessionEdit
v-model:visible="showEdit"
:data="current"
@done="reload"
/>
<!-- 导入弹窗 -->
<CreditCourtSessionImport v-model:visible="showImport" @done="reload" />
</a-page-header>
</template>
<script lang="ts" setup>
import { createVNode, ref, computed } from 'vue';
import { createVNode, ref } from 'vue';
import { message, Modal } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import type { EleProTable } from 'ele-admin-pro';
@@ -58,11 +66,21 @@
DatasourceFunction,
ColumnItem
} from 'ele-admin-pro/es/ele-pro-table/types';
import Search from './components/search.vue';
import {getPageTitle} from '@/utils/common';
import Search from '@/views/credit/components/CreditSearchToolbar.vue';
import { exportCreditData } from '../utils/export';
import { getPageTitle } from '@/utils/common';
import CreditCourtSessionEdit from './components/creditCourtSessionEdit.vue';
import { pageCreditCourtSession, removeCreditCourtSession, removeBatchCreditCourtSession } from '@/api/credit/creditCourtSession';
import type { CreditCourtSession, CreditCourtSessionParam } from '@/api/credit/creditCourtSession/model';
import CreditCourtSessionImport from './components/credit-court-session-import.vue';
import {
pageCreditCourtSession,
listCreditCourtSession,
removeCreditCourtSession,
removeBatchCreditCourtSession
} from '@/api/credit/creditCourtSession';
import type {
CreditCourtSession,
CreditCourtSessionParam
} from '@/api/credit/creditCourtSession/model';
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
@@ -73,37 +91,45 @@
const current = ref<CreditCourtSession | null>(null);
// 是否显示编辑弹窗
const showEdit = ref(false);
// 是否显示导入弹窗
const showImport = ref(false);
// 是否显示批量移动弹窗
const showMove = ref(false);
// 加载状态
const loading = ref(true);
// 搜索关键词
const searchText = ref('');
// 表格数据源
const datasource: DatasourceFunction = ({
page,
limit,
where,
where = {},
orders,
filters
}) => {
const params: CreditCourtSessionParam = { ...where };
if (filters) {
where.status = filters.status;
(params as any).status = filters.status;
}
if (!params.keywords && searchText.value) {
params.keywords = searchText.value;
}
return pageCreditCourtSession({
...where,
...params,
...orders,
page,
limit
});
};
// 完整的列配置(包含所有字段)
// 关键信息列
const columns = ref<ColumnItem[]>([
{
title: 'ID',
dataIndex: 'id',
key: 'id',
width: 90,
width: 80
},
{
title: '数据类型',
@@ -117,18 +143,6 @@
key: 'plaintiffAppellant',
ellipsis: true
},
{
title: '被告/被上诉人',
dataIndex: 'defendant appellee',
key: 'defendant appellee',
ellipsis: true
},
{
title: '其他当事人/第三人',
dataIndex: 'otherPartiesThirdParty',
key: 'otherPartiesThirdParty',
ellipsis: true
},
{
title: '发生时间',
dataIndex: 'occurrenceTime',
@@ -165,66 +179,19 @@
key: 'dataStatus',
ellipsis: true
},
{
title: '备注',
dataIndex: 'comments',
key: 'comments',
ellipsis: true
},
{
title: '是否推荐',
dataIndex: 'recommend',
key: 'recommend',
width: 120
},
{
title: '排序(数字越小越靠前)',
dataIndex: 'sortNumber',
key: 'sortNumber',
width: 120
},
{
title: '状态, 0正常, 1冻结',
dataIndex: 'status',
key: 'status',
width: 120
},
{
title: '是否删除, 0否, 1是',
dataIndex: 'deleted',
key: 'deleted',
width: 120
},
{
title: '用户ID',
dataIndex: 'userId',
key: 'userId',
width: 120
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
width: 200,
width: 180,
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd HH:mm:ss')
},
{
title: '修改时间',
dataIndex: 'updateTime',
key: 'updateTime',
width: 200,
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd HH:mm:ss')
},
{
title: '操作',
key: 'action',
width: 180,
width: 160,
fixed: 'right',
align: 'center',
hideInSetting: true
@@ -233,8 +200,12 @@
/* 搜索 */
const reload = (where?: CreditCourtSessionParam) => {
if (where && Object.prototype.hasOwnProperty.call(where, 'keywords')) {
searchText.value = where.keywords ?? '';
}
const targetWhere = where ?? { keywords: searchText.value || undefined };
selection.value = [];
tableRef?.value?.reload({ where: where });
tableRef?.value?.reload({ where: targetWhere });
};
/* 打开编辑弹窗 */
@@ -248,6 +219,41 @@
showMove.value = true;
};
/* 打开导入弹窗 */
const openImport = () => {
showImport.value = true;
};
/* 导出 */
const exportData = () => {
exportCreditData<CreditCourtSession>({
filename: '开庭公告',
columns: [
{ title: 'ID', dataIndex: 'id' },
{ title: '数据类型', dataIndex: 'dataType' },
{ title: '原告/上诉人', dataIndex: 'plaintiffAppellant' },
{ title: '发生时间', dataIndex: 'occurrenceTime' },
{ title: '案号', dataIndex: 'caseNumber' },
{ title: '案由', dataIndex: 'causeOfAction' },
{ title: '涉案金额', dataIndex: 'involvedAmount' },
{ title: '法院', dataIndex: 'courtName' },
{ title: '数据状态', dataIndex: 'dataStatus' },
{
title: '创建时间',
dataIndex: 'createTime',
formatter: (record: CreditCourtSession) =>
record.createTime
? toDateString(record.createTime, 'yyyy-MM-dd HH:mm:ss')
: ''
}
],
fetchData: () =>
listCreditCourtSession({
keywords: searchText.value || undefined
})
});
};
/* 删除单个 */
const remove = (row: CreditCourtSession) => {
const hide = message.loading('请求中..', 0);

View File

@@ -0,0 +1,260 @@
<!-- 编辑弹窗 -->
<template>
<ele-modal
:width="800"
:visible="visible"
:maskClosable="false"
:maxable="maxable"
:title="isUpdate ? '编辑客户' : '添加客户'"
:body-style="{ paddingBottom: '28px' }"
@update:visible="updateVisible"
@ok="save"
>
<a-form
ref="formRef"
:model="form"
:rules="rules"
:label-col="styleResponsive ? { md: 4, sm: 5, xs: 24 } : { flex: '90px' }"
:wrapper-col="
styleResponsive ? { md: 19, sm: 19, xs: 24 } : { flex: '1' }
"
>
<a-form-item label="客户" name="name">
<a-input
allow-clear
placeholder="请输入客户"
v-model:value="form.name"
/>
</a-form-item>
<a-form-item label="状态" name="statusTxt">
<a-input
allow-clear
placeholder="请输入状态"
v-model:value="form.statusTxt"
/>
</a-form-item>
<a-form-item label="销售金额(万元)" name="price">
<a-input
allow-clear
placeholder="请输入销售金额(万元)"
v-model:value="form.price"
/>
</a-form-item>
<a-form-item label="公开日期" name="publicDate">
<a-input
allow-clear
placeholder="请输入公开日期"
v-model:value="form.publicDate"
/>
</a-form-item>
<a-form-item label="数据来源" name="dataSource">
<a-input
allow-clear
placeholder="请输入数据来源"
v-model:value="form.dataSource"
/>
</a-form-item>
<a-form-item label="备注" name="comments">
<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>
</ele-modal>
</template>
<script lang="ts" setup>
import { ref, reactive, watch } from 'vue';
import { Form, message } from 'ant-design-vue';
import { assignObject, uuid } from 'ele-admin-pro';
import { addCreditCustomer, updateCreditCustomer } from '@/api/credit/creditCustomer';
import { CreditCustomer } from '@/api/credit/creditCustomer/model';
import { useThemeStore } from '@/store/modules/theme';
import { storeToRefs } from 'pinia';
import { ItemType } from 'ele-admin-pro/es/ele-image-upload/types';
import { FormInstance } from 'ant-design-vue/es/form';
import { FileRecord } from '@/api/system/file/model';
// 是否是修改
const isUpdate = ref(false);
const useForm = Form.useForm;
// 是否开启响应式布局
const themeStore = useThemeStore();
const { styleResponsive } = storeToRefs(themeStore);
const props = defineProps<{
// 弹窗是否打开
visible: boolean;
// 修改回显的数据
data?: CreditCustomer | null;
}>();
const emit = defineEmits<{
(e: 'done'): void;
(e: 'update:visible', visible: boolean): void;
}>();
// 提交状态
const loading = ref(false);
// 是否显示最大化切换按钮
const maxable = ref(true);
// 表格选中数据
const formRef = ref<FormInstance | null>(null);
const images = ref<ItemType[]>([]);
// 用户信息
const form = reactive<CreditCustomer>({
id: undefined,
name: undefined,
statusTxt: undefined,
price: undefined,
publicDate: undefined,
dataSource: undefined,
comments: undefined,
recommend: undefined,
sortNumber: undefined,
status: undefined,
deleted: undefined,
userId: undefined,
tenantId: undefined,
createTime: undefined,
updateTime: undefined,
creditCustomerId: undefined,
creditCustomerName: '',
status: 0,
comments: '',
sortNumber: 100
});
/* 更新visible */
const updateVisible = (value: boolean) => {
emit('update:visible', value);
};
// 表单验证规则
const rules = reactive({
creditCustomerName: [
{
required: true,
type: 'string',
message: '请填写客户名称',
trigger: 'blur'
}
]
});
const chooseImage = (data: FileRecord) => {
images.value.push({
uid: data.id,
url: data.path,
status: 'done'
});
form.image = data.path;
};
const onDeleteItem = (index: number) => {
images.value.splice(index, 1);
form.image = '';
};
const { resetFields } = useForm(form, rules);
/* 保存编辑 */
const save = () => {
if (!formRef.value) {
return;
}
formRef.value
.validate()
.then(() => {
loading.value = true;
const formData = {
...form
};
const saveOrUpdate = isUpdate.value ? updateCreditCustomer : addCreditCustomer;
saveOrUpdate(formData)
.then((msg) => {
loading.value = false;
message.success(msg);
updateVisible(false);
emit('done');
})
.catch((e) => {
loading.value = false;
message.error(e.message);
});
})
.catch(() => {});
};
watch(
() => props.visible,
(visible) => {
if (visible) {
images.value = [];
if (props.data) {
assignObject(form, props.data);
if(props.data.image){
images.value.push({
uid: uuid(),
url: props.data.image,
status: 'done'
})
}
isUpdate.value = true;
} else {
isUpdate.value = false;
}
} else {
resetFields();
}
},
{ immediate: true }
);
</script>

View File

@@ -0,0 +1,42 @@
<!-- 搜索表单 -->
<template>
<a-space :size="10" style="flex-wrap: wrap">
<a-button type="primary" class="ele-btn-icon" @click="add">
<template #icon>
<PlusOutlined />
</template>
<span>添加</span>
</a-button>
</a-space>
</template>
<script lang="ts" setup>
import { PlusOutlined } from '@ant-design/icons-vue';
import type { GradeParam } from '@/api/user/grade/model';
import { watch } from 'vue';
const props = withDefaults(
defineProps<{
// 选中的角色
selection?: [];
}>(),
{}
);
const emit = defineEmits<{
(e: 'search', where?: GradeParam): void;
(e: 'add'): void;
(e: 'remove'): void;
(e: 'batchMove'): void;
}>();
// 新增
const add = () => {
emit('add');
};
watch(
() => props.selection,
() => {}
);
</script>

View File

@@ -0,0 +1,301 @@
<template>
<a-page-header :title="getPageTitle()" @back="() => $router.go(-1)">
<a-card :bordered="false" :body-style="{ padding: '16px' }">
<ele-pro-table
ref="tableRef"
row-key="id"
:columns="columns"
:datasource="datasource"
:customRow="customRow"
tool-class="ele-toolbar-form"
class="sys-org-table"
>
<template #toolbar>
<search
@search="reload"
:selection="selection"
@add="openEdit"
@remove="removeBatch"
@batchMove="openMove"
/>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'image'">
<a-image :src="record.image" :width="50" />
</template>
<template v-if="column.key === 'status'">
<a-tag v-if="record.status === 0" color="green">显示</a-tag>
<a-tag v-if="record.status === 1" color="red">隐藏</a-tag>
</template>
<template v-if="column.key === 'action'">
<a-space>
<a @click="openEdit(record)">修改</a>
<a-divider type="vertical" />
<a-popconfirm
title="确定要删除此记录吗?"
@confirm="remove(record)"
>
<a class="ele-text-danger">删除</a>
</a-popconfirm>
</a-space>
</template>
</template>
</ele-pro-table>
</a-card>
<!-- 编辑弹窗 -->
<CreditCustomerEdit
v-model:visible="showEdit"
:data="current"
@done="reload"
/>
</a-page-header>
</template>
<script lang="ts" setup>
import { createVNode, ref, computed } from 'vue';
import { message, Modal } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import type { EleProTable } from 'ele-admin-pro';
import { toDateString } from 'ele-admin-pro';
import type {
DatasourceFunction,
ColumnItem
} from 'ele-admin-pro/es/ele-pro-table/types';
import Search from './components/search.vue';
import { getPageTitle } from '@/utils/common';
import CreditCustomerEdit from './components/creditCustomerEdit.vue';
import {
pageCreditCustomer,
removeCreditCustomer,
removeBatchCreditCustomer
} from '@/api/credit/creditCustomer';
import type {
CreditCustomer,
CreditCustomerParam
} from '@/api/credit/creditCustomer/model';
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
// 表格选中数据
const selection = ref<CreditCustomer[]>([]);
// 当前编辑数据
const current = ref<CreditCustomer | null>(null);
// 是否显示编辑弹窗
const showEdit = ref(false);
// 是否显示批量移动弹窗
const showMove = ref(false);
// 加载状态
const loading = ref(true);
// 表格数据源
const datasource: DatasourceFunction = ({
page,
limit,
where,
orders,
filters
}) => {
if (filters) {
where.status = filters.status;
}
return pageCreditCustomer({
...where,
...orders,
page,
limit
});
};
// 完整的列配置(包含所有字段)
const columns = ref<ColumnItem[]>([
{
title: 'ID',
dataIndex: 'id',
key: 'id',
width: 90
},
{
title: '客户',
dataIndex: 'name',
key: 'name',
ellipsis: true
},
{
title: '状态',
dataIndex: 'statusTxt',
key: 'statusTxt',
ellipsis: true
},
{
title: '销售金额(万元)',
dataIndex: 'price',
key: 'price',
width: 120
},
{
title: '公开日期',
dataIndex: 'publicDate',
key: 'publicDate',
width: 120
},
{
title: '数据来源',
dataIndex: 'dataSource',
key: 'dataSource',
ellipsis: true
},
{
title: '备注',
dataIndex: 'comments',
key: 'comments',
ellipsis: true
},
{
title: '是否推荐',
dataIndex: 'recommend',
key: 'recommend',
width: 120
},
{
title: '排序(数字越小越靠前)',
dataIndex: 'sortNumber',
key: 'sortNumber',
width: 120
},
{
title: '状态, 0正常, 1冻结',
dataIndex: 'status',
key: 'status',
width: 120
},
{
title: '是否删除, 0否, 1是',
dataIndex: 'deleted',
key: 'deleted',
width: 120
},
{
title: '用户ID',
dataIndex: 'userId',
key: 'userId',
width: 120
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
width: 200,
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd HH:mm:ss')
},
{
title: '修改时间',
dataIndex: 'updateTime',
key: 'updateTime',
width: 200,
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd HH:mm:ss')
},
{
title: '操作',
key: 'action',
width: 180,
fixed: 'right',
align: 'center',
hideInSetting: true
}
]);
/* 搜索 */
const reload = (where?: CreditCustomerParam) => {
selection.value = [];
tableRef?.value?.reload({ where: where });
};
/* 打开编辑弹窗 */
const openEdit = (row?: CreditCustomer) => {
current.value = row ?? null;
showEdit.value = true;
};
/* 打开批量移动弹窗 */
const openMove = () => {
showMove.value = true;
};
/* 删除单个 */
const remove = (row: CreditCustomer) => {
const hide = message.loading('请求中..', 0);
removeCreditCustomer(row.id)
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
};
/* 批量删除 */
const removeBatch = () => {
if (!selection.value.length) {
message.error('请至少选择一条数据');
return;
}
Modal.confirm({
title: '提示',
content: '确定要删除选中的记录吗?',
icon: createVNode(ExclamationCircleOutlined),
maskClosable: true,
onOk: () => {
const hide = message.loading('请求中..', 0);
removeBatchCreditCustomer(selection.value.map((d) => d.id))
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
}
});
};
/* 查询 */
const query = () => {
loading.value = true;
};
/* 自定义行属性 */
const customRow = (record: CreditCustomer) => {
return {
// 行点击事件
onClick: () => {
// console.log(record);
},
// 行双击事件
onDblclick: () => {
openEdit(record);
}
};
};
query();
</script>
<script lang="ts">
export default {
name: 'CreditCustomer'
};
</script>
<style lang="less" scoped></style>

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 { importCreditDeliveryNotice } from '@/api/credit/creditDeliveryNotice';
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-delivery-notice/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;
importCreditDeliveryNotice(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

@@ -37,7 +37,7 @@
<a-input
allow-clear
placeholder="请输入被告/被上诉人"
v-model:value="form.defendant appellee"
v-model:value="form.appellee"
/>
</a-form-item>
<a-form-item label="其他当事人/第三人" name="otherPartiesThirdParty">
@@ -188,7 +188,7 @@
id: undefined,
dataType: undefined,
plaintiffAppellant: undefined,
defendant appellee: undefined,
appellee: undefined,
otherPartiesThirdParty: undefined,
occurrenceTime: undefined,
caseNumber: undefined,

View File

@@ -17,6 +17,8 @@
@add="openEdit"
@remove="removeBatch"
@batchMove="openMove"
@importData="openImport"
@exportData="exportData"
/>
</template>
<template #bodyCell="{ column, record }">
@@ -45,11 +47,16 @@
<!-- 编辑弹窗 -->
<CreditDeliveryNoticeEdit v-model:visible="showEdit" :data="current" @done="reload" />
<!-- 导入弹窗 -->
<CreditDeliveryNoticeImport
v-model:visible="showImport"
@done="reload"
/>
</a-page-header>
</template>
<script lang="ts" setup>
import { createVNode, ref, computed } from 'vue';
import { createVNode, ref } from 'vue';
import { message, Modal } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import type { EleProTable } from 'ele-admin-pro';
@@ -58,11 +65,21 @@
DatasourceFunction,
ColumnItem
} from 'ele-admin-pro/es/ele-pro-table/types';
import Search from './components/search.vue';
import {getPageTitle} from '@/utils/common';
import Search from '@/views/credit/components/CreditSearchToolbar.vue';
import { exportCreditData } from '../utils/export';
import { getPageTitle } from '@/utils/common';
import CreditDeliveryNoticeEdit from './components/creditDeliveryNoticeEdit.vue';
import { pageCreditDeliveryNotice, removeCreditDeliveryNotice, removeBatchCreditDeliveryNotice } from '@/api/credit/creditDeliveryNotice';
import type { CreditDeliveryNotice, CreditDeliveryNoticeParam } from '@/api/credit/creditDeliveryNotice/model';
import CreditDeliveryNoticeImport from './components/credit-delivery-notice-import.vue';
import {
pageCreditDeliveryNotice,
listCreditDeliveryNotice,
removeCreditDeliveryNotice,
removeBatchCreditDeliveryNotice
} from '@/api/credit/creditDeliveryNotice';
import type {
CreditDeliveryNotice,
CreditDeliveryNoticeParam
} from '@/api/credit/creditDeliveryNotice/model';
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
@@ -73,37 +90,45 @@
const current = ref<CreditDeliveryNotice | null>(null);
// 是否显示编辑弹窗
const showEdit = ref(false);
// 是否显示导入弹窗
const showImport = ref(false);
// 是否显示批量移动弹窗
const showMove = ref(false);
// 加载状态
const loading = ref(true);
// 搜索关键词
const searchText = ref('');
// 表格数据源
const datasource: DatasourceFunction = ({
page,
limit,
where,
where = {},
orders,
filters
}) => {
const params: CreditDeliveryNoticeParam = { ...where };
if (filters) {
where.status = filters.status;
(params as any).status = filters.status;
}
if (!params.keywords && searchText.value) {
params.keywords = searchText.value;
}
return pageCreditDeliveryNotice({
...where,
...params,
...orders,
page,
limit
});
};
// 完整的列配置(包含所有字段)
// 关键信息列
const columns = ref<ColumnItem[]>([
{
title: 'ID',
dataIndex: 'id',
key: 'id',
width: 90,
width: 80
},
{
title: '数据类型',
@@ -117,18 +142,6 @@
key: 'plaintiffAppellant',
ellipsis: true
},
{
title: '被告/被上诉人',
dataIndex: 'defendant appellee',
key: 'defendant appellee',
ellipsis: true
},
{
title: '其他当事人/第三人',
dataIndex: 'otherPartiesThirdParty',
key: 'otherPartiesThirdParty',
ellipsis: true
},
{
title: '发生时间',
dataIndex: 'occurrenceTime',
@@ -165,66 +178,19 @@
key: 'dataStatus',
ellipsis: true
},
{
title: '备注',
dataIndex: 'comments',
key: 'comments',
ellipsis: true
},
{
title: '是否推荐',
dataIndex: 'recommend',
key: 'recommend',
width: 120
},
{
title: '排序(数字越小越靠前)',
dataIndex: 'sortNumber',
key: 'sortNumber',
width: 120
},
{
title: '状态, 0正常, 1冻结',
dataIndex: 'status',
key: 'status',
width: 120
},
{
title: '是否删除, 0否, 1是',
dataIndex: 'deleted',
key: 'deleted',
width: 120
},
{
title: '用户ID',
dataIndex: 'userId',
key: 'userId',
width: 120
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
width: 200,
width: 180,
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd HH:mm:ss')
},
{
title: '修改时间',
dataIndex: 'updateTime',
key: 'updateTime',
width: 200,
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd HH:mm:ss')
},
{
title: '操作',
key: 'action',
width: 180,
width: 160,
fixed: 'right',
align: 'center',
hideInSetting: true
@@ -233,8 +199,12 @@
/* 搜索 */
const reload = (where?: CreditDeliveryNoticeParam) => {
if (where && Object.prototype.hasOwnProperty.call(where, 'keywords')) {
searchText.value = where.keywords ?? '';
}
const targetWhere = where ?? { keywords: searchText.value || undefined };
selection.value = [];
tableRef?.value?.reload({ where: where });
tableRef?.value?.reload({ where: targetWhere });
};
/* 打开编辑弹窗 */
@@ -248,6 +218,41 @@
showMove.value = true;
};
/* 打开导入弹窗 */
const openImport = () => {
showImport.value = true;
};
/* 导出 */
const exportData = () => {
exportCreditData<CreditDeliveryNotice>({
filename: '送达公告',
columns: [
{ title: 'ID', dataIndex: 'id' },
{ title: '数据类型', dataIndex: 'dataType' },
{ title: '原告/上诉人', dataIndex: 'plaintiffAppellant' },
{ title: '发生时间', dataIndex: 'occurrenceTime' },
{ title: '案号', dataIndex: 'caseNumber' },
{ title: '案由', dataIndex: 'causeOfAction' },
{ title: '涉案金额', dataIndex: 'involvedAmount' },
{ title: '法院', dataIndex: 'courtName' },
{ title: '数据状态', dataIndex: 'dataStatus' },
{
title: '创建时间',
dataIndex: 'createTime',
formatter: (record: CreditDeliveryNotice) =>
record.createTime
? toDateString(record.createTime, 'yyyy-MM-dd HH:mm:ss')
: ''
}
],
fetchData: () =>
listCreditDeliveryNotice({
keywords: searchText.value || undefined
})
});
};
/* 删除单个 */
const remove = (row: CreditDeliveryNotice) => {
const hide = message.loading('请求中..', 0);

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 { importCreditExternal } from '@/api/credit/creditExternal';
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-external/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;
importCreditExternal(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

@@ -17,6 +17,8 @@
@add="openEdit"
@remove="removeBatch"
@batchMove="openMove"
@importData="openImport"
@exportData="exportData"
/>
</template>
<template #bodyCell="{ column, record }">
@@ -45,11 +47,13 @@
<!-- 编辑弹窗 -->
<CreditExternalEdit v-model:visible="showEdit" :data="current" @done="reload" />
<!-- 导入弹窗 -->
<CreditExternalImport v-model:visible="showImport" @done="reload" />
</a-page-header>
</template>
<script lang="ts" setup>
import { createVNode, ref, computed } from 'vue';
import { createVNode, ref } from 'vue';
import { message, Modal } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import type { EleProTable } from 'ele-admin-pro';
@@ -58,11 +62,21 @@
DatasourceFunction,
ColumnItem
} from 'ele-admin-pro/es/ele-pro-table/types';
import Search from './components/search.vue';
import {getPageTitle} from '@/utils/common';
import Search from '@/views/credit/components/CreditSearchToolbar.vue';
import { exportCreditData } from '../utils/export';
import { getPageTitle } from '@/utils/common';
import CreditExternalEdit from './components/creditExternalEdit.vue';
import { pageCreditExternal, removeCreditExternal, removeBatchCreditExternal } from '@/api/credit/creditExternal';
import type { CreditExternal, CreditExternalParam } from '@/api/credit/creditExternal/model';
import CreditExternalImport from './components/credit-external-import.vue';
import {
pageCreditExternal,
listCreditExternal,
removeCreditExternal,
removeBatchCreditExternal
} from '@/api/credit/creditExternal';
import type {
CreditExternal,
CreditExternalParam
} from '@/api/credit/creditExternal/model';
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
@@ -73,37 +87,45 @@
const current = ref<CreditExternal | null>(null);
// 是否显示编辑弹窗
const showEdit = ref(false);
// 是否显示导入弹窗
const showImport = ref(false);
// 是否显示批量移动弹窗
const showMove = ref(false);
// 加载状态
const loading = ref(true);
// 搜索关键词
const searchText = ref('');
// 表格数据源
const datasource: DatasourceFunction = ({
page,
limit,
where,
where = {},
orders,
filters
}) => {
const params: CreditExternalParam = { ...where };
if (filters) {
where.status = filters.status;
(params as any).status = filters.status;
}
if (!params.keywords && searchText.value) {
params.keywords = searchText.value;
}
return pageCreditExternal({
...where,
...params,
...orders,
page,
limit
});
};
// 完整的列配置(包含所有字段)
// 关键信息列
const columns = ref<ColumnItem[]>([
{
title: 'ID',
dataIndex: 'id',
key: 'id',
width: 90,
width: 80
},
{
title: '被投资企业名称',
@@ -121,7 +143,8 @@
title: '法定代表人姓名',
dataIndex: 'legalRepresentative',
key: 'legalRepresentative',
ellipsis: true
ellipsis: true,
width: 120
},
{
title: '注册资本(金额)',
@@ -145,19 +168,7 @@
title: '认缴出资额',
dataIndex: 'subscribedInvestmentAmount',
key: 'subscribedInvestmentAmount',
width: 120
},
{
title: '认缴出资日期',
dataIndex: 'subscribedInvestmentDate',
key: 'subscribedInvestmentDate',
width: 120
},
{
title: '间接持股比例',
dataIndex: 'indirectShareholdingRatio',
key: 'indirectShareholdingRatio',
width: 120
ellipsis: true
},
{
title: '投资日期',
@@ -177,78 +188,19 @@
key: 'industry',
ellipsis: true
},
{
title: '投资数量',
dataIndex: 'investmentCount',
key: 'investmentCount',
width: 120
},
{
title: '关联产品/机构',
dataIndex: 'relatedProductsInstitutions',
key: 'relatedProductsInstitutions',
ellipsis: true
},
{
title: '备注',
dataIndex: 'comments',
key: 'comments',
ellipsis: true
},
{
title: '是否推荐',
dataIndex: 'recommend',
key: 'recommend',
width: 120
},
{
title: '排序(数字越小越靠前)',
dataIndex: 'sortNumber',
key: 'sortNumber',
width: 120
},
{
title: '状态, 0正常, 1冻结',
dataIndex: 'status',
key: 'status',
width: 120
},
{
title: '是否删除, 0否, 1是',
dataIndex: 'deleted',
key: 'deleted',
width: 120
},
{
title: '用户ID',
dataIndex: 'userId',
key: 'userId',
width: 120
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
width: 200,
width: 180,
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd HH:mm:ss')
},
{
title: '修改时间',
dataIndex: 'updateTime',
key: 'updateTime',
width: 200,
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd HH:mm:ss')
},
{
title: '操作',
key: 'action',
width: 180,
width: 160,
fixed: 'right',
align: 'center',
hideInSetting: true
@@ -257,8 +209,12 @@
/* 搜索 */
const reload = (where?: CreditExternalParam) => {
if (where && Object.prototype.hasOwnProperty.call(where, 'keywords')) {
searchText.value = where.keywords ?? '';
}
const targetWhere = where ?? { keywords: searchText.value || undefined };
selection.value = [];
tableRef?.value?.reload({ where: where });
tableRef?.value?.reload({ where: targetWhere });
};
/* 打开编辑弹窗 */
@@ -272,6 +228,43 @@
showMove.value = true;
};
/* 打开导入弹窗 */
const openImport = () => {
showImport.value = true;
};
/* 导出 */
const exportData = () => {
exportCreditData<CreditExternal>({
filename: '对外投资',
columns: [
{ title: 'ID', dataIndex: 'id' },
{ title: '被投资企业名称', dataIndex: 'name' },
{ title: '企业状态', dataIndex: 'statusTxt' },
{ title: '法定代表人姓名', dataIndex: 'legalRepresentative' },
{ title: '注册资本(金额)', dataIndex: 'registeredCapital' },
{ title: '成立日期', dataIndex: 'establishmentDate' },
{ title: '持股比例', dataIndex: 'shareholdingRatio' },
{ title: '认缴出资额', dataIndex: 'subscribedInvestmentAmount' },
{ title: '投资日期', dataIndex: 'investmentDate' },
{ title: '所属地区', dataIndex: 'region' },
{ title: '所属行业', dataIndex: 'industry' },
{
title: '创建时间',
dataIndex: 'createTime',
formatter: (record: CreditExternal) =>
record.createTime
? toDateString(record.createTime, 'yyyy-MM-dd HH:mm:ss')
: ''
}
],
fetchData: () =>
listCreditExternal({
keywords: searchText.value || undefined
})
});
};
/* 删除单个 */
const remove = (row: CreditExternal) => {
const hide = message.loading('请求中..', 0);

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 { importCreditFinalVersion } from '@/api/credit/creditFinalVersion';
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-final-version/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;
importCreditFinalVersion(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

@@ -37,7 +37,7 @@
<a-input
allow-clear
placeholder="请输入被告/被上诉人"
v-model:value="form.defendant appellee"
v-model:value="form.appellee"
/>
</a-form-item>
<a-form-item label="其他当事人/第三人" name="otherPartiesThirdParty">
@@ -188,7 +188,7 @@
id: undefined,
dataType: undefined,
plaintiffAppellant: undefined,
defendant appellee: undefined,
appellee: undefined,
otherPartiesThirdParty: undefined,
occurrenceTime: undefined,
caseNumber: undefined,

View File

@@ -17,6 +17,8 @@
@add="openEdit"
@remove="removeBatch"
@batchMove="openMove"
@importData="openImport"
@exportData="exportData"
/>
</template>
<template #bodyCell="{ column, record }">
@@ -45,11 +47,16 @@
<!-- 编辑弹窗 -->
<CreditFinalVersionEdit v-model:visible="showEdit" :data="current" @done="reload" />
<!-- 导入弹窗 -->
<CreditFinalVersionImport
v-model:visible="showImport"
@done="reload"
/>
</a-page-header>
</template>
<script lang="ts" setup>
import { createVNode, ref, computed } from 'vue';
import { createVNode, ref } from 'vue';
import { message, Modal } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import type { EleProTable } from 'ele-admin-pro';
@@ -58,11 +65,21 @@
DatasourceFunction,
ColumnItem
} from 'ele-admin-pro/es/ele-pro-table/types';
import Search from './components/search.vue';
import {getPageTitle} from '@/utils/common';
import Search from '@/views/credit/components/CreditSearchToolbar.vue';
import { exportCreditData } from '../utils/export';
import { getPageTitle } from '@/utils/common';
import CreditFinalVersionEdit from './components/creditFinalVersionEdit.vue';
import { pageCreditFinalVersion, removeCreditFinalVersion, removeBatchCreditFinalVersion } from '@/api/credit/creditFinalVersion';
import type { CreditFinalVersion, CreditFinalVersionParam } from '@/api/credit/creditFinalVersion/model';
import CreditFinalVersionImport from './components/credit-final-version-import.vue';
import {
pageCreditFinalVersion,
listCreditFinalVersion,
removeCreditFinalVersion,
removeBatchCreditFinalVersion
} from '@/api/credit/creditFinalVersion';
import type {
CreditFinalVersion,
CreditFinalVersionParam
} from '@/api/credit/creditFinalVersion/model';
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
@@ -73,31 +90,39 @@
const current = ref<CreditFinalVersion | null>(null);
// 是否显示编辑弹窗
const showEdit = ref(false);
// 是否显示导入弹窗
const showImport = ref(false);
// 是否显示批量移动弹窗
const showMove = ref(false);
// 加载状态
const loading = ref(true);
// 搜索关键词
const searchText = ref('');
// 表格数据源
const datasource: DatasourceFunction = ({
page,
limit,
where,
where = {},
orders,
filters
}) => {
const params: CreditFinalVersionParam = { ...where };
if (filters) {
where.status = filters.status;
(params as any).status = filters.status;
}
if (!params.keywords && searchText.value) {
params.keywords = searchText.value;
}
return pageCreditFinalVersion({
...where,
...params,
...orders,
page,
limit
});
};
// 完整的列配置(包含所有字段)
// 关键信息列
const columns = ref<ColumnItem[]>([
{
title: 'ID',
@@ -117,18 +142,6 @@
key: 'plaintiffAppellant',
ellipsis: true
},
{
title: '被告/被上诉人',
dataIndex: 'defendant appellee',
key: 'defendant appellee',
ellipsis: true
},
{
title: '其他当事人/第三人',
dataIndex: 'otherPartiesThirdParty',
key: 'otherPartiesThirdParty',
ellipsis: true
},
{
title: '发生时间',
dataIndex: 'occurrenceTime',
@@ -165,66 +178,19 @@
key: 'dataStatus',
ellipsis: true
},
{
title: '备注',
dataIndex: 'comments',
key: 'comments',
ellipsis: true
},
{
title: '是否推荐',
dataIndex: 'recommend',
key: 'recommend',
width: 120
},
{
title: '排序(数字越小越靠前)',
dataIndex: 'sortNumber',
key: 'sortNumber',
width: 120
},
{
title: '状态, 0正常, 1冻结',
dataIndex: 'status',
key: 'status',
width: 120
},
{
title: '是否删除, 0否, 1是',
dataIndex: 'deleted',
key: 'deleted',
width: 120
},
{
title: '用户ID',
dataIndex: 'userId',
key: 'userId',
width: 120
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
width: 200,
width: 180,
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd HH:mm:ss')
},
{
title: '修改时间',
dataIndex: 'updateTime',
key: 'updateTime',
width: 200,
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd HH:mm:ss')
},
{
title: '操作',
key: 'action',
width: 180,
width: 160,
fixed: 'right',
align: 'center',
hideInSetting: true
@@ -233,8 +199,12 @@
/* 搜索 */
const reload = (where?: CreditFinalVersionParam) => {
if (where && Object.prototype.hasOwnProperty.call(where, 'keywords')) {
searchText.value = where.keywords ?? '';
}
const targetWhere = where ?? { keywords: searchText.value || undefined };
selection.value = [];
tableRef?.value?.reload({ where: where });
tableRef?.value?.reload({ where: targetWhere });
};
/* 打开编辑弹窗 */
@@ -248,6 +218,41 @@
showMove.value = true;
};
/* 打开导入弹窗 */
const openImport = () => {
showImport.value = true;
};
/* 导出 */
const exportData = () => {
exportCreditData<CreditFinalVersion>({
filename: '终本案件',
columns: [
{ title: 'ID', dataIndex: 'id' },
{ title: '数据类型', dataIndex: 'dataType' },
{ title: '原告/上诉人', dataIndex: 'plaintiffAppellant' },
{ title: '发生时间', dataIndex: 'occurrenceTime' },
{ title: '案号', dataIndex: 'caseNumber' },
{ title: '案由', dataIndex: 'causeOfAction' },
{ title: '涉案金额', dataIndex: 'involvedAmount' },
{ title: '法院', dataIndex: 'courtName' },
{ title: '数据状态', dataIndex: 'dataStatus' },
{
title: '创建时间',
dataIndex: 'createTime',
formatter: (record: CreditFinalVersion) =>
record.createTime
? toDateString(record.createTime, 'yyyy-MM-dd HH:mm:ss')
: ''
}
],
fetchData: () =>
listCreditFinalVersion({
keywords: searchText.value || undefined
})
});
};
/* 删除单个 */
const remove = (row: CreditFinalVersion) => {
const hide = message.loading('请求中..', 0);

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 { importCreditGqdj } from '@/api/credit/creditGqdj';
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-gqdj/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;
importCreditGqdj(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

@@ -37,7 +37,7 @@
<a-input
allow-clear
placeholder="请输入被告/被上诉人"
v-model:value="form.defendant appellee"
v-model:value="form.appellee"
/>
</a-form-item>
<a-form-item label="其他当事人/第三人" name="otherPartiesThirdParty">
@@ -188,7 +188,7 @@
id: undefined,
dataType: undefined,
plaintiffAppellant: undefined,
defendant appellee: undefined,
appellee: undefined,
otherPartiesThirdParty: undefined,
occurrenceTime: undefined,
caseNumber: undefined,

View File

@@ -17,6 +17,8 @@
@add="openEdit"
@remove="removeBatch"
@batchMove="openMove"
@importData="openImport"
@exportData="exportData"
/>
</template>
<template #bodyCell="{ column, record }">
@@ -45,11 +47,13 @@
<!-- 编辑弹窗 -->
<CreditGqdjEdit v-model:visible="showEdit" :data="current" @done="reload" />
<!-- 导入弹窗 -->
<CreditGqdjImport v-model:visible="showImport" @done="reload" />
</a-page-header>
</template>
<script lang="ts" setup>
import { createVNode, ref, computed } from 'vue';
import { createVNode, ref } from 'vue';
import { message, Modal } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import type { EleProTable } from 'ele-admin-pro';
@@ -58,11 +62,21 @@
DatasourceFunction,
ColumnItem
} from 'ele-admin-pro/es/ele-pro-table/types';
import Search from './components/search.vue';
import {getPageTitle} from '@/utils/common';
import Search from '@/views/credit/components/CreditSearchToolbar.vue';
import { exportCreditData } from '../utils/export';
import { getPageTitle } from '@/utils/common';
import CreditGqdjEdit from './components/creditGqdjEdit.vue';
import { pageCreditGqdj, removeCreditGqdj, removeBatchCreditGqdj } from '@/api/credit/creditGqdj';
import type { CreditGqdj, CreditGqdjParam } from '@/api/credit/creditGqdj/model';
import CreditGqdjImport from './components/credit-gqdj-import.vue';
import {
pageCreditGqdj,
listCreditGqdj,
removeCreditGqdj,
removeBatchCreditGqdj
} from '@/api/credit/creditGqdj';
import type {
CreditGqdj,
CreditGqdjParam
} from '@/api/credit/creditGqdj/model';
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
@@ -73,37 +87,45 @@
const current = ref<CreditGqdj | null>(null);
// 是否显示编辑弹窗
const showEdit = ref(false);
// 是否显示导入弹窗
const showImport = ref(false);
// 是否显示批量移动弹窗
const showMove = ref(false);
// 加载状态
const loading = ref(true);
// 搜索关键词
const searchText = ref('');
// 表格数据源
const datasource: DatasourceFunction = ({
page,
limit,
where,
where = {},
orders,
filters
}) => {
const params: CreditGqdjParam = { ...where };
if (filters) {
where.status = filters.status;
(params as any).status = filters.status;
}
if (!params.keywords && searchText.value) {
params.keywords = searchText.value;
}
return pageCreditGqdj({
...where,
...params,
...orders,
page,
limit
});
};
// 完整的列配置(包含所有字段)
// 关键信息列
const columns = ref<ColumnItem[]>([
{
title: 'ID',
dataIndex: 'id',
key: 'id',
width: 90,
width: 80
},
{
title: '数据类型',
@@ -117,18 +139,6 @@
key: 'plaintiffAppellant',
ellipsis: true
},
{
title: '被告/被上诉人',
dataIndex: 'defendant appellee',
key: 'defendant appellee',
ellipsis: true
},
{
title: '其他当事人/第三人',
dataIndex: 'otherPartiesThirdParty',
key: 'otherPartiesThirdParty',
ellipsis: true
},
{
title: '发生时间',
dataIndex: 'occurrenceTime',
@@ -165,66 +175,19 @@
key: 'dataStatus',
ellipsis: true
},
{
title: '备注',
dataIndex: 'comments',
key: 'comments',
ellipsis: true
},
{
title: '是否推荐',
dataIndex: 'recommend',
key: 'recommend',
width: 120
},
{
title: '排序(数字越小越靠前)',
dataIndex: 'sortNumber',
key: 'sortNumber',
width: 120
},
{
title: '状态, 0正常, 1冻结',
dataIndex: 'status',
key: 'status',
width: 120
},
{
title: '是否删除, 0否, 1是',
dataIndex: 'deleted',
key: 'deleted',
width: 120
},
{
title: '用户ID',
dataIndex: 'userId',
key: 'userId',
width: 120
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
width: 200,
width: 180,
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd HH:mm:ss')
},
{
title: '修改时间',
dataIndex: 'updateTime',
key: 'updateTime',
width: 200,
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd HH:mm:ss')
},
{
title: '操作',
key: 'action',
width: 180,
width: 160,
fixed: 'right',
align: 'center',
hideInSetting: true
@@ -233,8 +196,12 @@
/* 搜索 */
const reload = (where?: CreditGqdjParam) => {
if (where && Object.prototype.hasOwnProperty.call(where, 'keywords')) {
searchText.value = where.keywords ?? '';
}
const targetWhere = where ?? { keywords: searchText.value || undefined };
selection.value = [];
tableRef?.value?.reload({ where: where });
tableRef?.value?.reload({ where: targetWhere });
};
/* 打开编辑弹窗 */
@@ -248,6 +215,41 @@
showMove.value = true;
};
/* 打开导入弹窗 */
const openImport = () => {
showImport.value = true;
};
/* 导出 */
const exportData = () => {
exportCreditData<CreditGqdj>({
filename: '股权冻结',
columns: [
{ title: 'ID', dataIndex: 'id' },
{ title: '数据类型', dataIndex: 'dataType' },
{ title: '原告/上诉人', dataIndex: 'plaintiffAppellant' },
{ title: '发生时间', dataIndex: 'occurrenceTime' },
{ title: '案号', dataIndex: 'caseNumber' },
{ title: '案由', dataIndex: 'causeOfAction' },
{ title: '涉案金额', dataIndex: 'involvedAmount' },
{ title: '法院', dataIndex: 'courtName' },
{ title: '数据状态', dataIndex: 'dataStatus' },
{
title: '创建时间',
dataIndex: 'createTime',
formatter: (record: CreditGqdj) =>
record.createTime
? toDateString(record.createTime, 'yyyy-MM-dd HH:mm:ss')
: ''
}
],
fetchData: () =>
listCreditGqdj({
keywords: searchText.value || undefined
})
});
};
/* 删除单个 */
const remove = (row: CreditGqdj) => {
const hide = message.loading('请求中..', 0);

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 { importCreditJudgmentDebtor } from '@/api/credit/creditJudgmentDebtor';
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/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;
importCreditJudgmentDebtor(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

@@ -17,6 +17,8 @@
@add="openEdit"
@remove="removeBatch"
@batchMove="openMove"
@importData="openImport"
@exportData="exportData"
/>
</template>
<template #bodyCell="{ column, record }">
@@ -45,11 +47,16 @@
<!-- 编辑弹窗 -->
<CreditJudgmentDebtorEdit v-model:visible="showEdit" :data="current" @done="reload" />
<!-- 导入弹窗 -->
<CreditJudgmentDebtorImport
v-model:visible="showImport"
@done="reload"
/>
</a-page-header>
</template>
<script lang="ts" setup>
import { createVNode, ref, computed } from 'vue';
import { createVNode, ref } from 'vue';
import { message, Modal } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import type { EleProTable } from 'ele-admin-pro';
@@ -58,11 +65,21 @@
DatasourceFunction,
ColumnItem
} from 'ele-admin-pro/es/ele-pro-table/types';
import Search from './components/search.vue';
import {getPageTitle} from '@/utils/common';
import Search from '@/views/credit/components/CreditSearchToolbar.vue';
import { exportCreditData } from '../utils/export';
import { getPageTitle } from '@/utils/common';
import CreditJudgmentDebtorEdit from './components/creditJudgmentDebtorEdit.vue';
import { pageCreditJudgmentDebtor, removeCreditJudgmentDebtor, removeBatchCreditJudgmentDebtor } from '@/api/credit/creditJudgmentDebtor';
import type { CreditJudgmentDebtor, CreditJudgmentDebtorParam } from '@/api/credit/creditJudgmentDebtor/model';
import CreditJudgmentDebtorImport from './components/credit-judgment-debtor-import.vue';
import {
pageCreditJudgmentDebtor,
listCreditJudgmentDebtor,
removeCreditJudgmentDebtor,
removeBatchCreditJudgmentDebtor
} from '@/api/credit/creditJudgmentDebtor';
import type {
CreditJudgmentDebtor,
CreditJudgmentDebtorParam
} from '@/api/credit/creditJudgmentDebtor/model';
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
@@ -73,37 +90,45 @@
const current = ref<CreditJudgmentDebtor | null>(null);
// 是否显示编辑弹窗
const showEdit = ref(false);
// 是否显示导入弹窗
const showImport = ref(false);
// 是否显示批量移动弹窗
const showMove = ref(false);
// 加载状态
const loading = ref(true);
// 搜索关键词
const searchText = ref('');
// 表格数据源
const datasource: DatasourceFunction = ({
page,
limit,
where,
where = {},
orders,
filters
}) => {
const params: CreditJudgmentDebtorParam = { ...where };
if (filters) {
where.status = filters.status;
(params as any).status = filters.status;
}
if (!params.keywords && searchText.value) {
params.keywords = searchText.value;
}
return pageCreditJudgmentDebtor({
...where,
...params,
...orders,
page,
limit
});
};
// 完整的列配置(包含所有字段)
// 关键信息列
const columns = ref<ColumnItem[]>([
{
title: 'ID',
dataIndex: 'id',
key: 'id',
width: 90,
width: 80
},
{
title: '案号',
@@ -147,66 +172,19 @@
key: 'dataStatus',
ellipsis: true
},
{
title: '备注',
dataIndex: 'comments',
key: 'comments',
ellipsis: true
},
{
title: '是否推荐',
dataIndex: 'recommend',
key: 'recommend',
width: 120
},
{
title: '排序(数字越小越靠前)',
dataIndex: 'sortNumber',
key: 'sortNumber',
width: 120
},
{
title: '状态, 0正常, 1冻结',
dataIndex: 'status',
key: 'status',
width: 120
},
{
title: '是否删除, 0否, 1是',
dataIndex: 'deleted',
key: 'deleted',
width: 120
},
{
title: '用户ID',
dataIndex: 'userId',
key: 'userId',
width: 120
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
width: 200,
width: 180,
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd HH:mm:ss')
},
{
title: '修改时间',
dataIndex: 'updateTime',
key: 'updateTime',
width: 200,
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd HH:mm:ss')
},
{
title: '操作',
key: 'action',
width: 180,
width: 160,
fixed: 'right',
align: 'center',
hideInSetting: true
@@ -215,8 +193,12 @@
/* 搜索 */
const reload = (where?: CreditJudgmentDebtorParam) => {
if (where && Object.prototype.hasOwnProperty.call(where, 'keywords')) {
searchText.value = where.keywords ?? '';
}
const targetWhere = where ?? { keywords: searchText.value || undefined };
selection.value = [];
tableRef?.value?.reload({ where: where });
tableRef?.value?.reload({ where: targetWhere });
};
/* 打开编辑弹窗 */
@@ -230,6 +212,40 @@
showMove.value = true;
};
/* 打开导入弹窗 */
const openImport = () => {
showImport.value = true;
};
/* 导出 */
const exportData = () => {
exportCreditData<CreditJudgmentDebtor>({
filename: '被执行人',
columns: [
{ title: 'ID', dataIndex: 'id' },
{ title: '案号', dataIndex: 'caseNumber' },
{ title: '被执行人名称', dataIndex: 'name' },
{ title: '证件号/组织机构代码', dataIndex: 'code' },
{ title: '立案日期', dataIndex: 'occurrenceTime' },
{ title: '执行标的(元)', dataIndex: 'amount' },
{ title: '法院', dataIndex: 'courtName' },
{ title: '数据状态', dataIndex: 'dataStatus' },
{
title: '创建时间',
dataIndex: 'createTime',
formatter: (record: CreditJudgmentDebtor) =>
record.createTime
? toDateString(record.createTime, 'yyyy-MM-dd HH:mm:ss')
: ''
}
],
fetchData: () =>
listCreditJudgmentDebtor({
keywords: searchText.value || undefined
})
});
};
/* 删除单个 */
const remove = (row: CreditJudgmentDebtor) => {
const hide = message.loading('请求中..', 0);

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 { importCreditJudicialDocument } from '@/api/credit/creditJudicialDocument';
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-judicial-document/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;
importCreditJudicialDocument(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

@@ -37,7 +37,7 @@
<a-input
allow-clear
placeholder="请输入被告/被上诉人"
v-model:value="form.defendant appellee"
v-model:value="form.appellee"
/>
</a-form-item>
<a-form-item label="其他当事人/第三人" name="otherPartiesThirdParty">
@@ -188,7 +188,7 @@
id: undefined,
dataType: undefined,
plaintiffAppellant: undefined,
defendant appellee: undefined,
appellee: undefined,
otherPartiesThirdParty: undefined,
occurrenceTime: undefined,
caseNumber: undefined,

View File

@@ -17,6 +17,8 @@
@add="openEdit"
@remove="removeBatch"
@batchMove="openMove"
@importData="openImport"
@exportData="exportData"
/>
</template>
<template #bodyCell="{ column, record }">
@@ -45,11 +47,16 @@
<!-- 编辑弹窗 -->
<CreditJudicialDocumentEdit v-model:visible="showEdit" :data="current" @done="reload" />
<!-- 导入弹窗 -->
<CreditJudicialDocumentImport
v-model:visible="showImport"
@done="reload"
/>
</a-page-header>
</template>
<script lang="ts" setup>
import { createVNode, ref, computed } from 'vue';
import { createVNode, ref } from 'vue';
import { message, Modal } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import type { EleProTable } from 'ele-admin-pro';
@@ -58,11 +65,21 @@
DatasourceFunction,
ColumnItem
} from 'ele-admin-pro/es/ele-pro-table/types';
import Search from './components/search.vue';
import {getPageTitle} from '@/utils/common';
import Search from '@/views/credit/components/CreditSearchToolbar.vue';
import { exportCreditData } from '../utils/export';
import { getPageTitle } from '@/utils/common';
import CreditJudicialDocumentEdit from './components/creditJudicialDocumentEdit.vue';
import { pageCreditJudicialDocument, removeCreditJudicialDocument, removeBatchCreditJudicialDocument } from '@/api/credit/creditJudicialDocument';
import type { CreditJudicialDocument, CreditJudicialDocumentParam } from '@/api/credit/creditJudicialDocument/model';
import CreditJudicialDocumentImport from './components/credit-judicial-document-import.vue';
import {
pageCreditJudicialDocument,
listCreditJudicialDocument,
removeCreditJudicialDocument,
removeBatchCreditJudicialDocument
} from '@/api/credit/creditJudicialDocument';
import type {
CreditJudicialDocument,
CreditJudicialDocumentParam
} from '@/api/credit/creditJudicialDocument/model';
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
@@ -73,37 +90,45 @@
const current = ref<CreditJudicialDocument | null>(null);
// 是否显示编辑弹窗
const showEdit = ref(false);
// 是否显示导入弹窗
const showImport = ref(false);
// 是否显示批量移动弹窗
const showMove = ref(false);
// 加载状态
const loading = ref(true);
// 搜索关键词
const searchText = ref('');
// 表格数据源
const datasource: DatasourceFunction = ({
page,
limit,
where,
where = {},
orders,
filters
}) => {
const params: CreditJudicialDocumentParam = { ...where };
if (filters) {
where.status = filters.status;
(params as any).status = filters.status;
}
if (!params.keywords && searchText.value) {
params.keywords = searchText.value;
}
return pageCreditJudicialDocument({
...where,
...params,
...orders,
page,
limit
});
};
// 完整的列配置(包含所有字段)
// 关键信息列
const columns = ref<ColumnItem[]>([
{
title: 'ID',
dataIndex: 'id',
key: 'id',
width: 90,
width: 80
},
{
title: '数据类型',
@@ -117,18 +142,6 @@
key: 'plaintiffAppellant',
ellipsis: true
},
{
title: '被告/被上诉人',
dataIndex: 'defendant appellee',
key: 'defendant appellee',
ellipsis: true
},
{
title: '其他当事人/第三人',
dataIndex: 'otherPartiesThirdParty',
key: 'otherPartiesThirdParty',
ellipsis: true
},
{
title: '发生时间',
dataIndex: 'occurrenceTime',
@@ -165,66 +178,19 @@
key: 'dataStatus',
ellipsis: true
},
{
title: '备注',
dataIndex: 'comments',
key: 'comments',
ellipsis: true
},
{
title: '是否推荐',
dataIndex: 'recommend',
key: 'recommend',
width: 120
},
{
title: '排序(数字越小越靠前)',
dataIndex: 'sortNumber',
key: 'sortNumber',
width: 120
},
{
title: '状态, 0正常, 1冻结',
dataIndex: 'status',
key: 'status',
width: 120
},
{
title: '是否删除, 0否, 1是',
dataIndex: 'deleted',
key: 'deleted',
width: 120
},
{
title: '用户ID',
dataIndex: 'userId',
key: 'userId',
width: 120
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
width: 200,
width: 180,
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd HH:mm:ss')
},
{
title: '修改时间',
dataIndex: 'updateTime',
key: 'updateTime',
width: 200,
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd HH:mm:ss')
},
{
title: '操作',
key: 'action',
width: 180,
width: 160,
fixed: 'right',
align: 'center',
hideInSetting: true
@@ -233,8 +199,12 @@
/* 搜索 */
const reload = (where?: CreditJudicialDocumentParam) => {
if (where && Object.prototype.hasOwnProperty.call(where, 'keywords')) {
searchText.value = where.keywords ?? '';
}
const targetWhere = where ?? { keywords: searchText.value || undefined };
selection.value = [];
tableRef?.value?.reload({ where: where });
tableRef?.value?.reload({ where: targetWhere });
};
/* 打开编辑弹窗 */
@@ -248,6 +218,41 @@
showMove.value = true;
};
/* 打开导入弹窗 */
const openImport = () => {
showImport.value = true;
};
/* 导出 */
const exportData = () => {
exportCreditData<CreditJudicialDocument>({
filename: '裁判文书',
columns: [
{ title: 'ID', dataIndex: 'id' },
{ title: '数据类型', dataIndex: 'dataType' },
{ title: '原告/上诉人', dataIndex: 'plaintiffAppellant' },
{ title: '发生时间', dataIndex: 'occurrenceTime' },
{ title: '案号', dataIndex: 'caseNumber' },
{ title: '案由', dataIndex: 'causeOfAction' },
{ title: '涉案金额', dataIndex: 'involvedAmount' },
{ title: '法院', dataIndex: 'courtName' },
{ title: '数据状态', dataIndex: 'dataStatus' },
{
title: '创建时间',
dataIndex: 'createTime',
formatter: (record: CreditJudicialDocument) =>
record.createTime
? toDateString(record.createTime, 'yyyy-MM-dd HH:mm:ss')
: ''
}
],
fetchData: () =>
listCreditJudicialDocument({
keywords: searchText.value || undefined
})
});
};
/* 删除单个 */
const remove = (row: CreditJudicialDocument) => {
const hide = message.loading('请求中..', 0);

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 { importCreditMediation } from '@/api/credit/creditMediation';
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-mediation/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;
importCreditMediation(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

@@ -37,7 +37,7 @@
<a-input
allow-clear
placeholder="请输入被告/被上诉人"
v-model:value="form.defendant appellee"
v-model:value="form.appellee"
/>
</a-form-item>
<a-form-item label="其他当事人/第三人" name="otherPartiesThirdParty">
@@ -188,7 +188,7 @@
id: undefined,
dataType: undefined,
plaintiffAppellant: undefined,
defendant appellee: undefined,
appellee: undefined,
otherPartiesThirdParty: undefined,
occurrenceTime: undefined,
caseNumber: undefined,

View File

@@ -17,6 +17,8 @@
@add="openEdit"
@remove="removeBatch"
@batchMove="openMove"
@importData="openImport"
@exportData="exportData"
/>
</template>
<template #bodyCell="{ column, record }">
@@ -45,11 +47,13 @@
<!-- 编辑弹窗 -->
<CreditMediationEdit v-model:visible="showEdit" :data="current" @done="reload" />
<!-- 导入弹窗 -->
<CreditMediationImport v-model:visible="showImport" @done="reload" />
</a-page-header>
</template>
<script lang="ts" setup>
import { createVNode, ref, computed } from 'vue';
import { createVNode, ref } from 'vue';
import { message, Modal } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import type { EleProTable } from 'ele-admin-pro';
@@ -58,11 +62,21 @@
DatasourceFunction,
ColumnItem
} from 'ele-admin-pro/es/ele-pro-table/types';
import Search from './components/search.vue';
import {getPageTitle} from '@/utils/common';
import Search from '@/views/credit/components/CreditSearchToolbar.vue';
import { exportCreditData } from '../utils/export';
import { getPageTitle } from '@/utils/common';
import CreditMediationEdit from './components/creditMediationEdit.vue';
import { pageCreditMediation, removeCreditMediation, removeBatchCreditMediation } from '@/api/credit/creditMediation';
import type { CreditMediation, CreditMediationParam } from '@/api/credit/creditMediation/model';
import CreditMediationImport from './components/credit-mediation-import.vue';
import {
pageCreditMediation,
listCreditMediation,
removeCreditMediation,
removeBatchCreditMediation
} from '@/api/credit/creditMediation';
import type {
CreditMediation,
CreditMediationParam
} from '@/api/credit/creditMediation/model';
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
@@ -73,37 +87,45 @@
const current = ref<CreditMediation | null>(null);
// 是否显示编辑弹窗
const showEdit = ref(false);
// 是否显示导入弹窗
const showImport = ref(false);
// 是否显示批量移动弹窗
const showMove = ref(false);
// 加载状态
const loading = ref(true);
// 搜索关键词
const searchText = ref('');
// 表格数据源
const datasource: DatasourceFunction = ({
page,
limit,
where,
where = {},
orders,
filters
}) => {
const params: CreditMediationParam = { ...where };
if (filters) {
where.status = filters.status;
(params as any).status = filters.status;
}
if (!params.keywords && searchText.value) {
params.keywords = searchText.value;
}
return pageCreditMediation({
...where,
...params,
...orders,
page,
limit
});
};
// 完整的列配置(包含所有字段)
// 关键信息列
const columns = ref<ColumnItem[]>([
{
title: 'ID',
dataIndex: 'id',
key: 'id',
width: 90,
width: 80
},
{
title: '数据类型',
@@ -117,18 +139,6 @@
key: 'plaintiffAppellant',
ellipsis: true
},
{
title: '被告/被上诉人',
dataIndex: 'defendant appellee',
key: 'defendant appellee',
ellipsis: true
},
{
title: '其他当事人/第三人',
dataIndex: 'otherPartiesThirdParty',
key: 'otherPartiesThirdParty',
ellipsis: true
},
{
title: '发生时间',
dataIndex: 'occurrenceTime',
@@ -165,66 +175,19 @@
key: 'dataStatus',
ellipsis: true
},
{
title: '备注',
dataIndex: 'comments',
key: 'comments',
ellipsis: true
},
{
title: '是否推荐',
dataIndex: 'recommend',
key: 'recommend',
width: 120
},
{
title: '排序(数字越小越靠前)',
dataIndex: 'sortNumber',
key: 'sortNumber',
width: 120
},
{
title: '状态, 0正常, 1冻结',
dataIndex: 'status',
key: 'status',
width: 120
},
{
title: '是否删除, 0否, 1是',
dataIndex: 'deleted',
key: 'deleted',
width: 120
},
{
title: '用户ID',
dataIndex: 'userId',
key: 'userId',
width: 120
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
width: 200,
width: 180,
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd HH:mm:ss')
},
{
title: '修改时间',
dataIndex: 'updateTime',
key: 'updateTime',
width: 200,
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd HH:mm:ss')
},
{
title: '操作',
key: 'action',
width: 180,
width: 160,
fixed: 'right',
align: 'center',
hideInSetting: true
@@ -233,8 +196,12 @@
/* 搜索 */
const reload = (where?: CreditMediationParam) => {
if (where && Object.prototype.hasOwnProperty.call(where, 'keywords')) {
searchText.value = where.keywords ?? '';
}
const targetWhere = where ?? { keywords: searchText.value || undefined };
selection.value = [];
tableRef?.value?.reload({ where: where });
tableRef?.value?.reload({ where: targetWhere });
};
/* 打开编辑弹窗 */
@@ -248,6 +215,41 @@
showMove.value = true;
};
/* 打开导入弹窗 */
const openImport = () => {
showImport.value = true;
};
/* 导出 */
const exportData = () => {
exportCreditData<CreditMediation>({
filename: '诉前调解',
columns: [
{ title: 'ID', dataIndex: 'id' },
{ title: '数据类型', dataIndex: 'dataType' },
{ title: '原告/上诉人', dataIndex: 'plaintiffAppellant' },
{ title: '发生时间', dataIndex: 'occurrenceTime' },
{ title: '案号', dataIndex: 'caseNumber' },
{ title: '案由', dataIndex: 'causeOfAction' },
{ title: '涉案金额', dataIndex: 'involvedAmount' },
{ title: '法院', dataIndex: 'courtName' },
{ title: '数据状态', dataIndex: 'dataStatus' },
{
title: '创建时间',
dataIndex: 'createTime',
formatter: (record: CreditMediation) =>
record.createTime
? toDateString(record.createTime, 'yyyy-MM-dd HH:mm:ss')
: ''
}
],
fetchData: () =>
listCreditMediation({
keywords: searchText.value || undefined
})
});
};
/* 删除单个 */
const remove = (row: CreditMediation) => {
const hide = message.loading('请求中..', 0);

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 { importCreditProject } from '@/api/credit/creditProject';
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-project/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;
importCreditProject(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

@@ -17,6 +17,8 @@
@add="openEdit"
@remove="removeBatch"
@batchMove="openMove"
@importData="openImport"
@exportData="exportData"
/>
</template>
<template #bodyCell="{ column, record }">
@@ -45,11 +47,13 @@
<!-- 编辑弹窗 -->
<CreditProjectEdit v-model:visible="showEdit" :data="current" @done="reload" />
<!-- 导入弹窗 -->
<CreditProjectImport v-model:visible="showImport" @done="reload" />
</a-page-header>
</template>
<script lang="ts" setup>
import { createVNode, ref, computed } from 'vue';
import { createVNode, ref } from 'vue';
import { message, Modal } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import type { EleProTable } from 'ele-admin-pro';
@@ -58,11 +62,21 @@
DatasourceFunction,
ColumnItem
} from 'ele-admin-pro/es/ele-pro-table/types';
import Search from './components/search.vue';
import {getPageTitle} from '@/utils/common';
import Search from '@/views/credit/components/CreditSearchToolbar.vue';
import { exportCreditData } from '../utils/export';
import { getPageTitle } from '@/utils/common';
import CreditProjectEdit from './components/creditProjectEdit.vue';
import { pageCreditProject, removeCreditProject, removeBatchCreditProject } from '@/api/credit/creditProject';
import type { CreditProject, CreditProjectParam } from '@/api/credit/creditProject/model';
import CreditProjectImport from './components/credit-project-import.vue';
import {
pageCreditProject,
listCreditProject,
removeCreditProject,
removeBatchCreditProject
} from '@/api/credit/creditProject';
import type {
CreditProject,
CreditProjectParam
} from '@/api/credit/creditProject/model';
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
@@ -73,37 +87,45 @@
const current = ref<CreditProject | null>(null);
// 是否显示编辑弹窗
const showEdit = ref(false);
// 是否显示导入弹窗
const showImport = ref(false);
// 是否显示批量移动弹窗
const showMove = ref(false);
// 加载状态
const loading = ref(true);
// 搜索关键词
const searchText = ref('');
// 表格数据源
const datasource: DatasourceFunction = ({
page,
limit,
where,
where = {},
orders,
filters
}) => {
const params: CreditProjectParam = { ...where };
if (filters) {
where.status = filters.status;
(params as any).status = filters.status;
}
if (!params.keywords && searchText.value) {
params.keywords = searchText.value;
}
return pageCreditProject({
...where,
...params,
...orders,
page,
limit
});
};
// 完整的列配置(包含所有字段)
// 关键信息列
const columns = ref<ColumnItem[]>([
{
title: 'ID',
dataIndex: 'id',
key: 'id',
width: 90,
width: 80
},
{
title: '项目名称',
@@ -111,18 +133,6 @@
key: 'name',
ellipsis: true
},
{
title: '唯一标识',
dataIndex: 'code',
key: 'code',
ellipsis: true
},
{
title: '类型, 0普通用户, 1招投标',
dataIndex: 'type',
key: 'type',
width: 120
},
{
title: '企业角色',
dataIndex: 'role',
@@ -153,24 +163,6 @@
key: 'province',
ellipsis: true
},
{
title: '所在城市',
dataIndex: 'city',
key: 'city',
ellipsis: true
},
{
title: '所在辖区',
dataIndex: 'region',
key: 'region',
ellipsis: true
},
{
title: '街道地址',
dataIndex: 'address',
key: 'address',
ellipsis: true
},
{
title: '招采单位名称',
dataIndex: 'procurementName',
@@ -195,55 +187,12 @@
key: 'releaseDate',
ellipsis: true
},
{
title: '备注',
dataIndex: 'comments',
key: 'comments',
ellipsis: true
},
{
title: '是否推荐',
dataIndex: 'recommend',
key: 'recommend',
width: 120
},
{
title: '到期时间',
dataIndex: 'expirationTime',
key: 'expirationTime',
width: 120
},
{
title: '排序(数字越小越靠前)',
dataIndex: 'sortNumber',
key: 'sortNumber',
width: 120
},
{
title: '状态, 0正常, 1冻结',
dataIndex: 'status',
key: 'status',
width: 120
},
{
title: '是否删除, 0否, 1是',
dataIndex: 'deleted',
key: 'deleted',
width: 120
},
{
title: '用户ID',
dataIndex: 'userId',
key: 'userId',
width: 120
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
width: 200,
width: 180,
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd HH:mm:ss')
},
@@ -260,7 +209,7 @@
{
title: '操作',
key: 'action',
width: 180,
width: 160,
fixed: 'right',
align: 'center',
hideInSetting: true
@@ -269,8 +218,12 @@
/* 搜索 */
const reload = (where?: CreditProjectParam) => {
if (where && Object.prototype.hasOwnProperty.call(where, 'keywords')) {
searchText.value = where.keywords ?? '';
}
const targetWhere = where ?? { keywords: searchText.value || undefined };
selection.value = [];
tableRef?.value?.reload({ where: where });
tableRef?.value?.reload({ where: targetWhere });
};
/* 打开编辑弹窗 */
@@ -284,6 +237,41 @@
showMove.value = true;
};
/* 打开导入弹窗 */
const openImport = () => {
showImport.value = true;
};
/* 导出 */
const exportData = () => {
exportCreditData<CreditProject>({
filename: '招投标',
columns: [
{ title: 'ID', dataIndex: 'id' },
{ title: '项目名称', dataIndex: 'name' },
{ title: '企业角色', dataIndex: 'role' },
{ title: '信息类型', dataIndex: 'infoType' },
{ title: '省份地区', dataIndex: 'province' },
{ title: '招采单位', dataIndex: 'procurementName' },
{ title: '中标单位', dataIndex: 'winningName' },
{ title: '中标金额', dataIndex: 'winningPrice' },
{ title: '发布日期', dataIndex: 'releaseDate' },
{
title: '创建时间',
dataIndex: 'createTime',
formatter: (record: CreditProject) =>
record.createTime
? toDateString(record.createTime, 'yyyy-MM-dd HH:mm:ss')
: ''
}
],
fetchData: () =>
listCreditProject({
keywords: searchText.value || undefined
})
});
};
/* 删除单个 */
const remove = (row: CreditProject) => {
const hide = message.loading('请求中..', 0);

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 { importCreditRiskRelation } from '@/api/credit/creditRiskRelation';
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-risk-relation/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;
importCreditRiskRelation(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

@@ -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 { importCreditSupplier } from '@/api/credit/creditSupplier';
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-supplier/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;
importCreditSupplier(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

@@ -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 { importCreditXgxf } from '@/api/credit/creditXgxf';
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-xgxf/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;
importCreditXgxf(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

@@ -37,7 +37,7 @@
<a-input
allow-clear
placeholder="请输入被告/被上诉人"
v-model:value="form.defendant appellee"
v-model:value="form.appellee"
/>
</a-form-item>
<a-form-item label="其他当事人/第三人" name="otherPartiesThirdParty">
@@ -188,7 +188,7 @@
id: undefined,
dataType: undefined,
plaintiffAppellant: undefined,
defendant appellee: undefined,
appellee: undefined,
otherPartiesThirdParty: undefined,
occurrenceTime: undefined,
caseNumber: undefined,

View File

@@ -17,6 +17,8 @@
@add="openEdit"
@remove="removeBatch"
@batchMove="openMove"
@importData="openImport"
@exportData="exportData"
/>
</template>
<template #bodyCell="{ column, record }">
@@ -45,11 +47,13 @@
<!-- 编辑弹窗 -->
<CreditXgxfEdit v-model:visible="showEdit" :data="current" @done="reload" />
<!-- 导入弹窗 -->
<CreditXgxfImport v-model:visible="showImport" @done="reload" />
</a-page-header>
</template>
<script lang="ts" setup>
import { createVNode, ref, computed } from 'vue';
import { createVNode, ref } from 'vue';
import { message, Modal } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import type { EleProTable } from 'ele-admin-pro';
@@ -58,11 +62,21 @@
DatasourceFunction,
ColumnItem
} from 'ele-admin-pro/es/ele-pro-table/types';
import Search from './components/search.vue';
import {getPageTitle} from '@/utils/common';
import Search from '@/views/credit/components/CreditSearchToolbar.vue';
import { exportCreditData } from '../utils/export';
import { getPageTitle } from '@/utils/common';
import CreditXgxfEdit from './components/creditXgxfEdit.vue';
import { pageCreditXgxf, removeCreditXgxf, removeBatchCreditXgxf } from '@/api/credit/creditXgxf';
import type { CreditXgxf, CreditXgxfParam } from '@/api/credit/creditXgxf/model';
import CreditXgxfImport from './components/credit-xgxf-import.vue';
import {
pageCreditXgxf,
listCreditXgxf,
removeCreditXgxf,
removeBatchCreditXgxf
} from '@/api/credit/creditXgxf';
import type {
CreditXgxf,
CreditXgxfParam
} from '@/api/credit/creditXgxf/model';
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
@@ -73,37 +87,45 @@
const current = ref<CreditXgxf | null>(null);
// 是否显示编辑弹窗
const showEdit = ref(false);
// 是否显示导入弹窗
const showImport = ref(false);
// 是否显示批量移动弹窗
const showMove = ref(false);
// 加载状态
const loading = ref(true);
// 搜索关键词
const searchText = ref('');
// 表格数据源
const datasource: DatasourceFunction = ({
page,
limit,
where,
where = {},
orders,
filters
}) => {
const params: CreditXgxfParam = { ...where };
if (filters) {
where.status = filters.status;
(params as any).status = filters.status;
}
if (!params.keywords && searchText.value) {
params.keywords = searchText.value;
}
return pageCreditXgxf({
...where,
...params,
...orders,
page,
limit
});
};
// 完整的列配置(包含所有字段)
// 关键信息列
const columns = ref<ColumnItem[]>([
{
title: 'ID',
dataIndex: 'id',
key: 'id',
width: 90,
width: 80
},
{
title: '数据类型',
@@ -117,18 +139,6 @@
key: 'plaintiffAppellant',
ellipsis: true
},
{
title: '被告/被上诉人',
dataIndex: 'defendant appellee',
key: 'defendant appellee',
ellipsis: true
},
{
title: '其他当事人/第三人',
dataIndex: 'otherPartiesThirdParty',
key: 'otherPartiesThirdParty',
ellipsis: true
},
{
title: '发生时间',
dataIndex: 'occurrenceTime',
@@ -165,66 +175,19 @@
key: 'dataStatus',
ellipsis: true
},
{
title: '备注',
dataIndex: 'comments',
key: 'comments',
ellipsis: true
},
{
title: '是否推荐',
dataIndex: 'recommend',
key: 'recommend',
width: 120
},
{
title: '排序(数字越小越靠前)',
dataIndex: 'sortNumber',
key: 'sortNumber',
width: 120
},
{
title: '状态, 0正常, 1冻结',
dataIndex: 'status',
key: 'status',
width: 120
},
{
title: '是否删除, 0否, 1是',
dataIndex: 'deleted',
key: 'deleted',
width: 120
},
{
title: '用户ID',
dataIndex: 'userId',
key: 'userId',
width: 120
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
width: 200,
width: 180,
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd HH:mm:ss')
},
{
title: '修改时间',
dataIndex: 'updateTime',
key: 'updateTime',
width: 200,
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd HH:mm:ss')
},
{
title: '操作',
key: 'action',
width: 180,
width: 160,
fixed: 'right',
align: 'center',
hideInSetting: true
@@ -233,8 +196,12 @@
/* 搜索 */
const reload = (where?: CreditXgxfParam) => {
if (where && Object.prototype.hasOwnProperty.call(where, 'keywords')) {
searchText.value = where.keywords ?? '';
}
const targetWhere = where ?? { keywords: searchText.value || undefined };
selection.value = [];
tableRef?.value?.reload({ where: where });
tableRef?.value?.reload({ where: targetWhere });
};
/* 打开编辑弹窗 */
@@ -248,6 +215,41 @@
showMove.value = true;
};
/* 打开导入弹窗 */
const openImport = () => {
showImport.value = true;
};
/* 导出 */
const exportData = () => {
exportCreditData<CreditXgxf>({
filename: '限制高消费',
columns: [
{ title: 'ID', dataIndex: 'id' },
{ title: '数据类型', dataIndex: 'dataType' },
{ title: '原告/上诉人', dataIndex: 'plaintiffAppellant' },
{ title: '发生时间', dataIndex: 'occurrenceTime' },
{ title: '案号', dataIndex: 'caseNumber' },
{ title: '案由', dataIndex: 'causeOfAction' },
{ title: '涉案金额', dataIndex: 'involvedAmount' },
{ title: '法院', dataIndex: 'courtName' },
{ title: '数据状态', dataIndex: 'dataStatus' },
{
title: '创建时间',
dataIndex: 'createTime',
formatter: (record: CreditXgxf) =>
record.createTime
? toDateString(record.createTime, 'yyyy-MM-dd HH:mm:ss')
: ''
}
],
fetchData: () =>
listCreditXgxf({
keywords: searchText.value || undefined
})
});
};
/* 删除单个 */
const remove = (row: CreditXgxf) => {
const hide = message.loading('请求中..', 0);