feat: 完善养成管理后台功能

This commit is contained in:
richjohnrambo
2026-09-19 17:07:47 +08:00
parent f6766d3dbd
commit c7265252d8
13 changed files with 1257 additions and 61 deletions
+66 -1
View File
@@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"fmt"
"net/url"
"strings"
"time"
@@ -11,11 +12,14 @@ import (
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/os/gctx"
"hotgo/internal/dao"
"hotgo/internal/library/contexts"
"hotgo/internal/library/imadmin"
"hotgo/internal/library/imtenant"
"hotgo/internal/library/location"
"hotgo/internal/model/entity"
"hotgo/internal/model/input/sysin"
"hotgo/internal/service"
@@ -86,6 +90,9 @@ func (s *sSysCultivateFlower) View(ctx context.Context, in *sysin.CultivateFlowe
func (s *sSysCultivateFlower) Edit(ctx context.Context, in *sysin.CultivateFlowerEditInp) (err error) {
tenantID := cultivateTenantID(ctx)
if err = validateCultivateAssets(ctx, tenantID, in); err != nil {
return err
}
operatorID := contexts.GetUserId(ctx)
now := time.Now().UTC()
version := "cat_" + now.Format("20060102_150405")
@@ -151,6 +158,59 @@ func (s *sSysCultivateFlower) Edit(ctx context.Context, in *sysin.CultivateFlowe
})
}
func validateCultivateAssets(ctx context.Context, tenantID int64, in *sysin.CultivateFlowerEditInp) error {
seen := make(map[string]struct{})
fileIDs := make([]string, 0, 1+len(in.StageRules)*2)
add := func(fileID string) {
fileID = strings.TrimSpace(fileID)
if fileID == "" {
return
}
if _, ok := seen[fileID]; ok {
return
}
seen[fileID] = struct{}{}
fileIDs = append(fileIDs, fileID)
}
add(in.IconFileId)
for _, rule := range in.StageRules {
add(rule.ImageFileId)
add(rule.AnimationFileId)
}
if len(fileIDs) == 0 {
return nil
}
tenant, err := resolveImAdminTenant(ctx, tenantID)
if err != nil {
return err
}
path := "/internal/cultivate/tenants/" + url.PathEscape(tenant.Code) + "/files/validate"
for offset := 0; offset < len(fileIDs); offset += 20 {
end := offset + 20
if end > len(fileIDs) {
end = len(fileIDs)
}
var out struct {
Items []struct {
FileId string `json:"file_id"`
ReviewStatus string `json:"review_status"`
} `json:"items"`
}
if err = imadmin.DefaultClient(ctx).InternalPost(ctx, path, map[string]any{"user_id": 0, "file_ids": fileIDs[offset:end]}, &out); err != nil {
return gerror.Wrap(err, "校验花种素材失败")
}
for _, item := range out.Items {
if item.ReviewStatus == "risky" {
return gerror.Newf("素材 %s 审核未通过", item.FileId)
}
if item.ReviewStatus == "pending" {
return gerror.Newf("素材 %s 尚在审核中", item.FileId)
}
}
}
return nil
}
func (s *sSysCultivateFlower) Status(ctx context.Context, in *sysin.CultivateFlowerStatusInp) error {
tenantID := cultivateTenantID(ctx)
operatorID := contexts.GetUserId(ctx)
@@ -185,7 +245,12 @@ func writeCultivateOperation(ctx context.Context, tx gdb.TX, tenantID, operatorI
}
beforeJSON, _ := json.Marshal(before)
afterJSON, _ := json.Marshal(after)
ipAddress, userAgent := "", ""
if request := ghttp.RequestFromCtx(ctx); request != nil {
ipAddress = location.GetClientIp(request)
userAgent = request.UserAgent()
}
c := dao.AdminOperationLog.Columns()
_, e = tx.Model(dao.AdminOperationLog.Table()).Data(g.Map{c.Id: id, c.TenantId: tenantID, c.OperatorId: operatorID, c.OperationType: operation, c.TargetType: targetType, c.TargetId: targetID, c.RequestId: gctx.CtxId(ctx), c.BeforeSnapshot: gjson.New(beforeJSON).MustToJsonString(), c.AfterSnapshot: gjson.New(afterJSON).MustToJsonString(), c.Reason: reason, c.IpAddress: "", c.UserAgent: "", c.CreatedAt: now}).Insert()
_, e = tx.Model(dao.AdminOperationLog.Table()).Data(g.Map{c.Id: id, c.TenantId: tenantID, c.OperatorId: operatorID, c.OperationType: operation, c.TargetType: targetType, c.TargetId: targetID, c.RequestId: gctx.CtxId(ctx), c.BeforeSnapshot: gjson.New(beforeJSON).MustToJsonString(), c.AfterSnapshot: gjson.New(afterJSON).MustToJsonString(), c.Reason: reason, c.IpAddress: ipAddress, c.UserAgent: userAgent, c.CreatedAt: now}).Insert()
return e
}