package models import ( "sync" "time" ) // OaSchedule OA日程(日历待办): yz_backend_oa_schedule // 日程按租户 tid + 用户 user_id 双重隔离,供 backend 日程管理页面的 // 月历视图与待办列表读写。schedule_date/start_time/end_time 均以 // "YYYY-MM-DD"、"HH:mm" 字符串存取,前端无需再做时区换算。 // // 顺延相关字段(source_id/carry_over/carry_count/carry_to_date): // 当天做不完的日程可"顺延到下一天"——原日程标记完成并置 carry_over=1, // 同时在目标日期生成一条待办,source_id 指向整条顺延链的源头日程, // carry_count 记录累计顺延次数,便于追溯一个任务跨了多少天。 type OaSchedule struct { ID uint64 `orm:"column(id);pk;auto" json:"id"` Tid int `orm:"column(tid)" json:"tid"` UserID uint64 `orm:"column(user_id)" json:"user_id"` UserName string `orm:"column(user_name);size(100);default()" json:"user_name"` Title string `orm:"column(title);size(255)" json:"title"` Content string `orm:"column(content);type(text);null" json:"content"` // Images 相关图片(截图/照片),存 JSON 数组:[{"id":1,"url":"","name":""}] Images string `orm:"column(images);type(text);null" json:"images"` ScheduleDate string `orm:"column(schedule_date);type(date)" json:"schedule_date"` StartTime string `orm:"column(start_time);size(8);default()" json:"start_time"` EndTime string `orm:"column(end_time);size(8);default()" json:"end_time"` AllDay int8 `orm:"column(all_day);default(1)" json:"all_day"` Color string `orm:"column(color);size(20);default(#409EFF)" json:"color"` Priority int8 `orm:"column(priority);default(0)" json:"priority"` Status int8 `orm:"column(status);default(0)" json:"status"` FinishTime *time.Time `orm:"column(finish_time);type(datetime);null" json:"finish_time"` SourceID uint64 `orm:"column(source_id);default(0)" json:"source_id"` CarryOver int8 `orm:"column(carry_over);default(0)" json:"carry_over"` CarryCount int `orm:"column(carry_count);default(0)" json:"carry_count"` CarryToDate string `orm:"column(carry_to_date);size(10);default()" json:"carry_to_date"` IsDeleted int8 `orm:"column(is_deleted);default(0)" json:"is_deleted"` CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"create_time"` UpdateTime *time.Time `orm:"column(update_time);auto_now;type(datetime);null" json:"update_time"` DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time"` } func (m *OaSchedule) TableName() string { return "yz_backend_oa_schedule" } var oaScheduleCarryColumnsOnce sync.Once // EnsureOaScheduleCarryColumns 为日程表补齐"顺延到下一天"与"相关图片"所需字段。 // 历史库可能早于该特性建表,这里在首次访问日程接口时自动补列, // 字段已存在时 MySQL 会报 duplicate column,统一忽略,不阻断主流程。 func EnsureOaScheduleCarryColumns() error { if Orm == nil { return nil } var err error oaScheduleCarryColumnsOnce.Do(func() { alters := []string{ "ALTER TABLE yz_backend_oa_schedule ADD COLUMN source_id bigint unsigned NOT NULL DEFAULT 0 COMMENT '顺延来源日程ID 0-原始日程'", "ALTER TABLE yz_backend_oa_schedule ADD COLUMN carry_over tinyint NOT NULL DEFAULT 0 COMMENT '是否已顺延到下一天 0-否 1-是'", "ALTER TABLE yz_backend_oa_schedule ADD COLUMN carry_count int NOT NULL DEFAULT 0 COMMENT '累计顺延次数'", "ALTER TABLE yz_backend_oa_schedule ADD COLUMN carry_to_date varchar(10) NOT NULL DEFAULT '' COMMENT '顺延目标日期(YYYY-MM-DD)'", "ALTER TABLE yz_backend_oa_schedule ADD COLUMN images text NULL COMMENT '相关图片JSON数组 [{id,url,name}]'", } for _, sql := range alters { if _, e := Orm.Raw(sql).Exec(); e != nil { err = e } } }) return err }