fix invite rule id precision
This commit is contained in:
parent
b7c0225dc3
commit
362069e2d4
@ -5,6 +5,7 @@ import (
|
|||||||
"chatapp3-golang/internal/integration"
|
"chatapp3-golang/internal/integration"
|
||||||
"chatapp3-golang/internal/model"
|
"chatapp3-golang/internal/model"
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
@ -526,3 +527,31 @@ func TestDispatchGoldReturnsGrantError(t *testing.T) {
|
|||||||
t.Fatalf("reward log status = %s, want %s", log.Status, rewardLogStatusFailed)
|
t.Fatalf("reward log status = %s, want %s", log.Status, rewardLogStatusFailed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestInviteRuleIDJSONUsesStringForSnowflakeIDs(t *testing.T) {
|
||||||
|
const ruleID int64 = 2048743937920790530
|
||||||
|
payload, err := json.Marshal(HomeResponse{
|
||||||
|
ValidCountTasks: []TaskView{{RuleID: ruleID, RuleType: ruleTypeInviterValidCount}},
|
||||||
|
InviterBindReward: RewardView{
|
||||||
|
RuleID: ruleID,
|
||||||
|
RuleType: ruleTypeInviterBind,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("json.Marshal() error = %v", err)
|
||||||
|
}
|
||||||
|
raw := string(payload)
|
||||||
|
if !strings.Contains(raw, `"ruleId":"2048743937920790530"`) {
|
||||||
|
t.Fatalf("ruleId was not encoded as a string: %s", raw)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTaskClaimRequestAcceptsStringRuleID(t *testing.T) {
|
||||||
|
var req TaskClaimRequest
|
||||||
|
if err := json.Unmarshal([]byte(`{"ruleId":"2048743937920790530"}`), &req); err != nil {
|
||||||
|
t.Fatalf("json.Unmarshal() error = %v", err)
|
||||||
|
}
|
||||||
|
if req.RuleID != 2048743937920790530 {
|
||||||
|
t.Fatalf("RuleID = %d, want 2048743937920790530", req.RuleID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,12 +1,17 @@
|
|||||||
package invite
|
package invite
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"chatapp3-golang/internal/common"
|
"chatapp3-golang/internal/common"
|
||||||
"chatapp3-golang/internal/config"
|
"chatapp3-golang/internal/config"
|
||||||
"chatapp3-golang/internal/integration"
|
"chatapp3-golang/internal/integration"
|
||||||
"chatapp3-golang/internal/model"
|
"chatapp3-golang/internal/model"
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/redis/go-redis/v9"
|
"github.com/redis/go-redis/v9"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
@ -43,7 +48,7 @@ var NewAppError = common.NewAppError
|
|||||||
|
|
||||||
// RewardView 是邀请活动奖励的通用展示结构。
|
// RewardView 是邀请活动奖励的通用展示结构。
|
||||||
type RewardView struct {
|
type RewardView struct {
|
||||||
RuleID int64 `json:"ruleId,omitempty"`
|
RuleID int64 `json:"ruleId,string,omitempty"`
|
||||||
RuleType string `json:"ruleType,omitempty"`
|
RuleType string `json:"ruleType,omitempty"`
|
||||||
Threshold int64 `json:"threshold,omitempty"`
|
Threshold int64 `json:"threshold,omitempty"`
|
||||||
GoldAmount int64 `json:"goldAmount"`
|
GoldAmount int64 `json:"goldAmount"`
|
||||||
@ -53,7 +58,7 @@ type RewardView struct {
|
|||||||
|
|
||||||
// TaskView 是邀请任务进度及领取状态的展示结构。
|
// TaskView 是邀请任务进度及领取状态的展示结构。
|
||||||
type TaskView struct {
|
type TaskView struct {
|
||||||
RuleID int64 `json:"ruleId"`
|
RuleID int64 `json:"ruleId,string"`
|
||||||
RuleType string `json:"ruleType"`
|
RuleType string `json:"ruleType"`
|
||||||
Threshold int64 `json:"threshold"`
|
Threshold int64 `json:"threshold"`
|
||||||
Progress int64 `json:"progress"`
|
Progress int64 `json:"progress"`
|
||||||
@ -171,11 +176,46 @@ type TaskClaimRequest struct {
|
|||||||
RuleID int64 `json:"ruleId"`
|
RuleID int64 `json:"ruleId"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON 允许 H5 按字符串提交 Snowflake 规则 ID,避免 JS Number 精度丢失。
|
||||||
|
func (r *TaskClaimRequest) UnmarshalJSON(data []byte) error {
|
||||||
|
var payload struct {
|
||||||
|
RuleID any `json:"ruleId"`
|
||||||
|
}
|
||||||
|
decoder := json.NewDecoder(bytes.NewReader(data))
|
||||||
|
decoder.UseNumber()
|
||||||
|
if err := decoder.Decode(&payload); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ruleID, err := parseClaimRuleID(payload.RuleID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
r.RuleID = ruleID
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseClaimRuleID(value any) (int64, error) {
|
||||||
|
switch typed := value.(type) {
|
||||||
|
case nil:
|
||||||
|
return 0, nil
|
||||||
|
case json.Number:
|
||||||
|
return typed.Int64()
|
||||||
|
case string:
|
||||||
|
raw := strings.TrimSpace(typed)
|
||||||
|
if raw == "" {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
return strconv.ParseInt(raw, 10, 64)
|
||||||
|
default:
|
||||||
|
return 0, fmt.Errorf("ruleId must be string or number")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TaskClaimResponse 是任务领取结果。
|
// TaskClaimResponse 是任务领取结果。
|
||||||
type TaskClaimResponse struct {
|
type TaskClaimResponse struct {
|
||||||
Claimed bool `json:"claimed"`
|
Claimed bool `json:"claimed"`
|
||||||
AlreadyClaimed bool `json:"alreadyClaimed"`
|
AlreadyClaimed bool `json:"alreadyClaimed"`
|
||||||
RuleID int64 `json:"ruleId"`
|
RuleID int64 `json:"ruleId,string"`
|
||||||
RuleType string `json:"ruleType"`
|
RuleType string `json:"ruleType"`
|
||||||
Progress int64 `json:"progress"`
|
Progress int64 `json:"progress"`
|
||||||
Threshold int64 `json:"threshold"`
|
Threshold int64 `json:"threshold"`
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user