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,758 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"git.5iot.com/iotlcm-public/iotlcm-app/internal/consts"
|
||||
"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/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
const (
|
||||
appWarningItemTypeCard = 1
|
||||
|
||||
appWarningUnitMb = 1
|
||||
|
||||
appWarningTypeCardTraffic = 1
|
||||
|
||||
appWarningMessageMethod = "3"
|
||||
|
||||
// 微信订阅消息模板 ID 默认值:物联卡预警提醒
|
||||
appWarningWechatTemplateIdDefault = "DMDP2PKktdtG1ES_3Ic1JcR0LGELQmWE6LunYyerHCY"
|
||||
)
|
||||
|
||||
type sAppWarning struct{}
|
||||
|
||||
type appWarningConfigRow = entity.TWarnConfig
|
||||
|
||||
func NewAppWarning() *sAppWarning {
|
||||
return &sAppWarning{}
|
||||
}
|
||||
|
||||
func init() {
|
||||
service.RegisterAppWarning(NewAppWarning())
|
||||
}
|
||||
|
||||
func (s *sAppWarning) ConfigList(ctx context.Context, param *model.AppWarningConfigListParam) (res *model.AppWarningConfigListModel, err error) {
|
||||
if param == nil {
|
||||
return nil, gerror.New("预警配置查询参数不能为空")
|
||||
}
|
||||
param.CardValue = strings.TrimSpace(param.CardValue)
|
||||
user, cardRow, cardModel, err := s.resolveWarningCard(ctx, param.CardValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var rows []*appWarningConfigRow
|
||||
err = s.configModel(ctx).
|
||||
Where(dao.TWarnConfig.Columns().TenantId, user.TenantId).
|
||||
Where(dao.TWarnConfig.Columns().ItemType, appWarningItemTypeCard).
|
||||
Where(dao.TWarnConfig.Columns().ItemId, cardRow.Id).
|
||||
Where(dao.TWarnConfig.Columns().WarnUnit, appWarningUnitMb).
|
||||
OrderAsc(dao.TWarnConfig.Columns().WarnUnit).
|
||||
Scan(&rows)
|
||||
if err != nil {
|
||||
return nil, gerror.Wrap(err, "查询预警配置失败,请稍后重试")
|
||||
}
|
||||
|
||||
wechatBound, wechatBindText, err := appUserWechatBindingStatus(ctx, user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &model.AppWarningConfigListModel{
|
||||
Card: cardModel,
|
||||
Items: s.configRowsToModels(rows),
|
||||
TemplateId: appWarningWechatTemplateId(ctx),
|
||||
TemplateReady: appWarningTemplateReady(ctx),
|
||||
WechatBound: wechatBound,
|
||||
WechatBindText: wechatBindText,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *sAppWarning) ConfigMeta(ctx context.Context) (res *model.AppWarningConfigMetaModel, err error) {
|
||||
user, err := appCurrentUser(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
wechatBound, wechatBindText, err := appUserWechatBindingStatus(ctx, user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &model.AppWarningConfigMetaModel{
|
||||
TemplateId: appWarningWechatTemplateId(ctx),
|
||||
TemplateReady: appWarningTemplateReady(ctx),
|
||||
WechatBound: wechatBound,
|
||||
WechatBindText: wechatBindText,
|
||||
AppNotifyEnabled: appWarningNotifyEnabledValue(nil),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *sAppWarning) ConfigSave(ctx context.Context, param *model.AppWarningConfigSaveParam) (res *model.AppWarningConfigSaveModel, err error) {
|
||||
if err = normalizeAppWarningSaveParam(param); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
user, cardRow, _, err := s.resolveWarningCard(ctx, param.CardValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
saveParam, err := s.prepareWarningSaveParam(ctx, nil, user, cardRow, param)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
now := gtime.Now()
|
||||
batchNo, err := appNextBatchNo(ctx, consts.BatchNoPrefixWarning)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data := appWarningBuildSaveRow(ctx, user, cardRow, saveParam, batchNo, now)
|
||||
|
||||
_, err = dao.TWarnConfig.Ctx(ctx).
|
||||
Data(data).
|
||||
OnConflict(
|
||||
dao.TWarnConfig.Columns().TenantId,
|
||||
dao.TWarnConfig.Columns().ItemType,
|
||||
dao.TWarnConfig.Columns().ItemId,
|
||||
dao.TWarnConfig.Columns().WarnUnit,
|
||||
).
|
||||
OnDuplicateEx(appWarningSaveDuplicateExcludeFields()).
|
||||
Save()
|
||||
if err != nil {
|
||||
return nil, gerror.Wrap(err, "保存预警配置失败,请稍后重试")
|
||||
}
|
||||
|
||||
config, err := s.findConfigByItem(ctx, user.TenantId, cardRow.Id, param.WarnUnit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
wechatBound, wechatBindText, err := appUserWechatBindingStatus(ctx, user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if config == nil || config.Id == 0 {
|
||||
return nil, gerror.New("保存预警配置后未查询到配置")
|
||||
}
|
||||
return &model.AppWarningConfigSaveModel{
|
||||
Id: config.Id,
|
||||
Config: s.configRowToModel(config),
|
||||
TemplateId: appWarningWechatTemplateId(ctx),
|
||||
TemplateReady: appWarningTemplateReady(ctx),
|
||||
WechatBound: wechatBound,
|
||||
WechatBindText: wechatBindText,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *sAppWarning) ConfigBatchSave(ctx context.Context, param *model.AppWarningConfigBatchSaveParam) (res *model.AppWarningConfigBatchSaveModel, err error) {
|
||||
user, err := appCurrentUser(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cardValues, configs, err := normalizeAppWarningBatchSaveParam(param)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cardLogic := NewAppCard()
|
||||
type validCard struct {
|
||||
Value string
|
||||
Row *appCardQueryRow
|
||||
}
|
||||
validCards := make([]validCard, 0, len(cardValues))
|
||||
failItems := make([]*model.AppWarningConfigBatchFailItem, 0)
|
||||
seenCardIds := make(map[int64]struct{}, len(cardValues))
|
||||
for _, cardValue := range cardValues {
|
||||
cardRow, err := cardLogic.findVisibleCard(ctx, user, cardValue)
|
||||
if err != nil {
|
||||
failItems = append(failItems, &model.AppWarningConfigBatchFailItem{CardValue: cardValue, Reason: "查询卡片失败"})
|
||||
continue
|
||||
}
|
||||
if cardRow == nil || cardRow.Id == 0 {
|
||||
failItems = append(failItems, &model.AppWarningConfigBatchFailItem{CardValue: cardValue, Reason: "卡片不存在或无权配置"})
|
||||
continue
|
||||
}
|
||||
if _, exists := seenCardIds[cardRow.Id]; exists {
|
||||
continue
|
||||
}
|
||||
if err = cardLogic.ensureOperateCard(ctx, user, cardRow, "配置预警"); err != nil {
|
||||
failItems = append(failItems, &model.AppWarningConfigBatchFailItem{CardValue: cardValue, Reason: err.Error()})
|
||||
continue
|
||||
}
|
||||
seenCardIds[cardRow.Id] = struct{}{}
|
||||
validCards = append(validCards, validCard{Value: cardValue, Row: cardRow})
|
||||
}
|
||||
if len(validCards) == 0 {
|
||||
return nil, gerror.New("没有可配置预警的卡片")
|
||||
}
|
||||
|
||||
now := gtime.Now()
|
||||
batchNo, err := appNextBatchNo(ctx, consts.BatchNoPrefixWarning)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = dao.TWarnConfig.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
|
||||
for _, card := range validCards {
|
||||
for _, config := range configs {
|
||||
saveParam, err := s.prepareWarningSaveParam(ctx, tx, user, card.Row, config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
data := appWarningBuildSaveRow(ctx, user, card.Row, saveParam, batchNo, now)
|
||||
if _, err = dao.TWarnConfig.Ctx(ctx).TX(tx).
|
||||
Data(data).
|
||||
OnConflict(
|
||||
dao.TWarnConfig.Columns().TenantId,
|
||||
dao.TWarnConfig.Columns().ItemType,
|
||||
dao.TWarnConfig.Columns().ItemId,
|
||||
dao.TWarnConfig.Columns().WarnUnit,
|
||||
).
|
||||
OnDuplicateEx(appWarningSaveDuplicateExcludeFields()).
|
||||
Save(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, gerror.Wrap(err, "批量保存预警配置失败,请稍后重试")
|
||||
}
|
||||
|
||||
wechatBound, wechatBindText, err := appUserWechatBindingStatus(ctx, user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &model.AppWarningConfigBatchSaveModel{
|
||||
BatchNo: batchNo,
|
||||
TotalCount: len(cardValues),
|
||||
SuccessCount: len(validCards),
|
||||
FailCount: len(failItems),
|
||||
FailItems: failItems,
|
||||
TemplateId: appWarningWechatTemplateId(ctx),
|
||||
TemplateReady: appWarningTemplateReady(ctx),
|
||||
WechatBound: wechatBound,
|
||||
WechatBindText: wechatBindText,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *sAppWarning) ConfigNotify(ctx context.Context, param *model.AppWarningConfigNotifyParam) (res *model.AppWarningConfigNotifyModel, err error) {
|
||||
if err = normalizeAppWarningNotifyParam(param); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
user, cardRow, _, err := s.resolveWarningCard(ctx, param.CardValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
config, err := s.findConfigByItem(ctx, user.TenantId, cardRow.Id, param.WarnUnit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if config == nil || config.Id == 0 {
|
||||
return nil, gerror.New("请先保存预警阈值后再设置小程序提醒")
|
||||
}
|
||||
|
||||
now := gtime.Now()
|
||||
_, err = dao.TWarnConfig.Ctx(ctx).
|
||||
Where(dao.TWarnConfig.Columns().TenantId, user.TenantId).
|
||||
Where(dao.TWarnConfig.Columns().ItemType, appWarningItemTypeCard).
|
||||
Where(dao.TWarnConfig.Columns().ItemId, cardRow.Id).
|
||||
Where(dao.TWarnConfig.Columns().WarnUnit, param.WarnUnit).
|
||||
Data(do.TWarnConfig{
|
||||
AppNotifyEnabled: appWarningNotifyEnabledValue(param.AppNotifyEnabled),
|
||||
UpdatedBy: user.UserId,
|
||||
UpdatedAt: now,
|
||||
}).
|
||||
Update()
|
||||
if err != nil {
|
||||
return nil, gerror.Wrap(err, "设置小程序预警通知失败,请稍后重试")
|
||||
}
|
||||
|
||||
config, err = s.findConfigByItem(ctx, user.TenantId, cardRow.Id, param.WarnUnit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
wechatBound, wechatBindText, err := appUserWechatBindingStatus(ctx, user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &model.AppWarningConfigNotifyModel{
|
||||
AppNotifyEnabled: appWarningNotifyEnabledValue(param.AppNotifyEnabled),
|
||||
Config: s.configRowToModel(config),
|
||||
TemplateId: appWarningWechatTemplateId(ctx),
|
||||
TemplateReady: appWarningTemplateReady(ctx),
|
||||
WechatBound: wechatBound,
|
||||
WechatBindText: wechatBindText,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *sAppWarning) ConfigBatchNotify(ctx context.Context, param *model.AppWarningConfigBatchNotifyParam) (res *model.AppWarningConfigBatchNotifyModel, err error) {
|
||||
user, err := appCurrentUser(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cardValues, err := normalizeAppWarningBatchNotifyParam(param)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cardLogic := NewAppCard()
|
||||
type validCard struct {
|
||||
Value string
|
||||
Row *appCardQueryRow
|
||||
}
|
||||
validCards := make([]validCard, 0, len(cardValues))
|
||||
failItems := make([]*model.AppWarningConfigBatchFailItem, 0)
|
||||
seenCardIds := make(map[int64]struct{}, len(cardValues))
|
||||
for _, cardValue := range cardValues {
|
||||
cardRow, err := cardLogic.findVisibleCard(ctx, user, cardValue)
|
||||
if err != nil {
|
||||
failItems = append(failItems, &model.AppWarningConfigBatchFailItem{CardValue: cardValue, Reason: "查询卡片失败"})
|
||||
continue
|
||||
}
|
||||
if cardRow == nil || cardRow.Id == 0 {
|
||||
failItems = append(failItems, &model.AppWarningConfigBatchFailItem{CardValue: cardValue, Reason: "卡片不存在或无权配置"})
|
||||
continue
|
||||
}
|
||||
if _, exists := seenCardIds[cardRow.Id]; exists {
|
||||
continue
|
||||
}
|
||||
if err = cardLogic.ensureOperateCard(ctx, user, cardRow, "配置预警"); err != nil {
|
||||
failItems = append(failItems, &model.AppWarningConfigBatchFailItem{CardValue: cardValue, Reason: err.Error()})
|
||||
continue
|
||||
}
|
||||
config, err := s.findConfigByItem(ctx, user.TenantId, cardRow.Id, param.WarnUnit)
|
||||
if err != nil {
|
||||
failItems = append(failItems, &model.AppWarningConfigBatchFailItem{CardValue: cardValue, Reason: "查询预警配置失败"})
|
||||
continue
|
||||
}
|
||||
if config == nil || config.Id == 0 {
|
||||
failItems = append(failItems, &model.AppWarningConfigBatchFailItem{CardValue: cardValue, Reason: "请先保存预警配置"})
|
||||
continue
|
||||
}
|
||||
seenCardIds[cardRow.Id] = struct{}{}
|
||||
validCards = append(validCards, validCard{Value: cardValue, Row: cardRow})
|
||||
}
|
||||
|
||||
now := gtime.Now()
|
||||
err = dao.TWarnConfig.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
|
||||
for _, card := range validCards {
|
||||
if _, err = dao.TWarnConfig.Ctx(ctx).TX(tx).
|
||||
Where(dao.TWarnConfig.Columns().TenantId, user.TenantId).
|
||||
Where(dao.TWarnConfig.Columns().ItemType, appWarningItemTypeCard).
|
||||
Where(dao.TWarnConfig.Columns().ItemId, card.Row.Id).
|
||||
Where(dao.TWarnConfig.Columns().WarnUnit, param.WarnUnit).
|
||||
Data(do.TWarnConfig{
|
||||
AppNotifyEnabled: appWarningNotifyEnabledValue(param.AppNotifyEnabled),
|
||||
UpdatedBy: user.UserId,
|
||||
UpdatedAt: now,
|
||||
}).
|
||||
Update(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, gerror.Wrap(err, "批量设置小程序预警通知失败,请稍后重试")
|
||||
}
|
||||
|
||||
wechatBound, wechatBindText, err := appUserWechatBindingStatus(ctx, user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &model.AppWarningConfigBatchNotifyModel{
|
||||
AppNotifyEnabled: appWarningNotifyEnabledValue(param.AppNotifyEnabled),
|
||||
TotalCount: len(cardValues),
|
||||
SuccessCount: len(validCards),
|
||||
FailCount: len(failItems),
|
||||
FailItems: failItems,
|
||||
TemplateId: appWarningWechatTemplateId(ctx),
|
||||
TemplateReady: appWarningTemplateReady(ctx),
|
||||
WechatBound: wechatBound,
|
||||
WechatBindText: wechatBindText,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *sAppWarning) resolveWarningCard(ctx context.Context, cardValue string) (*entity.SysUser, *appCardQueryRow, *model.AppCardModel, error) {
|
||||
user, err := appCurrentUser(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
cardLogic := NewAppCard()
|
||||
cardRow, err := cardLogic.findVisibleCard(ctx, user, cardValue)
|
||||
if err != nil {
|
||||
return nil, nil, nil, gerror.Wrap(err, "查询卡片失败,请稍后重试")
|
||||
}
|
||||
if cardRow == nil || cardRow.Id == 0 {
|
||||
return nil, nil, nil, gerror.New("卡片不存在或不在当前账号可配置范围内")
|
||||
}
|
||||
if err = cardLogic.ensureOperateCard(ctx, user, cardRow, "配置预警"); err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
return user, cardRow, cardLogic.cardRowToModel(ctx, cardRow, user, cardLogic.ownerType(ctx, user), true), nil
|
||||
}
|
||||
|
||||
func (s *sAppWarning) configModel(ctx context.Context) *gdb.Model {
|
||||
return dao.TWarnConfig.Ctx(ctx)
|
||||
}
|
||||
|
||||
func (s *sAppWarning) findConfigByItem(ctx context.Context, tenantId string, itemId int64, warnUnit int) (*appWarningConfigRow, error) {
|
||||
return s.findConfigByItemWithModel(
|
||||
dao.TWarnConfig.Ctx(ctx),
|
||||
tenantId,
|
||||
itemId,
|
||||
warnUnit,
|
||||
)
|
||||
}
|
||||
|
||||
func (s *sAppWarning) findConfigByItemWithTx(ctx context.Context, tx gdb.TX, tenantId string, itemId int64, warnUnit int) (*appWarningConfigRow, error) {
|
||||
return s.findConfigByItemWithModel(
|
||||
dao.TWarnConfig.Ctx(ctx).TX(tx),
|
||||
tenantId,
|
||||
itemId,
|
||||
warnUnit,
|
||||
)
|
||||
}
|
||||
|
||||
func (s *sAppWarning) findConfigByItemWithModel(mod *gdb.Model, tenantId string, itemId int64, warnUnit int) (*appWarningConfigRow, error) {
|
||||
var row *appWarningConfigRow
|
||||
err := mod.
|
||||
Where(dao.TWarnConfig.Columns().TenantId, tenantId).
|
||||
Where(dao.TWarnConfig.Columns().ItemType, appWarningItemTypeCard).
|
||||
Where(dao.TWarnConfig.Columns().ItemId, itemId).
|
||||
Where(dao.TWarnConfig.Columns().WarnUnit, warnUnit).
|
||||
Limit(1).
|
||||
Scan(&row)
|
||||
if err != nil {
|
||||
return nil, gerror.Wrap(err, "查询预警配置失败,请稍后重试")
|
||||
}
|
||||
return row, nil
|
||||
}
|
||||
|
||||
func (s *sAppWarning) prepareWarningSaveParam(
|
||||
ctx context.Context,
|
||||
tx gdb.TX,
|
||||
user *entity.SysUser,
|
||||
cardRow *appCardQueryRow,
|
||||
param *model.AppWarningConfigSaveParam,
|
||||
) (*model.AppWarningConfigSaveParam, error) {
|
||||
if param == nil {
|
||||
return nil, gerror.New("预警配置参数不能为空")
|
||||
}
|
||||
|
||||
saveParam := *param
|
||||
var (
|
||||
config *appWarningConfigRow
|
||||
err error
|
||||
)
|
||||
if tx != nil {
|
||||
config, err = s.findConfigByItemWithTx(ctx, tx, user.TenantId, cardRow.Id, param.WarnUnit)
|
||||
} else {
|
||||
config, err = s.findConfigByItem(ctx, user.TenantId, cardRow.Id, param.WarnUnit)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if config != nil {
|
||||
if saveParam.IsEnabled == nil {
|
||||
value := config.IsEnabled
|
||||
saveParam.IsEnabled = &value
|
||||
}
|
||||
if saveParam.AppNotifyEnabled == nil {
|
||||
value := config.AppNotifyEnabled
|
||||
saveParam.AppNotifyEnabled = &value
|
||||
}
|
||||
}
|
||||
return &saveParam, nil
|
||||
}
|
||||
|
||||
func (s *sAppWarning) configRowsToModels(rows []*appWarningConfigRow) []*model.AppWarningConfigModel {
|
||||
items := make([]*model.AppWarningConfigModel, 0, len(rows))
|
||||
for _, row := range rows {
|
||||
items = append(items, s.configRowToModel(row))
|
||||
}
|
||||
return items
|
||||
}
|
||||
|
||||
func (s *sAppWarning) configRowToModel(row *appWarningConfigRow) *model.AppWarningConfigModel {
|
||||
if row == nil {
|
||||
return nil
|
||||
}
|
||||
warnType := appWarningTypeByUnit(row.WarnUnit)
|
||||
return &model.AppWarningConfigModel{
|
||||
Id: row.Id,
|
||||
ItemType: row.ItemType,
|
||||
ItemId: row.ItemId,
|
||||
ItemCode: row.ItemCode,
|
||||
WarnType: warnType,
|
||||
WarnUnit: row.WarnUnit,
|
||||
WarnTitle: appWarningTitle(row.WarnUnit),
|
||||
UnitText: appWarningUnitText(row.WarnUnit),
|
||||
FirstWarn: row.FirstWarn,
|
||||
SecondWarn: row.SecondWarn,
|
||||
ThirdWarn: row.ThirdWarn,
|
||||
AutoAction: row.AutoAction,
|
||||
IsEnabled: row.IsEnabled,
|
||||
AppNotifyEnabled: row.AppNotifyEnabled,
|
||||
WxTemplateId: row.WxTemplateId,
|
||||
Remark: row.Remark,
|
||||
UpdatedAt: row.UpdatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
func normalizeAppWarningSaveParam(param *model.AppWarningConfigSaveParam) error {
|
||||
if param == nil {
|
||||
return gerror.New("预警配置参数不能为空")
|
||||
}
|
||||
param.CardValue = strings.TrimSpace(param.CardValue)
|
||||
param.Remark = strings.TrimSpace(param.Remark)
|
||||
if param.IsEnabled != nil && *param.IsEnabled != 0 && *param.IsEnabled != 1 {
|
||||
return gerror.New("启停状态无效")
|
||||
}
|
||||
if param.AppNotifyEnabled != nil && *param.AppNotifyEnabled != 0 && *param.AppNotifyEnabled != 1 {
|
||||
return gerror.New("小程序预警通知状态无效")
|
||||
}
|
||||
|
||||
switch param.WarnUnit {
|
||||
case appWarningUnitMb:
|
||||
return validateAppWarningTrafficMb(param.FirstWarn, param.SecondWarn, param.ThirdWarn)
|
||||
default:
|
||||
return gerror.New("小程序仅支持按MB配置流量预警")
|
||||
}
|
||||
}
|
||||
|
||||
func normalizeAppWarningBatchSaveParam(param *model.AppWarningConfigBatchSaveParam) ([]string, []*model.AppWarningConfigSaveParam, error) {
|
||||
if param == nil {
|
||||
return nil, nil, gerror.New("批量预警配置参数不能为空")
|
||||
}
|
||||
cardValues, err := normalizeAppWarningCardValues(param.CardValues)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if len(cardValues) > 100 {
|
||||
return nil, nil, gerror.New("单次批量预警配置最多支持100张卡")
|
||||
}
|
||||
|
||||
configs := make([]*model.AppWarningConfigSaveParam, 0, len(param.Configs))
|
||||
seenUnits := make(map[int]struct{}, len(param.Configs))
|
||||
for _, config := range param.Configs {
|
||||
if config == nil {
|
||||
continue
|
||||
}
|
||||
copied := model.AppWarningConfigSaveParam{
|
||||
WarnUnit: config.WarnUnit,
|
||||
FirstWarn: config.FirstWarn,
|
||||
SecondWarn: config.SecondWarn,
|
||||
ThirdWarn: config.ThirdWarn,
|
||||
IsEnabled: config.IsEnabled,
|
||||
AppNotifyEnabled: config.AppNotifyEnabled,
|
||||
Remark: config.Remark,
|
||||
}
|
||||
if _, exists := seenUnits[copied.WarnUnit]; exists {
|
||||
return nil, nil, gerror.New("同一预警类型不能重复配置")
|
||||
}
|
||||
if err := normalizeAppWarningSaveParam(&copied); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
seenUnits[copied.WarnUnit] = struct{}{}
|
||||
configs = append(configs, &copied)
|
||||
}
|
||||
if len(configs) == 0 {
|
||||
return nil, nil, gerror.New("请至少填写一项预警配置")
|
||||
}
|
||||
return cardValues, configs, nil
|
||||
}
|
||||
|
||||
func normalizeAppWarningNotifyParam(param *model.AppWarningConfigNotifyParam) error {
|
||||
if param == nil {
|
||||
return gerror.New("小程序预警通知参数不能为空")
|
||||
}
|
||||
param.CardValue = strings.TrimSpace(param.CardValue)
|
||||
if param.WarnUnit == 0 {
|
||||
param.WarnUnit = appWarningUnitMb
|
||||
}
|
||||
if param.AppNotifyEnabled == nil {
|
||||
return gerror.New("请选择是否开启小程序预警通知")
|
||||
}
|
||||
if *param.AppNotifyEnabled != 0 && *param.AppNotifyEnabled != 1 {
|
||||
return gerror.New("小程序预警通知状态无效")
|
||||
}
|
||||
if param.WarnUnit != appWarningUnitMb {
|
||||
return gerror.New("小程序仅支持配置MB流量预警通知")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func normalizeAppWarningBatchNotifyParam(param *model.AppWarningConfigBatchNotifyParam) ([]string, error) {
|
||||
if param == nil {
|
||||
return nil, gerror.New("批量小程序预警通知参数不能为空")
|
||||
}
|
||||
if param.WarnUnit == 0 {
|
||||
param.WarnUnit = appWarningUnitMb
|
||||
}
|
||||
if param.AppNotifyEnabled == nil {
|
||||
return nil, gerror.New("请选择是否开启小程序预警通知")
|
||||
}
|
||||
if *param.AppNotifyEnabled != 0 && *param.AppNotifyEnabled != 1 {
|
||||
return nil, gerror.New("小程序预警通知状态无效")
|
||||
}
|
||||
if param.WarnUnit != appWarningUnitMb {
|
||||
return nil, gerror.New("小程序仅支持配置MB流量预警通知")
|
||||
}
|
||||
cardValues, err := normalizeAppWarningCardValues(param.CardValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(cardValues) > 100 {
|
||||
return nil, gerror.New("单次批量预警通知最多支持100张卡")
|
||||
}
|
||||
return cardValues, nil
|
||||
}
|
||||
|
||||
func normalizeAppWarningCardValues(values []string) ([]string, error) {
|
||||
cardValues := make([]string, 0, len(values))
|
||||
seenCards := make(map[string]struct{}, len(values))
|
||||
for _, value := range values {
|
||||
value = strings.TrimSpace(value)
|
||||
if value == "" {
|
||||
continue
|
||||
}
|
||||
if _, exists := seenCards[value]; exists {
|
||||
continue
|
||||
}
|
||||
seenCards[value] = struct{}{}
|
||||
cardValues = append(cardValues, value)
|
||||
}
|
||||
if len(cardValues) == 0 {
|
||||
return nil, gerror.New("请选择需要配置预警的卡片")
|
||||
}
|
||||
return cardValues, nil
|
||||
}
|
||||
|
||||
func appWarningBuildSaveRow(ctx context.Context, user *entity.SysUser, cardRow *appCardQueryRow, param *model.AppWarningConfigSaveParam, batchNo string, now *gtime.Time) do.TWarnConfig {
|
||||
return do.TWarnConfig{
|
||||
TenantId: user.TenantId,
|
||||
BatchNo: batchNo,
|
||||
ItemType: appWarningItemTypeCard,
|
||||
ItemId: cardRow.Id,
|
||||
ItemCode: appWarningCardCode(cardRow),
|
||||
WarnUnit: param.WarnUnit,
|
||||
FirstWarn: param.FirstWarn,
|
||||
SecondWarn: param.SecondWarn,
|
||||
ThirdWarn: param.ThirdWarn,
|
||||
WarnMethods: appWarningMessageMethod,
|
||||
WarnPhones: "",
|
||||
WarnEmails: "",
|
||||
AutoAction: 0,
|
||||
IsEnabled: appWarningEnabledValue(param.IsEnabled),
|
||||
AppNotifyEnabled: appWarningNotifyEnabledValue(param.AppNotifyEnabled),
|
||||
WxTemplateId: appWarningWechatTemplateId(ctx),
|
||||
Remark: strings.TrimSpace(param.Remark),
|
||||
CreatedDept: appUserDeptOrDefault(user),
|
||||
CreatedBy: user.UserId,
|
||||
CreatedAt: now,
|
||||
UpdatedBy: user.UserId,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
}
|
||||
|
||||
func appWarningSaveDuplicateExcludeFields() string {
|
||||
columns := dao.TWarnConfig.Columns()
|
||||
return strings.Join([]string{
|
||||
columns.Id,
|
||||
columns.TenantId,
|
||||
columns.ItemType,
|
||||
columns.ItemId,
|
||||
columns.WarnUnit,
|
||||
columns.CreatedDept,
|
||||
columns.CreatedBy,
|
||||
columns.CreatedAt,
|
||||
}, ",")
|
||||
}
|
||||
|
||||
func validateAppWarningTrafficMb(first, second, third float64) error {
|
||||
if first <= 0 {
|
||||
return gerror.New("第一档阈值必须大于0")
|
||||
}
|
||||
if second < 0 || third < 0 {
|
||||
return gerror.New("预警阈值不能小于0")
|
||||
}
|
||||
if second > 0 && second <= first {
|
||||
return gerror.New("第二档阈值必须大于第一档")
|
||||
}
|
||||
if third > 0 {
|
||||
if second <= 0 {
|
||||
return gerror.New("配置第三档时必须先配置第二档")
|
||||
}
|
||||
if third <= second {
|
||||
return gerror.New("第三档阈值必须大于第二档")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func appWarningEnabledValue(value *int) int {
|
||||
if value == nil {
|
||||
return 1
|
||||
}
|
||||
return *value
|
||||
}
|
||||
|
||||
func appWarningNotifyEnabledValue(value *int) int {
|
||||
if value == nil {
|
||||
return 0
|
||||
}
|
||||
return *value
|
||||
}
|
||||
|
||||
func appWarningTypeByUnit(warnUnit int) int {
|
||||
switch warnUnit {
|
||||
case appWarningUnitMb:
|
||||
return appWarningTypeCardTraffic
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func appWarningTitle(warnUnit int) string {
|
||||
switch warnUnit {
|
||||
case appWarningUnitMb:
|
||||
return "流量使用预警"
|
||||
default:
|
||||
return "预警配置"
|
||||
}
|
||||
}
|
||||
|
||||
func appWarningUnitText(warnUnit int) string {
|
||||
switch warnUnit {
|
||||
case appWarningUnitMb:
|
||||
return "MB"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func appWarningCardCode(card *appCardQueryRow) string {
|
||||
if card == nil {
|
||||
return ""
|
||||
}
|
||||
return appFirstNotEmpty(card.Iccid, card.Msisdn, card.Imsi, card.Imei)
|
||||
}
|
||||
|
||||
func appWarningWechatTemplateId(ctx context.Context) string {
|
||||
return strings.TrimSpace(g.Cfg().MustGet(ctx, "appWarning.wechatSubscribeTemplateId", appWarningWechatTemplateIdDefault).String())
|
||||
}
|
||||
|
||||
func appWarningTemplateReady(ctx context.Context) bool {
|
||||
value := appWarningWechatTemplateId(ctx)
|
||||
return value != "" && !strings.Contains(strings.ToUpper(value), "TODO") && !strings.Contains(strings.ToUpper(value), "REPLACE")
|
||||
}
|
||||
Reference in New Issue
Block a user