up
This commit is contained in:
@@ -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 会自动添加新字段
|
||||||
|
- 前端颜色选择与日程类型联动
|
||||||
@@ -27,17 +27,17 @@ type TabCalendar struct {
|
|||||||
|
|
||||||
// TabCalendarEvent 日历事件表
|
// TabCalendarEvent 日历事件表
|
||||||
type TabCalendarEvent struct {
|
type TabCalendarEvent struct {
|
||||||
ID uint `gorm:"primarykey"`
|
ID uint `gorm:"primarykey"`
|
||||||
CalendarID uint `gorm:"not null;index;comment:关联日历ID"`
|
CalendarID uint `gorm:"not null;index;comment:关联日历ID"`
|
||||||
UserID uint `gorm:"not null;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:事件标题"`
|
||||||
Title string `gorm:"size:200;not null;comment:事件标题"`
|
StartDate *time.Time `gorm:"size:10;not null;index;comment:开始日期 YYYY-MM-DD"`
|
||||||
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"`
|
||||||
EndDate *time.Time `gorm:"size:10;not null;index;comment:结束日期 YYYY-MM-DD"`
|
IsAllDay bool `gorm:"default:true;comment:是否全日事件"`
|
||||||
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:背景颜色"`
|
BgColor string `gorm:"size:50;default:#3788d9;comment:背景颜色"`
|
||||||
IsPublic bool `gorm:"default:false;comment:是否为公共日程"`
|
IsPublic bool `gorm:"default:false;comment:是否为公共日程"`
|
||||||
Remark string `gorm:"type:text;comment:备注"`
|
Remark string `gorm:"type:text;comment:备注"`
|
||||||
|
|
||||||
CreatedAt *time.Time `gorm:"type:datetime;autoCreateTime;comment:创建时间"`
|
CreatedAt *time.Time `gorm:"type:datetime;autoCreateTime;comment:创建时间"`
|
||||||
UpdatedAt *time.Time `gorm:"type:datetime;autoUpdateTime;comment:最后修改时间"`
|
UpdatedAt *time.Time `gorm:"type:datetime;autoUpdateTime;comment:最后修改时间"`
|
||||||
@@ -376,19 +376,24 @@ func ApiCalendar(r *gin.RouterGroup) {
|
|||||||
color, _ := data["color"].(string)
|
color, _ := data["color"].(string)
|
||||||
remark, _ := data["remark"].(string)
|
remark, _ := data["remark"].(string)
|
||||||
isPublic, _ := data["is_public"].(bool)
|
isPublic, _ := data["is_public"].(bool)
|
||||||
|
scheduleType, _ := data["schedule_type"].(string)
|
||||||
|
if scheduleType == "" {
|
||||||
|
scheduleType = "work"
|
||||||
|
}
|
||||||
|
|
||||||
startDate, _ := time.Parse("2006-01-02 15:04:05", startStr)
|
startDate, _ := time.Parse("2006-01-02 15:04:05", startStr)
|
||||||
endDate, _ := time.Parse("2006-01-02 15:04:05", endStr)
|
endDate, _ := time.Parse("2006-01-02 15:04:05", endStr)
|
||||||
|
|
||||||
event := TabCalendarEvent{
|
event := TabCalendarEvent{
|
||||||
CalendarID: calendarID,
|
CalendarID: calendarID,
|
||||||
UserID: user.ID,
|
UserID: user.ID,
|
||||||
Title: title,
|
Title: title,
|
||||||
StartDate: &startDate,
|
StartDate: &startDate,
|
||||||
EndDate: &endDate,
|
EndDate: &endDate,
|
||||||
BgColor: color,
|
ScheduleType: scheduleType,
|
||||||
IsPublic: isPublic,
|
BgColor: color,
|
||||||
Remark: remark,
|
IsPublic: isPublic,
|
||||||
|
Remark: remark,
|
||||||
}
|
}
|
||||||
if event.BgColor == "" {
|
if event.BgColor == "" {
|
||||||
event.BgColor = calendar.Color
|
event.BgColor = calendar.Color
|
||||||
@@ -442,17 +447,22 @@ func ApiCalendar(r *gin.RouterGroup) {
|
|||||||
color, _ := data["color"].(string)
|
color, _ := data["color"].(string)
|
||||||
remark, _ := data["remark"].(string)
|
remark, _ := data["remark"].(string)
|
||||||
isPublic, _ := data["is_public"].(bool)
|
isPublic, _ := data["is_public"].(bool)
|
||||||
|
scheduleType, _ := data["schedule_type"].(string)
|
||||||
|
if scheduleType == "" {
|
||||||
|
scheduleType = "work"
|
||||||
|
}
|
||||||
|
|
||||||
startDate, _ := time.Parse("2006-01-02 15:04:05", startStr)
|
startDate, _ := time.Parse("2006-01-02 15:04:05", startStr)
|
||||||
endDate, _ := time.Parse("2006-01-02 15:04:05", endStr)
|
endDate, _ := time.Parse("2006-01-02 15:04:05", endStr)
|
||||||
|
|
||||||
newEvent := TabCalendarEvent{
|
newEvent := TabCalendarEvent{
|
||||||
Title: title,
|
Title: title,
|
||||||
StartDate: &startDate,
|
StartDate: &startDate,
|
||||||
EndDate: &endDate,
|
EndDate: &endDate,
|
||||||
BgColor: color,
|
ScheduleType: scheduleType,
|
||||||
IsPublic: isPublic,
|
BgColor: color,
|
||||||
Remark: remark,
|
IsPublic: isPublic,
|
||||||
|
Remark: remark,
|
||||||
}
|
}
|
||||||
if newEvent.BgColor == "" {
|
if newEvent.BgColor == "" {
|
||||||
// 获取日历颜色
|
// 获取日历颜色
|
||||||
|
|||||||
@@ -312,6 +312,7 @@
|
|||||||
"standby": "Standby",
|
"standby": "Standby",
|
||||||
"personal_holiday": "Personal Holiday",
|
"personal_holiday": "Personal Holiday",
|
||||||
"public_holiday": "Public Holiday",
|
"public_holiday": "Public Holiday",
|
||||||
|
"event_type": "Event Type",
|
||||||
"to": "To",
|
"to": "To",
|
||||||
"close": "Close",
|
"close": "Close",
|
||||||
"copy": "Copy",
|
"copy": "Copy",
|
||||||
|
|||||||
@@ -312,6 +312,7 @@
|
|||||||
"standby": "备用",
|
"standby": "备用",
|
||||||
"personal_holiday": "个人假期",
|
"personal_holiday": "个人假期",
|
||||||
"public_holiday": "公众假期",
|
"public_holiday": "公众假期",
|
||||||
|
"event_type": "日程类型",
|
||||||
"to": "至",
|
"to": "至",
|
||||||
"close": "关闭",
|
"close": "关闭",
|
||||||
"copy": "复制",
|
"copy": "复制",
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ const eventData = ref({
|
|||||||
startDate: "",
|
startDate: "",
|
||||||
endDate: "",
|
endDate: "",
|
||||||
color: "#3788d9",
|
color: "#3788d9",
|
||||||
|
scheduleType: "work",
|
||||||
isPublic: false,
|
isPublic: false,
|
||||||
isEditing: false,
|
isEditing: false,
|
||||||
isEditable: false,
|
isEditable: false,
|
||||||
@@ -78,13 +79,14 @@ function closeEventModal() {
|
|||||||
showModal.value = false
|
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 = {
|
eventData.value = {
|
||||||
id: id,
|
id: id,
|
||||||
title: title,
|
title: title,
|
||||||
startDate: dateStr,
|
startDate: dateStr,
|
||||||
endDate: dataEnd,
|
endDate: dataEnd,
|
||||||
color: color,
|
color: color,
|
||||||
|
scheduleType: scheduleType,
|
||||||
isPublic: isPublic,
|
isPublic: isPublic,
|
||||||
isEditing: isEditing,
|
isEditing: isEditing,
|
||||||
isEditable: isEditable,
|
isEditable: isEditable,
|
||||||
@@ -99,6 +101,7 @@ function editEvent(info) {
|
|||||||
parseInt(info.event.id),
|
parseInt(info.event.id),
|
||||||
info.event.title,
|
info.event.title,
|
||||||
info.event.backgroundColor,
|
info.event.backgroundColor,
|
||||||
|
info.event.extendedProps?.scheduleType || "work",
|
||||||
info.event.extendedProps?.isPublic || false,
|
info.event.extendedProps?.isPublic || false,
|
||||||
true,
|
true,
|
||||||
info.event.durationEditable,
|
info.event.durationEditable,
|
||||||
@@ -108,6 +111,11 @@ function editEvent(info) {
|
|||||||
function selectColor(colorValue) {
|
function selectColor(colorValue) {
|
||||||
if (eventData.value.isEditable) {
|
if (eventData.value.isEditable) {
|
||||||
eventData.value.color = colorValue
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectedColor = colorOptions.value.find(c => c.value === eventData.value.color)
|
|
||||||
const scheduleType = selectedColor ? selectedColor.type : "work"
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let result
|
let result
|
||||||
if (eventData.value.isEditing) {
|
if (eventData.value.isEditing) {
|
||||||
@@ -144,7 +149,7 @@ async function saveEvent() {
|
|||||||
? eventData.value.endDate
|
? eventData.value.endDate
|
||||||
: DateUtils.toRealEnd(eventData.value.endDate),
|
: DateUtils.toRealEnd(eventData.value.endDate),
|
||||||
),
|
),
|
||||||
schedule_type: scheduleType,
|
schedule_type: eventData.value.scheduleType,
|
||||||
is_public: eventData.value.isPublic,
|
is_public: eventData.value.isPublic,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@@ -157,7 +162,7 @@ async function saveEvent() {
|
|||||||
? eventData.value.endDate
|
? eventData.value.endDate
|
||||||
: DateUtils.toRealEnd(eventData.value.endDate),
|
: DateUtils.toRealEnd(eventData.value.endDate),
|
||||||
),
|
),
|
||||||
schedule_type: scheduleType,
|
schedule_type: eventData.value.scheduleType,
|
||||||
is_public: eventData.value.isPublic,
|
is_public: eventData.value.isPublic,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -218,6 +223,10 @@ async function getEvents() {
|
|||||||
backgroundColor: item.BgColor,
|
backgroundColor: item.BgColor,
|
||||||
borderColor: item.ID === pageData.value.seleEventID ? "#000000" : "#F7F7F7",
|
borderColor: item.ID === pageData.value.seleEventID ? "#000000" : "#F7F7F7",
|
||||||
allDay: true,
|
allDay: true,
|
||||||
|
extendedProps: {
|
||||||
|
scheduleType: item.ScheduleType || "work",
|
||||||
|
isPublic: item.IsPublic || false,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -391,8 +400,6 @@ const calendarOptions = ref({
|
|||||||
|
|
||||||
eventDrop(info) {
|
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 startStr = info.event.startStr
|
||||||
const endStr = info.event.end ? info.event.endStr : startStr
|
const endStr = info.event.end ? info.event.endStr : startStr
|
||||||
calendarApi.updateEvent({
|
calendarApi.updateEvent({
|
||||||
@@ -400,7 +407,7 @@ const calendarOptions = ref({
|
|||||||
title: info.event.title,
|
title: info.event.title,
|
||||||
start: toDatetime(startStr),
|
start: toDatetime(startStr),
|
||||||
end: toDatetime(startStr === endStr ? endStr : DateUtils.toRealEnd(endStr)),
|
end: toDatetime(startStr === endStr ? endStr : DateUtils.toRealEnd(endStr)),
|
||||||
schedule_type: scheduleType,
|
schedule_type: info.event.extendedProps?.scheduleType || "work",
|
||||||
}).then(r => {
|
}).then(r => {
|
||||||
if (r.errCode !== 0) toast.error(t('message.server_error'))
|
if (r.errCode !== 0) toast.error(t('message.server_error'))
|
||||||
else getEvents()
|
else getEvents()
|
||||||
@@ -569,6 +576,12 @@ onMounted(() => {
|
|||||||
</div>
|
</div>
|
||||||
</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">
|
<div class="mb-4 flex items-center justify-between">
|
||||||
<span class="text-gray-700">{{ t('calendar.is_public_event') }}</span>
|
<span class="text-gray-700">{{ t('calendar.is_public_event') }}</span>
|
||||||
|
|||||||
Reference in New Issue
Block a user