更新角色管理相关内容
This commit is contained in:
@@ -2,6 +2,7 @@ package controllers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"regexp"
|
||||
"strconv"
|
||||
@@ -289,14 +290,103 @@ func (c *BackendOaScheduleController) Stats() {
|
||||
}
|
||||
|
||||
type oaSchedulePayload struct {
|
||||
Title string `json:"title"`
|
||||
Content string `json:"content"`
|
||||
ScheduleDate string `json:"schedule_date"`
|
||||
StartTime string `json:"start_time"`
|
||||
EndTime string `json:"end_time"`
|
||||
AllDay int8 `json:"all_day"`
|
||||
Color string `json:"color"`
|
||||
Priority int8 `json:"priority"`
|
||||
Title string `json:"title"`
|
||||
Content string `json:"content"`
|
||||
ScheduleDate string `json:"schedule_date"`
|
||||
StartTime string `json:"start_time"`
|
||||
EndTime string `json:"end_time"`
|
||||
AllDay int8 `json:"all_day"`
|
||||
Color string `json:"color"`
|
||||
Priority int8 `json:"priority"`
|
||||
// 提醒绑定:开启后会在提醒工具生成一条提醒任务,并把其 ID 回写到 ReminderID。
|
||||
ReminderEnabled bool `json:"reminder_enabled"`
|
||||
ReminderTime string `json:"reminder_time"`
|
||||
RemindChannels []string `json:"remind_channels"`
|
||||
AdvanceMinutes int `json:"advance_minutes"`
|
||||
}
|
||||
|
||||
// oaReminderChannels 允许的提醒渠道集合。
|
||||
var oaReminderChannels = map[string]bool{
|
||||
"SMS": true, "EMAIL": true, "BARK": true, "SITE_MSG": true,
|
||||
}
|
||||
|
||||
// createOaScheduleReminder 为 OA 日程创建一条绑定的提醒任务。
|
||||
// 复用提醒工具的数据模型(yz_backend_schedule + yz_backend_schedule_reminder):
|
||||
// 生成一条 BackendSchedule,再按渠道逐条生成提醒记录,返回 BackendSchedule.ID
|
||||
// 作为 OA 日程的 reminder_id。EMAIL/BARK 渠道会附带确认回执令牌与重复发送配置。
|
||||
func createOaScheduleReminder(tid int, userID uint64, title, content, reminderTime string, channels []string, advanceMinutes int) (uint64, error) {
|
||||
if strings.TrimSpace(reminderTime) == "" {
|
||||
return 0, fmt.Errorf("提醒时间不能为空")
|
||||
}
|
||||
schedTime, err := time.ParseInLocation("2006-01-02 15:04:05", reminderTime, time.Local)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("提醒时间格式不合法")
|
||||
}
|
||||
if advanceMinutes < 0 {
|
||||
advanceMinutes = 0
|
||||
}
|
||||
title = strings.TrimSpace(title)
|
||||
if title == "" {
|
||||
title = "日程提醒"
|
||||
}
|
||||
|
||||
bs := models.BackendSchedule{
|
||||
Tid: tid,
|
||||
Title: title,
|
||||
Content: content,
|
||||
ScheduleTime: schedTime,
|
||||
UserID: userID,
|
||||
}
|
||||
schedID, err := models.Orm.Insert(&bs)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("创建提醒任务失败: %v", err)
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
for _, ch := range channels {
|
||||
ch = strings.ToUpper(strings.TrimSpace(ch))
|
||||
if !oaReminderChannels[ch] {
|
||||
continue
|
||||
}
|
||||
firstSend := schedTime.Add(-time.Duration(advanceMinutes) * time.Minute)
|
||||
reminder := models.BackendScheduleReminder{
|
||||
Tid: tid,
|
||||
ScheduleID: uint64(schedID),
|
||||
RemindChannel: ch,
|
||||
AdvanceMinutes: advanceMinutes,
|
||||
NextRemindTime: firstSend,
|
||||
ReceiverUserID: userID,
|
||||
RemindStatus: 0,
|
||||
CreateTime: now,
|
||||
UpdateTime: now,
|
||||
}
|
||||
if ch == "EMAIL" || ch == "BARK" {
|
||||
token := backendGenerateToken()
|
||||
reminder.AckToken = &token
|
||||
reminder.RepeatIntervalMinutes = 10
|
||||
reminder.MaxSendCount = 5
|
||||
} else {
|
||||
reminder.RepeatIntervalMinutes = 0
|
||||
reminder.MaxSendCount = 1
|
||||
}
|
||||
if _, err := models.Orm.Insert(&reminder); err != nil {
|
||||
return 0, fmt.Errorf("创建提醒失败: %v", err)
|
||||
}
|
||||
}
|
||||
return uint64(schedID), nil
|
||||
}
|
||||
|
||||
// deleteBoundReminder 软删除 OA 日程绑定的提醒任务及其提醒记录。
|
||||
// 删除日程或关闭提醒时使用,避免提醒工具里残留孤立任务。
|
||||
func deleteBoundReminder(scheduleID uint64) {
|
||||
if scheduleID == 0 {
|
||||
return
|
||||
}
|
||||
_, _ = models.Orm.QueryTable(new(models.BackendSchedule)).
|
||||
Filter("id", scheduleID).Delete()
|
||||
_, _ = models.Orm.QueryTable(new(models.BackendScheduleReminder)).
|
||||
Filter("schedule_id", scheduleID).
|
||||
Update(map[string]interface{}{"IsDeleted": 1, "UpdateTime": time.Now()})
|
||||
}
|
||||
|
||||
// oaScheduleImage 日程相关图片(截图/照片),只存文件引用,不存二进制。
|
||||
@@ -393,6 +483,29 @@ func (c *BackendOaScheduleController) parseOaSchedulePayload() (oaSchedulePayloa
|
||||
if payload.Color == "" {
|
||||
payload.Color = "#409EFF"
|
||||
}
|
||||
|
||||
// 提醒绑定校验:开启提醒时必须选择渠道且提醒时间合法。
|
||||
if payload.ReminderEnabled {
|
||||
validChannels := make([]string, 0, len(payload.RemindChannels))
|
||||
for _, ch := range payload.RemindChannels {
|
||||
ch = strings.ToUpper(strings.TrimSpace(ch))
|
||||
if oaReminderChannels[ch] {
|
||||
validChannels = append(validChannels, ch)
|
||||
}
|
||||
}
|
||||
payload.RemindChannels = validChannels
|
||||
if len(validChannels) == 0 {
|
||||
c.oasJsonErr(400, 400, "请至少选择一个提醒渠道")
|
||||
return payload, false
|
||||
}
|
||||
if _, err := time.ParseInLocation("2006-01-02 15:04:05", payload.ReminderTime, time.Local); err != nil {
|
||||
c.oasJsonErr(400, 400, "提醒时间格式不合法,支持 YYYY-MM-DD HH:mm:ss")
|
||||
return payload, false
|
||||
}
|
||||
if payload.AdvanceMinutes < 0 {
|
||||
payload.AdvanceMinutes = 0
|
||||
}
|
||||
}
|
||||
return payload, true
|
||||
}
|
||||
|
||||
@@ -432,6 +545,30 @@ func (c *BackendOaScheduleController) Create() {
|
||||
return
|
||||
}
|
||||
|
||||
// 开启提醒:生成绑定的提醒任务,并把其 ID 回写到日程。
|
||||
if payload.ReminderEnabled {
|
||||
rid, rerr := createOaScheduleReminder(
|
||||
claims.TenantId,
|
||||
uint64(claims.UserID),
|
||||
payload.Title,
|
||||
payload.Content,
|
||||
payload.ReminderTime,
|
||||
payload.RemindChannels,
|
||||
payload.AdvanceMinutes,
|
||||
)
|
||||
if rerr != nil {
|
||||
// 回滚已创建的日程,避免产生孤立日程
|
||||
_, _ = models.Orm.QueryTable(new(models.OaSchedule)).Filter("id", item.ID).Delete()
|
||||
c.oasJsonErr(500, 500, rerr.Error())
|
||||
return
|
||||
}
|
||||
item.ReminderID = rid
|
||||
if _, err := models.Orm.Update(item, "ReminderID"); err != nil {
|
||||
c.oasJsonErr(500, 500, "保存失败")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
c.oasOk(item)
|
||||
}
|
||||
|
||||
@@ -477,9 +614,34 @@ func (c *BackendOaScheduleController) Update() {
|
||||
item.Priority = payload.Priority
|
||||
item.UpdateTime = &now
|
||||
|
||||
// 重新绑定提醒:先创建新提醒,成功后再删除旧提醒(关闭提醒则清掉绑定)。
|
||||
// 顺序反过来可避免"新提醒创建失败却删掉了原提醒"导致提醒丢失。
|
||||
if payload.ReminderEnabled {
|
||||
rid, rerr := createOaScheduleReminder(
|
||||
claims.TenantId,
|
||||
uint64(claims.UserID),
|
||||
payload.Title,
|
||||
payload.Content,
|
||||
payload.ReminderTime,
|
||||
payload.RemindChannels,
|
||||
payload.AdvanceMinutes,
|
||||
)
|
||||
if rerr != nil {
|
||||
c.oasJsonErr(500, 500, rerr.Error())
|
||||
return
|
||||
}
|
||||
if item.ReminderID > 0 {
|
||||
deleteBoundReminder(item.ReminderID)
|
||||
}
|
||||
item.ReminderID = rid
|
||||
} else if item.ReminderID > 0 {
|
||||
deleteBoundReminder(item.ReminderID)
|
||||
item.ReminderID = 0
|
||||
}
|
||||
|
||||
if _, err := models.Orm.Update(&item,
|
||||
"Title", "Content", "ScheduleDate", "StartTime", "EndTime",
|
||||
"AllDay", "Color", "Priority", "UpdateTime"); err != nil {
|
||||
"AllDay", "Color", "Priority", "ReminderID", "UpdateTime"); err != nil {
|
||||
c.oasJsonErr(500, 500, "保存失败")
|
||||
return
|
||||
}
|
||||
@@ -555,21 +717,31 @@ func (c *BackendOaScheduleController) Delete() {
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
n, err := models.Orm.QueryTable(new(models.OaSchedule)).
|
||||
var item models.OaSchedule
|
||||
err = models.Orm.QueryTable(new(models.OaSchedule)).
|
||||
Filter("id", id).
|
||||
Filter("is_deleted", 0).
|
||||
Filter("tid", claims.TenantId).
|
||||
Filter("user_id", claims.UserID).
|
||||
Update(map[string]interface{}{
|
||||
"IsDeleted": int8(1),
|
||||
"DeleteTime": now,
|
||||
"UpdateTime": now,
|
||||
})
|
||||
if err != nil || n == 0 {
|
||||
One(&item)
|
||||
if err != nil {
|
||||
c.oasJsonErr(404, 404, "日程不存在或已删除")
|
||||
return
|
||||
}
|
||||
|
||||
// 先删除绑定的提醒任务,避免提醒工具里残留孤立任务
|
||||
if item.ReminderID > 0 {
|
||||
deleteBoundReminder(item.ReminderID)
|
||||
}
|
||||
|
||||
item.IsDeleted = 1
|
||||
item.DeleteTime = &now
|
||||
item.UpdateTime = &now
|
||||
if _, err := models.Orm.Update(&item, "IsDeleted", "DeleteTime", "UpdateTime"); err != nil {
|
||||
c.oasJsonErr(500, 500, "删除失败")
|
||||
return
|
||||
}
|
||||
|
||||
c.oasOk(nil)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user