feat: admin 使用固定 ID 并补全全角色权限和演示数据

This commit is contained in:
zetaloop
2026-05-03 08:09:43 +08:00
parent 776ecc479f
commit 9a32850030
6 changed files with 89 additions and 30 deletions
+35 -11
View File
@@ -6,14 +6,28 @@ import (
"strings" "strings"
"time" "time"
"juwan-backend/app/snowflake/rpc/snowflake" "juwan-backend/app/users/rpc/internal/models/schema"
"juwan-backend/app/users/rpc/internal/models/users" "juwan-backend/app/users/rpc/internal/models/users"
"juwan-backend/app/users/rpc/internal/svc" "juwan-backend/app/users/rpc/internal/svc"
"juwan-backend/common/utils/pwdUtils" "juwan-backend/common/utils/pwdUtils"
"juwan-backend/pkg/types"
"github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/core/logx"
) )
const adminUserID int64 = 100000
var adminVerifiedRoles = types.TextArray{
Elements: []string{"consumer", "player", "owner", "admin"},
Valid: true,
}
var adminVerificationStatus = schema.VerificationStatusStruct{
Consumer: "approved",
Player: "approved",
Owner: "approved",
}
func initAdmin(svcCtx *svc.ServiceContext) { func initAdmin(svcCtx *svc.ServiceContext) {
username := strings.TrimSpace(os.Getenv("ADMIN_USERNAME")) username := strings.TrimSpace(os.Getenv("ADMIN_USERNAME"))
password := strings.TrimSpace(os.Getenv("ADMIN_PASSWORD")) password := strings.TrimSpace(os.Getenv("ADMIN_PASSWORD"))
@@ -24,8 +38,9 @@ func initAdmin(svcCtx *svc.ServiceContext) {
go func() { go func() {
ctx := context.Background() ctx := context.Background()
var existing bool
for i := range 30 { for i := range 30 {
exists, err := svcCtx.UsersModelRW.Users.Query().Where(users.UsernameEQ(username)).Exist(ctx) ok, err := svcCtx.UsersModelRW.Users.Query().Where(users.UsernameEQ(username)).Exist(ctx)
if err != nil { if err != nil {
if i < 29 { if i < 29 {
time.Sleep(time.Second) time.Sleep(time.Second)
@@ -34,10 +49,23 @@ func initAdmin(svcCtx *svc.ServiceContext) {
logx.Errorf("check admin user: %v", err) logx.Errorf("check admin user: %v", err)
return return
} }
if exists { existing = ok
break
}
if existing {
err := svcCtx.UsersModelRW.Users.Update().
Where(users.UsernameEQ(username)).
SetIsAdmin(true).
SetVerifiedRoles(adminVerifiedRoles).
SetVerificationStatus(adminVerificationStatus).
Exec(ctx)
if err != nil {
logx.Errorf("reconcile admin user: %v", err)
return return
} }
break logx.Infof("reconciled admin user: %s", username)
return
} }
hashedPassword, err := pwdUtils.HashPassword(password) hashedPassword, err := pwdUtils.HashPassword(password)
@@ -46,14 +74,8 @@ func initAdmin(svcCtx *svc.ServiceContext) {
return return
} }
resp, err := svcCtx.Snowflake.NextId(ctx, &snowflake.NextIdReq{})
if err != nil {
logx.Errorf("generate admin user ID: %v", err)
return
}
_, err = svcCtx.UsersModelRW.Users.Create(). _, err = svcCtx.UsersModelRW.Users.Create().
SetID(resp.Id). SetID(adminUserID).
SetUsername(username). SetUsername(username).
SetPasswordHash(hashedPassword). SetPasswordHash(hashedPassword).
SetEmail(email). SetEmail(email).
@@ -63,6 +85,8 @@ func initAdmin(svcCtx *svc.ServiceContext) {
SetCurrentRole("consumer"). SetCurrentRole("consumer").
SetNickname(username). SetNickname(username).
SetIsAdmin(true). SetIsAdmin(true).
SetVerifiedRoles(adminVerifiedRoles).
SetVerificationStatus(adminVerificationStatus).
Save(ctx) Save(ctx)
if err != nil { if err != nil {
logx.Errorf("create admin user: %v", err) logx.Errorf("create admin user: %v", err)
+12
View File
@@ -1,4 +1,14 @@
INSERT INTO posts (id, author_id, author_role, title, content, tags, like_count, comment_count) VALUES INSERT INTO posts (id, author_id, author_role, title, content, tags, like_count, comment_count) VALUES
(100000, 100000, 'admin', '新赛季代练活动上线:首单立减 20',
'新赛季开启,聚玩新一轮活动来了:
活动期间:
- 新用户首单立减 20 元,最低 19.9 起
- 老用户推荐新人,双方各得 30 元代金券
- 周末下单额外送一局陪玩体验
所有活动可在下单时自动生效,有任何问题可在社区留言或私信我。祝大家上分顺利!',
ARRAY['活动','公告','新赛季'], 20, 1),
(100001, 100001, 'player', '新赛季中单法师强度排行', (100001, 100001, 'player', '新赛季中单法师强度排行',
'新赛季中单法师的强度有了不少变化,这里给大家分析一下当前版本的T0-T2梯队。 '新赛季中单法师的强度有了不少变化,这里给大家分析一下当前版本的T0-T2梯队。
@@ -31,6 +41,7 @@ T2: 佐伊、妮蔻
ARRAY['英雄联盟','心得','上分'], 15, 4); ARRAY['英雄联盟','心得','上分'], 15, 4);
INSERT INTO comments (id, post_id, author_id, content, like_count) VALUES INSERT INTO comments (id, post_id, author_id, content, like_count) VALUES
(100000, 100000, 100001, '这波活动真香,已经下单了', 5),
(100001, 100001, 100002, '阿狸确实强,ban率太高了', 3), (100001, 100001, 100002, '阿狸确实强,ban率太高了', 3),
(100002, 100001, 100006, '维克托感觉也是T0级别的', 1), (100002, 100001, 100006, '维克托感觉也是T0级别的', 1),
(100003, 100001, 100003, '法师版本确实舒服', 2), (100003, 100001, 100003, '法师版本确实舒服', 2),
@@ -45,6 +56,7 @@ INSERT INTO comments (id, post_id, author_id, content, like_count) VALUES
(100012, 100005, 100003, '赞同,我也是靠精通少数英雄上的不朽', 1); (100012, 100005, 100003, '赞同,我也是靠精通少数英雄上的不朽', 1);
INSERT INTO post_likes (id, post_id, user_id) VALUES INSERT INTO post_likes (id, post_id, user_id) VALUES
(109100, 100000, 100001),(109099, 100000, 100002),(109098, 100000, 100006),(109097, 100000, 100007),(109096, 100000, 100008),
(109101, 100001, 100002),(109102, 100001, 100003),(109103, 100001, 100006),(109104, 100001, 100007), (109101, 100001, 100002),(109102, 100001, 100003),(109103, 100001, 100006),(109104, 100001, 100007),
(109105, 100002, 100001),(109106, 100002, 100006), (109105, 100002, 100001),(109106, 100002, 100006),
(109107, 100003, 100001),(109108, 100003, 100002), (109107, 100003, 100001),(109108, 100003, 100002),
+5 -1
View File
@@ -1,4 +1,5 @@
INSERT INTO players (id, user_id, status, rating, total_orders, completed_orders, gender, tags, games, shop_id) VALUES INSERT INTO players (id, user_id, status, rating, total_orders, completed_orders, gender, tags, games, shop_id) VALUES
(100000, 100000, 'available', 5.00, 0, 0, false, ARRAY['LOL王者','VALORANT不朽','多游戏'], ARRAY[100001,100002,100003,100005]::bigint[], 100000),
(100001, 100001, 'available', 4.85, 128, 120, false, ARRAY['中单','法师','上分快'], ARRAY[100001,100002]::bigint[], 100001), (100001, 100001, 'available', 4.85, 128, 120, false, ARRAY['中单','法师','上分快'], ARRAY[100001,100002]::bigint[], 100001),
(100002, 100002, 'available', 4.72, 95, 88, true, ARRAY['上单','刺客','高端局'], ARRAY[100001]::bigint[], 100001), (100002, 100002, 'available', 4.72, 95, 88, true, ARRAY['上单','刺客','高端局'], ARRAY[100001]::bigint[], 100001),
(100003, 100003, 'busy', 4.90, 67, 65, false, ARRAY['决斗','不朽段位'], ARRAY[100003]::bigint[], 100002), (100003, 100003, 'busy', 4.90, 67, 65, false, ARRAY['决斗','不朽段位'], ARRAY[100003]::bigint[], 100002),
@@ -14,4 +15,7 @@ INSERT INTO player_services (id, player_id, game_id, title, description, price,
(100007, 100003, 100003, 'VALORANT 陪玩', '不朽段位陪玩,教学向', 40.00, '', '不朽', ARRAY['全天']), (100007, 100003, 100003, 'VALORANT 陪玩', '不朽段位陪玩,教学向', 40.00, '', '不朽', ARRAY['全天']),
(100008, 100004, 100001, 'LOL 黄金上分', '黄金到铂金,新手友好', 39.00, '', '黄金→铂金', ARRAY['全天']), (100008, 100004, 100001, 'LOL 黄金上分', '黄金到铂金,新手友好', 39.00, '', '黄金→铂金', ARRAY['全天']),
(100009, 100004, 100003, 'VALORANT 白银上分', '白银到黄金,基础教学', 45.00, '', '白银→黄金', ARRAY['全天']), (100009, 100004, 100003, 'VALORANT 白银上分', '白银到黄金,基础教学', 45.00, '', '白银→黄金', ARRAY['全天']),
(100010, 100004, 100005, '原神深渊代打', '深渊12层满星', 80.00, '', '深渊12层', ARRAY['全天']); (100010, 100004, 100005, '原神深渊代打', '深渊12层满星', 80.00, '', '深渊12层', ARRAY['全天']),
(100011, 100000, 100001, 'LOL 全段位上分', '铂金到王者全段位接单,经验丰富', 88.00, '', '铂金→王者', ARRAY['全天']),
(100012, 100000, 100003, 'VALORANT 高端陪玩','不朽段位陪练,教学向,耐心稳重', 50.00, '', '不朽', ARRAY['晚间','周末']),
(100013, 100000, 100002, '王者荣耀 巅峰赛带飞','巅峰赛 2300+ 老玩家,稳定上分', 66.00, '', '星耀→王者', ARRAY['全天']);
+3
View File
@@ -1,4 +1,6 @@
INSERT INTO shops (id, owner_id, name, description, rating, total_orders, player_count, commission_type, commission_value, dispatch_mode, announcements) VALUES INSERT INTO shops (id, owner_id, name, description, rating, total_orders, player_count, commission_type, commission_value, dispatch_mode, announcements) VALUES
(100000, 100000, '聚玩官方代练', '平台直营代练团队,专业稳定,支持多游戏,7天无理由退款', 5.00, 0, 1, 'percentage', 10.00, 'manual',
ARRAY['新用户首单 9 折','周末下单送陪玩券']),
(100001, 100004, '星辰代练工作室', '专业LOL/王者代练,7天无理由退款', 4.80, 256, 2, 'percentage', 15.00, 'manual', (100001, 100004, '星辰代练工作室', '专业LOL/王者代练,7天无理由退款', 4.80, 256, 2, 'percentage', 15.00, 'manual',
ARRAY['新店开业,首单九折!','招募高端局打手,待遇从优']), ARRAY['新店开业,首单九折!','招募高端局打手,待遇从优']),
(100002, 100005, '狼群电竞俱乐部', '高端局代练团队,大师以上段位保证', 4.65, 180, 1, 'percentage', 12.00, 'auto', (100002, 100005, '狼群电竞俱乐部', '高端局代练团队,大师以上段位保证', 4.65, 180, 1, 'percentage', 12.00, 'auto',
@@ -7,6 +9,7 @@ INSERT INTO shops (id, owner_id, name, description, rating, total_orders, player
ARRAY['支持LOL/VALORANT/原神']); ARRAY['支持LOL/VALORANT/原神']);
INSERT INTO shop_players (id, shop_id, player_id, is_primary) VALUES INSERT INTO shop_players (id, shop_id, player_id, is_primary) VALUES
(109000, 100000, 100000, true),
(109001, 100001, 100001, true), (109001, 100001, 100001, true),
(109002, 100001, 100002, false), (109002, 100001, 100002, false),
(109003, 100002, 100003, true), (109003, 100002, 100003, true),
+32 -17
View File
@@ -1,63 +1,78 @@
INSERT INTO users (id, username, password_hash, email, nickname, avatar, bio, "current_role", verified_roles, verification_status) VALUES INSERT INTO users (id, username, password_hash, email, nickname, avatar, bio, "current_role", verified_roles, verification_status, is_admin) VALUES
(100000, 'admin',
crypt('admin123', gen_salt('bf')),
'admin@juwan.local', '聚玩小助手', '', '平台运营,有问题找我',
'admin', ARRAY['consumer','player','owner','admin'],
'{"consumer":"approved","player":"approved","owner":"approved"}'::jsonb,
true),
(100001, 'player_lux', (100001, 'player_lux',
crypt('test1234', gen_salt('bf')), crypt('test1234', gen_salt('bf')),
'lux@test.local', '光辉女郎', '', '王者段位代练,擅长中单法师', 'lux@test.local', '光辉女郎', '', '王者段位代练,擅长中单法师',
'player', ARRAY['consumer','player'], 'player', ARRAY['consumer','player'],
'{"consumer":"approved","player":"approved"}'::jsonb), '{"consumer":"approved","player":"approved"}'::jsonb,
false),
(100002, 'player_yasuo', (100002, 'player_yasuo',
crypt('test1234', gen_salt('bf')), crypt('test1234', gen_salt('bf')),
'yasuo@test.local', '疾风剑豪', '', '国服亚索,上分快准狠', 'yasuo@test.local', '疾风剑豪', '', '国服亚索,上分快准狠',
'player', ARRAY['consumer','player'], 'player', ARRAY['consumer','player'],
'{"consumer":"approved","player":"approved"}'::jsonb), '{"consumer":"approved","player":"approved"}'::jsonb,
false),
(100003, 'player_jett', (100003, 'player_jett',
crypt('test1234', gen_salt('bf')), crypt('test1234', gen_salt('bf')),
'jett@test.local', '飞刀小姐', '', 'VALORANT 不朽段位', 'jett@test.local', '飞刀小姐', '', 'VALORANT 不朽段位',
'player', ARRAY['consumer','player'], 'player', ARRAY['consumer','player'],
'{"consumer":"approved","player":"approved"}'::jsonb), '{"consumer":"approved","player":"approved"}'::jsonb,
false),
(100004, 'owner_star', (100004, 'owner_star',
crypt('test1234', gen_salt('bf')), crypt('test1234', gen_salt('bf')),
'star@test.local', '星辰工作室', '', '专业代练工作室,诚信经营', 'star@test.local', '星辰工作室', '', '专业代练工作室,诚信经营',
'owner', ARRAY['consumer','owner'], 'owner', ARRAY['consumer','owner'],
'{"consumer":"approved","owner":"approved"}'::jsonb), '{"consumer":"approved","owner":"approved"}'::jsonb,
false),
(100005, 'owner_wolf', (100005, 'owner_wolf',
crypt('test1234', gen_salt('bf')), crypt('test1234', gen_salt('bf')),
'wolf@test.local', '狼群电竞', '', '高端局代练团队', 'wolf@test.local', '狼群电竞', '', '高端局代练团队',
'owner', ARRAY['consumer','owner'], 'owner', ARRAY['consumer','owner'],
'{"consumer":"approved","owner":"approved"}'::jsonb), '{"consumer":"approved","owner":"approved"}'::jsonb,
false),
(100006, 'consumer_test', (100006, 'consumer_test',
crypt('test1234', gen_salt('bf')), crypt('test1234', gen_salt('bf')),
'consumer@test.local', '普通玩家小明', '', '想上钻石', 'consumer@test.local', '普通玩家小明', '', '想上钻石',
'consumer', ARRAY['consumer'], 'consumer', ARRAY['consumer'],
'{"consumer":"approved"}'::jsonb), '{"consumer":"approved"}'::jsonb,
false),
(100007, 'consumer_test2', (100007, 'consumer_test2',
crypt('test1234', gen_salt('bf')), crypt('test1234', gen_salt('bf')),
'consumer2@test.local', '快乐玩家小红', '', '想找人带上分', 'consumer2@test.local', '快乐玩家小红', '', '想找人带上分',
'consumer', ARRAY['consumer'], 'consumer', ARRAY['consumer'],
'{"consumer":"approved"}'::jsonb), '{"consumer":"approved"}'::jsonb,
false),
(100008, 'player_owner_duo', (100008, 'player_owner_duo',
crypt('test1234', gen_salt('bf')), crypt('test1234', gen_salt('bf')),
'duo@test.local', '全能选手', '', '既是打手也是店主', 'duo@test.local', '全能选手', '', '既是打手也是店主',
'player', ARRAY['consumer','player','owner'], 'player', ARRAY['consumer','player','owner'],
'{"consumer":"approved","player":"approved","owner":"approved"}'::jsonb); '{"consumer":"approved","player":"approved","owner":"approved"}'::jsonb,
false);
INSERT INTO user_preferences (user_id) VALUES INSERT INTO user_preferences (user_id) VALUES
(100001),(100002),(100003),(100004),(100005),(100006),(100007),(100008); (100000),(100001),(100002),(100003),(100004),(100005),(100006),(100007),(100008);
INSERT INTO user_verifications (id, user_id, role, status, materials, reviewed_by, reviewed_at) VALUES INSERT INTO user_verifications (id, user_id, role, status, materials, reviewed_by, reviewed_at) VALUES
(100001, 100001, 'player', 'approved', '{"id_card":"mock://id1.jpg","rank_screenshot":"mock://rank1.jpg"}'::jsonb, 702627789228081152, NOW()), (100001, 100001, 'player', 'approved', '{"id_card":"mock://id1.jpg","rank_screenshot":"mock://rank1.jpg"}'::jsonb, 100000, NOW()),
(100002, 100002, 'player', 'approved', '{"id_card":"mock://id2.jpg","rank_screenshot":"mock://rank2.jpg"}'::jsonb, 702627789228081152, NOW()), (100002, 100002, 'player', 'approved', '{"id_card":"mock://id2.jpg","rank_screenshot":"mock://rank2.jpg"}'::jsonb, 100000, NOW()),
(100003, 100003, 'player', 'approved', '{"id_card":"mock://id3.jpg","rank_screenshot":"mock://rank3.jpg"}'::jsonb, 702627789228081152, NOW()), (100003, 100003, 'player', 'approved', '{"id_card":"mock://id3.jpg","rank_screenshot":"mock://rank3.jpg"}'::jsonb, 100000, NOW()),
(100004, 100004, 'owner', 'approved', '{"business_license":"mock://biz1.jpg"}'::jsonb, 702627789228081152, NOW()), (100004, 100004, 'owner', 'approved', '{"business_license":"mock://biz1.jpg"}'::jsonb, 100000, NOW()),
(100005, 100005, 'owner', 'approved', '{"business_license":"mock://biz2.jpg"}'::jsonb, 702627789228081152, NOW()), (100005, 100005, 'owner', 'approved', '{"business_license":"mock://biz2.jpg"}'::jsonb, 100000, NOW()),
(100006, 100008, 'player', 'approved', '{"id_card":"mock://id8.jpg","rank_screenshot":"mock://rank8.jpg"}'::jsonb, 702627789228081152, NOW()), (100006, 100008, 'player', 'approved', '{"id_card":"mock://id8.jpg","rank_screenshot":"mock://rank8.jpg"}'::jsonb, 100000, NOW()),
(100007, 100008, 'owner', 'approved', '{"business_license":"mock://biz8.jpg"}'::jsonb, 702627789228081152, NOW()); (100007, 100008, 'owner', 'approved', '{"business_license":"mock://biz8.jpg"}'::jsonb, 100000, NOW());
INSERT INTO user_follows (id, follower_id, followee_id) VALUES INSERT INTO user_follows (id, follower_id, followee_id) VALUES
(100001, 100006, 100001), (100001, 100006, 100001),
+1
View File
@@ -1,4 +1,5 @@
INSERT INTO wallets (user_id, balance, frozen_balance) VALUES INSERT INTO wallets (user_id, balance, frozen_balance) VALUES
(100000, 99999.00, 0.00),
(100001, 2580.00, 0.00), (100001, 2580.00, 0.00),
(100002, 1890.00, 0.00), (100002, 1890.00, 0.00),
(100003, 3200.00, 0.00), (100003, 3200.00, 0.00),