fix: 账务报表优化
This commit is contained in:
@@ -35,8 +35,10 @@ export interface FinanceReportVO {
|
||||
|
||||
/** 财务报表查询参数 */
|
||||
export interface ReportQueryParams {
|
||||
/** 查询日期 yyyy-MM */
|
||||
date: string;
|
||||
/** 起始月份 yyyy-MM */
|
||||
beginDate: string;
|
||||
/** 结束月份 yyyy-MM */
|
||||
endDate: string;
|
||||
}
|
||||
|
||||
export interface ApiResult<T> {
|
||||
|
||||
@@ -22,6 +22,12 @@
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.dateRangeSelector {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.reportTitle {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
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 { useReportsModel } from './model/useReportsModel';
|
||||
import { useEffect, useContainerSize } from '@/hooks';
|
||||
@@ -15,12 +15,15 @@ export default defineComponent({
|
||||
setup() {
|
||||
const {
|
||||
dateRange,
|
||||
preset,
|
||||
handleDateRangeChange,
|
||||
handlePresetChange,
|
||||
summary,
|
||||
chartData,
|
||||
detailColumns,
|
||||
detailData,
|
||||
formatMoney,
|
||||
PRESET_OPTIONS,
|
||||
} = useReportsModel();
|
||||
|
||||
// ===== echarts 组合图 =====
|
||||
@@ -194,13 +197,23 @@ export default defineComponent({
|
||||
平台资金流水概览,包括收入、退款、提现、用户余额等核心财务指标
|
||||
</div>
|
||||
</div>
|
||||
<RangePicker
|
||||
picker="month"
|
||||
format="YYYY-MM"
|
||||
value={dateRange.value}
|
||||
onUpdate:value={handleDateRangeChange}
|
||||
style={{ width: '240px' }}
|
||||
/>
|
||||
<div class={styles.dateRangeSelector}>
|
||||
<RangePicker
|
||||
picker="month"
|
||||
format="YYYY-MM"
|
||||
value={dateRange.value}
|
||||
onUpdate:value={handleDateRangeChange}
|
||||
style={{ width: '240px' }}
|
||||
/>
|
||||
<Select
|
||||
value={preset.value}
|
||||
onUpdate:value={handlePresetChange}
|
||||
options={[...PRESET_OPTIONS]}
|
||||
placeholder="请选择"
|
||||
allowClear
|
||||
style={{ width: '120px' }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* ===== 统计卡 ===== */}
|
||||
@@ -211,9 +224,7 @@ export default defineComponent({
|
||||
<div class={styles.statValue} style={{ color: item.accentColor }}>
|
||||
¥{formatMoney(item.value)}
|
||||
</div>
|
||||
<div class={styles.statDesc} style="visibility: hidden;">
|
||||
-
|
||||
</div>
|
||||
{/* 趋势文字暂时隐藏 */}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -1,8 +1,58 @@
|
||||
import { computed, ref } from 'vue';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { useRequest } from '@/hooks/useRequest';
|
||||
import { getFinanceReport, type FinanceReportVO } from './services';
|
||||
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 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 参数 =====
|
||||
const buildQueryParams = () => {
|
||||
const [start, end] = dateRange.value;
|
||||
@@ -130,10 +192,17 @@ export function useReportsModel() {
|
||||
}));
|
||||
});
|
||||
|
||||
// ===== 时间范围变更 =====
|
||||
// ===== 时间范围变更(限制最大跨度 1 年,同步快捷选项) =====
|
||||
const handleDateRangeChange = (val: any) => {
|
||||
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 {
|
||||
dateRange,
|
||||
preset,
|
||||
loading,
|
||||
handleDateRangeChange,
|
||||
handlePresetChange,
|
||||
summary,
|
||||
chartData,
|
||||
detailColumns,
|
||||
detailData,
|
||||
formatMoney,
|
||||
PRESET_OPTIONS: PRESET_OPTIONS as any,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user