280 lines
9.9 KiB
Go
280 lines
9.9 KiB
Go
package sys
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/url"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"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/os/gctx"
|
|
"github.com/gogf/gf/v2/os/gtime"
|
|
|
|
"hotgo/internal/library/contexts"
|
|
"hotgo/internal/library/cultivateadmin"
|
|
"hotgo/internal/model/input/form"
|
|
"hotgo/internal/model/input/sysin"
|
|
"hotgo/internal/service"
|
|
)
|
|
|
|
type sSysCultivateFlower struct{}
|
|
|
|
func NewSysCultivateFlower() *sSysCultivateFlower { return &sSysCultivateFlower{} }
|
|
func init() { service.RegisterSysCultivateFlower(NewSysCultivateFlower()) }
|
|
|
|
type cultivateFlowerDTO struct {
|
|
ID string `json:"id"`
|
|
FlowerCode string `json:"flowerCode"`
|
|
FlowerName string `json:"flowerName"`
|
|
FlowerDesc string `json:"flowerDesc"`
|
|
IconFileID string `json:"iconFileId"`
|
|
Status string `json:"status"`
|
|
ConfigVersion string `json:"configVersion"`
|
|
DailyWaterLimit uint `json:"dailyWaterLimit"`
|
|
DailyFertilizeLimit uint `json:"dailyFertilizeLimit"`
|
|
ShareConfig any `json:"shareConfig"`
|
|
SortNo int `json:"sortNo"`
|
|
StageCount int `json:"stageCount"`
|
|
StageRules []*cultivateStageRuleDTO `json:"stageRules"`
|
|
CreatedAt *gtime.Time `json:"createdAt"`
|
|
UpdatedAt *gtime.Time `json:"updatedAt"`
|
|
}
|
|
|
|
type cultivateStageRuleDTO struct {
|
|
ID string `json:"id"`
|
|
Stage string `json:"stage"`
|
|
NextStage string `json:"nextStage"`
|
|
RequiredPoints uint `json:"requiredPoints"`
|
|
WaterPoints uint `json:"waterPoints"`
|
|
FertilizePoints uint `json:"fertilizePoints"`
|
|
WaitHours uint `json:"waitHours"`
|
|
AllowedActions []string `json:"allowedActions"`
|
|
ImageFileID string `json:"imageFileId"`
|
|
AnimationFileID string `json:"animationFileId"`
|
|
ProgressTextTemplate string `json:"progressTextTemplate"`
|
|
CompletionText string `json:"completionText"`
|
|
SortNo int `json:"sortNo"`
|
|
}
|
|
|
|
func cultivateTenantID(ctx context.Context) int64 {
|
|
id := contexts.GetTenantId(ctx)
|
|
if id <= 0 {
|
|
id = g.Cfg().MustGet(ctx, "cultivate.defaultTenantId", 1).Int64()
|
|
}
|
|
return id
|
|
}
|
|
|
|
func cultivateAdminScope(ctx context.Context) (cultivateadmin.Scope, error) {
|
|
tenant, err := resolveImAdminTenant(ctx, cultivateTenantID(ctx))
|
|
if err != nil {
|
|
return cultivateadmin.Scope{}, err
|
|
}
|
|
operatorID := contexts.GetUserId(ctx)
|
|
if operatorID <= 0 {
|
|
return cultivateadmin.Scope{}, gerror.New("当前管理员身份无效")
|
|
}
|
|
return cultivateadmin.Scope{
|
|
TenantID: tenant.Id, TenantCode: tenant.Code, OperatorID: operatorID,
|
|
RoleKey: contexts.GetRoleKey(ctx), RequestID: gctx.CtxId(ctx),
|
|
}, nil
|
|
}
|
|
|
|
func (s *sSysCultivateFlower) List(ctx context.Context, in *sysin.CultivateFlowerListInp) (list []*sysin.CultivateFlowerListModel, totalCount int, err error) {
|
|
if err = in.Filter(ctx); err != nil {
|
|
return nil, 0, err
|
|
}
|
|
scope, err := cultivateAdminScope(ctx)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
normalizeCultivatePage(&in.PageReq)
|
|
values := cultivatePageValues(in.Page, in.PerPage)
|
|
cultivateSetQuery(values, "flower_code", in.FlowerCode)
|
|
cultivateSetQuery(values, "flower_name", in.FlowerName)
|
|
cultivateSetQuery(values, "status", in.Status)
|
|
cultivateSetQuery(values, "config_version", in.ConfigVersion)
|
|
setTimeRange(values, in.CreatedAt)
|
|
var page cultivateadmin.Page[cultivateFlowerDTO]
|
|
if err = cultivateadmin.DefaultClient(ctx).Get(ctx, scope, "/flowers", values, &page); err != nil {
|
|
return nil, 0, err
|
|
}
|
|
list = make([]*sysin.CultivateFlowerListModel, 0, len(page.Items))
|
|
for index := range page.Items {
|
|
item, convertErr := flowerListModel(&page.Items[index])
|
|
if convertErr != nil {
|
|
return nil, 0, convertErr
|
|
}
|
|
list = append(list, item)
|
|
}
|
|
return list, page.Total, nil
|
|
}
|
|
|
|
func (s *sSysCultivateFlower) View(ctx context.Context, in *sysin.CultivateFlowerViewInp) (*sysin.CultivateFlowerViewModel, error) {
|
|
if err := in.Filter(ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
scope, err := cultivateAdminScope(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var item cultivateFlowerDTO
|
|
if err = cultivateadmin.DefaultClient(ctx).Get(ctx, scope, "/flowers/"+strconv.FormatUint(in.Id, 10), nil, &item); err != nil {
|
|
return nil, err
|
|
}
|
|
return flowerViewModel(&item)
|
|
}
|
|
|
|
func (s *sSysCultivateFlower) Edit(ctx context.Context, in *sysin.CultivateFlowerEditInp) error {
|
|
if err := in.Filter(ctx); err != nil {
|
|
return err
|
|
}
|
|
scope, err := cultivateAdminScope(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
payload := flowerPayload(in)
|
|
var response struct {
|
|
ID string `json:"id"`
|
|
}
|
|
if in.Id == 0 {
|
|
err = cultivateadmin.DefaultClient(ctx).Post(ctx, scope, "/flowers", payload, &response)
|
|
} else {
|
|
err = cultivateadmin.DefaultClient(ctx).Put(ctx, scope, "/flowers/"+strconv.FormatUint(in.Id, 10), payload, &response)
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if in.Id == 0 && response.ID != "" {
|
|
in.Id, err = strconv.ParseUint(response.ID, 10, 64)
|
|
if err != nil {
|
|
return gerror.Wrap(err, "解析养成服务花种ID失败")
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *sSysCultivateFlower) Status(ctx context.Context, in *sysin.CultivateFlowerStatusInp) error {
|
|
if err := in.Filter(ctx); err != nil {
|
|
return err
|
|
}
|
|
scope, err := cultivateAdminScope(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return cultivateadmin.DefaultClient(ctx).Post(ctx, scope, "/flowers/"+strconv.FormatUint(in.Id, 10)+"/status", map[string]any{
|
|
"status": in.Status, "reason": strings.TrimSpace(in.Reason),
|
|
}, nil)
|
|
}
|
|
|
|
func flowerPayload(in *sysin.CultivateFlowerEditInp) map[string]any {
|
|
shareConfig := map[string]any{}
|
|
if in.ShareConfig != nil {
|
|
_ = json.Unmarshal([]byte(in.ShareConfig.MustToJsonString()), &shareConfig)
|
|
}
|
|
rules := make([]map[string]any, 0, len(in.StageRules))
|
|
for _, rule := range in.StageRules {
|
|
if rule == nil {
|
|
continue
|
|
}
|
|
rules = append(rules, map[string]any{
|
|
"id": strconv.FormatUint(rule.Id, 10), "stage": rule.Stage, "next_stage": rule.NextStage,
|
|
"required_points": rule.RequiredPoints, "water_points": rule.WaterPoints, "fertilize_points": rule.FertilizePoints,
|
|
"wait_hours": rule.WaitHours, "allowed_actions": rule.AllowedActions, "image_file_id": rule.ImageFileId, "animation_file_id": rule.AnimationFileId,
|
|
"progress_text_template": rule.ProgressTextTemplate, "completion_text": rule.CompletionText, "sort_no": rule.SortNo,
|
|
})
|
|
}
|
|
return map[string]any{
|
|
"flower_code": in.FlowerCode, "flower_name": in.FlowerName, "flower_desc": in.FlowerDesc,
|
|
"icon_file_id": in.IconFileId, "status": in.Status, "daily_water_limit": in.DailyWaterLimit,
|
|
"daily_fertilize_limit": in.DailyFertilizeLimit, "share_config": shareConfig, "sort_no": in.SortNo, "stage_rules": rules,
|
|
}
|
|
}
|
|
|
|
func flowerListModel(item *cultivateFlowerDTO) (*sysin.CultivateFlowerListModel, error) {
|
|
id, err := parseCultivateUint(item.ID, "花种ID")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &sysin.CultivateFlowerListModel{
|
|
Id: id, FlowerCode: item.FlowerCode, FlowerName: item.FlowerName, FlowerDesc: item.FlowerDesc,
|
|
IconFileId: item.IconFileID, Status: item.Status, ConfigVersion: item.ConfigVersion,
|
|
DailyWaterLimit: item.DailyWaterLimit, DailyFertilizeLimit: item.DailyFertilizeLimit,
|
|
SortNo: item.SortNo, StageCount: item.StageCount, CreatedAt: item.CreatedAt, UpdatedAt: item.UpdatedAt,
|
|
}, nil
|
|
}
|
|
|
|
func flowerViewModel(item *cultivateFlowerDTO) (*sysin.CultivateFlowerViewModel, error) {
|
|
list, err := flowerListModel(item)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
shareConfig, _ := json.Marshal(item.ShareConfig)
|
|
result := &sysin.CultivateFlowerViewModel{
|
|
CultivateFlowerEditInp: sysin.CultivateFlowerEditInp{
|
|
Id: list.Id, FlowerCode: list.FlowerCode, FlowerName: list.FlowerName, FlowerDesc: list.FlowerDesc,
|
|
IconFileId: list.IconFileId, Status: list.Status, DailyWaterLimit: list.DailyWaterLimit,
|
|
DailyFertilizeLimit: list.DailyFertilizeLimit, ShareConfig: gjson.New(string(shareConfig)), SortNo: list.SortNo,
|
|
},
|
|
ConfigVersion: list.ConfigVersion, CreatedAt: list.CreatedAt, UpdatedAt: list.UpdatedAt,
|
|
}
|
|
for _, rule := range item.StageRules {
|
|
id, parseErr := parseCultivateUint(rule.ID, "成长阶段ID")
|
|
if parseErr != nil {
|
|
return nil, parseErr
|
|
}
|
|
result.StageRules = append(result.StageRules, &sysin.CultivateStageRuleEditInp{
|
|
Id: id, Stage: rule.Stage, NextStage: rule.NextStage, RequiredPoints: rule.RequiredPoints,
|
|
WaterPoints: rule.WaterPoints, FertilizePoints: rule.FertilizePoints, WaitHours: rule.WaitHours, AllowedActions: rule.AllowedActions,
|
|
ImageFileId: rule.ImageFileID, AnimationFileId: rule.AnimationFileID,
|
|
ProgressTextTemplate: rule.ProgressTextTemplate, CompletionText: rule.CompletionText, SortNo: rule.SortNo,
|
|
})
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func parseCultivateUint(value, field string) (uint64, error) {
|
|
id, err := strconv.ParseUint(strings.TrimSpace(value), 10, 64)
|
|
if err != nil || id == 0 {
|
|
return 0, gerror.Newf("养成服务返回的%s不正确", field)
|
|
}
|
|
return id, nil
|
|
}
|
|
|
|
func normalizeCultivatePage(page *form.PageReq) {
|
|
if page.Page <= 0 {
|
|
page.Page = 1
|
|
}
|
|
if page.PerPage <= 0 {
|
|
page.PerPage = 10
|
|
}
|
|
if page.PerPage > 100 {
|
|
page.PerPage = 100
|
|
}
|
|
}
|
|
|
|
func cultivatePageValues(page, perPage int) url.Values {
|
|
return url.Values{"page": []string{strconv.Itoa(page)}, "per_page": []string{strconv.Itoa(perPage)}}
|
|
}
|
|
|
|
func cultivateSetQuery(values url.Values, key, value string) {
|
|
if value = strings.TrimSpace(value); value != "" {
|
|
values.Set(key, value)
|
|
}
|
|
}
|
|
|
|
func setTimeRange(values url.Values, value []*gtime.Time) {
|
|
if len(value) != 2 {
|
|
return
|
|
}
|
|
if value[0] != nil {
|
|
values.Set("created_from", value[0].Format(time.RFC3339))
|
|
}
|
|
if value[1] != nil {
|
|
values.Set("created_to", value[1].Format(time.RFC3339))
|
|
}
|
|
}
|