fix: 账务报表优化

This commit is contained in:
ZhuRui
2026-08-05 18:19:34 +08:00
parent b496fb60e2
commit e542d7bdf3
4 changed files with 106 additions and 15 deletions
+4 -2
View File
@@ -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;
+15 -4
View File
@@ -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,6 +197,7 @@ export default defineComponent({
退 退
</div> </div>
</div> </div>
<div class={styles.dateRangeSelector}>
<RangePicker <RangePicker
picker="month" picker="month"
format="YYYY-MM" format="YYYY-MM"
@@ -201,6 +205,15 @@ export default defineComponent({
onUpdate:value={handleDateRangeChange} onUpdate:value={handleDateRangeChange}
style={{ width: '240px' }} 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,
}; };
} }