fix: 账务报表优化
This commit is contained in:
@@ -35,8 +35,10 @@ export interface FinanceReportVO {
|
|||||||
|
|
||||||
/** 财务报表查询参数 */
|
/** 财务报表查询参数 */
|
||||||
export interface ReportQueryParams {
|
export interface ReportQueryParams {
|
||||||
/** 查询日期 yyyy-MM */
|
/** 起始月份 yyyy-MM */
|
||||||
date: string;
|
beginDate: string;
|
||||||
|
/** 结束月份 yyyy-MM */
|
||||||
|
endDate: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ApiResult<T> {
|
export interface ApiResult<T> {
|
||||||
|
|||||||
@@ -22,6 +22,12 @@
|
|||||||
gap: 6px;
|
gap: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dateRangeSelector {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
.reportTitle {
|
.reportTitle {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { defineComponent, ref, nextTick } from 'vue';
|
import { defineComponent, ref, nextTick } from 'vue';
|
||||||
import { DatePicker, Table } from 'ant-design-vue';
|
import { DatePicker, Select, Table } from 'ant-design-vue';
|
||||||
import * as echarts from 'echarts';
|
import * as echarts from 'echarts';
|
||||||
import { useReportsModel } from './model/useReportsModel';
|
import { useReportsModel } from './model/useReportsModel';
|
||||||
import { useEffect, useContainerSize } from '@/hooks';
|
import { useEffect, useContainerSize } from '@/hooks';
|
||||||
@@ -15,12 +15,15 @@ export default defineComponent({
|
|||||||
setup() {
|
setup() {
|
||||||
const {
|
const {
|
||||||
dateRange,
|
dateRange,
|
||||||
|
preset,
|
||||||
handleDateRangeChange,
|
handleDateRangeChange,
|
||||||
|
handlePresetChange,
|
||||||
summary,
|
summary,
|
||||||
chartData,
|
chartData,
|
||||||
detailColumns,
|
detailColumns,
|
||||||
detailData,
|
detailData,
|
||||||
formatMoney,
|
formatMoney,
|
||||||
|
PRESET_OPTIONS,
|
||||||
} = useReportsModel();
|
} = useReportsModel();
|
||||||
|
|
||||||
// ===== echarts 组合图 =====
|
// ===== echarts 组合图 =====
|
||||||
@@ -194,13 +197,23 @@ export default defineComponent({
|
|||||||
平台资金流水概览,包括收入、退款、提现、用户余额等核心财务指标
|
平台资金流水概览,包括收入、退款、提现、用户余额等核心财务指标
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<RangePicker
|
<div class={styles.dateRangeSelector}>
|
||||||
picker="month"
|
<RangePicker
|
||||||
format="YYYY-MM"
|
picker="month"
|
||||||
value={dateRange.value}
|
format="YYYY-MM"
|
||||||
onUpdate:value={handleDateRangeChange}
|
value={dateRange.value}
|
||||||
style={{ width: '240px' }}
|
onUpdate:value={handleDateRangeChange}
|
||||||
/>
|
style={{ width: '240px' }}
|
||||||
|
/>
|
||||||
|
<Select
|
||||||
|
value={preset.value}
|
||||||
|
onUpdate:value={handlePresetChange}
|
||||||
|
options={[...PRESET_OPTIONS]}
|
||||||
|
placeholder="请选择"
|
||||||
|
allowClear
|
||||||
|
style={{ width: '120px' }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* ===== 统计卡 ===== */}
|
{/* ===== 统计卡 ===== */}
|
||||||
@@ -211,9 +224,7 @@ export default defineComponent({
|
|||||||
<div class={styles.statValue} style={{ color: item.accentColor }}>
|
<div class={styles.statValue} style={{ color: item.accentColor }}>
|
||||||
¥{formatMoney(item.value)}
|
¥{formatMoney(item.value)}
|
||||||
</div>
|
</div>
|
||||||
<div class={styles.statDesc} style="visibility: hidden;">
|
{/* 趋势文字暂时隐藏 */}
|
||||||
-
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,8 +1,58 @@
|
|||||||
import { computed, ref } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
|
import { message } from 'ant-design-vue';
|
||||||
import { useRequest } from '@/hooks/useRequest';
|
import { useRequest } from '@/hooks/useRequest';
|
||||||
import { getFinanceReport, type FinanceReportVO } from './services';
|
import { getFinanceReport, type FinanceReportVO } from './services';
|
||||||
import dayjs, { type Dayjs } from 'dayjs';
|
import dayjs, { type Dayjs } from 'dayjs';
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// 常量
|
||||||
|
// ============================================================
|
||||||
|
|
||||||
|
/** 快捷时间段选项 */
|
||||||
|
export const PRESET_OPTIONS = [
|
||||||
|
{ value: 'thisMonth' as const, label: '本月' },
|
||||||
|
{ value: 'lastMonth' as const, label: '上月' },
|
||||||
|
{ value: 'thisQuarter' as const, label: '本季度' },
|
||||||
|
{ value: 'thisYear' as const, label: '本年' },
|
||||||
|
];
|
||||||
|
|
||||||
|
type PresetValue = (typeof PRESET_OPTIONS)[number]['value'];
|
||||||
|
|
||||||
|
/** 根据快捷选项获取日期范围 */
|
||||||
|
function getPresetRange(preset: PresetValue): [Dayjs, Dayjs] {
|
||||||
|
switch (preset) {
|
||||||
|
case 'thisMonth':
|
||||||
|
return [dayjs().startOf('month'), dayjs().endOf('month')];
|
||||||
|
case 'lastMonth':
|
||||||
|
return [
|
||||||
|
dayjs().subtract(1, 'month').startOf('month'),
|
||||||
|
dayjs().subtract(1, 'month').endOf('month'),
|
||||||
|
];
|
||||||
|
case 'thisQuarter': {
|
||||||
|
const m = dayjs().month();
|
||||||
|
const start = dayjs()
|
||||||
|
.month(Math.floor(m / 3) * 3)
|
||||||
|
.startOf('month');
|
||||||
|
return [start, start.add(2, 'month').endOf('month')];
|
||||||
|
}
|
||||||
|
case 'thisYear':
|
||||||
|
return [dayjs().startOf('year'), dayjs().endOf('year')];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 判断时间范围是否匹配某个快捷选项 */
|
||||||
|
function matchPreset(range: [Dayjs, Dayjs]): PresetValue | undefined {
|
||||||
|
const a = range[0].format('YYYY-MM');
|
||||||
|
const b = range[1].format('YYYY-MM');
|
||||||
|
for (const opt of PRESET_OPTIONS) {
|
||||||
|
const [ps, pe] = getPresetRange(opt.value);
|
||||||
|
if (ps.format('YYYY-MM') === a && pe.format('YYYY-MM') === b) {
|
||||||
|
return opt.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// 工具
|
// 工具
|
||||||
// ============================================================
|
// ============================================================
|
||||||
@@ -34,6 +84,18 @@ export function useReportsModel() {
|
|||||||
// ===== 时间范围(年月区间选择器) =====
|
// ===== 时间范围(年月区间选择器) =====
|
||||||
const dateRange = ref<[Dayjs, Dayjs]>([dayjs().startOf('month'), dayjs().startOf('month')]);
|
const dateRange = ref<[Dayjs, Dayjs]>([dayjs().startOf('month'), dayjs().startOf('month')]);
|
||||||
|
|
||||||
|
// ===== 快捷时间段下拉 =====
|
||||||
|
const preset = ref<PresetValue | undefined>('thisMonth');
|
||||||
|
|
||||||
|
const handlePresetChange = (val: any) => {
|
||||||
|
if (!val || !PRESET_OPTIONS.some((o) => o.value === val)) {
|
||||||
|
preset.value = undefined;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
preset.value = val;
|
||||||
|
dateRange.value = getPresetRange(val);
|
||||||
|
};
|
||||||
|
|
||||||
// ===== 构建 API 参数 =====
|
// ===== 构建 API 参数 =====
|
||||||
const buildQueryParams = () => {
|
const buildQueryParams = () => {
|
||||||
const [start, end] = dateRange.value;
|
const [start, end] = dateRange.value;
|
||||||
@@ -130,10 +192,17 @@ export function useReportsModel() {
|
|||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
// ===== 时间范围变更 =====
|
// ===== 时间范围变更(限制最大跨度 1 年,同步快捷选项) =====
|
||||||
const handleDateRangeChange = (val: any) => {
|
const handleDateRangeChange = (val: any) => {
|
||||||
if (!val || val.length < 2) return;
|
if (!val || val.length < 2) return;
|
||||||
dateRange.value = [dayjs(val[0]), dayjs(val[1])];
|
const [s, e] = [dayjs(val[0]), dayjs(val[1])];
|
||||||
|
if (Math.abs(e.diff(s, 'month')) > 11) {
|
||||||
|
message.warning('时间跨度不能超过 1 年');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dateRange.value = [s, e];
|
||||||
|
// 同步快捷下拉:匹配到预设则选中,否则清空
|
||||||
|
preset.value = matchPreset([s, e]);
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 千分位格式金额(页面渲染用) */
|
/** 千分位格式金额(页面渲染用) */
|
||||||
@@ -147,12 +216,15 @@ export function useReportsModel() {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
dateRange,
|
dateRange,
|
||||||
|
preset,
|
||||||
loading,
|
loading,
|
||||||
handleDateRangeChange,
|
handleDateRangeChange,
|
||||||
|
handlePresetChange,
|
||||||
summary,
|
summary,
|
||||||
chartData,
|
chartData,
|
||||||
detailColumns,
|
detailColumns,
|
||||||
detailData,
|
detailData,
|
||||||
formatMoney,
|
formatMoney,
|
||||||
|
PRESET_OPTIONS: PRESET_OPTIONS as any,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user