更新代码
This commit is contained in:
+204
-111
@@ -2,6 +2,7 @@ package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
@@ -89,83 +90,213 @@ func SaveSiteReminderConfig(retentionDays int, autoRead int8) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SendSiteReminder 发送站内信
|
||||
// targetType: platform (平台端), tenant_all (管理端所有用户), role (平台角色), tenant (特定租户)
|
||||
func SendSiteReminder(title, content string, senderID uint64, senderType string, targetType string, targetRoleID uint64, targetTenantID uint64) error {
|
||||
var receiverIDs []uint64
|
||||
var receiverType string
|
||||
// reminderReceiver 站内信接收人(用户ID + 所属端类型)
|
||||
type reminderReceiver struct {
|
||||
ID uint64
|
||||
Type string // platform-平台端 tenant-租户端
|
||||
}
|
||||
|
||||
// queryEnabledAdminUserIDs 查询启用的平台用户ID;cond 为附加过滤条件(可为 nil)。
|
||||
func queryEnabledAdminUserIDs(cond *orm.Condition) ([]uint64, error) {
|
||||
qs := models.Orm.QueryTable(new(models.AdminUser)).
|
||||
Filter("status", 1).
|
||||
Filter("delete_time__isnull", true)
|
||||
if cond != nil {
|
||||
qs = qs.SetCond(orm.NewCondition().
|
||||
And("status", 1).
|
||||
And("delete_time__isnull", true).
|
||||
AndCond(cond))
|
||||
}
|
||||
var list []models.AdminUser
|
||||
if _, err := qs.All(&list, "id"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ids := make([]uint64, 0, len(list))
|
||||
for _, u := range list {
|
||||
ids = append(ids, u.ID)
|
||||
}
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
// queryEnabledTenantUserIDs 查询启用的租户用户ID;cond 为附加过滤条件(可为 nil)。
|
||||
func queryEnabledTenantUserIDs(cond *orm.Condition) ([]uint64, error) {
|
||||
qs := models.Orm.QueryTable(new(models.SystemTenantUser)).
|
||||
Filter("status", 1).
|
||||
Filter("delete_time__isnull", true)
|
||||
if cond != nil {
|
||||
qs = qs.SetCond(orm.NewCondition().
|
||||
And("status", 1).
|
||||
And("delete_time__isnull", true).
|
||||
AndCond(cond))
|
||||
}
|
||||
var list []models.SystemTenantUser
|
||||
if _, err := qs.All(&list, "id"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ids := make([]uint64, 0, len(list))
|
||||
for _, u := range list {
|
||||
ids = append(ids, u.ID)
|
||||
}
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
// marshalTargetIDs 将多选目标ID序列化为 JSON 字符串(空列表返回 nil)。
|
||||
func marshalTargetIDs(targetIDs []uint64) *string {
|
||||
if len(targetIDs) == 0 {
|
||||
return nil
|
||||
}
|
||||
b, err := json.Marshal(targetIDs)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
s := string(b)
|
||||
return &s
|
||||
}
|
||||
|
||||
// legacyTargetColumns 旧字段兼容写入:role → target_role_id,tenant → target_tenant_id(取首个)
|
||||
func legacyTargetColumns(targetType string, targetIDs []uint64) (roleID, tenantID uint64) {
|
||||
if len(targetIDs) == 0 {
|
||||
return 0, 0
|
||||
}
|
||||
switch targetType {
|
||||
case "platform":
|
||||
receiverType = "platform"
|
||||
var list []models.AdminUser
|
||||
_, err := models.Orm.QueryTable(new(models.AdminUser)).Filter("status", 1).Filter("delete_time__isnull", true).All(&list, "id")
|
||||
if err != nil {
|
||||
return fmt.Errorf("查询平台用户失败: %w", err)
|
||||
}
|
||||
for _, u := range list {
|
||||
receiverIDs = append(receiverIDs, u.ID)
|
||||
}
|
||||
case "tenant_all":
|
||||
receiverType = "tenant"
|
||||
var list []models.SystemTenantUser
|
||||
_, err := models.Orm.QueryTable(new(models.SystemTenantUser)).Filter("status", 1).Filter("delete_time__isnull", true).All(&list, "id")
|
||||
if err != nil {
|
||||
return fmt.Errorf("查询租户用户失败: %w", err)
|
||||
}
|
||||
for _, u := range list {
|
||||
receiverIDs = append(receiverIDs, u.ID)
|
||||
}
|
||||
case "role":
|
||||
receiverType = "platform"
|
||||
var list []models.AdminUser
|
||||
_, err := models.Orm.QueryTable(new(models.AdminUser)).Filter("status", 1).Filter("role_id", targetRoleID).Filter("delete_time__isnull", true).All(&list, "id")
|
||||
if err != nil {
|
||||
return fmt.Errorf("根据角色查询用户失败: %w", err)
|
||||
}
|
||||
for _, u := range list {
|
||||
receiverIDs = append(receiverIDs, u.ID)
|
||||
}
|
||||
return targetIDs[0], 0
|
||||
case "tenant":
|
||||
receiverType = "tenant"
|
||||
var list []models.SystemTenantUser
|
||||
_, err := models.Orm.QueryTable(new(models.SystemTenantUser)).Filter("status", 1).Filter("tid", targetTenantID).Filter("delete_time__isnull", true).All(&list, "id")
|
||||
if err != nil {
|
||||
return fmt.Errorf("根据租户查询用户失败: %w", err)
|
||||
return 0, targetIDs[0]
|
||||
}
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
// resolveReminderReceivers 解析接收目标 → 接收人集合(按端区分类型,已去重)。
|
||||
// targetType:
|
||||
// all 全平台(平台端 + 租户端所有启用用户)
|
||||
// platform 平台端所有启用用户
|
||||
// tenant_all 租户端所有租户的启用用户
|
||||
// tenant_role 指定租户角色(可多选)下的启用用户
|
||||
// tenant 指定租户(可多选)下的启用用户
|
||||
// tenant_user 指定租户用户(可多选)
|
||||
// role 兼容旧数据:指定平台角色(可多选)下的启用用户
|
||||
func resolveReminderReceivers(targetType string, targetIDs []uint64) ([]reminderReceiver, error) {
|
||||
receivers := make([]reminderReceiver, 0)
|
||||
seen := map[string]bool{}
|
||||
appendIDs := func(ids []uint64, rtype string) {
|
||||
for _, id := range ids {
|
||||
if id == 0 {
|
||||
continue
|
||||
}
|
||||
key := fmt.Sprintf("%s_%d", rtype, id)
|
||||
if seen[key] {
|
||||
continue
|
||||
}
|
||||
seen[key] = true
|
||||
receivers = append(receivers, reminderReceiver{ID: id, Type: rtype})
|
||||
}
|
||||
for _, u := range list {
|
||||
receiverIDs = append(receiverIDs, u.ID)
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("未知的发送目标类型: %s", targetType)
|
||||
}
|
||||
|
||||
if len(receiverIDs) == 0 {
|
||||
switch targetType {
|
||||
case "all": // 全平台:平台端 + 租户端所有启用用户
|
||||
adminIDs, err := queryEnabledAdminUserIDs(nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("查询平台用户失败: %w", err)
|
||||
}
|
||||
tenantIDs, err := queryEnabledTenantUserIDs(nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("查询租户用户失败: %w", err)
|
||||
}
|
||||
appendIDs(adminIDs, "platform")
|
||||
appendIDs(tenantIDs, "tenant")
|
||||
case "platform": // 平台端所有启用用户
|
||||
adminIDs, err := queryEnabledAdminUserIDs(nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("查询平台用户失败: %w", err)
|
||||
}
|
||||
appendIDs(adminIDs, "platform")
|
||||
case "tenant_all": // 租户端所有租户的启用用户
|
||||
tenantIDs, err := queryEnabledTenantUserIDs(nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("查询租户用户失败: %w", err)
|
||||
}
|
||||
appendIDs(tenantIDs, "tenant")
|
||||
case "tenant_role": // 指定租户角色(可多选)下的启用用户
|
||||
if len(targetIDs) == 0 {
|
||||
return nil, fmt.Errorf("请选择接收的租户角色")
|
||||
}
|
||||
tenantIDs, err := queryEnabledTenantUserIDs(orm.NewCondition().And("group_id__in", targetIDs))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("根据租户角色查询用户失败: %w", err)
|
||||
}
|
||||
appendIDs(tenantIDs, "tenant")
|
||||
case "tenant": // 指定租户(可多选)下的启用用户
|
||||
if len(targetIDs) == 0 {
|
||||
return nil, fmt.Errorf("请选择接收的租户")
|
||||
}
|
||||
tenantIDs, err := queryEnabledTenantUserIDs(orm.NewCondition().And("tid__in", targetIDs))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("根据租户查询用户失败: %w", err)
|
||||
}
|
||||
appendIDs(tenantIDs, "tenant")
|
||||
case "tenant_user": // 指定租户用户(可多选)
|
||||
if len(targetIDs) == 0 {
|
||||
return nil, fmt.Errorf("请选择接收的租户用户")
|
||||
}
|
||||
tenantIDs, err := queryEnabledTenantUserIDs(orm.NewCondition().And("id__in", targetIDs))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("查询租户用户失败: %w", err)
|
||||
}
|
||||
appendIDs(tenantIDs, "tenant")
|
||||
case "role": // 兼容旧数据:平台角色(可多选)下的启用用户
|
||||
if len(targetIDs) == 0 {
|
||||
return nil, fmt.Errorf("请选择接收的角色")
|
||||
}
|
||||
adminIDs, err := queryEnabledAdminUserIDs(orm.NewCondition().And("role_id__in", targetIDs))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("根据角色查询用户失败: %w", err)
|
||||
}
|
||||
appendIDs(adminIDs, "platform")
|
||||
default:
|
||||
return nil, fmt.Errorf("未知的发送目标类型: %s", targetType)
|
||||
}
|
||||
return receivers, nil
|
||||
}
|
||||
|
||||
// SendSiteReminder 发送站内信
|
||||
// targetType: all (全平台), platform (平台端), tenant_all (租户端所有租户),
|
||||
// tenant_role (租户角色), tenant (指定租户), tenant_user (指定租户用户), role (平台角色-旧)
|
||||
func SendSiteReminder(title, content string, senderID uint64, senderType string, targetType string, targetIDs []uint64) error {
|
||||
receivers, err := resolveReminderReceivers(targetType, targetIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(receivers) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
targetIDsJSON := marshalTargetIDs(targetIDs)
|
||||
legacyRoleID, legacyTenantID := legacyTargetColumns(targetType, targetIDs)
|
||||
|
||||
now := time.Now()
|
||||
batchID := fmt.Sprintf("%d_%d", now.UnixNano(), senderID)
|
||||
var reminders []models.SystemReminderList
|
||||
for _, rid := range receiverIDs {
|
||||
reminders := make([]models.SystemReminderList, 0, len(receivers))
|
||||
for _, r := range receivers {
|
||||
reminders = append(reminders, models.SystemReminderList{
|
||||
Title: title,
|
||||
Content: content,
|
||||
SenderID: senderID,
|
||||
SenderType: senderType,
|
||||
ReceiverID: rid,
|
||||
ReceiverType: receiverType,
|
||||
ReceiverID: r.ID,
|
||||
ReceiverType: r.Type,
|
||||
IsRead: 0,
|
||||
CreateTime: &now,
|
||||
BatchID: batchID,
|
||||
TargetType: targetType,
|
||||
TargetRoleID: targetRoleID,
|
||||
TargetTenantID: targetTenantID,
|
||||
TargetIDs: targetIDsJSON,
|
||||
TargetRoleID: legacyRoleID,
|
||||
TargetTenantID: legacyTenantID,
|
||||
})
|
||||
}
|
||||
|
||||
// 批量插入
|
||||
_, err := models.Orm.InsertMulti(100, reminders)
|
||||
_, err = models.Orm.InsertMulti(100, reminders)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -280,7 +411,7 @@ func ListSentReminders(senderID uint64, page, pageSize int) ([]models.SystemRemi
|
||||
}
|
||||
|
||||
// UpdateSentReminder 更新已发出的消息(更新该批次下所有接收者的消息,支持修改目标接收群体)
|
||||
func UpdateSentReminder(batchID string, title, content, targetType string, targetRoleID, targetTenantID uint64) error {
|
||||
func UpdateSentReminder(batchID string, title, content, targetType string, targetIDs []uint64) error {
|
||||
// 1. 获取当前发送者ID (从该批次中任意一条记录中获取)
|
||||
var firstRecord models.SystemReminderList
|
||||
err := models.Orm.QueryTable(new(models.SystemReminderList)).Filter("batch_id", batchID).Limit(1).One(&firstRecord)
|
||||
@@ -291,54 +422,14 @@ func UpdateSentReminder(batchID string, title, content, targetType string, targe
|
||||
senderType := firstRecord.SenderType
|
||||
|
||||
// 2. 根据新的目标接收群体获取接收人列表
|
||||
var receiverIDs []uint64
|
||||
var receiverType string
|
||||
|
||||
switch targetType {
|
||||
case "platform":
|
||||
receiverType = "platform"
|
||||
var list []models.AdminUser
|
||||
_, err := models.Orm.QueryTable(new(models.AdminUser)).Filter("status", 1).Filter("delete_time__isnull", true).All(&list, "id")
|
||||
if err != nil {
|
||||
return fmt.Errorf("查询平台用户失败: %w", err)
|
||||
}
|
||||
for _, u := range list {
|
||||
receiverIDs = append(receiverIDs, u.ID)
|
||||
}
|
||||
case "tenant_all":
|
||||
receiverType = "tenant"
|
||||
var list []models.SystemTenantUser
|
||||
_, err := models.Orm.QueryTable(new(models.SystemTenantUser)).Filter("status", 1).Filter("delete_time__isnull", true).All(&list, "id")
|
||||
if err != nil {
|
||||
return fmt.Errorf("查询租户用户失败: %w", err)
|
||||
}
|
||||
for _, u := range list {
|
||||
receiverIDs = append(receiverIDs, u.ID)
|
||||
}
|
||||
case "role":
|
||||
receiverType = "platform"
|
||||
var list []models.AdminUser
|
||||
_, err := models.Orm.QueryTable(new(models.AdminUser)).Filter("status", 1).Filter("role_id", targetRoleID).Filter("delete_time__isnull", true).All(&list, "id")
|
||||
if err != nil {
|
||||
return fmt.Errorf("根据角色查询用户失败: %w", err)
|
||||
}
|
||||
for _, u := range list {
|
||||
receiverIDs = append(receiverIDs, u.ID)
|
||||
}
|
||||
case "tenant":
|
||||
receiverType = "tenant"
|
||||
var list []models.SystemTenantUser
|
||||
_, err := models.Orm.QueryTable(new(models.SystemTenantUser)).Filter("status", 1).Filter("tid", targetTenantID).Filter("delete_time__isnull", true).All(&list, "id")
|
||||
if err != nil {
|
||||
return fmt.Errorf("根据租户查询用户失败: %w", err)
|
||||
}
|
||||
for _, u := range list {
|
||||
receiverIDs = append(receiverIDs, u.ID)
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("未知的发送目标类型: %s", targetType)
|
||||
receivers, err := resolveReminderReceivers(targetType, targetIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
targetIDsJSON := marshalTargetIDs(targetIDs)
|
||||
legacyRoleID, legacyTenantID := legacyTargetColumns(targetType, targetIDs)
|
||||
|
||||
// 3. 获取该批次中现有的所有记录 (包括已删除的)
|
||||
var existingRecords []models.SystemReminderList
|
||||
_, err = models.Orm.QueryTable(new(models.SystemReminderList)).Filter("batch_id", batchID).All(&existingRecords)
|
||||
@@ -354,8 +445,8 @@ func UpdateSentReminder(batchID string, title, content, targetType string, targe
|
||||
}
|
||||
|
||||
newReceiverMap := make(map[string]bool)
|
||||
for _, rid := range receiverIDs {
|
||||
key := fmt.Sprintf("%s_%d", receiverType, rid)
|
||||
for _, r := range receivers {
|
||||
key := fmt.Sprintf("%s_%d", r.Type, r.ID)
|
||||
newReceiverMap[key] = true
|
||||
}
|
||||
|
||||
@@ -377,16 +468,17 @@ func UpdateSentReminder(batchID string, title, content, targetType string, targe
|
||||
|
||||
// B. 对于仍然在新接收者列表中的用户,更新标题、内容、以及 target 信息;如果原来被删除了,清除 delete_time
|
||||
var newInserts []models.SystemReminderList
|
||||
for _, rid := range receiverIDs {
|
||||
key := fmt.Sprintf("%s_%d", receiverType, rid)
|
||||
for _, r := range receivers {
|
||||
key := fmt.Sprintf("%s_%d", r.Type, r.ID)
|
||||
if rec, exists := existingMap[key]; exists {
|
||||
rec.Title = title
|
||||
rec.Content = content
|
||||
rec.TargetType = targetType
|
||||
rec.TargetRoleID = targetRoleID
|
||||
rec.TargetTenantID = targetTenantID
|
||||
|
||||
cols := []string{"Title", "Content", "TargetType", "TargetRoleID", "TargetTenantID"}
|
||||
rec.TargetIDs = targetIDsJSON
|
||||
rec.TargetRoleID = legacyRoleID
|
||||
rec.TargetTenantID = legacyTenantID
|
||||
|
||||
cols := []string{"Title", "Content", "TargetType", "TargetIDs", "TargetRoleID", "TargetTenantID"}
|
||||
if rec.DeleteTime != nil {
|
||||
rec.DeleteTime = nil
|
||||
rec.IsRead = 0
|
||||
@@ -403,14 +495,15 @@ func UpdateSentReminder(batchID string, title, content, targetType string, targe
|
||||
Content: content,
|
||||
SenderID: senderID,
|
||||
SenderType: senderType,
|
||||
ReceiverID: rid,
|
||||
ReceiverType: receiverType,
|
||||
ReceiverID: r.ID,
|
||||
ReceiverType: r.Type,
|
||||
IsRead: 0,
|
||||
CreateTime: &now,
|
||||
BatchID: batchID,
|
||||
TargetType: targetType,
|
||||
TargetRoleID: targetRoleID,
|
||||
TargetTenantID: targetTenantID,
|
||||
TargetIDs: targetIDsJSON,
|
||||
TargetRoleID: legacyRoleID,
|
||||
TargetTenantID: legacyTenantID,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user