Commit a717b181 authored by 沈翠玲's avatar 沈翠玲

资产导入对接接口

parent bf422b1d
......@@ -23,6 +23,9 @@ VITE_GLOB_API_URL =
# 接口前缀
VITE_GLOB_API_URL_PREFIX = /api
# websocket地址
VITE_APP_SOCKET_URL = ws://192.168.31.128:8080
# 文件上传地址
VITE_GLOB_UPLOAD_URL=
......
......@@ -13,6 +13,9 @@ VITE_GLOB_API_URL =
# 接口前缀
VITE_GLOB_API_URL_PREFIX = /api
# websocket地址
VITE_APP_SOCKET_URL = ws://8.152.205.9:8080
# 图片上传地址
VITE_GLOB_UPLOAD_URL=
......
......@@ -62,7 +62,8 @@
"vue": "^3.5.12",
"vue-router": "^4.5.0",
"vxe-pc-ui": "^4.3.27",
"vxe-table": "^4.9.23"
"vxe-table": "^4.9.23",
"ws": "^8.18.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.1.4",
......
import request from '@/utils/http/index';
// 获取未分配的资产统计
export const getLoanDistribute = (params) => {
return request.get('/LoanDistribute/totalLoan', params);
};
......@@ -7,3 +7,7 @@ export const LoanSubmit = (params) => {
export const importLoanPage = (params) => {
return request.get('/importLoan/page', params);
};
// 校验
export const checkLoanExcel = (params) => {
return request.get('/LoanExcel/check', params);
};
......@@ -71,6 +71,9 @@
dataCallback: {
type: Function,
},
paramCallback: {
type: Function,
},
requestError: {
type: Function,
},
......@@ -102,7 +105,8 @@
props.initParam,
props.showPagination,
props.dataCallback,
props.requestError
props.requestError,
props.paramCallback
);
// 显示搜索
......
import { reactive, toRefs, computed } from 'vue';
export function useProTable(api, initParam = {}, isPageable, dataCallBack, requestError) {
export function useProTable(
api,
initParam = {},
isPageable,
dataCallBack,
requestError,
paramCallback
) {
const state = reactive({
loading: false,
// 表格数据
......@@ -62,7 +69,9 @@ export function useProTable(api, initParam = {}, isPageable, dataCallBack, reque
state.loading = true;
// 先把初始化参数和分页参数放到总参数里面
Object.assign(state.totalParam, initParam, isPageable ? pageParam.value : {});
let { result } = await api({ ...state.searchInitParam, ...state.totalParam });
let param = { ...state.searchInitParam, ...state.totalParam };
paramCallback && (param = paramCallback(param));
let { result } = await api(param);
dataCallBack && (result = dataCallBack(result));
state.tableData = isPageable ? result.content : result;
......
......@@ -93,7 +93,7 @@ export function setupVxeTabele(app) {
},
},
grid: {
size: 'small'
size: 'small',
},
});
lazyVxeUI(app);
......
import { defineStore } from 'pinia';
import piniaPersistConfig from '@/stores/helper/persist';
import { logout } from '@/api/auth';
import useSocketStore from './websocket';
export const useUserStore = defineStore({
id: 'admin-user',
state: () => ({
......@@ -39,6 +39,8 @@ export const useUserStore = defineStore({
},
async logout() {
await logout();
const socketStore = useSocketStore();
socketStore.closeWs();
this.token = '';
this.userInfo = null;
this.isTenant = false;
......
import { defineStore } from 'pinia';
// import WebSocket from 'ws';
const useSocketStore = defineStore('socket', {
state: () => ({
ws: undefined,
heartTimeOut: 40000, //监测心跳时间 40秒
//this.isReConnection = false
lockReconnect: false, //避免重连
timerReconnect: undefined,
timerHeart: undefined,
timerServerHeart: undefined,
handClose: false,
msg: '',
}),
actions: {
connection(url, token) {
if ('WebSocket' in window) {
this.createWebSocket(url, token);
} else {
console.log('您的浏览器不支持websocket通信');
}
},
//初始化
createWebSocket(url, token) {
try {
this.ws = new WebSocket(url, token); //
this.initWebsocket();
} catch (e) {
console.log('catch eeeee=', e);
this.reConnection();
}
},
initWebsocket() {
//建立连接
this.ws.onopen = (e) => {
//webSocket业务订阅——可以有多个业务
this.ws.send('hello server');
console.log('连接成功');
//连接成功后,需要开启监测心跳
this.heartCheck();
};
this.ws.onmessage = (messages) => {
console.log(messages.data);
let msg = messages.data;
if (msg.includes('{')) {
msg = JSON.parse(msg);
}
this.msg = msg;
//接收到消息后,需要开启监测心跳
this.heartCheck();
};
this.ws.onerror = (e) => {
//连不上时onerror 和 onclose 监听同时会捕捉到
console.log('连接失败');
// 连失败需要重连
this.reConnection();
};
this.ws.onclose = (e) => {
console.log('关闭连接');
//是否正常关闭 正常关闭不需要重连, 否则需要重连
if (!this.handClose) {
this.reConnection();
}
};
},
clearTimer() {
this.timerReconnect && clearTimeout(this.timerReconnect);
this.timerHeart && clearTimeout(this.timerHeart);
this.timerServerHeart && clearTimeout(this.timerServerHeart);
},
//重连
reConnection() {
console.log('重新连接');
if (this.lockReconnect) {
return;
}
this.lockReconnect = true;
if (this.timerReconnect) {
clearTimeout(this.timerReconnect);
}
//没连上会一直重连, 设置迟延,避免请求过多
this.timerReconnect = setTimeout(() => {
//setTimeout 到点了执行
this.connection();
this.lockReconnect = false;
}, 5000);
},
//心跳
heartCheck() {
console.log('监测心跳');
if (this.timerHeart) {
clearTimeout(this.timerHeart);
}
// if(this.timerServerHeart){
// clearTimeout(this.timerServerHeart)
// }
this.timerHeart = setTimeout(() => {
console.log('PING');
this.ws.send('PING');
// this.timerServerHeart = setTimeout(() => {
// // 断了
// this.ws.close()
// }, 5000);
this.lockReconnect = false;
}, this.heartTimeOut); //40秒
},
//发送消息
sendMsg(data) {
console.log('发送消息');
if (this.ws.readyState === WebSocket.OPEN) {
this.ws.send(JSON.stringify(data));
}
},
//关闭连接 手动关闭
closeWs() {
console.log('手动关闭ws');
this.handClose = true;
this.clearTimer();
this.ws.close();
},
},
});
export default useSocketStore;
......@@ -25,6 +25,7 @@ export function getAppEnvConfig() {
VITE_GLOB_API_URL,
VITE_GLOB_APP_SHORT_NAME,
VITE_GLOB_API_URL_PREFIX,
VITE_APP_SOCKET_URL,
VITE_GLOB_UPLOAD_URL,
VITE_GLOB_FILE_URL,
VITE_USE_MOCK,
......@@ -42,6 +43,7 @@ export function getAppEnvConfig() {
VITE_GLOB_API_URL,
VITE_GLOB_APP_SHORT_NAME,
VITE_GLOB_API_URL_PREFIX,
VITE_APP_SOCKET_URL,
VITE_GLOB_UPLOAD_URL,
VITE_GLOB_FILE_URL,
VITE_USE_MOCK,
......
......@@ -67,13 +67,16 @@
import { useRoute, useRouter } from 'vue-router';
import { initDynamicRouter } from '@/router/modules/dynamicRouter';
import { useUserStore } from '@/stores/modules/user';
import useSocketStore from '@/stores/modules/websocket';
import { useTabsStore } from '@/stores/modules/tabs';
import { useKeepAliveStore } from '@/stores/modules/keepAlive';
import { HOME_URL } from '@/config';
import { login, getToken, getUserInfo } from '@/api/auth';
import TenantModal from '@/components/TenantModal/index.vue';
import { getAppEnvConfig } from '@/utils/env';
const envs = getAppEnvConfig();
const userStore = useUserStore();
const socketStore = useSocketStore();
const tabsStore = useTabsStore();
const keepAliveStore = useKeepAliveStore();
const tenantRef = ref();
......@@ -143,6 +146,9 @@
const { result: userInfo } = await getUserInfo();
userStore.setUserInfo(userInfo);
let url = `${envs.VITE_APP_SOCKET_URL}/websocket/${userInfo.id}`;
console.log('url', url, userInfo);
socketStore.connection(url, result);
// 如果有多个租户,需要选择租户进入系统
if (userInfo.tenants.length > 1) {
tenantRef.value.openModal();
......
<template>
<div class="table-box">
<span class="text"> 稽核管理 🍓🍇🍈🍉</span>
<div>
<ProTable :config="config" :data="data" ref="caseLRef">
<!-- 表格 header 按钮 -->
<template #left_buttons>
<el-button
type="primary"
@click="audit"
:disabled="!selectdList || selectdList.length === 0"
>发起稽核</el-button
>
</template>
</ProTable>
</div>
<callDrawer ref="callDrawerRef" @success="query()"></callDrawer>
<el-image-viewer :url-list="srcList" v-if="RefImage" @close="RefImage = false" />
</div>
</template>
<script setup name="systemLog"></script>
<script setup name="case-audit" lang="jsx">
import { Picture, Download } from '@element-plus/icons-vue';
import { inject } from 'vue';
import { ElButton } from 'element-plus';
import { onMounted } from 'vue';
import { getAppEnvConfig } from '@/utils/env';
const envs = getAppEnvConfig();
import { reactive, ref } from 'vue';
const downloadfile = inject('download');
const allocationModalRef = ref();
const caseLRef = ref();
const selectdList = ref([]);
const callDrawerRef = ref();
const srcList = ref([]);
const RefImage = ref(false);
const onCheckboxChange = (row) => {
selectdList.value = row.records;
};
const followStatusOpt = [
{ label: '接通后挂断', value: 'hang_up' },
{ label: '接通有实质进展', value: 'progress' },
{ label: '接通有效转告', value: 'pass_on' },
{ label: '接通拒绝转告', value: 'no_pass' },
{ label: '接听后挂断', value: 'Hang_up_after_answering' },
{ label: '接通无应答', value: 'No_response_when_connected' },
{ label: '称与债人无关', value: 'Claims_unrelated_to_creditors' },
{ label: '称非本人', value: 'Claiming_not_to_be_myself' },
{ label: '无人接听', value: 'no_answer' },
{ label: '关机', value: 'Shutdown' },
{ label: '空号', value: 'dead_number' },
{ label: '占线/忙音/正在通话中', value: 'Busy' },
{ label: '停机', value: 'closing_down' },
{ label: '机器人回复', value: 'Robot_reply' },
{ label: '微信', value: 'WeChat' },
{ label: '短信', value: 'short_message' },
{ label: 'QQ', value: 'QQ' },
{ label: '飞书', value: 'fly' },
{ label: '钉钉', value: 'DING' },
];
const phoneResultStatusOpt = [
{ label: '后续再跟进', value: 'later' },
{ label: '承诺还款', value: 'Promise_Repayment' },
{ label: '暂无还款意愿', value: 'No_Repay' },
{ label: '要求停催', value: 'Stop_Urging' },
{ label: '情绪激动抗拒', value: 'resistance' },
{ label: '拒绝还款', value: 'Refuse_Repayment' },
{ label: '已还款', value: 'Repaired' },
{ label: '代履行还款', value: 'repayment_others' },
];
const callTelephone = (row) => {
callDrawerRef.value.openModal(JSON.parse(JSON.stringify(row)));
};
const config = reactive({
columns: [
{ type: 'checkbox', title: '', width: 40 },
{ field: 'id', title: '跟进记录ID', width: 90 },
{
field: 'caseId',
title: '案件ID',
width: 80,
search: { el: 'input', props: { clearable: true } },
},
{
field: 'trackTime',
title: '跟进日期',
width: 100,
search: {
el: 'date-picker',
props: { type: 'datetime', valueFormat: 'YYYY-MM-DD HH:mm:ss' },
},
},
{
field: 'nextTime',
title: '下次跟进时间',
width: 110,
search: {
el: 'date-picker',
props: { type: 'datetime', valueFormat: 'YYYY-MM-DD HH:mm:ss' },
},
},
{
field: 'guarantor.name',
title: '联系人姓名',
width: 110,
search: { el: 'input', props: { clearable: true }, key: 'guarantorName' },
},
{
field: 'guarantor.phone',
title: '联系人号码',
width: 110,
search: { el: 'input', props: { clearable: true }, key: 'guarantorPhone' },
},
{
field: 'followStatus',
title: '拨打跟进结果',
width: 120,
enum: followStatusOpt,
search: { el: 'select', props: { filterable: true }, span: 1 },
fieldNames: { label: 'label', value: 'value' },
slots: {
default: ({ row }) => {
return (
<>
{row.followStatus
? followStatusOpt.find((v) => v.value === row.followStatus).label
: ''}
</>
);
},
},
},
{
field: 'phoneResultStatus',
title: '拨打处置状态',
width: 120,
enum: phoneResultStatusOpt,
search: { el: 'select', props: { filterable: true }, span: 1 },
fieldNames: { label: 'label', value: 'value' },
slots: {
default: ({ row }) => {
return (
<>
{row.phoneResultStatus
? phoneResultStatusOpt.find((v) => v.value === row.phoneResultStatus).label
: ''}
</>
);
},
},
},
{
field: 'phoneResultStatus',
title: '稽核状态',
width: 80,
enum: phoneResultStatusOpt,
search: { el: 'select', props: { filterable: true }, span: 1 },
fieldNames: { label: 'label', value: 'value' },
slots: {
default: ({ row }) => {
return (
<>
{row.phoneResultStatus
? phoneResultStatusOpt.find((v) => v.value === row.phoneResultStatus).label
: ''}
</>
);
},
},
},
{
field: 'remark',
title: '备注',
width: 80,
search: { el: 'input', props: { clearable: true } },
},
{
field: 'voices',
title: '通话录音',
width: 80,
slots: {
default: ({ row, rowIndex }) => {
if (row.voices && row.voices.length > 0) {
return (
<>
{row.voices.map((item, index) => (
<el-icon>
<Download onClick={() => download(item)} />
</el-icon>
))}
</>
);
}
},
},
},
{
field: 'code',
title: '微信图片附件',
width: 80,
slots: {
default: ({ row, rowIndex }) => {
if (row.images && row.images.length > 0) {
return (
<>
<el-icon>
<Picture onClick={() => preview(row, 'images')} />
</el-icon>
</>
);
}
},
},
},
{
field: 'code',
title: '短信图片附件',
width: 80,
slots: {
default: ({ row, rowIndex }) => {
if (row.notes && row.notes.length > 0) {
return (
<>
<el-icon>
<Picture onClick={() => preview(row, 'notes')} />
</el-icon>
</>
);
}
},
},
},
{
field: 'code',
title: '其他图片附件',
width: 80,
slots: {
default: ({ row, rowIndex }) => {
if (row.others && row.others.length > 0) {
return (
<>
<el-icon>
<Picture onClick={() => preview(row, 'others')} />
</el-icon>
</>
);
}
},
},
},
{
field: 'code',
title: '操作',
width: 80,
slots: {
default: ({ row, rowIndex }) => {
if (row.others && row.others.length > 0) {
return (
<>
<ElButton type="primary" onClick={() => callTelephone(row)}>
处理
</ElButton>
</>
);
}
},
},
},
],
onCheckboxChange: onCheckboxChange,
});
const preview = (item, type) => {
const list = [];
item[type].forEach((v) => {
list.push(envs.VITE_GLOB_API_URL_PREFIX + '/sys/static/' + v);
});
RefImage.value = true;
srcList.value = list;
};
const download = (item) => {
const name = item.slice(item.lastIndexOf('/') + 1, item.length);
downloadfile(envs.VITE_GLOB_API_URL_PREFIX + '/sys/static/' + item, {}, name);
};
const audit = (row) => {
if (
!caseLRef.value.element.getCheckboxRecords() ||
caseLRef.value.element.getCheckboxRecords().length === 0
)
return;
console.log('111', caseLRef.value.element.getCheckboxRecords());
allocationModalRef.value.openModal(JSON.parse(JSON.stringify(row)));
};
const query = () => caseLRef.value?.search();
onMounted(() => {
query();
});
const data = [
{ name: 'admin', code: 'admin', role: 'superadmin' },
{ name: 'account1', code: 'account1', role: 'user' },
{ name: 'account2', code: 'account2', role: 'user' },
{ name: 'account3', code: 'account3', role: 'user' },
{ name: 'account3', code: 'account3', role: 'user' },
{ name: 'account3', code: 'account3', role: 'user' },
{ name: 'account3', code: 'account3', role: 'user' },
{ name: 'account3', code: 'account3', role: 'user' },
{ name: 'account3', code: 'account3', role: 'user' },
{ name: 'account3', code: 'account3', role: 'user' },
];
</script>
<template>
<div class="table-box">
<div>
<ProTable :config="config" :data="data" ref="caseLRef">
<ProTable
:config="config"
ref="caseLRef"
:api="getLoanDistribute"
:paramCallback="paramCallback"
>
<template #table_top>
<div class="flex">
<div>未分配案件数:<span class="text-blue-500 mr-1">1000</span></div>
<div>未分配CPE数:<span class="text-blue-500 mr-1">1000</span></div>
<div>未分配总金额数:<span class="text-blue-500 mr-1">1000</span></div>
<div class="mr-2"
>未分配案件数:<span class="text-blue-500 mr-1">{{ statisis.unCaseNum }}</span
></div
>
<div class="mr-2"
>未分配CPE数:<span class="text-blue-500 mr-1">{{ statisis.unCustomerNum }}</span
></div
>
<div class="mr-2"
>未分配总金额数:<span class="text-blue-500 mr-1">{{ statisis.unAmount }}</span
></div
>
</div>
</template>
<!-- 表格 header 按钮 -->
<template #left_buttons>
<el-button type="primary" @click="allocation">分配 </el-button>
<el-button type="primary">撤回 </el-button>
<el-button type="primary">撤案 </el-button>
<el-button
type="primary"
@click="allocation"
:disabled="!selectdList || selectdList.length < 1"
>分配
</el-button>
<el-button type="primary" :disabled="!selectdList || selectdList.length < 1"
>撤回
</el-button>
<el-button type="primary" :disabled="!selectdList || selectdList.length < 1"
>撤案
</el-button>
</template>
</ProTable>
</div>
......@@ -23,14 +46,28 @@
<script setup name="case-allocation">
import allocationModal from './components/allocationModal.vue';
import { getLoanDistribute } from '@/api/allcation';
import { reactive, ref } from 'vue';
import { onMounted } from 'vue';
const allocationModalRef = ref();
const caseLRef = ref();
const selectdList = ref([]);
const onCheckboxChange = (row) => {
selectdList.value = row.records;
};
const statisis = ref({});
const getStatisis = (params) => {
getLoanDistribute(params).then((res) => {
if (res.success) {
statisis.value = res.result;
}
});
};
const paramCallback = (param) => {
const obj = JSON.parse(JSON.stringify(param));
getStatisis();
return obj;
};
const config = reactive({
columns: [
{ type: 'checkbox', title: '', width: '40px' },
......@@ -117,24 +154,11 @@
});
const allocation = (row) => {
if (
!caseLRef.value.element.getCheckboxRecords() ||
caseLRef.value.element.getCheckboxRecords().length === 0
)
return;
console.log('111', caseLRef.value.element.getCheckboxRecords());
allocationModalRef.value.openModal(JSON.parse(JSON.stringify(row)));
};
const data = [
{ name: 'admin', code: 'admin', role: 'superadmin' },
{ name: 'account1', code: 'account1', role: 'user' },
{ name: 'account2', code: 'account2', role: 'user' },
{ name: 'account3', code: 'account3', role: 'user' },
{ name: 'account3', code: 'account3', role: 'user' },
{ name: 'account3', code: 'account3', role: 'user' },
{ name: 'account3', code: 'account3', role: 'user' },
{ name: 'account3', code: 'account3', role: 'user' },
{ name: 'account3', code: 'account3', role: 'user' },
{ name: 'account3', code: 'account3', role: 'user' },
];
const query = () => caseLRef.value?.search();
onMounted(() => {
query();
});
</script>
......@@ -231,15 +231,6 @@
onCellClick: onCellClick,
});
const allocation = (row) => {
if (
!caseLRef.value.element.getCheckboxRecords() ||
caseLRef.value.element.getCheckboxRecords().length === 0
)
return;
console.log('111', caseLRef.value.element.getCheckboxRecords());
caseModalRef.value.openModal(JSON.parse(JSON.stringify(row)));
};
const query = () => caseLRef.value?.search();
onMounted(() => {
......
<template>
<vxe-modal
v-model="showModal"
title="检查结果"
@hide="onHide"
height="582"
width="1003"
show-footer
esc-closable
>
<vxe-button @click="exportEvent">直接导出 CSV 文件</vxe-button>
<ProTable
:config="config"
ref="ProTableRef"
:data="table"
:showPagination="false"
:showToolBar="false"
>
</ProTable>
<template #footer> </template>
</vxe-modal>
</template>
<script setup>
import { computed } from 'vue';
import { reactive, ref } from 'vue';
const showModal = ref(false);
const table = ref(undefined);
const ProTableRef = ref();
const config = reactive({
exportConfig: {},
toolbarConfig: { enabled: false },
columns: [
{ field: 'row', title: '行' },
{
field: 'value',
title: '错误值',
},
{
field: 'message',
title: '错误描述',
},
],
});
const exportEvent = () => {
if (ProTableRef.value && ProTableRef.value.element) {
ProTableRef.value.element.exportData({
type: 'csv',
});
}
};
const onHide = () => {
table.value = null;
};
const openModal = (account) => {
showModal.value = true;
table.value = account;
Object.assign(form, account);
};
defineExpose({
openModal,
});
</script>
<style lang="scss" scoped></style>
......@@ -30,12 +30,20 @@
<div class="mb-1">2、检查数据</div>
<div>
<div class="flex items-center">
<el-button type="danger" @click="checkData">检查</el-button>
<span class="ml-2"> 通过 </span>
<el-button type="danger" @click="checkData" :disabled="!form.path">检查</el-button>
<span class="ml-2" v-if="checkObj.check">
<span class="mr-2 text-gray-400">通过{{ checkObj.result.success }}</span>
<span class="text-gray-400">失败{{ checkObj.result.error }}</span>
</span>
</div>
<!-- 进度条 -->
<el-progress v-if="progressFlag" :percentage="loadProgress" />
<div class="mt-2 text-sm text-blue-500 underline cursor-pointer">下载检查结果</div>
<!-- <el-progress v-if="progressFlag" :percentage="loadProgress" /> -->
<div
class="mt-2 text-sm text-blue-500 underline cursor-pointer"
v-if="checkObj.check"
@click="openError"
>下载检查结果</div
>
</div>
</div>
<div class="flex-1">
......@@ -49,12 +57,22 @@
<el-input v-model="form.contractNo" placeholder="请输入" style="width: 100%" />
</el-form-item>
</el-form>
<el-button type="primary" @click="submitData">上传</el-button>
<el-button
type="primary"
@click="submitData"
:disabled="!form.path || !checkObj.checksuccess"
>上传</el-button
>
</div>
</div>
</div>
<div>
<ProTable :config="config" :api="importLoanPage" ref="ProTableRef">
<ProTable
:config="config"
:api="importLoanPage"
ref="ProTableRef"
:paramCallback="paramCallback"
>
<!-- 表格 header 按钮 -->
<!-- <template #left_buttons>
<el-button type="primary">新增菜单 </el-button>
......@@ -62,6 +80,7 @@
</ProTable>
</div>
<caseDetailModal ref="caseDetailModalRef" />
<errorModal ref="errorModalRef" />
</div>
</template>
......@@ -69,12 +88,13 @@
import { getAppEnvConfig } from '@/utils/env';
import caseDetailModal from './components/caseDetailModal.vue';
import errorModal from './components/errorModal.vue';
import { reactive, ref } from 'vue';
import { computed, onMounted } from 'vue';
import { ElButton, ElMessage } from 'element-plus';
import { Upload } from '@element-plus/icons-vue';
import { inject } from 'vue';
import { LoanSubmit, importLoanPage } from '@/api/import';
import { LoanSubmit, importLoanPage, checkLoanExcel } from '@/api/import';
const downloadfile = inject('download');
const envs = getAppEnvConfig();
......@@ -84,8 +104,30 @@
const options = ref([]);
const loadProgress = ref(0);
const caseDetailModalRef = ref();
const errorModalRef = ref();
const uploadRef = ref();
const isFold = ref(true);
const checkObj = reactive({
check: false,
checksuccess: false,
result: {
success: null,
error: null,
loanErrors: [],
},
});
const paramCallback = (param) => {
const obj = JSON.parse(JSON.stringify(param));
if (obj['createTime']) {
if (obj['createTime'][0]) obj['createTimeBegin'] = obj['createTime'][0];
if (obj['createTime'][1]) obj['createTimeEnd'] = obj['createTime'][1];
delete obj['createTime'];
}
return obj;
};
const openError = () => {
errorModalRef.value.openModal(JSON.parse(JSON.stringify(checkObj.result.loanErrors)));
};
const config = reactive({
columns: [
{
......@@ -192,7 +234,21 @@
const downloadtemplate = () => {
downloadfile('/LoanExcel/downloadTemplate', {}, '模版.xls');
};
const checkData = () => {};
const checkData = () => {
checkLoanExcel({
fileUrl: form.path,
}).then((res) => {
if (res.success) {
checkObj.result.success = res.result.success;
checkObj.result.error = res.result.error;
if (checkObj.result.error.length === 0) {
checkObj.checksuccess = true;
}
checkObj.result.loanErrors = res.result.loanErrors;
checkObj.check = true;
}
});
};
const handleFileSuccess = (response, file, fileList) => {
if (!response.success) {
......@@ -214,6 +270,8 @@
};
const handleRemove = () => {
form.path = '';
checkObj.check = false;
checkObj.checksuccess = false;
};
const linkZK = (row) => {
caseDetailModalRef.value.openModal(JSON.parse(JSON.stringify(row)));
......@@ -235,7 +293,7 @@
});
uploadRef.value.clearFiles();
form.path = '';
query()
query();
});
};
onMounted(() => {
......
......@@ -9,7 +9,9 @@
@click="accountFormModalRef?.openModal()"
>新增</el-button
>
<el-button v-permission="'AccountDelete'" type="danger" :icon="Delete" @click="handleDelete">删除</el-button>
<el-button v-permission="'AccountDelete'" type="danger" :icon="Delete" @click="handleDelete"
>删除</el-button
>
</template>
</ProTable>
......
......@@ -4291,6 +4291,11 @@ write-file-atomic@^5.0.1:
imurmurhash "^0.1.4"
signal-exit "^4.0.1"
ws@^8.18.0:
version "8.18.0"
resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc"
integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==
xe-utils@^3.5.26, xe-utils@^3.5.32:
version "3.5.32"
resolved "https://registry.npmmirror.com/xe-utils/-/xe-utils-3.5.32.tgz#a5f5194c024b64e249b8cd2c6b43a452722457b0"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment