This commit is contained in:
2026-05-06 18:55:17 +08:00
parent 7369fe4117
commit fcc6acbcee
5 changed files with 91 additions and 34 deletions
+32
View File
@@ -0,0 +1,32 @@
# 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 会自动添加新字段
- 前端颜色选择与日程类型联动
+11 -1
View File
@@ -30,11 +30,11 @@ type TabCalendarEvent struct {
ID uint `gorm:"primarykey"`
CalendarID uint `gorm:"not null;index;comment:关联日历ID"`
UserID uint `gorm:"not null;comment:创建人ID"`
//UsersID []uint `gorm:"type:json; null;comment:其他关联用户ID"`
Title string `gorm:"size:200;not null;comment:事件标题"`
StartDate *time.Time `gorm:"size:10;not null;index;comment:开始日期 YYYY-MM-DD"`
EndDate *time.Time `gorm:"size:10;not null;index;comment:结束日期 YYYY-MM-DD"`
IsAllDay bool `gorm:"default:true;comment:是否全日事件"`
ScheduleType string `gorm:"size:50;default:work;comment:日程类型: work-工作 duty-值班 exam-考试 standby-待命 personal_holiday-调休 personal_holiday-公假"`
BgColor string `gorm:"size:50;default:#3788d9;comment:背景颜色"`
IsPublic bool `gorm:"default:false;comment:是否为公共日程"`
Remark string `gorm:"type:text;comment:备注"`
@@ -376,6 +376,10 @@ func ApiCalendar(r *gin.RouterGroup) {
color, _ := data["color"].(string)
remark, _ := data["remark"].(string)
isPublic, _ := data["is_public"].(bool)
scheduleType, _ := data["schedule_type"].(string)
if scheduleType == "" {
scheduleType = "work"
}
startDate, _ := time.Parse("2006-01-02 15:04:05", startStr)
endDate, _ := time.Parse("2006-01-02 15:04:05", endStr)
@@ -386,6 +390,7 @@ func ApiCalendar(r *gin.RouterGroup) {
Title: title,
StartDate: &startDate,
EndDate: &endDate,
ScheduleType: scheduleType,
BgColor: color,
IsPublic: isPublic,
Remark: remark,
@@ -442,6 +447,10 @@ func ApiCalendar(r *gin.RouterGroup) {
color, _ := data["color"].(string)
remark, _ := data["remark"].(string)
isPublic, _ := data["is_public"].(bool)
scheduleType, _ := data["schedule_type"].(string)
if scheduleType == "" {
scheduleType = "work"
}
startDate, _ := time.Parse("2006-01-02 15:04:05", startStr)
endDate, _ := time.Parse("2006-01-02 15:04:05", endStr)
@@ -450,6 +459,7 @@ func ApiCalendar(r *gin.RouterGroup) {
Title: title,
StartDate: &startDate,
EndDate: &endDate,
ScheduleType: scheduleType,
BgColor: color,
IsPublic: isPublic,
Remark: remark,
+1
View File
@@ -312,6 +312,7 @@
"standby": "Standby",
"personal_holiday": "Personal Holiday",
"public_holiday": "Public Holiday",
"event_type": "Event Type",
"to": "To",
"close": "Close",
"copy": "Copy",
+1
View File
@@ -312,6 +312,7 @@
"standby": "备用",
"personal_holiday": "个人假期",
"public_holiday": "公众假期",
"event_type": "日程类型",
"to": "至",
"close": "关闭",
"copy": "复制",
@@ -37,6 +37,7 @@ const eventData = ref({
startDate: "",
endDate: "",
color: "#3788d9",
scheduleType: "work",
isPublic: false,
isEditing: false,
isEditable: false,
@@ -78,13 +79,14 @@ function closeEventModal() {
showModal.value = false
}
function openEventModal(dateStr, dataEnd, id = 0, title = "", color = "#3788d9", isPublic = false, isEditing = false, isEditable = true) {
function openEventModal(dateStr, dataEnd, id = 0, title = "", color = "#3788d9", scheduleType = "work", isPublic = false, isEditing = false, isEditable = true) {
eventData.value = {
id: id,
title: title,
startDate: dateStr,
endDate: dataEnd,
color: color,
scheduleType: scheduleType,
isPublic: isPublic,
isEditing: isEditing,
isEditable: isEditable,
@@ -99,6 +101,7 @@ function editEvent(info) {
parseInt(info.event.id),
info.event.title,
info.event.backgroundColor,
info.event.extendedProps?.scheduleType || "work",
info.event.extendedProps?.isPublic || false,
true,
info.event.durationEditable,
@@ -108,6 +111,11 @@ function editEvent(info) {
function selectColor(colorValue) {
if (eventData.value.isEditable) {
eventData.value.color = colorValue
// 根据颜色更新日程类型
const selectedColor = colorOptions.value.find(c => c.value === colorValue)
if (selectedColor) {
eventData.value.scheduleType = selectedColor.type
}
}
}
@@ -129,9 +137,6 @@ async function saveEvent() {
return
}
const selectedColor = colorOptions.value.find(c => c.value === eventData.value.color)
const scheduleType = selectedColor ? selectedColor.type : "work"
try {
let result
if (eventData.value.isEditing) {
@@ -144,7 +149,7 @@ async function saveEvent() {
? eventData.value.endDate
: DateUtils.toRealEnd(eventData.value.endDate),
),
schedule_type: scheduleType,
schedule_type: eventData.value.scheduleType,
is_public: eventData.value.isPublic,
})
} else {
@@ -157,7 +162,7 @@ async function saveEvent() {
? eventData.value.endDate
: DateUtils.toRealEnd(eventData.value.endDate),
),
schedule_type: scheduleType,
schedule_type: eventData.value.scheduleType,
is_public: eventData.value.isPublic,
})
}
@@ -218,6 +223,10 @@ async function getEvents() {
backgroundColor: item.BgColor,
borderColor: item.ID === pageData.value.seleEventID ? "#000000" : "#F7F7F7",
allDay: true,
extendedProps: {
scheduleType: item.ScheduleType || "work",
isPublic: item.IsPublic || false,
},
})
})
}
@@ -391,8 +400,6 @@ const calendarOptions = ref({
eventDrop(info) {
// 拖拽后直接更新
const selectedColor = colorOptions.value.find(c => c.value === info.event.backgroundColor)
const scheduleType = selectedColor ? selectedColor.type : "work"
const startStr = info.event.startStr
const endStr = info.event.end ? info.event.endStr : startStr
calendarApi.updateEvent({
@@ -400,7 +407,7 @@ const calendarOptions = ref({
title: info.event.title,
start: toDatetime(startStr),
end: toDatetime(startStr === endStr ? endStr : DateUtils.toRealEnd(endStr)),
schedule_type: scheduleType,
schedule_type: info.event.extendedProps?.scheduleType || "work",
}).then(r => {
if (r.errCode !== 0) toast.error(t('message.server_error'))
else getEvents()
@@ -569,6 +576,12 @@ onMounted(() => {
</div>
</div>
<!-- 日程类型标签 -->
<div class="mb-4 px-1">
<span class="text-sm text-gray-600">{{ t('schedule.event_type') }}: </span>
<span class="text-sm font-medium" :style="{ color: eventData.color }">{{ t('schedule.' + eventData.scheduleType) || eventData.scheduleType }}</span>
</div>
<!-- 公共日程开关 -->
<div class="mb-4 flex items-center justify-between">
<span class="text-gray-700">{{ t('calendar.is_public_event') }}</span>