feat: 集成 apisbo.com 中国节假日 API 自动获取+缓存

- 新增 holidays.py 服务:按年获取节假日数据,缓存到 system_config
- 区分 holiday(工作日假日)和 workday(调休上班日)两种类型
- is_working_day() 支持调休判断:周末在 workdays 集合中视为工作日
- 启动时自动从 API 刷新当年+明年数据,失败则使用缓存
- 系统设置新增「从 API 刷新」按钮,支局长可手动触发
- 支持 2010-2026 年数据,API 免费免鉴权

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-07-12 14:17:31 +08:00
parent a63bd6874c
commit 7dcb22f573
7 changed files with 199 additions and 33 deletions
+18 -1
View File
@@ -17,6 +17,7 @@ const notificationTime = ref('17:30')
const notificationTimeLoading = ref(false)
const holidays = ref('')
const holidaysLoading = ref(false)
const holidaysRefreshing = ref(false)
const importLoading = ref(false)
const importFile = ref<File | null>(null)
@@ -90,6 +91,19 @@ async function handleSaveHolidays() {
} finally { holidaysLoading.value = false }
}
async function handleRefreshHolidays() {
holidaysRefreshing.value = true
try {
const res = await api.post('/system-config/refresh-holidays')
ElMessage.success(`节假日数据已刷新:${res.data.holidays} 个假日,${res.data.workdays} 个调休`)
// Reload the config display
const cfg = await api.get('/system-config')
if (cfg.data?.holidays) holidays.value = cfg.data.holidays
} catch (e: any) {
ElMessage.error(e.response?.data?.detail || '刷新失败')
} finally { holidaysRefreshing.value = false }
}
function handleImportFile(e: Event) {
const target = e.target as HTMLInputElement
if (target.files?.[0]) importFile.value = target.files[0]
@@ -246,7 +260,10 @@ async function handleImportPreview() {
/>
<el-button type="primary" :loading="holidaysLoading" @click="handleSaveHolidays" size="small">保存</el-button>
</div>
<p style="color:var(--warm-gray);font-size:12px;margin-top:6px">配置后仪表盘和催办提醒在这些日期将跳过填报检查周末自动跳过无需配置</p>
<p style="color:var(--warm-gray);font-size:12px;margin-top:6px">
数据来源apisbo.com 中国节假日 API · 周末自动跳过无需配置
<el-button :loading="holidaysRefreshing" @click="handleRefreshHolidays" size="small" text type="primary" style="margin-left:8px"> API 刷新</el-button>
</p>
</div>
</div>
</el-card>