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
@@ -22,6 +22,12 @@
gap: 6px;
}
.dateRangeSelector {
display: flex;
align-items: center;
gap: 12px;
}
.reportTitle {
font-size: 20px;
font-weight: 600;
+22 -11
View File
@@ -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,
};
}