package service import ( "blazing/cool" "blazing/modules/player/model" "fmt" "strings" "github.com/gogf/gf/v2/frame/g" ) type DoneService struct { BaseService } func NewDoneService(id uint32) *DoneService { return &DoneService{ BaseService: BaseService{userid: id, Service: &cool.Service{Model: model.NewMilestone(), UniqueKey: map[string]string{ "player_id": "角色名称不能重复", }}, }, } } // ID // 击杀-捕捉 func (s *DoneService) UpdatePet(ptye model.PetInfo, res ...uint32) { //属性->属性值->ID 击杀-捕捉-炫彩击杀-炫彩捕捉 雄性 雌性 args := []uint32{ptye.ID} r1 := s.get(model.MilestoneMode.Pet, args) results := make([]uint32, len(res)) if r1 != nil { results = r1.Results } for i, v := range res { results[i] += v } s.update(model.MilestoneMode.Pet, args, results) } func (s *DoneService) UpdateRoom(res ...uint32) { args := []uint32{0} r1 := s.get(model.MilestoneMode.Room, args) results := make([]uint32, len(res)) if r1 != nil { results = r1.Results } for i, v := range res { results[i] += v } s.update(model.MilestoneMode.Room, args, results) } // 内部方法,实现更新 func (s *DoneService) update(ptye model.EnumMilestone, args []uint32, results []uint32) { if cool.Config.ServerInfo.IsVip != 0 { return } whereArgs, whereParams := buildJSONBArrayAnyCondition("args", args) if t, _ := s.dbm_fix(s.Model).Where("done_type", ptye).Wheref(whereArgs, whereParams...). Wheref(`jsonb_typeof(args) = ?`, "array").Exist(); t { s.dbm_fix(s.Model).Where("done_type", ptye).Wheref(whereArgs, whereParams...). Wheref(`jsonb_typeof(args) = ?`, "array").Data( g.Map{ "results": results, }, ).Update() } else { r := g.Map{ "player_id": s.userid, "done_type": ptye, "args": args, "results": results, } s.dbm_fix(s.Model).Data(r).Insert() } } func (s *DoneService) get(ptye model.EnumMilestone, args []uint32) *model.Milestone { var Barges *model.Milestone whereArgs, whereParams := buildJSONBArrayAnyCondition("args", args) s.dbm_fix(s.Model).Where("done_type", ptye).Wheref(whereArgs, whereParams...). Wheref(`jsonb_typeof(args) = ?`, "array").Scan(&Barges) return Barges } func buildJSONBArrayAnyCondition(column string, values []uint32) (string, []any) { if len(values) == 0 { return "FALSE", nil } clauses := make([]string, 0, len(values)+1) params := make([]any, 0, len(values)+1) for _, value := range values { clauses = append(clauses, fmt.Sprintf( `EXISTS (SELECT 1 FROM jsonb_array_elements_text(CASE WHEN jsonb_typeof(%s) = 'array' THEN %s ELSE '[]'::jsonb END) AS elem WHERE elem = CAST(? AS text))`, column, column, )) params = append(params, value) } clauses = append(clauses, fmt.Sprintf( `CASE WHEN jsonb_typeof(%s) = 'array' THEN jsonb_array_length(%s) ELSE -1 END = ?`, column, column, )) params = append(params, len(values)) return strings.Join(clauses, " AND "), params } func (s *DoneService) PetBarge(start, end uint32) []model.Milestone { var Barges []model.Milestone s.dbm_fix(s.Model).Where("done_type", model.MilestoneMode.Pet). Wheref(`jsonb_typeof(args) = ?`, "array"). Wheref(`jsonb_typeof(args) != ?`, "'[]'::jsonb"). Wheref(`(args->> 0)::int BETWEEN ? AND ?`, start, end). Scan(&Barges) return Barges }