This commit is contained in:
2026-10-24 13:32:34 +08:00
parent 72a93e7701
commit cd0aa98dc0
74 changed files with 7928 additions and 1037 deletions
@@ -25,15 +25,21 @@ import { ref, watch } from "vue";
import { ThinkOrderInfoParam } from "@/api/think/thinkOrderInfo/model";
import { messageLoading } from "ele-admin-pro";
import dayjs from "dayjs";
import { thinkOrderExportData } from "@/api/think/thinkOrder";
import {
exportThinkOrderTrainingBusiness,
thinkOrderExportData
} from "@/api/think/thinkOrder";
import { ThinkOrder, ThinkOrderParam } from "@/api/think/thinkOrder/model";
const props = withDefaults(
defineProps<{
// 选中的角色
selection?: [];
type?: number;
}>(),
{}
{
type: 0
}
);
const emit = defineEmits<{
@@ -85,7 +91,16 @@ const reload = () => {
// 导出
const handleExport = async () => {
const hide = messageLoading("导出中...", 0);
const res = await thinkOrderExportData(where);
const [d1, d2] = dateRange.value ?? [];
const params = {
...where,
createTimeStart: d1 ? dayjs(d1).unix() : undefined,
createTimeEnd: d2 ? dayjs(d2).unix() : undefined
};
const res =
props.type === 2
? await exportThinkOrderTrainingBusiness(params)
: await thinkOrderExportData(params);
hide();
window.open(res.url);
};
@@ -0,0 +1,131 @@
<template>
<div class="training-report">
<div
v-for="section in sections"
:key="section.key || section.title"
class="report-section"
>
<table class="report-table">
<thead>
<tr>
<th colspan="9" class="section-title">
{{ section.title }}
</th>
</tr>
<tr>
<th rowspan="2" class="institution-col">培训机构名称</th>
<th colspan="2">开卡统计</th>
<th colspan="2">核销次数</th>
<th colspan="2">过期次数</th>
<th colspan="2">未核销次数</th>
</tr>
<tr>
<th>次数</th>
<th>收款金额</th>
<th>次数</th>
<th>核销金额</th>
<th>次数</th>
<th>过期金额</th>
<th>次数</th>
<th>剩余金额</th>
</tr>
</thead>
<tbody>
<tr v-for="row in section.rows || []" :key="row.trainingInstitutionName">
<td>{{ row.trainingInstitutionName || "-" }}</td>
<td>{{ formatCount(row.openCount) }}</td>
<td>{{ formatAmount(row.openAmount) }}</td>
<td>{{ formatCount(row.verifyCount) }}</td>
<td>{{ formatAmount(row.verifyAmount) }}</td>
<td>{{ formatCount(row.expiredCount) }}</td>
<td>{{ formatAmount(row.expiredAmount) }}</td>
<td>{{ formatCount(row.unverifiedCount) }}</td>
<td>{{ formatAmount(row.remainingAmount) }}</td>
</tr>
<tr class="total-row">
<td>合计</td>
<td>{{ formatCount(section.total?.openCount) }}</td>
<td>{{ formatAmount(section.total?.openAmount) }}</td>
<td>{{ formatCount(section.total?.verifyCount) }}</td>
<td>{{ formatAmount(section.total?.verifyAmount) }}</td>
<td>{{ formatCount(section.total?.expiredCount) }}</td>
<td>{{ formatAmount(section.total?.expiredAmount) }}</td>
<td>{{ formatCount(section.total?.unverifiedCount) }}</td>
<td>{{ formatAmount(section.total?.remainingAmount) }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
<script lang="ts" setup>
import type { ThinkTrainingBusinessSection } from "@/api/think/thinkOrder/model";
defineProps<{
sections: ThinkTrainingBusinessSection[];
}>();
const formatCount = (value?: number | string) => {
if (value === undefined || value === null || value === "") {
return "0";
}
return String(value);
};
const formatAmount = (value?: number | string) => {
if (value === undefined || value === null || value === "") {
return "0";
}
return String(value);
};
</script>
<style lang="less" scoped>
.training-report {
display: flex;
flex-direction: column;
gap: 28px;
}
.report-section {
overflow-x: auto;
}
.report-table {
width: 100%;
min-width: 1200px;
border-collapse: collapse;
table-layout: fixed;
background: #fff;
}
.report-table th,
.report-table td {
padding: 12px 10px;
border: 1px solid #1f1f1f;
font-size: 14px;
line-height: 1.45;
text-align: center;
vertical-align: middle;
word-break: break-all;
}
.report-table th {
font-weight: 600;
}
.section-title {
font-size: 22px;
line-height: 1.4;
padding: 16px 12px !important;
}
.institution-col {
width: 240px;
}
.total-row td {
font-weight: 600;
}
</style>
+73 -54
View File
@@ -3,91 +3,118 @@
<div class="ele-body">
<a-card :bordered="false" :body-style="{ padding: '16px' }">
<a-space style="margin-bottom: 1rem">
<a-button @click="changeType(0)" :type="type === 0 ? 'primary' : ''">收款汇总表</a-button>
<a-button @click="changeType(1)" :type="type === 1 ? 'primary' : ''">收入日报表及汇总表</a-button>
<a-button @click="changeType(0)" :type="type === 0 ? 'primary' : ''">
收款汇总表
</a-button>
<a-button @click="changeType(1)" :type="type === 1 ? 'primary' : ''">
收入日报表及汇总表
</a-button>
<a-button @click="changeType(2)" :type="type === 2 ? 'primary' : ''">
培训业务报表
</a-button>
</a-space>
<a-spin :spinning="loading">
<search
@search="searchData"
@reload="reload"
<search @search="searchData" @reload="reload" :type="type" />
<a-table
v-if="type === 0"
:scroll="{ y: tableHeight }"
:data-source="incomeList"
:columns="columns"
:pagination="false"
/>
<a-table v-if="type === 0"
:scroll="{ y: tableHeight }"
:data-source="list"
:columns="columns"
:pagination="false"
/>
<a-table v-else
:scroll="{ y: tableHeight }"
:data-source="list"
:columns="columns1"
:pagination="false"
<a-table
v-else-if="type === 1"
:scroll="{ y: tableHeight }"
:data-source="cardList"
:columns="columns1"
:pagination="false"
/>
<training-business-report v-else :sections="trainingSections" />
</a-spin>
</a-card>
</div>
<OrderList v-model:visible="showList" v-if="showList" :pay-type="payTypeList" :sid="sid"
:showType="showType" :showCardType="showCardType" :type="type" :isPayTime="type === 0"
:create-time-start="createTimeStart" :wechat-order="wechatOrder"
:create-time-end="createTimeEnd" />
<OrderList
v-model:visible="showList"
v-if="showList"
:pay-type="payTypeList"
:sid="sid"
:showType="showType"
:showCardType="showCardType"
:type="type"
:isPayTime="type === 0"
:create-time-start="createTimeStart"
:wechat-order="wechatOrder"
:create-time-end="createTimeEnd"
/>
</div>
</template>
<script lang="ts" setup>
import { ref } from "vue";
import type {
ColumnItem
} from "ele-admin-pro/es/ele-pro-table/types";
import type { ColumnItem } from "ele-admin-pro/es/ele-pro-table/types";
import Search from "./components/search.vue";
import TrainingBusinessReport from "./components/trainingBusinessReport.vue";
import {
getThinkOrderExcelData, getThinkOrderExcelDataForCard
getThinkOrderExcelData,
getThinkOrderExcelDataForCard,
getThinkOrderTrainingBusinessData
} from "@/api/think/thinkOrder";
import type {
ThinkOrderParam
ThinkOrderParam,
ThinkTrainingBusinessSection
} from "@/api/think/thinkOrder/model";
import OrderList from "./components/OrderList.vue";
import dayjs from "dayjs";
// 加载状态
const loading = ref(true);
const showType = ref(false);
const showCardType = ref(false);
const type = ref<number>(0);
const changeType = (val) => {
type.value = val;
getList();
};
const tableHeight = document.body.clientHeight - 330;
console.log(tableHeight);
const createTimeStart = ref();
const createTimeEnd = ref();
const list = ref<any[]>([]);
const incomeList = ref<any[]>([]);
const cardList = ref<any[]>([]);
const trainingSections = ref<ThinkTrainingBusinessSection[]>([]);
const sid = ref<number>(0);
const wechatOrder = ref<string>("");
const payTypeList = ref<number[]>([]);
const showList = ref(false);
const getList = async () => {
loading.value = true;
list.value = [];
incomeList.value = [];
cardList.value = [];
trainingSections.value = [];
const params = {
createTimeStart: createTimeStart.value
? dayjs(createTimeStart.value).unix()
: undefined,
createTimeEnd: createTimeEnd.value
? dayjs(createTimeEnd.value).unix()
: undefined
};
if (type.value === 0) {
list.value = await getThinkOrderExcelData({
createTimeStart: createTimeStart.value ? dayjs(createTimeStart.value).unix() : undefined,
createTimeEnd: createTimeEnd.value ? dayjs(createTimeEnd.value).unix() : undefined
});
incomeList.value = await getThinkOrderExcelData(params);
} else if (type.value === 1) {
cardList.value = await getThinkOrderExcelDataForCard(params);
} else {
list.value = await getThinkOrderExcelDataForCard({
createTimeStart: createTimeStart.value ? dayjs(createTimeStart.value).unix() : undefined,
createTimeEnd: createTimeEnd.value ? dayjs(createTimeEnd.value).unix() : undefined
});
trainingSections.value = await getThinkOrderTrainingBusinessData(params);
}
loading.value = false;
};
const changeType = (val: number) => {
type.value = val;
getList();
};
createTimeStart.value = dayjs().format("YYYY-MM-DD");
createTimeEnd.value = dayjs().format("YYYY-MM-DD 23:59:59");
getList();
const sid = ref<number>(0);
const wechatOrder = ref<string>("");
const columns1 = ref<ColumnItem[]>([
{
title: "场馆名称",
@@ -166,7 +193,6 @@ const columns1 = ref<ColumnItem[]>([
customCell: (row) => {
return {
onClick: () => {
console.log(row);
sid.value = row.sid;
wechatOrder.value = "";
payTypeList.value = [2, 3, 12, 15];
@@ -185,7 +211,6 @@ const columns1 = ref<ColumnItem[]>([
}
]);
// 表格列配置
const columns = ref<ColumnItem[]>([
{
title: "场馆名称",
@@ -307,11 +332,9 @@ const columns = ref<ColumnItem[]>([
}
]);
/* 搜索 */
const searchData = (param: ThinkOrderParam) => {
createTimeStart.value = param.createTimeStart;
createTimeEnd.value = param.createTimeEnd;
console.log(createTimeEnd.value);
getList();
};
@@ -320,11 +343,6 @@ const reload = () => {
createTimeEnd.value = dayjs().format("YYYY-MM-DD");
getList();
};
const payTypeList = ref<number[]>([]);
const showList = ref(false);
</script>
<script lang="ts">
@@ -335,6 +353,7 @@ export default {
components: MenuIcons
};
</script>
<style lang="less" scoped>
.tag-icon {
padding-right: 6px;