新增禾圃集应用(appCode=garden)的版本策略管理功能,包括后端接口、前端API、页面路由、数据库迁移及相关常量配置,支持对不同平台和渠道的版本策略进行增删改查操作,与现有讯工捷使(appCode=im)版本管理功能保持一致的架构和交互逻辑。
173 lines
6.0 KiB
Go
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
|
|
}
|