Files
im_manager/server/internal/logic/sys/im_app_release.go
T
Austin 2c5995073f feat: 新增禾圃集应用版本更新管理功能
新增禾圃集应用(appCode=garden)的版本策略管理功能,包括后端接口、前端API、页面路由、数据库迁移及相关常量配置,支持对不同平台和渠道的版本策略进行增删改查操作,与现有讯工捷使(appCode=im)版本管理功能保持一致的架构和交互逻辑。
2026-10-12 15:31:11 +08:00

173 lines
6.0 KiB
Go

package sys
import (
"context"
"fmt"
"hotgo/internal/consts"
"hotgo/internal/library/contexts"
"hotgo/internal/library/imkafka"
"hotgo/internal/library/imtenant"
"hotgo/internal/model/input/sysin"
"hotgo/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 imAppReleasesTable = "im_app_releases"
type sSysImAppRelease struct{}
func NewSysImAppRelease() *sSysImAppRelease { return &sSysImAppRelease{} }
func init() {
service.RegisterSysImAppRelease(NewSysImAppRelease())
}
func (s *sSysImAppRelease) List(ctx context.Context, in *sysin.ImAppReleaseListInp) (list []*sysin.ImAppReleaseModel, totalCount int, err error) {
if err = in.Filter(ctx); err != nil {
return
}
db := imtenant.RegistryDB()
if err = s.ensureDefaults(ctx, db); err != nil {
return
}
mod := s.model(ctx, db)
if in.AppCode != "" {
mod = mod.Where("app_code", in.AppCode)
}
if in.Platform != "" {
mod = mod.Where("platform", in.Platform)
}
if in.Channel != "" {
mod = mod.WhereLike("channel", "%"+in.Channel+"%")
}
mod = mod.Page(in.Page, in.PerPage).OrderAsc("app_code").OrderAsc("platform").OrderAsc("channel")
if err = mod.ScanAndCount(&list, &totalCount, false); err != nil {
err = gerror.Wrap(err, "获取IM客户端版本策略失败,请稍后重试!")
return
}
return
}
func (s *sSysImAppRelease) Edit(ctx context.Context, in *sysin.ImAppReleaseEditInp) (err error) {
if err = in.Filter(ctx); err != nil {
return
}
db := imtenant.RegistryDB()
if err = s.ensureDefaults(ctx, db); err != nil {
return
}
data := g.Map{
"app_code": in.AppCode,
"platform": in.Platform,
"channel": in.Channel,
"latest_version": in.LatestVersion,
"min_supported_version": in.MinSupportedVersion,
"update_type": in.UpdateType,
"release_notes": in.ReleaseNotes,
"store_url": in.StoreUrl,
"package_url": in.PackageUrl,
"checksum": in.Checksum,
"remind_after_seconds": in.RemindAfterSeconds,
"published_at": gtime.Now(),
"updated_at": gtime.Now(),
}
action := "im_app_release_create"
targetId := in.Id
if in.Id > 0 {
if _, err = db.Model(imAppReleasesTable).Safe().Ctx(ctx).WherePri(in.Id).Data(data).Update(); err != nil {
return gerror.Wrap(err, "更新IM客户端版本策略失败,请稍后重试!")
}
action = "im_app_release_update"
} else {
data["created_at"] = gtime.Now()
if _, err = db.Model(imAppReleasesTable).Safe().Ctx(ctx).Data(data).Insert(); err != nil {
return gerror.Wrap(err, "新增IM客户端版本策略失败,请稍后重试!")
}
idValue, err := db.Model(imAppReleasesTable).Safe().Ctx(ctx).Fields("id").
Where("app_code", in.AppCode).Where("platform", in.Platform).Where("channel", in.Channel).Value()
if err != nil {
return gerror.Wrap(err, "获取IM客户端版本策略ID失败,请稍后重试!")
}
targetId = idValue.Int64()
}
_ = writeImAdminAudit(ctx, 0, action, "im_app_release", targetId, "success", g.Map{
"app_code": in.AppCode, "platform": in.Platform, "channel": in.Channel, "update_type": in.UpdateType,
})
if err = imkafka.PublishConfigEvent(ctx, imkafka.ConfigEventInput{
TenantCode: "*", EventType: "app.release.updated", Group: "app_release",
Keys: []string{in.AppCode, in.Platform, in.Channel}, BizID: in.AppCode + ":" + in.Platform + ":" + in.Channel,
Actor: &imkafka.Actor{Type: "admin", ID: fmt.Sprint(contexts.GetUserId(ctx))},
CreatedBy: contexts.GetUserId(ctx),
}); err != nil {
g.Log().Warningf(ctx, "版本策略已保存,缓存失效事件等待 Outbox 重试: %v", err)
}
return nil
}
func (s *sSysImAppRelease) model(ctx context.Context, db gdb.DB) *gdb.Model {
return db.Model(imAppReleasesTable).Safe().Ctx(ctx).Fields(
"id",
"app_code",
"platform",
"channel",
"latest_version",
"min_supported_version",
"update_type",
"release_notes",
"store_url",
"package_url",
"checksum",
"remind_after_seconds",
"published_at",
"created_at",
"updated_at",
)
}
func (s *sSysImAppRelease) ensureDefaults(ctx context.Context, db gdb.DB) (err error) {
apps := []string{consts.ImAppCodeIm, consts.ImAppCodeGarden}
defaults := []g.Map{
{"platform": consts.ImAppPlatformIos, "channel": "stable", "latest_version": "1.0.0", "min_supported_version": "1.0.0", "update_type": consts.ImAppUpdateTypeNone, "release_notes": "当前已是最新版本。", "remind_after_seconds": 0},
{"platform": consts.ImAppPlatformAndroid, "channel": "stable", "latest_version": "1.0.0", "min_supported_version": "1.0.0", "update_type": consts.ImAppUpdateTypeNone, "release_notes": "当前已是最新版本。", "remind_after_seconds": 0},
}
now := gtime.Now()
for _, appCode := range apps {
for _, item := range defaults {
var count int
if count, err = db.Model(imAppReleasesTable).Safe().Ctx(ctx).
Where("app_code", appCode).
Where("platform", item["platform"]).Where("channel", item["channel"]).Count(); err != nil {
return gerror.Wrap(err, "检查IM客户端默认版本策略失败,请稍后重试!")
}
if count > 0 {
continue
}
row := g.Map{
"app_code": appCode,
"platform": item["platform"],
"channel": item["channel"],
"latest_version": item["latest_version"],
"min_supported_version": item["min_supported_version"],
"update_type": item["update_type"],
"release_notes": item["release_notes"],
"remind_after_seconds": item["remind_after_seconds"],
"store_url": "",
"package_url": "",
"checksum": "",
"published_at": now,
"created_at": now,
"updated_at": now,
}
if _, err = db.Model(imAppReleasesTable).Safe().Ctx(ctx).Data(row).Insert(); err != nil {
return gerror.Wrap(err, "初始化IM客户端默认版本策略失败,请稍后重试!")
}
}
}
return nil
}