|
@@ -285,23 +285,25 @@
|
|
|
<template #header>
|
|
<template #header>
|
|
|
<div class="card-header">
|
|
<div class="card-header">
|
|
|
<span>转账记录</span>
|
|
<span>转账记录</span>
|
|
|
- <!-- <el-button
|
|
|
|
|
|
|
+ <el-button
|
|
|
type="primary"
|
|
type="primary"
|
|
|
icon="Download"
|
|
icon="Download"
|
|
|
class="ml-auto"
|
|
class="ml-auto"
|
|
|
- @click="showDownloadMenu = true"
|
|
|
|
|
|
|
+ :loading="transferExportLoading"
|
|
|
|
|
+ v-hasPerm="['module_payment:account:transfer:list']"
|
|
|
|
|
+ @click="handleExportTransfer"
|
|
|
>
|
|
>
|
|
|
下载报表
|
|
下载报表
|
|
|
- </el-button> -->
|
|
|
|
|
|
|
+ </el-button>
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
<div class="mb-4">
|
|
<div class="mb-4">
|
|
|
<el-form :inline="true" :model="transferSearchForm">
|
|
<el-form :inline="true" :model="transferSearchForm">
|
|
|
<el-form-item label="订单号">
|
|
<el-form-item label="订单号">
|
|
|
- <el-input v-model="transferSearchForm.out_biz_no" placeholder="请输入订单号" clearable />
|
|
|
|
|
|
|
+ <el-input v-model="transferSearchForm.out_biz_no" placeholder="请输入订单号" clearable style="width: 220px" />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
<el-form-item label="状态">
|
|
<el-form-item label="状态">
|
|
|
- <el-select v-model="transferSearchForm.status" placeholder="请选择状态" clearable>
|
|
|
|
|
|
|
+ <el-select v-model="transferSearchForm.status" placeholder="请选择状态" clearable style="width: 180px">
|
|
|
<el-option label="处理中" value="DEALING" />
|
|
<el-option label="处理中" value="DEALING" />
|
|
|
<el-option label="成功" value="SUCCESS" />
|
|
<el-option label="成功" value="SUCCESS" />
|
|
|
<el-option label="失败" value="FAIL" />
|
|
<el-option label="失败" value="FAIL" />
|
|
@@ -309,15 +311,27 @@
|
|
|
</el-select>
|
|
</el-select>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
<el-form-item v-if="is_platform_user" label="租户">
|
|
<el-form-item v-if="is_platform_user" label="租户">
|
|
|
- <el-select v-model="transferSearchForm.tenant_id" placeholder="选择租户" clearable filterable>
|
|
|
|
|
|
|
+ <el-select v-model="transferSearchForm.tenant_id" placeholder="选择租户" clearable filterable style="width: 180px">
|
|
|
<el-option v-for="t in allTenantData" :key="t.id" :label="t.name" :value="t.id" />
|
|
<el-option v-for="t in allTenantData" :key="t.id" :label="t.name" :value="t.id" />
|
|
|
</el-select>
|
|
</el-select>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
<el-form-item label="企业">
|
|
<el-form-item label="企业">
|
|
|
- <el-select v-model="transferSearchForm.enterprise_id" placeholder="选择企业" clearable filterable>
|
|
|
|
|
|
|
+ <el-select v-model="transferSearchForm.enterprise_id" placeholder="选择企业" clearable filterable style="width: 180px">
|
|
|
<el-option v-for="e in enterpriseStore.getEnterpriseList" :key="e.enterprise_id" :label="e.name" :value="e.enterprise_id" />
|
|
<el-option v-for="e in enterpriseStore.getEnterpriseList" :key="e.enterprise_id" :label="e.name" :value="e.enterprise_id" />
|
|
|
</el-select>
|
|
</el-select>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
|
|
+ <el-form-item label="时间范围">
|
|
|
|
|
+ <el-date-picker
|
|
|
|
|
+ v-model="transferSearchForm.dateRange"
|
|
|
|
|
+ type="daterange"
|
|
|
|
|
+ range-separator="至"
|
|
|
|
|
+ start-placeholder="开始日期"
|
|
|
|
|
+ end-placeholder="结束日期"
|
|
|
|
|
+ value-format="YYYY-MM-DD"
|
|
|
|
|
+ style="width: 280px"
|
|
|
|
|
+ @change="handleTransferDateChange"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
<el-form-item>
|
|
<el-form-item>
|
|
|
<el-button type="primary" @click="handleTransferSearch">查询</el-button>
|
|
<el-button type="primary" @click="handleTransferSearch">查询</el-button>
|
|
|
<el-button @click="handleTransferSearchReset">重置</el-button>
|
|
<el-button @click="handleTransferSearchReset">重置</el-button>
|
|
@@ -350,7 +364,11 @@
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
<el-table-column prop="order_title" label="转账标题" min-width="150" />
|
|
<el-table-column prop="order_title" label="转账标题" min-width="150" />
|
|
|
- <el-table-column prop="created_time" label="创建时间" min-width="160" />
|
|
|
|
|
|
|
+ <el-table-column prop="created_time" label="创建时间" min-width="160">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ {{ row.created_time ? dayjs(row.created_time).format("YYYY-MM-DD HH:mm:ss") : "" }}
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
<el-table-column label="操作" width="160" fixed="right">
|
|
<el-table-column label="操作" width="160" fixed="right">
|
|
|
<template #default="{ row }">
|
|
<template #default="{ row }">
|
|
|
<el-button type="primary" link @click="handleViewTransferDetail(row.out_biz_no)">
|
|
<el-button type="primary" link @click="handleViewTransferDetail(row.out_biz_no)">
|
|
@@ -725,43 +743,6 @@
|
|
|
<el-button type="primary" :loading="withdrawLoading" @click="handleWithdraw">确认提现</el-button>
|
|
<el-button type="primary" :loading="withdrawLoading" @click="handleWithdraw">确认提现</el-button>
|
|
|
</template>
|
|
</template>
|
|
|
</el-dialog>
|
|
</el-dialog>
|
|
|
-
|
|
|
|
|
- <!-- 下载报表弹窗 -->
|
|
|
|
|
- <el-dialog title="下载转账报表" v-model="showDownloadMenu" width="500px" :close-on-click-modal="false">
|
|
|
|
|
- <div class="download-options">
|
|
|
|
|
- <div class="option-group">
|
|
|
|
|
- <p class="option-title">快捷时间范围</p>
|
|
|
|
|
- <div class="option-buttons">
|
|
|
|
|
- <el-button
|
|
|
|
|
- v-for="option in quickOptions"
|
|
|
|
|
- :key="option.value"
|
|
|
|
|
- :type="selectedQuickOption === option.value ? 'primary' : ''"
|
|
|
|
|
- @click="selectedQuickOption = option.value"
|
|
|
|
|
- >
|
|
|
|
|
- {{ option.label }}
|
|
|
|
|
- </el-button>
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
- <div class="option-group mt-4">
|
|
|
|
|
- <p class="option-title">自定义时间范围</p>
|
|
|
|
|
- <el-date-picker
|
|
|
|
|
- v-model="customDateRange"
|
|
|
|
|
- type="daterange"
|
|
|
|
|
- range-separator="至"
|
|
|
|
|
- start-placeholder="开始日期"
|
|
|
|
|
- end-placeholder="结束日期"
|
|
|
|
|
- class="w-full"
|
|
|
|
|
- @change="handleCustomDateChange"
|
|
|
|
|
- />
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
- <template #footer>
|
|
|
|
|
- <el-button @click="showDownloadMenu = false">取消</el-button>
|
|
|
|
|
- <el-button type="primary" @click="handleDownload" :loading="downloadLoading">
|
|
|
|
|
- 下载报表
|
|
|
|
|
- </el-button>
|
|
|
|
|
- </template>
|
|
|
|
|
- </el-dialog>
|
|
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
@@ -783,6 +764,7 @@ import { Refresh, Loading, Plus, QuestionFilled } from "@element-plus/icons-vue"
|
|
|
import { ElMessage, ElMessageBox } from "element-plus";
|
|
import { ElMessage, ElMessageBox } from "element-plus";
|
|
|
import type { FormInstance, FormRules } from "element-plus";
|
|
import type { FormInstance, FormRules } from "element-plus";
|
|
|
import * as ExcelJS from "exceljs";
|
|
import * as ExcelJS from "exceljs";
|
|
|
|
|
+import dayjs from "dayjs";
|
|
|
|
|
|
|
|
const enterpriseStore = useEnterpriseStore();
|
|
const enterpriseStore = useEnterpriseStore();
|
|
|
const userStore = useUserStore();
|
|
const userStore = useUserStore();
|
|
@@ -799,18 +781,7 @@ const depositLoading = ref(false);
|
|
|
const transferLoading = ref(false);
|
|
const transferLoading = ref(false);
|
|
|
const consumeLoading = ref(false);
|
|
const consumeLoading = ref(false);
|
|
|
const transferListLoading = ref(false);
|
|
const transferListLoading = ref(false);
|
|
|
-const downloadLoading = ref(false);
|
|
|
|
|
-
|
|
|
|
|
-const showDownloadMenu = ref(false);
|
|
|
|
|
-const selectedQuickOption = ref("today");
|
|
|
|
|
-const customDateRange = ref<Date[] | null>(null);
|
|
|
|
|
-
|
|
|
|
|
-const quickOptions = [
|
|
|
|
|
- { label: "当天", value: "today" },
|
|
|
|
|
- { label: "近3天", value: "3days" },
|
|
|
|
|
- { label: "近15天", value: "15days" },
|
|
|
|
|
- { label: "近30天", value: "30days" },
|
|
|
|
|
-];
|
|
|
|
|
|
|
+const transferExportLoading = ref(false);
|
|
|
|
|
|
|
|
const authorizeFormRef = ref<FormInstance>();
|
|
const authorizeFormRef = ref<FormInstance>();
|
|
|
const createFormRef = ref<FormInstance>();
|
|
const createFormRef = ref<FormInstance>();
|
|
@@ -1160,6 +1131,9 @@ const transferSearchForm = reactive({
|
|
|
status: "",
|
|
status: "",
|
|
|
tenant_id: undefined as number | undefined,
|
|
tenant_id: undefined as number | undefined,
|
|
|
enterprise_id: undefined as string | undefined,
|
|
enterprise_id: undefined as string | undefined,
|
|
|
|
|
+ dateRange: null as string[] | null,
|
|
|
|
|
+ start_time: undefined as string | undefined,
|
|
|
|
|
+ end_time: undefined as string | undefined,
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
const allTenantData = ref<TenantTable[]>([]);
|
|
const allTenantData = ref<TenantTable[]>([]);
|
|
@@ -1249,18 +1223,18 @@ function downloadTemplate() {
|
|
|
|
|
|
|
|
// 设置表头
|
|
// 设置表头
|
|
|
worksheet.columns = [
|
|
worksheet.columns = [
|
|
|
- { header: "转账金额", key: "amount", width: 15 },
|
|
|
|
|
- { header: "转账标题", key: "order_title", width: 20 },
|
|
|
|
|
- { header: "收款方姓名", key: "payee_name", width: 15 },
|
|
|
|
|
- { header: "收款方账号类型", key: "payee_type", width: 15 },
|
|
|
|
|
- { header: "收款方账号", key: "payee_account", width: 30 },
|
|
|
|
|
- { header: "银行账户类型(1:公司账户,2:个人账户)", key: "bank_type", width: 30 },
|
|
|
|
|
- { header: "银行名称(公司账户必填)", key: "bank_name", width: 20 },
|
|
|
|
|
- { header: "开户省份(非必填)", key: "bank_province", width: 15 },
|
|
|
|
|
- { header: "开户城市(非必填)", key: "bank_city", width: 15 },
|
|
|
|
|
- { header: "支行名称(非必填)", key: "bank_branch", width: 20 },
|
|
|
|
|
- { header: "联行号(非必填)", key: "bank_code", width: 15 },
|
|
|
|
|
- { header: "备注(非必填)", key: "remark", width: 20 },
|
|
|
|
|
|
|
+ { header: "转账金额(必填)", key: "amount", width: 15 },
|
|
|
|
|
+ { header: "转账标题(必填)", key: "order_title", width: 20 },
|
|
|
|
|
+ { header: "收款方姓名(必填)", key: "payee_name", width: 15 },
|
|
|
|
|
+ { header: "收款方账号类型(必填:支付宝/银行卡)", key: "payee_type", width: 20 },
|
|
|
|
|
+ { header: "收款方账号(必填)", key: "payee_account", width: 30 },
|
|
|
|
|
+ { header: "银行账户类型(1:公司账户,2:个人账户;银行卡必填)", key: "bank_type", width: 30 },
|
|
|
|
|
+ { header: "银行名称(对公账户必填)", key: "bank_name", width: 20 },
|
|
|
|
|
+ { header: "开户省份(对公账户必填)", key: "bank_province", width: 15 },
|
|
|
|
|
+ { header: "开户城市(对公账户必填)", key: "bank_city", width: 15 },
|
|
|
|
|
+ { header: "支行名称(对公账户必填)", key: "bank_branch", width: 20 },
|
|
|
|
|
+ { header: "联行号(对公账户必填)", key: "bank_code", width: 15 },
|
|
|
|
|
+ { header: "备注(必填)", key: "remark", width: 20 },
|
|
|
];
|
|
];
|
|
|
|
|
|
|
|
// 添加示例数据
|
|
// 添加示例数据
|
|
@@ -1759,11 +1733,24 @@ async function handleTransferSearch() {
|
|
|
await fetchTransferList();
|
|
await fetchTransferList();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+function handleTransferDateChange() {
|
|
|
|
|
+ if (transferSearchForm.dateRange && transferSearchForm.dateRange.length === 2) {
|
|
|
|
|
+ transferSearchForm.start_time = (transferSearchForm.dateRange as any)[0];
|
|
|
|
|
+ transferSearchForm.end_time = (transferSearchForm.dateRange as any)[1];
|
|
|
|
|
+ } else {
|
|
|
|
|
+ transferSearchForm.start_time = undefined;
|
|
|
|
|
+ transferSearchForm.end_time = undefined;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
function handleTransferSearchReset() {
|
|
function handleTransferSearchReset() {
|
|
|
transferSearchForm.out_biz_no = "";
|
|
transferSearchForm.out_biz_no = "";
|
|
|
transferSearchForm.status = "";
|
|
transferSearchForm.status = "";
|
|
|
transferSearchForm.tenant_id = undefined;
|
|
transferSearchForm.tenant_id = undefined;
|
|
|
transferSearchForm.enterprise_id = undefined;
|
|
transferSearchForm.enterprise_id = undefined;
|
|
|
|
|
+ transferSearchForm.dateRange = null;
|
|
|
|
|
+ transferSearchForm.start_time = undefined;
|
|
|
|
|
+ transferSearchForm.end_time = undefined;
|
|
|
handleTransferSearch();
|
|
handleTransferSearch();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1777,6 +1764,8 @@ async function fetchTransferList() {
|
|
|
status: transferSearchForm.status || undefined,
|
|
status: transferSearchForm.status || undefined,
|
|
|
tenant_id: transferSearchForm.tenant_id || undefined,
|
|
tenant_id: transferSearchForm.tenant_id || undefined,
|
|
|
enterprise_id: transferSearchForm.enterprise_id || undefined,
|
|
enterprise_id: transferSearchForm.enterprise_id || undefined,
|
|
|
|
|
+ start_time: transferSearchForm.start_time || undefined,
|
|
|
|
|
+ end_time: transferSearchForm.end_time || undefined,
|
|
|
});
|
|
});
|
|
|
transferList.value = res.data.data?.items || res.data.data?.list || [];
|
|
transferList.value = res.data.data?.items || res.data.data?.list || [];
|
|
|
transferPage.total = res.data.data.total || 0;
|
|
transferPage.total = res.data.data.total || 0;
|
|
@@ -2046,101 +2035,33 @@ onMounted(async() => {
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
-async function handleDownload() {
|
|
|
|
|
- downloadLoading.value = true;
|
|
|
|
|
|
|
+async function handleExportTransfer() {
|
|
|
|
|
+ transferExportLoading.value = true;
|
|
|
try {
|
|
try {
|
|
|
- let start_time: string;
|
|
|
|
|
- let end_time: string;
|
|
|
|
|
-
|
|
|
|
|
- if (selectedQuickOption.value !== "custom") {
|
|
|
|
|
- const range = calculateTimeRange(selectedQuickOption.value);
|
|
|
|
|
- start_time = range.start_time;
|
|
|
|
|
- end_time = range.end_time;
|
|
|
|
|
- } else {
|
|
|
|
|
- if (!customDateRange.value || customDateRange.value.length !== 2) {
|
|
|
|
|
- ElMessage.warning("请选择时间范围");
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
- const [start, end] = customDateRange.value;
|
|
|
|
|
- start_time = formatDateTime(start, "start");
|
|
|
|
|
- end_time = formatDateTime(end, "end");
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
const res = await AccountAPI.exportTransferReport({
|
|
const res = await AccountAPI.exportTransferReport({
|
|
|
- start_time,
|
|
|
|
|
- end_time,
|
|
|
|
|
- enterprise_id: currentEnterpriseId.value || undefined,
|
|
|
|
|
|
|
+ out_biz_no: transferSearchForm.out_biz_no || undefined,
|
|
|
|
|
+ status: transferSearchForm.status || undefined,
|
|
|
|
|
+ tenant_id: transferSearchForm.tenant_id || undefined,
|
|
|
|
|
+ enterprise_id: transferSearchForm.enterprise_id || undefined,
|
|
|
|
|
+ start_time: transferSearchForm.start_time || undefined,
|
|
|
|
|
+ end_time: transferSearchForm.end_time || undefined,
|
|
|
});
|
|
});
|
|
|
-
|
|
|
|
|
const blob = new Blob([res.data], {
|
|
const blob = new Blob([res.data], {
|
|
|
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
|
});
|
|
});
|
|
|
const url = window.URL.createObjectURL(blob);
|
|
const url = window.URL.createObjectURL(blob);
|
|
|
const a = document.createElement("a");
|
|
const a = document.createElement("a");
|
|
|
a.href = url;
|
|
a.href = url;
|
|
|
- a.download = `转账报表_${start_time}_${end_time}.xlsx`;
|
|
|
|
|
|
|
+ a.download = "转账记录.xlsx";
|
|
|
document.body.appendChild(a);
|
|
document.body.appendChild(a);
|
|
|
a.click();
|
|
a.click();
|
|
|
document.body.removeChild(a);
|
|
document.body.removeChild(a);
|
|
|
window.URL.revokeObjectURL(url);
|
|
window.URL.revokeObjectURL(url);
|
|
|
-
|
|
|
|
|
- ElMessage.success("报表下载成功");
|
|
|
|
|
- showDownloadMenu.value = false;
|
|
|
|
|
- selectedQuickOption.value = "today";
|
|
|
|
|
- customDateRange.value = null;
|
|
|
|
|
|
|
+ ElMessage.success("导出成功");
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
- ElMessage.error("下载失败,请稍后重试");
|
|
|
|
|
|
|
+ ElMessage.error("导出失败,请稍后重试");
|
|
|
} finally {
|
|
} finally {
|
|
|
- downloadLoading.value = false;
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-function calculateTimeRange(type: string): { start_time: string; end_time: string } {
|
|
|
|
|
- const now = new Date();
|
|
|
|
|
- const start = new Date();
|
|
|
|
|
-
|
|
|
|
|
- switch (type) {
|
|
|
|
|
- case "today":
|
|
|
|
|
- start.setHours(0, 0, 0, 0);
|
|
|
|
|
- break;
|
|
|
|
|
- case "3days":
|
|
|
|
|
- start.setDate(now.getDate() - 3);
|
|
|
|
|
- start.setHours(0, 0, 0, 0);
|
|
|
|
|
- break;
|
|
|
|
|
- case "15days":
|
|
|
|
|
- start.setDate(now.getDate() - 15);
|
|
|
|
|
- start.setHours(0, 0, 0, 0);
|
|
|
|
|
- break;
|
|
|
|
|
- case "30days":
|
|
|
|
|
- start.setDate(now.getDate() - 30);
|
|
|
|
|
- start.setHours(0, 0, 0, 0);
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- const end = new Date(now);
|
|
|
|
|
- end.setHours(23, 59, 59, 999);
|
|
|
|
|
-
|
|
|
|
|
- return {
|
|
|
|
|
- start_time: formatDateTime(start),
|
|
|
|
|
- end_time: formatDateTime(end),
|
|
|
|
|
- };
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-function formatDateTime(date: Date, type: string = "start"): string {
|
|
|
|
|
- const year = date.getFullYear();
|
|
|
|
|
- const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
|
|
|
- const day = String(date.getDate()).padStart(2, "0");
|
|
|
|
|
-
|
|
|
|
|
- if (type === "start") {
|
|
|
|
|
- return `${year}-${month}-${day} 00:00:00`;
|
|
|
|
|
- } else {
|
|
|
|
|
- return `${year}-${month}-${day} 23:59:59`;
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-function handleCustomDateChange() {
|
|
|
|
|
- if (customDateRange.value && customDateRange.value.length === 2) {
|
|
|
|
|
- selectedQuickOption.value = "custom";
|
|
|
|
|
|
|
+ transferExportLoading.value = false;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -2235,21 +2156,4 @@ function handleCustomDateChange() {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-.download-options {
|
|
|
|
|
- .option-group {
|
|
|
|
|
- .option-title {
|
|
|
|
|
- font-size: 14px;
|
|
|
|
|
- font-weight: 500;
|
|
|
|
|
- color: #606266;
|
|
|
|
|
- margin-bottom: 12px;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- .option-buttons {
|
|
|
|
|
- display: flex;
|
|
|
|
|
- flex-wrap: wrap;
|
|
|
|
|
- gap: 8px;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
</style>
|
|
</style>
|