fix: 🧩 图标显示问题;增加收入和支出合计显示
This commit is contained in:
parent
2a75ff30e0
commit
476d4677a5
|
@ -20,7 +20,7 @@ VITE_BASE_API_RETRY=5
|
||||||
VITE_BASE_API_RETRY_DELAY=3000
|
VITE_BASE_API_RETRY_DELAY=3000
|
||||||
|
|
||||||
# 是否在打包时使用cdn替换本地库 替换 true 不替换 false
|
# 是否在打包时使用cdn替换本地库 替换 true 不替换 false
|
||||||
VITE_CDN=true
|
VITE_CDN=false
|
||||||
|
|
||||||
# 是否启用gzip压缩或brotli压缩(分两种情况,删除原始文件和不删除原始文件)
|
# 是否启用gzip压缩或brotli压缩(分两种情况,删除原始文件和不删除原始文件)
|
||||||
# 压缩时不删除原始文件的配置:gzip、brotli、both(同时开启 gzip 与 brotli 压缩)、none(不开启压缩,默认)
|
# 压缩时不删除原始文件的配置:gzip、brotli、both(同时开启 gzip 与 brotli 压缩)、none(不开启压缩,默认)
|
||||||
|
|
|
@ -3,6 +3,16 @@ import type { BaseResult, ResultTable } from '@/api/service/types';
|
||||||
|
|
||||||
/** 账单信息---获取账单信息列表 */
|
/** 账单信息---获取账单信息列表 */
|
||||||
export const fetchGetBillList = (data: any) => {
|
export const fetchGetBillList = (data: any) => {
|
||||||
|
data = {
|
||||||
|
userId: data.userId,
|
||||||
|
amount: data.amount,
|
||||||
|
type: data.type,
|
||||||
|
description: data.description,
|
||||||
|
startDate: data.startDate,
|
||||||
|
endDate: data.endDate,
|
||||||
|
pageSize: data.pageSize,
|
||||||
|
currentPage: data.currentPage,
|
||||||
|
};
|
||||||
return http.request<BaseResult<ResultTable>>('get', `bill/getBillList/${data.currentPage}/${data.pageSize}`, { params: data });
|
return http.request<BaseResult<ResultTable>>('get', `bill/getBillList/${data.currentPage}/${data.pageSize}`, { params: data });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,21 @@ import type { BaseResult, ResultTable } from '@/api/service/types';
|
||||||
|
|
||||||
/** 账单信息---获取账单信息列表 */
|
/** 账单信息---获取账单信息列表 */
|
||||||
export const fetchGetUserBillList = (data: any) => {
|
export const fetchGetUserBillList = (data: any) => {
|
||||||
// 删除这个请求参数
|
data = {
|
||||||
delete data.date;
|
amount: data.amount,
|
||||||
|
type: data.type,
|
||||||
|
description: data.description,
|
||||||
|
startDate: data.startDate,
|
||||||
|
endDate: data.endDate,
|
||||||
|
pageSize: data.pageSize,
|
||||||
|
currentPage: data.currentPage,
|
||||||
|
};
|
||||||
return http.request<BaseResult<ResultTable>>('get', `bill/noManage/getUserBillList/${data.currentPage}/${data.pageSize}`, { params: data });
|
return http.request<BaseResult<ResultTable>>('get', `bill/noManage/getUserBillList/${data.currentPage}/${data.pageSize}`, { params: data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 账单信息---账单收入和支出 */
|
/** 账单信息---账单收入和支出 */
|
||||||
export const fetchGetExpendOrIncome = (data: any) => {
|
export const fetchGetExpendOrIncome = (data: any) => {
|
||||||
|
data = { userId: data.userId, type: data.type, startDate: data.startDate, endDate: data.endDate };
|
||||||
return http.request<BaseResult<object>>('get', 'bill/noManage/getExpendOrIncome', { params: data });
|
return http.request<BaseResult<object>>('get', 'bill/noManage/getExpendOrIncome', { params: data });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,166 +0,0 @@
|
||||||
<script lang="tsx" setup>
|
|
||||||
import { useRenderIcon } from '@/components/CommonIcon/src/hooks';
|
|
||||||
import PureTable from '@pureadmin/table';
|
|
||||||
import { $t } from '@/plugins/i18n';
|
|
||||||
import { ElTag, ElText } from 'element-plus';
|
|
||||||
import { onMounted, reactive, ref, watch } from 'vue';
|
|
||||||
import { fetchGetUserBillList } from '@/api/v1/financial/user/billUser';
|
|
||||||
import Empty from './empty.svg?component';
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
financialType: { type: Number as PropType<any>, default: undefined },
|
|
||||||
startDate: { type: String as PropType<any>, default: undefined },
|
|
||||||
endDate: { type: String as PropType<any>, default: undefined },
|
|
||||||
});
|
|
||||||
|
|
||||||
const columns: TableColumnList = [
|
|
||||||
{ type: 'index', index: (index: number) => index + 1, label: '序号', width: 60 },
|
|
||||||
// 金额
|
|
||||||
{
|
|
||||||
label: $t('amount'),
|
|
||||||
prop: 'amount',
|
|
||||||
sortable: true,
|
|
||||||
formatter({ type, amount }) {
|
|
||||||
return type === -1 ? (
|
|
||||||
<ElText size={'large'} type={'danger'} style={{ fontWeight: 800 }}>
|
|
||||||
- {amount}¥
|
|
||||||
</ElText>
|
|
||||||
) : (
|
|
||||||
<ElText size={'large'} type={'success'} style={{ fontWeight: 800 }}>
|
|
||||||
+ {amount}¥
|
|
||||||
</ElText>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
width: 200,
|
|
||||||
},
|
|
||||||
// 类别
|
|
||||||
{
|
|
||||||
label: $t('categoryName'),
|
|
||||||
prop: 'categoryName',
|
|
||||||
width: 150,
|
|
||||||
formatter({ categoryName }) {
|
|
||||||
return <ElTag effect={'plain'}>{categoryName}</ElTag>;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// 描述
|
|
||||||
{ label: $t('description'), prop: 'description' },
|
|
||||||
// 交易日期
|
|
||||||
{
|
|
||||||
label: $t('transactionDate'),
|
|
||||||
prop: 'transactionDate',
|
|
||||||
width: 190,
|
|
||||||
sortable: true,
|
|
||||||
formatter({ transactionDate }) {
|
|
||||||
return (
|
|
||||||
<ElText type={'success'} style={{ fontWeight: 800 }}>
|
|
||||||
{transactionDate}
|
|
||||||
</ElText>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const form = reactive({
|
|
||||||
// 类型:1 - 收入,-1 - 支出
|
|
||||||
type: props.financialType,
|
|
||||||
// 开始交易日期
|
|
||||||
startDate: props.startDate,
|
|
||||||
// 结束交易日期
|
|
||||||
endDate: props.endDate,
|
|
||||||
pagination: {
|
|
||||||
pageSize: 10,
|
|
||||||
currentPage: 1,
|
|
||||||
layout: 'prev, pager, next',
|
|
||||||
total: 1,
|
|
||||||
align: 'center',
|
|
||||||
hideOnSinglePage: false,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const dataList = ref([]);
|
|
||||||
const loading = ref(false);
|
|
||||||
|
|
||||||
/* 初始化数据 */
|
|
||||||
async function onSearch() {
|
|
||||||
loading.value = true;
|
|
||||||
|
|
||||||
const result = await fetchGetUserBillList({ ...form, ...form.pagination });
|
|
||||||
dataList.value = result.data.list;
|
|
||||||
form.pagination.currentPage = result.data.pageNo;
|
|
||||||
form.pagination.pageSize = result.data.pageSize;
|
|
||||||
form.pagination.total = result.data.total;
|
|
||||||
|
|
||||||
loading.value = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 修改分页 */
|
|
||||||
async function onCurrentChange(page: number) {
|
|
||||||
form.pagination.currentPage = page;
|
|
||||||
await onSearch();
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
watch(
|
|
||||||
() => props,
|
|
||||||
async () => {
|
|
||||||
form.startDate = props.startDate;
|
|
||||||
form.endDate = props.endDate;
|
|
||||||
await onSearch();
|
|
||||||
},
|
|
||||||
{ immediate: true, deep: true },
|
|
||||||
);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<pure-table
|
|
||||||
:columns="columns"
|
|
||||||
:data="dataList"
|
|
||||||
:loading="loading"
|
|
||||||
:loading-config="{ background: 'transparent' }"
|
|
||||||
:pagination="form.pagination"
|
|
||||||
alignWhole="center"
|
|
||||||
row-key="id"
|
|
||||||
showOverflowTooltip
|
|
||||||
@page-current-change="onCurrentChange"
|
|
||||||
>
|
|
||||||
<template #empty>
|
|
||||||
<el-empty :image-size="60" description="暂无数据" style="height: 430px">
|
|
||||||
<template #image>
|
|
||||||
<Empty />
|
|
||||||
</template>
|
|
||||||
</el-empty>
|
|
||||||
</template>
|
|
||||||
<template #operation="{ row }">
|
|
||||||
<el-button :icon="useRenderIcon('ri:search-line')" :title="`查看序号为${row.id}的详情`" circle plain size="small" />
|
|
||||||
</template>
|
|
||||||
</pure-table>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
.pure-table-filter {
|
|
||||||
.el-table-filter__list {
|
|
||||||
min-width: 80px;
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
li {
|
|
||||||
line-height: 28px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
:deep(.el-table) {
|
|
||||||
--el-table-border: none;
|
|
||||||
--el-table-border-color: transparent;
|
|
||||||
|
|
||||||
.el-empty__description {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-scrollbar__bar {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -19,13 +19,9 @@ const props = defineProps({
|
||||||
});
|
});
|
||||||
|
|
||||||
const { isDark } = useDark();
|
const { isDark } = useDark();
|
||||||
|
|
||||||
const theme = computed(() => (isDark.value ? 'dark' : 'light'));
|
const theme = computed(() => (isDark.value ? 'dark' : 'light'));
|
||||||
|
|
||||||
const chartRef = ref();
|
const chartRef = ref();
|
||||||
const { setOptions } = useECharts(chartRef, {
|
const { setOptions } = useECharts(chartRef, { theme });
|
||||||
theme,
|
|
||||||
});
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props,
|
() => props,
|
||||||
|
|
|
@ -22,40 +22,23 @@ watch(
|
||||||
async () => {
|
async () => {
|
||||||
await nextTick(); // 确保DOM更新完成后再执行
|
await nextTick(); // 确保DOM更新完成后再执行
|
||||||
setOptions({
|
setOptions({
|
||||||
tooltip: {
|
tooltip: { trigger: 'item' },
|
||||||
trigger: 'item',
|
legend: { show: true, textStyle: { color: '#606266', fontSize: '0.875rem' }, bottom: 0 },
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
textStyle: {
|
|
||||||
color: '#606266',
|
|
||||||
fontSize: '0.875rem',
|
|
||||||
},
|
|
||||||
bottom: 0,
|
|
||||||
},
|
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
type: 'pie',
|
type: 'pie',
|
||||||
radius: [16, 130],
|
radius: [10, 110],
|
||||||
roseType: 'area',
|
roseType: 'area',
|
||||||
center: ['50%', '43%'],
|
center: ['50%', '30%'],
|
||||||
labelLine: { length: 3, length2: 6, smooth: true },
|
labelLine: { length: 3, length2: 6, smooth: true },
|
||||||
itemStyle: {
|
itemStyle: { borderRadius: [5, 5, 5, 5] },
|
||||||
borderRadius: [5, 5, 5, 5],
|
label: { position: 'outer', alignTo: 'edge', edgeDistance: 10 },
|
||||||
},
|
|
||||||
label: {
|
|
||||||
position: 'outer',
|
|
||||||
alignTo: 'edge',
|
|
||||||
edgeDistance: 10,
|
|
||||||
},
|
|
||||||
data: props.categoryData,
|
data: props.categoryData,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
{
|
{ deep: true, immediate: true },
|
||||||
deep: true,
|
|
||||||
immediate: true,
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -7,37 +7,60 @@ import CharLine from '@/components/Analyse/char-line.vue';
|
||||||
import CharPie from '@/components/Analyse/char-pie.vue';
|
import CharPie from '@/components/Analyse/char-pie.vue';
|
||||||
import { $t } from '@/plugins/i18n';
|
import { $t } from '@/plugins/i18n';
|
||||||
import { currentMouth, currentWeek, currentYear } from '@/enums/dateEnums';
|
import { currentMouth, currentWeek, currentYear } from '@/enums/dateEnums';
|
||||||
import AnalyseTable from '@/components/Analyse/analyse-table.vue';
|
import AnalyseTable from '@/components/Analyse/table/analyse-table.vue';
|
||||||
|
|
||||||
interface Title {
|
interface Title {
|
||||||
|
// 分析标题
|
||||||
analyse: string;
|
analyse: string;
|
||||||
|
// 分类标题
|
||||||
category: string;
|
category: string;
|
||||||
|
// 表格标题
|
||||||
table: string;
|
table: string;
|
||||||
|
// 排行榜标题
|
||||||
top: string;
|
top: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
// 标题
|
||||||
title: { type: Object as PropType<Title> },
|
title: { type: Object as PropType<Title> },
|
||||||
|
// 收入还是支出类型
|
||||||
financialType: { type: Number as PropType<any> },
|
financialType: { type: Number as PropType<any> },
|
||||||
|
// 总和
|
||||||
|
count: { type: Number as PropType<any>, default: 0 },
|
||||||
|
// 分析概览图表颜色
|
||||||
color: {
|
color: {
|
||||||
type: Array as PropType<Array<string>>,
|
type: Array as PropType<Array<string>>,
|
||||||
},
|
},
|
||||||
|
// 表格数据
|
||||||
|
dataList: { type: Array as PropType<any>, default: () => [] },
|
||||||
|
// 查询的表单
|
||||||
|
form: { type: Object as PropType<any>, default: () => ({}) },
|
||||||
|
// 修改当前页
|
||||||
|
onCurrentChange: {
|
||||||
|
type: Function as PropType<any>,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
|
// 查询的日期
|
||||||
date: {
|
date: {
|
||||||
type: Array as PropType<Array<number>>,
|
type: Array as PropType<Array<number>>,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
},
|
},
|
||||||
|
// 概览分析x轴数据
|
||||||
analyseXAxis: {
|
analyseXAxis: {
|
||||||
type: Array as PropType<Array<number>>,
|
type: Array as PropType<Array<number>>,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
},
|
},
|
||||||
|
// 分析数据
|
||||||
analyseData: {
|
analyseData: {
|
||||||
type: Array as PropType<Array<number>>,
|
type: Array as PropType<Array<number>>,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
},
|
},
|
||||||
|
// 分类数据
|
||||||
categoryData: {
|
categoryData: {
|
||||||
type: Array as PropType<Array<number>>,
|
type: Array as PropType<Array<number>>,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
},
|
},
|
||||||
|
// 排行榜数据
|
||||||
topData: {
|
topData: {
|
||||||
type: Array as PropType<Array<number>>,
|
type: Array as PropType<Array<number>>,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
|
@ -46,10 +69,8 @@ const props = defineProps({
|
||||||
const emits = defineEmits(['emitDateRange']);
|
const emits = defineEmits(['emitDateRange']);
|
||||||
|
|
||||||
const { isDark } = useDark();
|
const { isDark } = useDark();
|
||||||
|
|
||||||
// 选择查询日期范围
|
// 选择查询日期范围
|
||||||
const dateRange = ref(props.date);
|
const dateRange = ref(props.date);
|
||||||
|
|
||||||
// 日期范围选择
|
// 日期范围选择
|
||||||
const shortcuts = [
|
const shortcuts = [
|
||||||
{ text: $t('thisWeek'), value: currentWeek },
|
{ text: $t('thisWeek'), value: currentWeek },
|
||||||
|
@ -67,11 +88,13 @@ const onChangeDateRange = () => {
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-row :gutter="24" justify="space-around">
|
<el-row :gutter="24" justify="space-around">
|
||||||
|
<!-- 分析概览 -->
|
||||||
<re-col v-motion :enter="{ opacity: 1, y: 0, transition: { delay: 400 } }" :initial="{ opacity: 0, y: 100 }" :value="18" :xs="24" class="mb-[18px]">
|
<re-col v-motion :enter="{ opacity: 1, y: 0, transition: { delay: 400 } }" :initial="{ opacity: 0, y: 100 }" :value="18" :xs="24" class="mb-[18px]">
|
||||||
<el-card class="bar-card" shadow="never">
|
<el-card class="bar-card" shadow="never">
|
||||||
<div class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
<span class="text-md font-medium">{{ title.analyse }}</span>
|
<span class="text-md font-medium">{{ title.analyse }}</span>
|
||||||
<span>
|
<span>
|
||||||
|
<slot name="formBefore" />
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="dateRange"
|
v-model="dateRange"
|
||||||
:end-placeholder="$t('endDate')"
|
:end-placeholder="$t('endDate')"
|
||||||
|
@ -83,6 +106,8 @@ const onChangeDateRange = () => {
|
||||||
value-format="YYYY-MM-DD"
|
value-format="YYYY-MM-DD"
|
||||||
@change="onChangeDateRange"
|
@change="onChangeDateRange"
|
||||||
/>
|
/>
|
||||||
|
<slot name="formAfter" />
|
||||||
|
<el-text class="ml-2" size="large" type="danger">{{ $t('sumUp') }}:{{ count.toFixed(2) }}</el-text>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-between items-start mt-3">
|
<div class="flex justify-between items-start mt-3">
|
||||||
|
@ -91,6 +116,7 @@ const onChangeDateRange = () => {
|
||||||
</el-card>
|
</el-card>
|
||||||
</re-col>
|
</re-col>
|
||||||
|
|
||||||
|
<!-- 分类图表-->
|
||||||
<re-col v-motion :enter="{ opacity: 1, y: 0, transition: { delay: 400 } }" :initial="{ opacity: 0, y: 100 }" :value="6" :xs="24" class="mb-[18px]">
|
<re-col v-motion :enter="{ opacity: 1, y: 0, transition: { delay: 400 } }" :initial="{ opacity: 0, y: 100 }" :value="6" :xs="24" class="mb-[18px]">
|
||||||
<el-card class="bar-card" shadow="never">
|
<el-card class="bar-card" shadow="never">
|
||||||
<div class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
|
@ -102,15 +128,17 @@ const onChangeDateRange = () => {
|
||||||
</el-card>
|
</el-card>
|
||||||
</re-col>
|
</re-col>
|
||||||
|
|
||||||
|
<!-- 数据统计表格 -->
|
||||||
<re-col v-motion :enter="{ opacity: 1, y: 0, transition: { delay: 560 } }" :initial="{ opacity: 0, y: 100 }" :value="18" :xs="24" class="mb-[18px]">
|
<re-col v-motion :enter="{ opacity: 1, y: 0, transition: { delay: 560 } }" :initial="{ opacity: 0, y: 100 }" :value="18" :xs="24" class="mb-[18px]">
|
||||||
<el-card class="h-[580px]" shadow="never">
|
<el-card class="h-[580px]" shadow="never">
|
||||||
<div class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
<span class="text-md font-medium">{{ title.table }}</span>
|
<span class="text-md font-medium">{{ title.table }}</span>
|
||||||
</div>
|
</div>
|
||||||
<analyse-table :endDate="dateRange[1]" :financialType="financialType" :startDate="dateRange[0]" class="mt-3" />
|
<analyse-table :data-list="dataList" :form="form" :on-current-change="onCurrentChange" class="mt-3" />
|
||||||
</el-card>
|
</el-card>
|
||||||
</re-col>
|
</re-col>
|
||||||
|
|
||||||
|
<!-- 排行榜 -->
|
||||||
<re-col v-motion :enter="{ opacity: 1, y: 0, transition: { delay: 560 } }" :initial="{ opacity: 0, y: 100 }" :value="6" :xs="24" class="mb-[18px]">
|
<re-col v-motion :enter="{ opacity: 1, y: 0, transition: { delay: 560 } }" :initial="{ opacity: 0, y: 100 }" :value="6" :xs="24" class="mb-[18px]">
|
||||||
<el-card shadow="never">
|
<el-card shadow="never">
|
||||||
<div class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import PureTable from '@pureadmin/table';
|
||||||
|
import Empty from './empty.svg?component';
|
||||||
|
import { columns } from '@/components/Analyse/table/columns';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
dataList: { type: Array as PropType<any>, default: () => [] },
|
||||||
|
form: { type: Object as PropType<any>, default: () => ({}) },
|
||||||
|
onCurrentChange: {
|
||||||
|
type: Function as PropType<any>,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<pure-table
|
||||||
|
:columns="columns"
|
||||||
|
:data="dataList"
|
||||||
|
:height="430"
|
||||||
|
:loading="form.loading"
|
||||||
|
:loading-config="{ background: 'transparent' }"
|
||||||
|
:pagination="form.pagination"
|
||||||
|
alignWhole="center"
|
||||||
|
row-key="id"
|
||||||
|
showOverflowTooltip
|
||||||
|
@page-current-change="onCurrentChange"
|
||||||
|
>
|
||||||
|
<template #empty>
|
||||||
|
<el-empty :image-size="60" description="暂无数据" style="height: 430px">
|
||||||
|
<template #image>
|
||||||
|
<Empty />
|
||||||
|
</template>
|
||||||
|
</el-empty>
|
||||||
|
</template>
|
||||||
|
</pure-table>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.pure-table-filter {
|
||||||
|
.el-table-filter__list {
|
||||||
|
min-width: 80px;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
li {
|
||||||
|
line-height: 28px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
:deep(.el-table) {
|
||||||
|
--el-table-border: none;
|
||||||
|
--el-table-border-color: transparent;
|
||||||
|
|
||||||
|
.el-empty__description {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-scrollbar__bar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,48 @@
|
||||||
|
import { $t } from '@/plugins/i18n';
|
||||||
|
|
||||||
|
export const columns: TableColumnList = [
|
||||||
|
{ type: 'index', index: (index: number) => index + 1, label: '序号', width: 60 },
|
||||||
|
// 金额
|
||||||
|
{
|
||||||
|
label: $t('amount'),
|
||||||
|
prop: 'amount',
|
||||||
|
sortable: true,
|
||||||
|
formatter({ type, amount }) {
|
||||||
|
return type === -1 ? (
|
||||||
|
<ElText size={'large'} type={'danger'} style={{ fontWeight: 800 }}>
|
||||||
|
- {amount}¥
|
||||||
|
</ElText>
|
||||||
|
) : (
|
||||||
|
<ElText size={'large'} type={'success'} style={{ fontWeight: 800 }}>
|
||||||
|
+ {amount}¥
|
||||||
|
</ElText>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
width: 200,
|
||||||
|
},
|
||||||
|
// 类别
|
||||||
|
{
|
||||||
|
label: $t('categoryName'),
|
||||||
|
prop: 'categoryName',
|
||||||
|
width: 150,
|
||||||
|
formatter({ categoryName }) {
|
||||||
|
return <ElTag effect={'plain'}>{categoryName}</ElTag>;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// 描述
|
||||||
|
{ label: $t('description'), prop: 'description' },
|
||||||
|
// 交易日期
|
||||||
|
{
|
||||||
|
label: $t('transactionDate'),
|
||||||
|
prop: 'transactionDate',
|
||||||
|
width: 190,
|
||||||
|
sortable: true,
|
||||||
|
formatter({ transactionDate }) {
|
||||||
|
return (
|
||||||
|
<ElText type={'success'} style={{ fontWeight: 800 }}>
|
||||||
|
{transactionDate}
|
||||||
|
</ElText>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
@ -1,10 +1,10 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import Analyse from '@/components/Analyse/index.vue';
|
import Analyse from '@/components/Analyse/index.vue';
|
||||||
import { onMounted, reactive, ref } from 'vue';
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
|
import { $t } from '@/plugins/i18n';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { currentMouth, days } from '@/enums/dateEnums';
|
import { currentMouth, days } from '@/enums/dateEnums';
|
||||||
import { fetchGetExpendOrIncome } from '@/api/v1/financial/user/billUser';
|
import { fetchGetExpendOrIncome, fetchGetUserBillList } from '@/api/v1/financial/user/billUser';
|
||||||
import { $t } from '@/plugins/i18n';
|
|
||||||
|
|
||||||
const title = {
|
const title = {
|
||||||
analyse: $t('expenditureAnalysis'),
|
analyse: $t('expenditureAnalysis'),
|
||||||
|
@ -19,11 +19,23 @@ const analyseData = ref([]);
|
||||||
const categoryList = ref([]);
|
const categoryList = ref([]);
|
||||||
// 排行榜数据
|
// 排行榜数据
|
||||||
const topList = ref([]);
|
const topList = ref([]);
|
||||||
|
// 表格数据
|
||||||
|
const dataList = ref([]);
|
||||||
|
// 总金额
|
||||||
|
const count = ref(0);
|
||||||
|
// 查询表单
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
type: -1,
|
type: -1,
|
||||||
startDate: dayjs(currentMouth[0]).format('YYYY-MM-DD'),
|
startDate: dayjs(currentMouth[0]).format('YYYY-MM-DD'),
|
||||||
endDate: dayjs(currentMouth[1]).format('YYYY-MM-DD'),
|
endDate: dayjs(currentMouth[1]).format('YYYY-MM-DD'),
|
||||||
|
pagination: {
|
||||||
|
pageSize: 10,
|
||||||
|
currentPage: 1,
|
||||||
|
layout: 'prev, pager, next',
|
||||||
|
total: 1,
|
||||||
|
align: 'center',
|
||||||
|
hideOnSinglePage: false,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
/** 查询账单支出 */
|
/** 查询账单支出 */
|
||||||
|
@ -33,6 +45,7 @@ const onSearch = async () => {
|
||||||
form.endDate = dayjs(form.endDate).format('YYYY-MM-DD');
|
form.endDate = dayjs(form.endDate).format('YYYY-MM-DD');
|
||||||
|
|
||||||
// 获取数据
|
// 获取数据
|
||||||
|
await onTableSearch();
|
||||||
const result = await fetchGetExpendOrIncome(form);
|
const result = await fetchGetExpendOrIncome(form);
|
||||||
if (result.code !== 200) return;
|
if (result.code !== 200) return;
|
||||||
|
|
||||||
|
@ -42,6 +55,10 @@ const onSearch = async () => {
|
||||||
result.data.chartList.forEach(item => {
|
result.data.chartList.forEach(item => {
|
||||||
const transactionDate = item.transactionDate;
|
const transactionDate = item.transactionDate;
|
||||||
const date = `${dayjs(transactionDate).format('MM-DD')} ${days[dayjs(transactionDate).day()]}`;
|
const date = `${dayjs(transactionDate).format('MM-DD')} ${days[dayjs(transactionDate).day()]}`;
|
||||||
|
// 计算总和
|
||||||
|
count.value += Number(item.amount);
|
||||||
|
|
||||||
|
// 设置坐标数据
|
||||||
analyseData.value.push(item.amount);
|
analyseData.value.push(item.amount);
|
||||||
analyseXAxis.value.push(date);
|
analyseXAxis.value.push(date);
|
||||||
});
|
});
|
||||||
|
@ -60,6 +77,26 @@ const onSearch = async () => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* 初始化数据 */
|
||||||
|
async function onTableSearch() {
|
||||||
|
form.loading = true;
|
||||||
|
|
||||||
|
// 查询账单数据
|
||||||
|
const result = await fetchGetUserBillList({ ...form, ...form.pagination });
|
||||||
|
dataList.value = result.data.list;
|
||||||
|
form.pagination.currentPage = result.data.pageNo;
|
||||||
|
form.pagination.pageSize = result.data.pageSize;
|
||||||
|
form.pagination.total = result.data.total;
|
||||||
|
|
||||||
|
form.loading = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 修改分页 */
|
||||||
|
async function onCurrentChange(page: number) {
|
||||||
|
form.pagination.currentPage = page;
|
||||||
|
await onSearch();
|
||||||
|
}
|
||||||
|
|
||||||
/** 选择查询日期 */
|
/** 选择查询日期 */
|
||||||
const onChangeDateRange = async dateRange => {
|
const onChangeDateRange = async dateRange => {
|
||||||
form.startDate = dateRange[0];
|
form.startDate = dateRange[0];
|
||||||
|
@ -78,8 +115,12 @@ onMounted(() => {
|
||||||
:analyseXAxis="analyseXAxis"
|
:analyseXAxis="analyseXAxis"
|
||||||
:category-data="categoryList"
|
:category-data="categoryList"
|
||||||
:color="['#41b6ff', '#F56C6C']"
|
:color="['#41b6ff', '#F56C6C']"
|
||||||
|
:count="count"
|
||||||
|
:data-list="dataList"
|
||||||
:date="[form.startDate, form.endDate]"
|
:date="[form.startDate, form.endDate]"
|
||||||
:financialType="form.type"
|
:financialType="form.type"
|
||||||
|
:form="form"
|
||||||
|
:on-current-change="onCurrentChange"
|
||||||
:title="title"
|
:title="title"
|
||||||
:top-data="topList"
|
:top-data="topList"
|
||||||
@emit-date-range="onChangeDateRange"
|
@emit-date-range="onChangeDateRange"
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import Analyse from '@/components/Analyse/index.vue';
|
import Analyse from '@/components/Analyse/index.vue';
|
||||||
import { onMounted, reactive, ref } from 'vue';
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
import { currentMouth, days } from '@/enums/dateEnums';
|
|
||||||
import { fetchGetExpendOrIncome } from '@/api/v1/financial/user/billUser';
|
|
||||||
import { $t } from '@/plugins/i18n';
|
import { $t } from '@/plugins/i18n';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
import { currentMouth, days } from '@/enums/dateEnums';
|
||||||
|
import { fetchGetExpendOrIncome, fetchGetUserBillList } from '@/api/v1/financial/user/billUser';
|
||||||
|
|
||||||
const title = {
|
const title = {
|
||||||
analyse: $t('revenueAnalysis'),
|
analyse: $t('revenueAnalysis'),
|
||||||
|
@ -20,20 +20,33 @@ const analyseData = ref([]);
|
||||||
const categoryList = ref([]);
|
const categoryList = ref([]);
|
||||||
// 排行榜数据
|
// 排行榜数据
|
||||||
const topList = ref([]);
|
const topList = ref([]);
|
||||||
|
// 表格数据
|
||||||
|
const dataList = ref([]);
|
||||||
|
// 总金额
|
||||||
|
const count = ref(0);
|
||||||
|
// 查询表单
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
type: 1,
|
type: 1,
|
||||||
startDate: dayjs(currentMouth[0]).format('YYYY-MM-DD'),
|
startDate: dayjs(currentMouth[0]).format('YYYY-MM-DD'),
|
||||||
endDate: dayjs(currentMouth[1]).format('YYYY-MM-DD'),
|
endDate: dayjs(currentMouth[1]).format('YYYY-MM-DD'),
|
||||||
|
pagination: {
|
||||||
|
pageSize: 10,
|
||||||
|
currentPage: 1,
|
||||||
|
layout: 'prev, pager, next',
|
||||||
|
total: 1,
|
||||||
|
align: 'center',
|
||||||
|
hideOnSinglePage: false,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
/** 查询账单收入 */
|
/** 查询账单支出 */
|
||||||
const onSearch = async () => {
|
const onSearch = async () => {
|
||||||
// 格式化请求数据
|
// 格式化请求数据
|
||||||
form.startDate = dayjs(form.startDate).format('YYYY-MM-DD');
|
form.startDate = dayjs(form.startDate).format('YYYY-MM-DD');
|
||||||
form.endDate = dayjs(form.endDate).format('YYYY-MM-DD');
|
form.endDate = dayjs(form.endDate).format('YYYY-MM-DD');
|
||||||
|
|
||||||
// 获取数据
|
// 获取数据
|
||||||
|
await onTableSearch();
|
||||||
const result = await fetchGetExpendOrIncome(form);
|
const result = await fetchGetExpendOrIncome(form);
|
||||||
if (result.code !== 200) return;
|
if (result.code !== 200) return;
|
||||||
|
|
||||||
|
@ -43,6 +56,10 @@ const onSearch = async () => {
|
||||||
result.data.chartList.forEach(item => {
|
result.data.chartList.forEach(item => {
|
||||||
const transactionDate = item.transactionDate;
|
const transactionDate = item.transactionDate;
|
||||||
const date = `${dayjs(transactionDate).format('MM-DD')} ${days[dayjs(transactionDate).day()]}`;
|
const date = `${dayjs(transactionDate).format('MM-DD')} ${days[dayjs(transactionDate).day()]}`;
|
||||||
|
// 计算总和
|
||||||
|
count.value += Number(item.amount);
|
||||||
|
|
||||||
|
// 设置坐标数据
|
||||||
analyseData.value.push(item.amount);
|
analyseData.value.push(item.amount);
|
||||||
analyseXAxis.value.push(date);
|
analyseXAxis.value.push(date);
|
||||||
});
|
});
|
||||||
|
@ -61,6 +78,25 @@ const onSearch = async () => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* 初始化数据 */
|
||||||
|
async function onTableSearch() {
|
||||||
|
form.loading = true;
|
||||||
|
|
||||||
|
const result = await fetchGetUserBillList({ ...form, ...form.pagination });
|
||||||
|
dataList.value = result.data.list;
|
||||||
|
form.pagination.currentPage = result.data.pageNo;
|
||||||
|
form.pagination.pageSize = result.data.pageSize;
|
||||||
|
form.pagination.total = result.data.total;
|
||||||
|
|
||||||
|
form.loading = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 修改分页 */
|
||||||
|
async function onCurrentChange(page: number) {
|
||||||
|
form.pagination.currentPage = page;
|
||||||
|
await onSearch();
|
||||||
|
}
|
||||||
|
|
||||||
/** 选择查询日期 */
|
/** 选择查询日期 */
|
||||||
const onChangeDateRange = async dateRange => {
|
const onChangeDateRange = async dateRange => {
|
||||||
form.startDate = dateRange[0];
|
form.startDate = dateRange[0];
|
||||||
|
@ -79,8 +115,12 @@ onMounted(() => {
|
||||||
:analyseXAxis="analyseXAxis"
|
:analyseXAxis="analyseXAxis"
|
||||||
:category-data="categoryList"
|
:category-data="categoryList"
|
||||||
:color="['#41b6ff', '#67C23A']"
|
:color="['#41b6ff', '#67C23A']"
|
||||||
|
:count="count"
|
||||||
|
:data-list="dataList"
|
||||||
:date="[form.startDate, form.endDate]"
|
:date="[form.startDate, form.endDate]"
|
||||||
:financialType="form.type"
|
:financialType="form.type"
|
||||||
|
:form="form"
|
||||||
|
:on-current-change="onCurrentChange"
|
||||||
:title="title"
|
:title="title"
|
||||||
:top-data="topList"
|
:top-data="topList"
|
||||||
@emit-date-range="onChangeDateRange"
|
@emit-date-range="onChangeDateRange"
|
||||||
|
|
|
@ -0,0 +1,167 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import Analyse from '@/components/Analyse/index.vue';
|
||||||
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
|
import { $t } from '@/plugins/i18n';
|
||||||
|
import LoadingSvg from '@/assets/svg/loading.svg';
|
||||||
|
import { useAdminUserStore } from '@/store/system/adminUser';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import { currentMouth, days } from '@/enums/dateEnums';
|
||||||
|
import { fetchGetExpendOrIncome } from '@/api/v1/financial/user/billUser';
|
||||||
|
import { fetchGetBillList } from '@/api/v1/financial/admin/bill';
|
||||||
|
|
||||||
|
const title = {
|
||||||
|
analyse: $t('expenditureAnalysis'),
|
||||||
|
category: $t('paymentLedger'),
|
||||||
|
table: $t('dataStatistics'),
|
||||||
|
top: $t('rankingList'),
|
||||||
|
};
|
||||||
|
const adminUserStore = useAdminUserStore();
|
||||||
|
const loading = ref(false);
|
||||||
|
// 用户信息列表
|
||||||
|
const userDataList = ref();
|
||||||
|
|
||||||
|
// 分析概览
|
||||||
|
const analyseXAxis = ref([]);
|
||||||
|
const analyseData = ref([]);
|
||||||
|
// 分类数据
|
||||||
|
const categoryList = ref([]);
|
||||||
|
// 排行榜数据
|
||||||
|
const topList = ref([]);
|
||||||
|
const dataList = ref([]);
|
||||||
|
// 总金额
|
||||||
|
const count = ref(0);
|
||||||
|
|
||||||
|
// 查询表单
|
||||||
|
const form = reactive({
|
||||||
|
userId: undefined,
|
||||||
|
type: -1,
|
||||||
|
startDate: dayjs(currentMouth[0]).format('YYYY-MM-DD'),
|
||||||
|
endDate: dayjs(currentMouth[1]).format('YYYY-MM-DD'),
|
||||||
|
pagination: {
|
||||||
|
pageSize: 10,
|
||||||
|
currentPage: 1,
|
||||||
|
layout: 'prev, pager, next',
|
||||||
|
total: 1,
|
||||||
|
align: 'center',
|
||||||
|
hideOnSinglePage: false,
|
||||||
|
},
|
||||||
|
loading: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
/** 查询账单支出 */
|
||||||
|
const onSearch = async () => {
|
||||||
|
// 格式化请求数据
|
||||||
|
form.startDate = dayjs(form.startDate).format('YYYY-MM-DD');
|
||||||
|
form.endDate = dayjs(form.endDate).format('YYYY-MM-DD');
|
||||||
|
|
||||||
|
// 获取数据
|
||||||
|
await onTableSearch();
|
||||||
|
const result = await fetchGetExpendOrIncome(form);
|
||||||
|
if (result.code !== 200) return;
|
||||||
|
|
||||||
|
// 分析概览
|
||||||
|
analyseData.value = [];
|
||||||
|
analyseXAxis.value = [];
|
||||||
|
result.data.chartList.forEach(item => {
|
||||||
|
const transactionDate = item.transactionDate;
|
||||||
|
const date = `${dayjs(transactionDate).format('MM-DD')} ${days[dayjs(transactionDate).day()]}`;
|
||||||
|
// 计算总和
|
||||||
|
count.value += Number(item.amount);
|
||||||
|
|
||||||
|
// 设置坐标数据
|
||||||
|
analyseData.value.push(item.amount);
|
||||||
|
analyseXAxis.value.push(date);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 分类数据
|
||||||
|
categoryList.value = result.data.categoryAmounts.map(categoryAmount => ({
|
||||||
|
value: categoryAmount.amount,
|
||||||
|
name: categoryAmount.categoryName,
|
||||||
|
}));
|
||||||
|
|
||||||
|
// 排行榜
|
||||||
|
topList.value = result.data.list.map(item => {
|
||||||
|
const transactionDate = item.transactionDate;
|
||||||
|
const date = `${dayjs(transactionDate).format('YYYY-MM-DD')} ${days[dayjs(transactionDate).day()]}`;
|
||||||
|
return { date, amount: item.amount, name: item.categoryName };
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 初始化数据 */
|
||||||
|
async function onTableSearch() {
|
||||||
|
form.loading = true;
|
||||||
|
|
||||||
|
// 查询账单数据
|
||||||
|
const result = await fetchGetBillList({ ...form, ...form.pagination });
|
||||||
|
dataList.value = result.data.list;
|
||||||
|
form.pagination.currentPage = result.data.pageNo;
|
||||||
|
form.pagination.pageSize = result.data.pageSize;
|
||||||
|
form.pagination.total = result.data.total;
|
||||||
|
|
||||||
|
form.loading = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 修改分页 */
|
||||||
|
async function onCurrentChange(page: number) {
|
||||||
|
form.pagination.currentPage = page;
|
||||||
|
await onSearch();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 选择查询日期 */
|
||||||
|
const onChangeDateRange = dateRange => {
|
||||||
|
form.startDate = dateRange[0];
|
||||||
|
form.endDate = dateRange[1];
|
||||||
|
onSearch();
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 查询用户信息 */
|
||||||
|
const onSearchUserinfo = async (keyword: string) => {
|
||||||
|
loading.value = true;
|
||||||
|
userDataList.value = await adminUserStore.queryUser({ keyword });
|
||||||
|
loading.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
onSearch();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Analyse
|
||||||
|
:analyse-data="analyseData"
|
||||||
|
:analyseXAxis="analyseXAxis"
|
||||||
|
:category-data="categoryList"
|
||||||
|
:color="['#41b6ff', '#F56C6C']"
|
||||||
|
:count="count"
|
||||||
|
:data-list="dataList"
|
||||||
|
:date="[form.startDate, form.endDate]"
|
||||||
|
:financialType="form.type"
|
||||||
|
:form="form"
|
||||||
|
:on-current-change="onCurrentChange"
|
||||||
|
:title="title"
|
||||||
|
:top-data="topList"
|
||||||
|
@emit-date-range="onChangeDateRange"
|
||||||
|
>
|
||||||
|
<template #formBefore>
|
||||||
|
<el-select
|
||||||
|
v-model="form.userId"
|
||||||
|
:loading="loading"
|
||||||
|
:placeholder="$t('user')"
|
||||||
|
:remote-method="onSearchUserinfo"
|
||||||
|
class="!w-[180px]"
|
||||||
|
clearable
|
||||||
|
filterable
|
||||||
|
remote
|
||||||
|
remote-show-suffix
|
||||||
|
@change="onSearch"
|
||||||
|
>
|
||||||
|
<el-option v-for="item in userDataList" :key="item.id" :label="item.username" :value="item.id" />
|
||||||
|
<template #loading>
|
||||||
|
<el-icon class="is-loading">
|
||||||
|
<LoadingSvg />
|
||||||
|
</el-icon>
|
||||||
|
</template>
|
||||||
|
</el-select>
|
||||||
|
</template>
|
||||||
|
</Analyse>
|
||||||
|
</template>
|
|
@ -0,0 +1,168 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import Analyse from '@/components/Analyse/index.vue';
|
||||||
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
|
import { $t } from '@/plugins/i18n';
|
||||||
|
import LoadingSvg from '@/assets/svg/loading.svg';
|
||||||
|
import { useAdminUserStore } from '@/store/system/adminUser';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import { currentMouth, days } from '@/enums/dateEnums';
|
||||||
|
import { fetchGetExpendOrIncome } from '@/api/v1/financial/user/billUser';
|
||||||
|
import { fetchGetBillList } from '@/api/v1/financial/admin/bill';
|
||||||
|
|
||||||
|
const title = {
|
||||||
|
analyse: $t('revenueAnalysis'),
|
||||||
|
category: $t('incomeBrackets'),
|
||||||
|
table: $t('dataStatistics'),
|
||||||
|
top: $t('rankingList'),
|
||||||
|
};
|
||||||
|
|
||||||
|
const adminUserStore = useAdminUserStore();
|
||||||
|
const loading = ref(false);
|
||||||
|
// 用户信息列表
|
||||||
|
const userDataList = ref();
|
||||||
|
|
||||||
|
// 分析概览
|
||||||
|
const analyseXAxis = ref([]);
|
||||||
|
const analyseData = ref([]);
|
||||||
|
// 分类数据
|
||||||
|
const categoryList = ref([]);
|
||||||
|
// 排行榜数据
|
||||||
|
const topList = ref([]);
|
||||||
|
const dataList = ref([]);
|
||||||
|
// 总金额
|
||||||
|
const count = ref(0);
|
||||||
|
|
||||||
|
// 查询表单
|
||||||
|
const form = reactive({
|
||||||
|
userId: undefined,
|
||||||
|
type: 1,
|
||||||
|
startDate: dayjs(currentMouth[0]).format('YYYY-MM-DD'),
|
||||||
|
endDate: dayjs(currentMouth[1]).format('YYYY-MM-DD'),
|
||||||
|
pagination: {
|
||||||
|
pageSize: 10,
|
||||||
|
currentPage: 1,
|
||||||
|
layout: 'prev, pager, next',
|
||||||
|
total: 1,
|
||||||
|
align: 'center',
|
||||||
|
hideOnSinglePage: false,
|
||||||
|
},
|
||||||
|
loading: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
/** 查询账单支出 */
|
||||||
|
const onSearch = async () => {
|
||||||
|
// 格式化请求数据
|
||||||
|
form.startDate = dayjs(form.startDate).format('YYYY-MM-DD');
|
||||||
|
form.endDate = dayjs(form.endDate).format('YYYY-MM-DD');
|
||||||
|
|
||||||
|
// 获取数据
|
||||||
|
await onTableSearch();
|
||||||
|
const result = await fetchGetExpendOrIncome(form);
|
||||||
|
if (result.code !== 200) return;
|
||||||
|
|
||||||
|
// 分析概览
|
||||||
|
analyseData.value = [];
|
||||||
|
analyseXAxis.value = [];
|
||||||
|
result.data.chartList.forEach(item => {
|
||||||
|
const transactionDate = item.transactionDate;
|
||||||
|
const date = `${dayjs(transactionDate).format('MM-DD')} ${days[dayjs(transactionDate).day()]}`;
|
||||||
|
// 计算总和
|
||||||
|
count.value += Number(item.amount);
|
||||||
|
|
||||||
|
// 设置坐标数据
|
||||||
|
analyseData.value.push(item.amount);
|
||||||
|
analyseXAxis.value.push(date);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 分类数据
|
||||||
|
categoryList.value = result.data.categoryAmounts.map(categoryAmount => ({
|
||||||
|
value: categoryAmount.amount,
|
||||||
|
name: categoryAmount.categoryName,
|
||||||
|
}));
|
||||||
|
|
||||||
|
// 排行榜
|
||||||
|
topList.value = result.data.list.map(item => {
|
||||||
|
const transactionDate = item.transactionDate;
|
||||||
|
const date = `${dayjs(transactionDate).format('YYYY-MM-DD')} ${days[dayjs(transactionDate).day()]}`;
|
||||||
|
return { date, amount: item.amount, name: item.categoryName };
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 查询表格数据 */
|
||||||
|
async function onTableSearch() {
|
||||||
|
form.loading = true;
|
||||||
|
|
||||||
|
// 获取账单数据
|
||||||
|
const result = await fetchGetBillList({ ...form, ...form.pagination });
|
||||||
|
dataList.value = result.data.list;
|
||||||
|
form.pagination.currentPage = result.data.pageNo;
|
||||||
|
form.pagination.pageSize = result.data.pageSize;
|
||||||
|
form.pagination.total = result.data.total;
|
||||||
|
|
||||||
|
form.loading = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 修改分页 */
|
||||||
|
async function onCurrentChange(page: number) {
|
||||||
|
form.pagination.currentPage = page;
|
||||||
|
await onSearch();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 选择查询日期 */
|
||||||
|
const onChangeDateRange = dateRange => {
|
||||||
|
form.startDate = dateRange[0];
|
||||||
|
form.endDate = dateRange[1];
|
||||||
|
onSearch();
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 查询用户数据 */
|
||||||
|
const onSearchUserinfo = async (keyword: string) => {
|
||||||
|
loading.value = true;
|
||||||
|
userDataList.value = await adminUserStore.queryUser({ keyword });
|
||||||
|
loading.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
onSearch();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Analyse
|
||||||
|
:analyse-data="analyseData"
|
||||||
|
:analyseXAxis="analyseXAxis"
|
||||||
|
:category-data="categoryList"
|
||||||
|
:color="['#41b6ff', '#67C23A']"
|
||||||
|
:count="count"
|
||||||
|
:data-list="dataList"
|
||||||
|
:date="[form.startDate, form.endDate]"
|
||||||
|
:financialType="form.type"
|
||||||
|
:form="form"
|
||||||
|
:on-current-change="onCurrentChange"
|
||||||
|
:title="title"
|
||||||
|
:top-data="topList"
|
||||||
|
@emit-date-range="onChangeDateRange"
|
||||||
|
>
|
||||||
|
<template #formBefore>
|
||||||
|
<el-select
|
||||||
|
v-model="form.userId"
|
||||||
|
:loading="loading"
|
||||||
|
:placeholder="$t('user')"
|
||||||
|
:remote-method="onSearchUserinfo"
|
||||||
|
class="!w-[180px]"
|
||||||
|
clearable
|
||||||
|
filterable
|
||||||
|
remote
|
||||||
|
remote-show-suffix
|
||||||
|
@change="onSearch"
|
||||||
|
>
|
||||||
|
<el-option v-for="item in userDataList" :key="item.id" :label="item.username" :value="item.id" />
|
||||||
|
<template #loading>
|
||||||
|
<el-icon class="is-loading">
|
||||||
|
<LoadingSvg />
|
||||||
|
</el-icon>
|
||||||
|
</template>
|
||||||
|
</el-select>
|
||||||
|
</template>
|
||||||
|
</Analyse>
|
||||||
|
</template>
|
Loading…
Reference in New Issue