From 2a3c3cdbf2398695d61633e072f98ee2757e9e27 Mon Sep 17 00:00:00 2001
From: longz <longzhaoz@qq.com>
Date: 星期二, 11 八月 2026 11:20:26 +0800
Subject: [PATCH] feat(appointment): 添加访客预约系统解除绑定功能
---
frontend-admin/src/views/DashboardView.vue | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 54 insertions(+), 1 deletions(-)
diff --git a/frontend-admin/src/views/DashboardView.vue b/frontend-admin/src/views/DashboardView.vue
index c9e42ab..1155b86 100644
--- a/frontend-admin/src/views/DashboardView.vue
+++ b/frontend-admin/src/views/DashboardView.vue
@@ -44,8 +44,10 @@
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="YYYY-MM-DD"
+ :disabled-date="disabledChartDate"
:clearable="false"
- @change="loadAppointmentStats"
+ @calendar-change="handleChartCalendarChange"
+ @change="handleChartDateRangeChange"
/>
</div>
</div>
@@ -158,6 +160,8 @@
};
const ALL_DEPT_VALUE = "ALL" as const;
+const DAY_MS = 24 * 60 * 60 * 1000;
+const MAX_CHART_RANGE_DAYS = 31;
const deptOptions = ref<DeptTreeOption[]>([]);
const deptFilter = ref<number | typeof ALL_DEPT_VALUE>(ALL_DEPT_VALUE);
@@ -167,6 +171,8 @@
let lineChartInstance: ECharts | null = null;
const chartDateRange = ref<[string, string]>(getCurrentWeekRange());
+const lastValidChartDateRange = ref<[string, string]>([...chartDateRange.value]);
+const chartPickerBaseDate = ref<Date | null>(null);
const overview = ref<DashboardOverview>({
startDate: "",
@@ -236,6 +242,53 @@
return `${year}-${month}-${day}`;
}
+function parseDateOnly(value?: string): Date | null {
+ if (!value) {
+ return null;
+ }
+ const parts = value.split("-").map(Number);
+ if (parts.length !== 3 || parts.some(Number.isNaN)) {
+ return null;
+ }
+ return new Date(parts[0], parts[1] - 1, parts[2]);
+}
+
+function daysBetween(start?: string, end?: string): number {
+ const startDate = parseDateOnly(start);
+ const endDate = parseDateOnly(end);
+ if (!startDate || !endDate) {
+ return 0;
+ }
+ return Math.floor(Math.abs(endDate.getTime() - startDate.getTime()) / DAY_MS) + 1;
+}
+
+function isChartDateRangeValid(range?: [string, string] | null): range is [string, string] {
+ return Array.isArray(range) && range.length === 2 && daysBetween(range[0], range[1]) <= MAX_CHART_RANGE_DAYS;
+}
+
+function disabledChartDate(date: Date) {
+ if (!chartPickerBaseDate.value) {
+ return false;
+ }
+ const diffDays = Math.abs(date.getTime() - chartPickerBaseDate.value.getTime()) / DAY_MS;
+ return diffDays > MAX_CHART_RANGE_DAYS - 1;
+}
+
+function handleChartCalendarChange(value: Date[]) {
+ chartPickerBaseDate.value = value?.[0] || null;
+}
+
+function handleChartDateRangeChange(value: [string, string] | null) {
+ chartPickerBaseDate.value = null;
+ if (!isChartDateRangeValid(value)) {
+ chartDateRange.value = [...lastValidChartDateRange.value];
+ ElMessage.warning(`预约数据最多只能查询${MAX_CHART_RANGE_DAYS}天`);
+ return;
+ }
+ lastValidChartDateRange.value = [...value];
+ loadAppointmentStats();
+}
+
function formatNumber(value: number | undefined): string {
return new Intl.NumberFormat("zh-CN").format(Number(value) || 0);
}
--
Gitblit v1.7.1