148 lines
6.7 KiB
Markdown
148 lines
6.7 KiB
Markdown
# 2026-05-06 日志
|
||
|
||
## 日历事件日程类型功能
|
||
|
||
### 修改内容
|
||
- **后端** `routers/apiCalendar.go`:
|
||
- `TabCalendarEvent` 结构体新增 `ScheduleType string` 字段(默认值 work)
|
||
- `addevent`/`updateevent` 接口解析并保存 `schedule_type` 参数
|
||
|
||
- **前端** `CalendarDetail.vue`:
|
||
- `eventData` 新增 `scheduleType` 字段
|
||
- `openEventModal`/`editEvent` 传递 `scheduleType`
|
||
- `selectColor` 函数联动更新 `scheduleType`
|
||
- `saveEvent`/`eventDrop` 提交 `schedule_type`
|
||
- `getEvents` 返回数据附加 `extendedProps.scheduleType`
|
||
- 模态框显示日程类型标签
|
||
|
||
- **i18n**:
|
||
- `zh-CN.json`: 新增 `event_type: "日程类型"`
|
||
- `en.json`: 新增 `event_type: "Event Type"`
|
||
|
||
### 日程类型选项
|
||
- work - 工作
|
||
- duty - 值班
|
||
- exam - 考试
|
||
- standby - 备用
|
||
- personal_holiday - 个人假期
|
||
- public_holiday - 公众假期
|
||
|
||
### 注意事项
|
||
- GORM AutoMigrate 会自动添加新字段
|
||
- 前端颜色选择与日程类型联动
|
||
|
||
## 修复:calendar/events jsonErr
|
||
|
||
**问题**:`fromGetCalendarEvents` 的 `start/end` 是 `*time.Time` 类型,无法直接解析字符串格式的日期。
|
||
|
||
**修复**:改为直接用类型断言解析字符串,用 `time.Parse("2006-01-02", ...)` 解析。
|
||
|
||
## 优化:BgColor 弃用,前端根据 ScheduleType 渲染颜色
|
||
|
||
**前端**:添加 `getColorByScheduleType()` 函数,`getEvents` 中使用 scheduleType 映射颜色。
|
||
|
||
**后端**:只存储 ScheduleType,不处理颜色逻辑。颜色完全由前端 `colorOptions` 控制。
|
||
|
||
## CalendarDetail 滚动标题快照对比
|
||
|
||
**功能**:每次 getEvents 存快照,数据变化或宽度变化时重新计算标题滚动。
|
||
|
||
**实现**:
|
||
- `pageData.lastEventsSnapshot`:存储上一次的 JSON 快照
|
||
- `getEvents()` 末尾对比快照,变化则 `setTimeout(recalcScrollTitles, 150)`
|
||
- `ResizeObserver` 监听日历容器宽度变化,防抖 150ms 后重算
|
||
- `applyScrollToTitle()`:清除旧状态 → 测量 overflow → 设置 `--scroll-distance` 和 `data-truncated` 属性
|
||
|
||
## CalendarList 编辑/删除按钮改用 canEdit
|
||
|
||
**改动**:
|
||
- `CalendarList.vue`:编辑/删除按钮 `v-if` 条件从 `calendar.UserID === userStore.userInfo?.ID` 改为 `calendar.canEdit`
|
||
- 移除废弃的 `useUserStore` 导入
|
||
|
||
## CalendarList 删除改用 ConfirmDialog 组件
|
||
|
||
**改动**:
|
||
- `CalendarList.vue` 导入并使用 `ConfirmDialog` 组件
|
||
- 新增 `showDeleteModal` + `deletingCalendar` 状态
|
||
- `deleteCalendar()` 改为打开确认弹窗,`confirmDelete()` 执行实际删除 API
|
||
- i18n 新增 `calendar.confirm_delete_message`:zh-CN「确定要删除日历「{name}」吗?此操作不可撤销。」,en 英文版
|
||
|
||
## 新增日历管理页面 /calendars/admin
|
||
|
||
**功能**:系统管理员查看所有日历列表,包含日程数量、创建者、创建时间。
|
||
|
||
**新增文件**:
|
||
- `src/views/calendar/CalendarAdminList.vue` - 日历管理列表组件
|
||
|
||
**路由修改** `src/router/index.js`:
|
||
- 新增 `/calendars/admin` 路由,指向 `CalendarAdminList.vue`
|
||
- 设置 `meta: { requireSysAdmin: true }` 要求管理员权限
|
||
|
||
**SysAdminView.vue**:
|
||
- `tabs` 数组新增 `{ id: 'calendar', label: t('calendar.admin_title'), to: '/calendars/admin' }`
|
||
|
||
**i18n 新增**:
|
||
- `zh-CN.json`: `calendar.admin_title = "日历管理"`, `calendar.event_count = "日程数量"`
|
||
- `en.json`: `calendar.admin_title = "Calendar Admin"`, `calendar.event_count = "Event Count"`
|
||
|
||
## 修复:CalendarAdminList eventCounts 未定义
|
||
|
||
**问题**:模板访问 `eventCounts[calendar.ID]` 但 `eventCounts` 从未声明,且 `fetchEventCounts` 未被调用。
|
||
|
||
**修复**:后端已直接返回 `event_count` 字段,改为模板直接用 `calendar.event_count ?? 0`,删除多余的 `eventCounts` ref 和 `fetchEventCounts` 函数。
|
||
|
||
## 新增:后端 TabCalendarEventUserBind 绑定表
|
||
|
||
**文件**:`routers/binds.go`
|
||
- 新增 `TabCalendarEventUserBind` 结构体(EventID/UserID/CreatorID/CreatedAt)
|
||
- 在 `BindsInit` AutoMigrate 中注册
|
||
|
||
## 新增:日历右键菜单(复制/粘贴日程)
|
||
|
||
**文件**:`CalendarDetail.vue`
|
||
|
||
**功能**:
|
||
- 右键日程事件弹出上下文菜单,显示「复制日程」「粘贴日程」
|
||
- 复制:将日程数据存入 `clipboard` ref
|
||
- 粘贴:以 clipboard 数据调用 `addEvent` API 创建新日程
|
||
- 点击任意位置关闭菜单
|
||
|
||
**实现**:
|
||
- `contextMenu` ref 管理菜单显示/位置/事件数据
|
||
- `clipboard` ref 存储复制的日程
|
||
- `eventDidMount` 中为每个事件绑定 `contextmenu` 事件
|
||
- `onMounted` 注册全局 click 关闭菜单,`onBeforeUnmount` 移除
|
||
- i18n 新增 `calendar.copy_event/paste_event/copy_success/paste_success/no_event_to_paste`
|
||
|
||
## 修复:粘贴多天日程时结束日期少1天
|
||
|
||
**问题**:Ctrl+V 粘贴大于1天的日程时,目标结束日期少1天。
|
||
|
||
**原因**:`pasteToDate` 中用 `new Date(targetEndMs).toISOString().split('T')[0]` 计算目标结束日期,`toISOString()` 输出 UTC 时间,在 UTC+8 时区下日期会往前偏移1天。
|
||
|
||
**修复**(`CalendarDetail.vue` `pasteToDate` 函数):
|
||
- 改用天数差 `Math.round((origEndDate - origStartDate) / 86400000)` 替代毫秒差
|
||
- 用本地日期方法 `targetEndDate.setDate(targetEndDate.getDate() + diffDays)` + 手动拼接 `YYYY-MM-DD`,替代 `toISOString().split('T')[0]`
|
||
|
||
## 修复:Ctrl+C 无法复制大于1天的日程
|
||
|
||
**问题**:Ctrl+C 复制多天日程后粘贴无效果。
|
||
|
||
**根因**:`calendarOptions.value.events` 中多天事件的 `end` 是 `DateUtils.toCalendarEnd()` 返回的 **Date 对象**(非字符串)。Ctrl+C 直接 `selectedEvent.end || selectedEvent.start` 存入 clipboard,导致 `pasteToDate` 调用 `clipboard.value.end.split('T')[0]` 时 Date 对象没有 `split` 方法而报错。单天事件因走 `isSameDay` 分支不解析 `end`,所以不受影响。
|
||
|
||
**修复**(`CalendarDetail.vue` `handleKeyDown` Ctrl+C 分支):
|
||
- 检测 `end` 是否为 Date 实例,如果是则用本地日期方法转为 `YYYY-MM-DD` 字符串再存入 clipboard
|
||
|
||
## 新增:编辑事件窗口显示创建者
|
||
|
||
**功能**:编辑事件模态框标题居中显示「xxx 创建」
|
||
|
||
**实现**(参考 ScheduleView.vue):
|
||
- 导入 `useUsersStore`,添加 `usersStore`
|
||
- `pageData.eventBindUserID`:数组,每项 `{ eventID, userID }`
|
||
- `getUserIdFromEventID(eventID)`:通过事件ID查创建者用户ID
|
||
- `getUsernameFromUserID(userID)`:调用 `usersStore.getUsernameFromUserID(userID)`(有缓存)
|
||
- `getEvents` 中遍历事件时 `pageData.value.eventBindUserID.push({ eventID: item.ID, userID: item.UserID })`
|
||
- 模态框标题新增 `<h5 v-if="eventData.isEditing && getUserIdFromEventID(eventData.id)">` 居中显示
|
||
- i18n:`calendar.created_by` = "{name} 创建" / "Created by {name}"
|