1、增加业务消息触发流程;
This commit is contained in:
parent
ac708767d7
commit
ed91928ae3
|
@ -519,6 +519,12 @@ func PushWXPayNotice(c *gin.Context) {
|
||||||
fundRecord.FundType = model.FundTypeExpressFee
|
fundRecord.FundType = model.FundTypeExpressFee
|
||||||
fundRecord.Remark = "借卡邮费"
|
fundRecord.Remark = "借卡邮费"
|
||||||
|
|
||||||
|
// 触发消息
|
||||||
|
model.TriggerBizEvent(model.BizTypeOnRentCard, model.EventOnDeliver, map[string]interface{}{
|
||||||
|
"order_id": order.ID,
|
||||||
|
"uid": order.Uid,
|
||||||
|
"createdAt": order.CreatedAt,
|
||||||
|
}, uint32(order.StoreId))
|
||||||
}
|
}
|
||||||
|
|
||||||
if notifyInfo.Attach == wxpay.WxPayMember {
|
if notifyInfo.Attach == wxpay.WxPayMember {
|
||||||
|
@ -1045,6 +1051,13 @@ func PushWXPayNotice(c *gin.Context) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("deliver task sub add err:", err)
|
logger.Error("deliver task sub add err:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 触发消息
|
||||||
|
model.TriggerBizEvent(model.BizTypeOnBuyGoods, model.EventOnDeliver, map[string]interface{}{
|
||||||
|
"order_id": goodsOrder.OrderId,
|
||||||
|
"uid": goodsOrder.Uid,
|
||||||
|
"goods_name": goods.Name,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fundRecord.Uid = uint32(goodsOrder.Uid)
|
fundRecord.Uid = uint32(goodsOrder.Uid)
|
||||||
|
@ -2053,6 +2066,12 @@ func HmPushWXPayNotice(c *gin.Context) {
|
||||||
fundRecord.FundType = model.FundTypeExpressFee
|
fundRecord.FundType = model.FundTypeExpressFee
|
||||||
fundRecord.Remark = "借卡邮费"
|
fundRecord.Remark = "借卡邮费"
|
||||||
|
|
||||||
|
// 触发消息
|
||||||
|
model.TriggerBizEvent(model.BizTypeOnRentCard, model.EventOnDeliver, map[string]interface{}{
|
||||||
|
"order_id": order.ID,
|
||||||
|
"uid": order.Uid,
|
||||||
|
"createdAt": order.CreatedAt,
|
||||||
|
}, uint32(order.StoreId))
|
||||||
}
|
}
|
||||||
|
|
||||||
if record.Attach == wxpay.WxPayMember {
|
if record.Attach == wxpay.WxPayMember {
|
||||||
|
@ -2573,6 +2592,13 @@ func HmPushWXPayNotice(c *gin.Context) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("deliver task sub add err:", err)
|
logger.Error("deliver task sub add err:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 触发消息
|
||||||
|
model.TriggerBizEvent(model.BizTypeOnBuyGoods, model.EventOnDeliver, map[string]interface{}{
|
||||||
|
"order_id": goodsOrder.OrderId,
|
||||||
|
"uid": goodsOrder.Uid,
|
||||||
|
"goods_name": goods.Name,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fundRecord.Uid = uint32(goodsOrder.Uid)
|
fundRecord.Uid = uint32(goodsOrder.Uid)
|
||||||
|
|
|
@ -433,6 +433,14 @@ func RentCardOrderCreate(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
go model.ShoppingCartCreateOrder(uc.Uid, req.GameCardList)
|
go model.ShoppingCartCreateOrder(uc.Uid, req.GameCardList)
|
||||||
|
|
||||||
|
// 触发消息
|
||||||
|
model.TriggerBizEvent(model.BizTypeOnRentCard, model.EventOnDeliver, map[string]interface{}{
|
||||||
|
"order_id": order.ID,
|
||||||
|
"uid": order.Uid,
|
||||||
|
"createdAt": order.CreatedAt,
|
||||||
|
}, uint32(order.StoreId))
|
||||||
|
|
||||||
RespOK(c, ret)
|
RespOK(c, ret)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
222
model/message.go
Normal file
222
model/message.go
Normal file
|
@ -0,0 +1,222 @@
|
||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"text/template"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
AnnouncementMessageType = 1 // 公告消息
|
||||||
|
BusinessMessageType = 2 // 业务消息
|
||||||
|
|
||||||
|
TargetTypeByAll = 1 // 接收对象类型:1=全员
|
||||||
|
TargetTypeByRole = 2 // 接收对象类型:2=角色
|
||||||
|
TargetTypeByUser = 3 // 接收对象类型:3=用户
|
||||||
|
|
||||||
|
MessageStatusOnDraft = 0 // 草稿
|
||||||
|
MessageStatusOnStart = 1 // 启用
|
||||||
|
MessageStatusOnDisable = 2 // 禁用
|
||||||
|
MessageStatusOnExpire = 3 // 已过期
|
||||||
|
|
||||||
|
MessageStart = 1 // 启用
|
||||||
|
MessageStop = 2 // 禁用
|
||||||
|
|
||||||
|
BizTypeOnAllot = "stock_transfer" // 库存调拨
|
||||||
|
BizTypeOnRentCard = "rent_card" // 租赁卡带
|
||||||
|
BizTypeOnBuyGoods = "buy_goods" // 购买商品(线上小程序)
|
||||||
|
|
||||||
|
EventOnAllot = "wait_receive" // 待收货
|
||||||
|
EventOnDeliver = "on_deliver" // 待发货
|
||||||
|
)
|
||||||
|
|
||||||
|
// SystemMessageConfig 消息配置主表(公告 + 业务统一)
|
||||||
|
// gen:qs
|
||||||
|
//
|
||||||
|
//go:generate goqueryset -in message.go
|
||||||
|
type SystemMessageConfig struct {
|
||||||
|
Model
|
||||||
|
|
||||||
|
MessageType uint8 `json:"message_type"` // 消息类型:1=公告,2=业务
|
||||||
|
Title string `json:"title"` // 消息标题
|
||||||
|
ContentTemplate string `json:"content_template"` // 消息模板内容,支持{{变量}}
|
||||||
|
Level uint8 `json:"level"` // 消息等级:1=普通,2=重要,3=紧急
|
||||||
|
DisplayMode uint8 `json:"display_mode"` // 展示方式:1=弹窗,2=滚动,3=弹窗+滚动
|
||||||
|
StartTime *time.Time `json:"start_time,omitempty"` // 公告生效时间
|
||||||
|
EndTime *time.Time `json:"end_time,omitempty"` // 公告失效时间
|
||||||
|
BizType string `json:"biz_type,omitempty"` // 业务类型
|
||||||
|
Event string `json:"event,omitempty"` // 事件类型
|
||||||
|
Status uint8 `json:"status"` // 状态:0=草稿,1=启用,2=禁用,3=已过期
|
||||||
|
}
|
||||||
|
|
||||||
|
// SystemMessageTarget 接收对象配置表(支持角色/部门/用户/全员)
|
||||||
|
// gen:qs
|
||||||
|
type SystemMessageTarget struct {
|
||||||
|
Model
|
||||||
|
|
||||||
|
MessageConfigID uint `json:"message_config_id"` // 对应消息配置 ID
|
||||||
|
TargetType uint8 `json:"target_type"` // 接收对象类型:1=全员,2=角色,3=用户
|
||||||
|
TargetID int64 `json:"target_id,omitempty"` // 对象ID(角色ID/用户ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SystemUserMessage 用户收到的消息记录表(实际发送记录)
|
||||||
|
// gen:qs
|
||||||
|
type SystemUserMessage struct {
|
||||||
|
Model
|
||||||
|
|
||||||
|
UserID int64 `json:"user_id"` // 接收用户ID
|
||||||
|
MessageConfigID uint `json:"message_config_id"` // 对应消息配置ID,可为空(被删时保留记录)
|
||||||
|
MessageType uint8 `json:"message_type"` // 消息类型:1=公告,2=业务
|
||||||
|
Title string `json:"title"` // 消息标题快照
|
||||||
|
Content string `json:"content"` // 渲染后内容
|
||||||
|
IsRead bool `json:"is_read"` // 是否阅读
|
||||||
|
ReadTime *time.Time `json:"read_time,omitempty"` // 阅读时间
|
||||||
|
IsVisible bool `json:"is_visible"` // 是否展示给用户
|
||||||
|
}
|
||||||
|
|
||||||
|
// TriggerBizEvent 业务消息-触发消息模版
|
||||||
|
func TriggerBizEvent(bizType, event string, inputVars map[string]interface{}, optionalReceivers ...uint32) error {
|
||||||
|
fmt.Println("TriggerBizEvent-start")
|
||||||
|
// 1. 查找启用的消息配置
|
||||||
|
var cfg SystemMessageConfig
|
||||||
|
err := DB.Table("system_message_config").Where("message_type = ? AND biz_type = ? AND event = ? AND status = 1",
|
||||||
|
BusinessMessageType, bizType, event).Find(&cfg).Error
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("query system_message_config err:", err)
|
||||||
|
return nil // 无需发送
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 渲染模板内容
|
||||||
|
content, err := RenderTemplate(cfg.ContentTemplate, inputVars)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("模板渲染失败:", err)
|
||||||
|
return fmt.Errorf("模板渲染失败: %w", err)
|
||||||
|
}
|
||||||
|
fmt.Println("content is:", content)
|
||||||
|
|
||||||
|
// 查找门店ID
|
||||||
|
var storeId uint32
|
||||||
|
if len(optionalReceivers) > 0 {
|
||||||
|
if event == EventOnAllot || event == EventOnDeliver { // 库存调拨-待收货消息、租赁订单-待发货消息
|
||||||
|
storeId = optionalReceivers[0]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Println("没有传入 optionalReceivers,使用默认配置")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 查找接收用户
|
||||||
|
receiverIDs, err := GetTargetUserIds(cfg.ID, storeId)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("获取接收人失败:", err)
|
||||||
|
return fmt.Errorf("获取接收人失败: %w", err)
|
||||||
|
}
|
||||||
|
fmt.Println("receiverIDs is:", receiverIDs)
|
||||||
|
|
||||||
|
// 4. 写入 user_message 表
|
||||||
|
for _, uid := range receiverIDs {
|
||||||
|
msg := SystemUserMessage{
|
||||||
|
UserID: uid,
|
||||||
|
MessageConfigID: uint(cfg.ID),
|
||||||
|
MessageType: BusinessMessageType,
|
||||||
|
Title: cfg.Title,
|
||||||
|
Content: content,
|
||||||
|
IsRead: false,
|
||||||
|
IsVisible: true,
|
||||||
|
}
|
||||||
|
err = DB.Create(&msg).Error
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("插入消息失败:", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("TriggerBizEvent-end")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTargetUserIds 获取接收用户函数模板(支持角色)
|
||||||
|
func GetTargetUserIds(configID uint32, storeId uint32) ([]int64, error) {
|
||||||
|
fmt.Println("******enter GetTargetUserIds******")
|
||||||
|
fmt.Println("storeId is :", storeId)
|
||||||
|
// 1.查询角色绑定
|
||||||
|
var targets []SystemMessageTarget
|
||||||
|
err := DB.Where("message_config_id = ? AND target_type = ?", configID, TargetTypeByRole).
|
||||||
|
Find(&targets).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2.查询该模版配置的所有角色
|
||||||
|
var roleIDs []int
|
||||||
|
for _, t := range targets {
|
||||||
|
roleIDs = append(roleIDs, int(t.TargetID))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3.查询该角色下的用户(包含字段 uid, store_data)
|
||||||
|
var users []SysUser
|
||||||
|
err = DB.Debug().Table("sys_user").
|
||||||
|
Where("role_id IN (?)", roleIDs).
|
||||||
|
Find(&users).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果 storeId == 0,直接返回所有 uid
|
||||||
|
if storeId == 0 {
|
||||||
|
var allUserIDs []int64
|
||||||
|
for _, user := range users {
|
||||||
|
allUserIDs = append(allUserIDs, int64(user.UserId))
|
||||||
|
}
|
||||||
|
return allUserIDs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4.筛选出门店有效用户
|
||||||
|
now := time.Now()
|
||||||
|
var validUserIDs []int64
|
||||||
|
|
||||||
|
for _, user := range users {
|
||||||
|
var storeList []StoreInfo
|
||||||
|
if err := json.Unmarshal([]byte(user.StoreData), &storeList); err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, store := range storeList {
|
||||||
|
// 解析时间
|
||||||
|
expireTime, err := time.Parse(StoreDateTimeFormat, store.ExpireTime)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// 包含当天有效时间
|
||||||
|
expireTime = expireTime.Add(24*time.Hour - time.Second)
|
||||||
|
if store.StoreID == uint64(storeId) && expireTime.After(now) {
|
||||||
|
fmt.Println("UserId is:", user.UserId)
|
||||||
|
validUserIDs = append(validUserIDs, int64(user.UserId))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("******leave GetTargetUserIds******")
|
||||||
|
|
||||||
|
return validUserIDs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RenderTemplate 渲染模版内容
|
||||||
|
func RenderTemplate(templateStr string, data map[string]interface{}) (string, error) {
|
||||||
|
// 创建模板实例
|
||||||
|
tmpl, err := template.New("msg").Option("missingkey=zero").Parse(templateStr)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 渲染
|
||||||
|
var buf bytes.Buffer
|
||||||
|
err = tmpl.Execute(&buf, data)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.String(), nil
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user