chore: 初始开源发布
iotlcm-app:小程序端 + 用户端服务。 - app/:uni-app 小程序前端(基于 unibest,MIT) - 微信 AppID → YOUR_WX_APPID,uni-app AppID → __UNI__YOURAPPID - 内网后端地址 → admin.iotlcm.example.com - 应用标题与 unibest 模板 README 重写(保留上游致谢与 MIT 声明) - server/:GoFrame 用户端服务(基于 XiuAdmin,Apache-2.0) - module xiuadmin → git.5iot.com/iotlcm-public/iotlcm-app(360 文件) - 支付回调地址 → app.iotlcm.example.com,商户名与应用名泛化 - 真实手机号 → 合法 11 位编造号(保留号段前 3 位 + 后 4 位) - 依赖号码尾部的断言同步更新 - 补 server/LICENSE(Apache-2.0) - 移除内部资产:CI 触发器 - 补根 README,LF 行尾 + .gitattributes 已知:TestSysDept_RefreshDeptAncestors 在源仓同一提交上同样失败,属既有缺陷。
This commit is contained in:
@@ -0,0 +1,197 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"git.5iot.com/iotlcm-public/iotlcm-app/internal/dao"
|
||||
"git.5iot.com/iotlcm-public/iotlcm-app/internal/model"
|
||||
"git.5iot.com/iotlcm-public/iotlcm-app/internal/model/do"
|
||||
"git.5iot.com/iotlcm-public/iotlcm-app/internal/model/entity"
|
||||
"git.5iot.com/iotlcm-public/iotlcm-app/internal/service"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
type sAppMessage struct{}
|
||||
|
||||
func NewAppMessage() *sAppMessage {
|
||||
return &sAppMessage{}
|
||||
}
|
||||
|
||||
func init() {
|
||||
service.RegisterAppMessage(NewAppMessage())
|
||||
}
|
||||
|
||||
func (s *sAppMessage) List(ctx context.Context, param *model.AppMessageListParam) (items []*model.AppMessageModel, total int, err error) {
|
||||
if param == nil {
|
||||
param = &model.AppMessageListParam{}
|
||||
}
|
||||
if param.Page <= 0 {
|
||||
param.Page = 1
|
||||
}
|
||||
if param.PageSize <= 0 {
|
||||
param.PageSize = 20
|
||||
}
|
||||
if param.PageSize > 100 {
|
||||
param.PageSize = 100
|
||||
}
|
||||
|
||||
user, err := appCurrentUser(ctx)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
mod := s.applyFilters(s.ownerMessageModel(ctx, user), param)
|
||||
total, err = mod.Count()
|
||||
if err != nil {
|
||||
return nil, 0, gerror.Wrap(err, "查询消息数量失败")
|
||||
}
|
||||
if total == 0 {
|
||||
return []*model.AppMessageModel{}, 0, nil
|
||||
}
|
||||
|
||||
if err = mod.
|
||||
Fields(appMessageFields()).
|
||||
Page(param.Page, param.PageSize).
|
||||
OrderDesc("COALESCE(ml." + dao.TMessageLog.Columns().SendTime + ", um." + dao.TUserMessage.Columns().CreatedAt + ")").
|
||||
OrderDesc("um." + dao.TUserMessage.Columns().MessageId).
|
||||
Scan(&items); err != nil {
|
||||
return nil, 0, gerror.Wrap(err, "查询消息列表失败")
|
||||
}
|
||||
|
||||
for _, item := range items {
|
||||
fillAppMessageText(item)
|
||||
}
|
||||
return items, total, nil
|
||||
}
|
||||
|
||||
func (s *sAppMessage) Detail(ctx context.Context, param *model.AppMessageDetailParam) (*model.AppMessageModel, error) {
|
||||
if param == nil || param.MessageId == 0 {
|
||||
return nil, gerror.New("消息ID不能为空")
|
||||
}
|
||||
|
||||
user, err := appCurrentUser(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var item *model.AppMessageModel
|
||||
if err = s.ownerMessageModel(ctx, user).
|
||||
Fields(appMessageFields()).
|
||||
Where("um."+dao.TUserMessage.Columns().MessageId, param.MessageId).
|
||||
Limit(1).
|
||||
Scan(&item); err != nil {
|
||||
return nil, gerror.Wrap(err, "查询消息详情失败")
|
||||
}
|
||||
if item == nil || item.MessageId == 0 {
|
||||
return nil, gerror.New("消息不存在或无权查看")
|
||||
}
|
||||
|
||||
fillAppMessageText(item)
|
||||
if item.IsRead == 0 {
|
||||
if err = s.Read(ctx, &model.AppMessageReadParam{Ids: []uint64{item.MessageId}}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
item.IsRead = 1
|
||||
}
|
||||
return item, nil
|
||||
}
|
||||
|
||||
func (s *sAppMessage) Read(ctx context.Context, param *model.AppMessageReadParam) error {
|
||||
if param == nil || len(param.Ids) == 0 {
|
||||
return gerror.New("消息ID不能为空")
|
||||
}
|
||||
|
||||
user, err := appCurrentUser(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = dao.TUserMessage.Ctx(ctx).
|
||||
Where(dao.TUserMessage.Columns().TenantId, user.TenantId).
|
||||
Where(dao.TUserMessage.Columns().UserId, user.UserId).
|
||||
WhereIn(dao.TUserMessage.Columns().MessageId, param.Ids).
|
||||
Where(dao.TUserMessage.Columns().IsRead, 0).
|
||||
Data(do.TUserMessage{
|
||||
IsRead: 1,
|
||||
UpdatedBy: user.UserId,
|
||||
UpdatedAt: gtime.Now(),
|
||||
}).
|
||||
Update()
|
||||
if err != nil {
|
||||
return gerror.Wrap(err, "标记消息已读失败")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *sAppMessage) ownerMessageModel(ctx context.Context, user *entity.SysUser) *gdb.Model {
|
||||
return dao.TUserMessage.Ctx(ctx).As("um").
|
||||
LeftJoin(dao.TMessageLog.Table()+" ml", "ml."+dao.TMessageLog.Columns().MessageLogId+" = um."+dao.TUserMessage.Columns().MessageLogId).
|
||||
Where("um."+dao.TUserMessage.Columns().TenantId, user.TenantId).
|
||||
Where("um."+dao.TUserMessage.Columns().UserId, user.UserId).
|
||||
Where("(ml."+dao.TMessageLog.Columns().MessageLogId+" IS NULL OR ml."+dao.TMessageLog.Columns().IsRecall+" = ?)", 0)
|
||||
}
|
||||
|
||||
func (s *sAppMessage) applyFilters(mod *gdb.Model, param *model.AppMessageListParam) *gdb.Model {
|
||||
if param.IsRead != nil {
|
||||
mod = mod.Where("um."+dao.TUserMessage.Columns().IsRead, *param.IsRead)
|
||||
}
|
||||
if param.MessageType != nil && *param.MessageType > 0 {
|
||||
mod = mod.Where("ml."+dao.TMessageLog.Columns().MessageType, *param.MessageType)
|
||||
}
|
||||
|
||||
keyword := strings.TrimSpace(param.Keyword)
|
||||
if keyword != "" {
|
||||
like := "%" + keyword + "%"
|
||||
mod = mod.Where(
|
||||
"(ml."+dao.TMessageLog.Columns().MessageTitle+" LIKE ? OR ml."+dao.TMessageLog.Columns().MessageContent+" LIKE ? OR ml."+dao.TMessageLog.Columns().MessageLink+" LIKE ?)",
|
||||
like, like, like,
|
||||
)
|
||||
}
|
||||
return mod
|
||||
}
|
||||
|
||||
func appMessageFields() string {
|
||||
return strings.Join([]string{
|
||||
"um." + dao.TUserMessage.Columns().MessageId + " AS message_id",
|
||||
"um." + dao.TUserMessage.Columns().MessageId + " AS id",
|
||||
"um." + dao.TUserMessage.Columns().MessageLogId + " AS message_log_id",
|
||||
"COALESCE(ml." + dao.TMessageLog.Columns().MessageType + ", 1) AS message_type",
|
||||
"COALESCE(ml." + dao.TMessageLog.Columns().MessageTitle + ", '') AS title",
|
||||
"COALESCE(ml." + dao.TMessageLog.Columns().MessageContent + ", '') AS content",
|
||||
"COALESCE(ml." + dao.TMessageLog.Columns().MessageLink + ", '') AS link",
|
||||
"um." + dao.TUserMessage.Columns().IsRead + " AS is_read",
|
||||
"um." + dao.TUserMessage.Columns().CreatedAt + " AS created_at",
|
||||
"um." + dao.TUserMessage.Columns().UpdatedAt + " AS updated_at",
|
||||
"COALESCE(ml." + dao.TMessageLog.Columns().SendTime + ", um." + dao.TUserMessage.Columns().CreatedAt + ") AS send_time",
|
||||
}, ", ")
|
||||
}
|
||||
|
||||
func fillAppMessageText(item *model.AppMessageModel) {
|
||||
if item == nil {
|
||||
return
|
||||
}
|
||||
item.Id = item.MessageId
|
||||
if strings.TrimSpace(item.Title) == "" {
|
||||
item.Title = "未命名消息"
|
||||
}
|
||||
item.MessageTypeText = appMessageTypeText(item.MessageType)
|
||||
}
|
||||
|
||||
func appMessageTypeText(messageType int) string {
|
||||
switch messageType {
|
||||
case 1:
|
||||
return "系统通知"
|
||||
case 2:
|
||||
return "平台公告"
|
||||
case 3:
|
||||
return "订单通知"
|
||||
case 4:
|
||||
return "账户通知"
|
||||
default:
|
||||
return "消息"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user