refactor(utils): 修复密码哈希比较逻辑错误 feat(user): 新增按状态筛选优惠券接口 docs: 添加虚拟发货与任务中心相关文档 fix(wechat): 修正Code2Session上下文传递问题 test: 补充订单折扣与积分转换测试用例 build: 更新配置文件与构建脚本 style: 清理多余的空行与注释
204 lines
8.1 KiB
Go
204 lines
8.1 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"os"
|
|
)
|
|
|
|
const (
|
|
BaseURL = "http://localhost:9991"
|
|
Token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidXNlcm5hbWUiOiJTdXBlciIsIm5pY2tuYW1lIjoiU3VwZXIiLCJpc19zdXBlciI6MSwicGxhdGZvcm0iOiLnrqHnkIbnq68iLCJleHAiOjE3NjU2NDIwMDYsIm5iZiI6MTc2NTM4MjgwNiwiaWF0IjoxNzY1MzgyODA2fQ.1pYRmSmFd-b4PudiYhGXgCv-LBr49_MMfNdyuc_7LXA"
|
|
)
|
|
|
|
func main() {
|
|
if len(os.Args) > 1 && os.Args[1] == "check-json" {
|
|
CheckAPIJSONTags()
|
|
return
|
|
}
|
|
|
|
fmt.Println("Starting to setup complete task center...")
|
|
|
|
// 1. 清理现有任务
|
|
tasks := doRequest("GET", "/api/admin/task-center/tasks", nil)
|
|
list := tasks["list"].([]interface{})
|
|
for _, t := range list {
|
|
task := t.(map[string]any)
|
|
id := int64(task["id"].(float64))
|
|
fmt.Printf("Deleting existing task: %d - %s\n", id, task["name"])
|
|
doRequest("DELETE", fmt.Sprintf("/api/admin/task-center/tasks/%d", id), nil)
|
|
}
|
|
|
|
// ---------------------------------------------------------
|
|
// 任务 1: 每日订单挑战 (Daily Order Challenge)
|
|
// ---------------------------------------------------------
|
|
t1ID := createTask("每日订单挑战", "每日完成订单挑战,赢取积分与道具", 1, 1)
|
|
upsertTiers(t1ID, []map[string]any{
|
|
{"metric": "order_count", "operator": ">=", "threshold": 1, "window": "daily", "repeatable": 1, "priority": 1},
|
|
{"metric": "order_count", "operator": ">=", "threshold": 10, "window": "daily", "repeatable": 1, "priority": 2},
|
|
{"metric": "order_count", "operator": ">=", "threshold": 100, "window": "daily", "repeatable": 1, "priority": 3},
|
|
})
|
|
// 获取 Tier IDs 并配置奖励
|
|
t1Tiers := listTiers(t1ID)
|
|
var r1 []map[string]any
|
|
for _, t := range t1Tiers {
|
|
p := int(t["Priority"].(float64))
|
|
tid := int64(t["ID"].(float64))
|
|
if p == 1 { // 1单 -> 1元(100积分)
|
|
r1 = append(r1, map[string]any{"tier_id": tid, "reward_type": "points", "reward_payload": map[string]int{"points": 100}, "quantity": 1})
|
|
} else if p == 2 { // 10单 -> 优惠券ID 1
|
|
r1 = append(r1, map[string]any{"tier_id": tid, "reward_type": "coupon", "reward_payload": map[string]int{"coupon_id": 1}, "quantity": 1})
|
|
} else if p == 3 { // 100单 -> 道具卡ID 1
|
|
r1 = append(r1, map[string]any{"tier_id": tid, "reward_type": "item_card", "reward_payload": map[string]int{"card_id": 1, "quantity": 1}, "quantity": 1})
|
|
}
|
|
}
|
|
upsertRewards(t1ID, r1)
|
|
fmt.Printf("Created Task [Daily Order]: %d\n", t1ID)
|
|
|
|
// ---------------------------------------------------------
|
|
// 任务 2: 每日邀请挑战 (Daily Invite Challenge)
|
|
// ---------------------------------------------------------
|
|
t2ID := createTask("每日邀请挑战", "每日邀请好友,奖励领不停", 1, 1)
|
|
upsertTiers(t2ID, []map[string]any{
|
|
{"metric": "invite_count", "operator": ">=", "threshold": 1, "window": "daily", "repeatable": 1, "priority": 1},
|
|
{"metric": "invite_count", "operator": ">=", "threshold": 10, "window": "daily", "repeatable": 1, "priority": 2},
|
|
{"metric": "invite_count", "operator": ">=", "threshold": 100, "window": "daily", "repeatable": 1, "priority": 3},
|
|
})
|
|
t2Tiers := listTiers(t2ID)
|
|
var r2 []map[string]any
|
|
for _, t := range t2Tiers {
|
|
p := int(t["Priority"].(float64))
|
|
tid := int64(t["ID"].(float64))
|
|
if p == 1 { // 1人 -> 1元(100积分)
|
|
r2 = append(r2, map[string]any{"tier_id": tid, "reward_type": "points", "reward_payload": map[string]int{"points": 100}, "quantity": 1})
|
|
} else if p == 2 { // 10人 -> 优惠券ID 1
|
|
r2 = append(r2, map[string]any{"tier_id": tid, "reward_type": "coupon", "reward_payload": map[string]int{"coupon_id": 1}, "quantity": 1})
|
|
} else if p == 3 { // 100人 -> 道具卡ID 1
|
|
r2 = append(r2, map[string]any{"tier_id": tid, "reward_type": "item_card", "reward_payload": map[string]int{"card_id": 1, "quantity": 1}, "quantity": 1})
|
|
}
|
|
}
|
|
upsertRewards(t2ID, r2)
|
|
fmt.Printf("Created Task [Daily Invite]: %d\n", t2ID)
|
|
|
|
// ---------------------------------------------------------
|
|
// 任务 3: 新人首单福利 (Newbie First Order) - Lifetime
|
|
// ---------------------------------------------------------
|
|
t3ID := createTask("新人首单福利", "完成首次订单,获得新人专属奖励", 1, 1)
|
|
upsertTiers(t3ID, []map[string]any{
|
|
{"metric": "first_order", "operator": "==", "threshold": 1, "window": "lifetime", "repeatable": 0, "priority": 1},
|
|
})
|
|
t3Tiers := listTiers(t3ID)
|
|
var r3 []map[string]any
|
|
for _, t := range t3Tiers {
|
|
// 首单奖励 500 积分
|
|
r3 = append(r3, map[string]any{"tier_id": int64(t["ID"].(float64)), "reward_type": "points", "reward_payload": map[string]int{"points": 500}, "quantity": 1})
|
|
}
|
|
upsertRewards(t3ID, r3)
|
|
fmt.Printf("Created Task [Newbie First Order]: %d\n", t3ID)
|
|
|
|
// ---------------------------------------------------------
|
|
// 任务 4: 邀请达人 (Master Inviter) - Lifetime Cumulative
|
|
// ---------------------------------------------------------
|
|
t4ID := createTask("邀请达人挑战", "累计邀请好友,解锁达人成就", 1, 1)
|
|
upsertTiers(t4ID, []map[string]any{
|
|
{"metric": "invite_count", "operator": ">=", "threshold": 50, "window": "lifetime", "repeatable": 0, "priority": 1},
|
|
{"metric": "invite_count", "operator": ">=", "threshold": 200, "window": "lifetime", "repeatable": 0, "priority": 2},
|
|
{"metric": "invite_count", "operator": ">=", "threshold": 500, "window": "lifetime", "repeatable": 0, "priority": 3},
|
|
})
|
|
t4Tiers := listTiers(t4ID)
|
|
var r4 []map[string]any
|
|
for _, t := range t4Tiers {
|
|
p := int(t["Priority"].(float64))
|
|
tid := int64(t["ID"].(float64))
|
|
if p == 1 { // 50人 -> 道具卡 ID 1 x2
|
|
r4 = append(r4, map[string]any{"tier_id": tid, "reward_type": "item_card", "reward_payload": map[string]int{"card_id": 1, "quantity": 2}, "quantity": 2})
|
|
} else if p == 2 { // 200人 -> 优惠券 ID 1 x5
|
|
r4 = append(r4, map[string]any{"tier_id": tid, "reward_type": "coupon", "reward_payload": map[string]int{"coupon_id": 1}, "quantity": 5})
|
|
} else if p == 3 { // 500人 -> 10000 积分
|
|
r4 = append(r4, map[string]any{"tier_id": tid, "reward_type": "points", "reward_payload": map[string]int{"points": 10000}, "quantity": 1})
|
|
}
|
|
}
|
|
upsertRewards(t4ID, r4)
|
|
fmt.Printf("Created Task [Master Inviter]: %d\n", t4ID)
|
|
|
|
fmt.Println("All tasks setup completed!")
|
|
}
|
|
|
|
func doRequest(method, path string, body any) map[string]any {
|
|
var bodyReader io.Reader
|
|
if body != nil {
|
|
b, _ := json.Marshal(body)
|
|
bodyReader = bytes.NewReader(b)
|
|
}
|
|
req, _ := http.NewRequest(method, BaseURL+path, bodyReader)
|
|
req.Header.Set("Authorization", Token)
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
b, _ := io.ReadAll(resp.Body)
|
|
if resp.StatusCode >= 400 {
|
|
panic(fmt.Sprintf("Status: %d, Body: %s", resp.StatusCode, string(b)))
|
|
}
|
|
|
|
var res map[string]any
|
|
json.Unmarshal(b, &res)
|
|
return res
|
|
}
|
|
|
|
func doRequestRaw(method, path string, body any) []byte {
|
|
var bodyReader io.Reader
|
|
if body != nil {
|
|
b, _ := json.Marshal(body)
|
|
bodyReader = bytes.NewReader(b)
|
|
}
|
|
req, _ := http.NewRequest(method, BaseURL+path, bodyReader)
|
|
req.Header.Set("Authorization", Token)
|
|
if body != nil {
|
|
req.Header.Set("Content-Type", "application/json")
|
|
}
|
|
resp, err := http.DefaultClient.Do(req)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer resp.Body.Close()
|
|
b, _ := io.ReadAll(resp.Body)
|
|
return b
|
|
}
|
|
|
|
func createTask(name, desc string, status, visibility int) int64 {
|
|
res := doRequest("POST", "/api/admin/task-center/tasks", map[string]any{
|
|
"name": name, "description": desc, "status": status, "visibility": visibility,
|
|
})
|
|
return int64(res["id"].(float64))
|
|
}
|
|
|
|
func upsertTiers(taskID int64, tiers []map[string]any) {
|
|
doRequest("POST", fmt.Sprintf("/api/admin/task-center/tasks/%d/tiers", taskID), map[string]any{
|
|
"tiers": tiers,
|
|
})
|
|
}
|
|
|
|
func listTiers(taskID int64) []map[string]any {
|
|
res := doRequest("GET", fmt.Sprintf("/api/admin/task-center/tasks/%d/tiers", taskID), nil)
|
|
list := res["list"].([]interface{})
|
|
var ret []map[string]any
|
|
for _, v := range list {
|
|
ret = append(ret, v.(map[string]any))
|
|
}
|
|
return ret
|
|
}
|
|
|
|
func upsertRewards(taskID int64, rewards []map[string]any) {
|
|
doRequest("POST", fmt.Sprintf("/api/admin/task-center/tasks/%d/rewards", taskID), map[string]any{
|
|
"rewards": rewards,
|
|
})
|
|
}
|