package main import ( "fmt" "time" "golang.org/x/crypto/bcrypt" ) // 生成用于测试的 SQL 脚本:创建两个有展品的账号 func main() { now := time.Now().UnixMilli() password := "password123" // 生成 password123 的 bcrypt hash hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) if err != nil { panic(err) } passwordHash := string(hashedPassword) // 用户1:user_id=100, star_id=88 user1ID := int64(100) star1ID := int64(88) user1Mobile := "13900001001" user1Nickname := "展馆测试用户1" hostProfile1ID := user1ID*1000000 + star1ID // 100000088 // 用户2:user_id=101, star_id=88 user2ID := int64(101) star2ID := int64(88) user2Mobile := "13900001002" user2Nickname := "展馆测试用户2" hostProfile2ID := user2ID*1000000 + star2ID // 101000088 // 资产ID(假设从 1000 开始) asset1ID := int64(1000) asset2ID := int64(1001) asset3ID := int64(1002) asset4ID := int64(1003) // 展位过期时间(7天后) expireAt := now + 7*24*3600*1000 fmt.Println("-- ========================================") fmt.Println("-- 创建两个有展品的测试账号") fmt.Println("-- 用户1: mobile=13900001001, password=password123, user_id=100") fmt.Println("-- 用户2: mobile=13900001002, password=password123, user_id=101") fmt.Println("-- ========================================") fmt.Println() // 用户1 fmt.Println("-- ========================================") fmt.Println("-- 用户1:创建用户、粉丝档案、展位、资产、展品") fmt.Println("-- ========================================") // 1. 插入用户 fmt.Printf(`INSERT INTO users (id, mobile, password_hash, is_active, created_at, updated_at) VALUES (%d, '%s', '%s', true, %d, %d) ON CONFLICT (mobile) DO UPDATE SET password_hash = EXCLUDED.password_hash; `, user1ID, user1Mobile, passwordHash, now, now) fmt.Println() // 2. 插入粉丝档案 fmt.Printf(`INSERT INTO fan_profiles (user_id, star_id, nickname, level, times, social, experience, coin_balance, crystal_balance, tags, starbook_limit, slot_limit, assets_count, is_active, created_at, updated_at) VALUES (%d, %d, '%s', 1, 1, 0, 0, 0, 1000, '[]'::jsonb, 3, 3, 2, true, %d, %d) ON CONFLICT (user_id, star_id) DO UPDATE SET nickname = EXCLUDED.nickname, crystal_balance = EXCLUDED.crystal_balance; `, user1ID, star1ID, user1Nickname, now, now) fmt.Println() // 3. 插入展位(3个,全部已解锁) for i := 1; i <= 3; i++ { slotID := int64(1000 + i) // slot_id: 1001, 1002, 1003 fmt.Printf(`INSERT INTO booth_slots (slot_id, host_profile_id, user_id, star_id, slot_index, visibility, is_enabled, unlock_type, unlock_value, created_at, updated_at) VALUES (%d, %d, %d, %d, %d, 'public', true, 'free', 0, %d, %d) ON CONFLICT (host_profile_id, slot_index) DO UPDATE SET is_enabled = EXCLUDED.is_enabled; `, slotID, hostProfile1ID, user1ID, star1ID, i, now, now) } fmt.Println() // 4. 插入资产(用户1的2个资产) fmt.Printf(`INSERT INTO assets (id, owner_uid, star_id, name, cover_url, material_url, description, rarity, tags, visibility, status, tx_hash, block_number, like_count, created_at, updated_at, minted_at, is_active) VALUES (%d, %d, %d, '测试藏品1-用户1', 'https://top-fans-test.oss-cn-shanghai.aliyuncs.com/asset/%d/%d/covers/%d.png', NULL, '用户1的第一个藏品', 1, '[]'::jsonb, 'public', 1, '0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b', 12345678, 5, %d, %d, %d, true), (%d, %d, %d, '测试藏品2-用户1', 'https://top-fans-test.oss-cn-shanghai.aliyuncs.com/asset/%d/%d/covers/%d.png', NULL, '用户1的第二个藏品', 2, '[]'::jsonb, 'public', 1, '0x2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c', 12345679, 8, %d, %d, %d, true) ON CONFLICT (id) DO NOTHING; `, asset1ID, user1ID, star1ID, user1ID, star1ID, asset1ID, now, now, now, asset2ID, user1ID, star1ID, user1ID, star1ID, asset2ID, now, now, now) fmt.Println() // 5. 插入展品展示(用户1的展位1和展位2放置了展品) slot1ID := int64(1001) slot2ID := int64(1002) fmt.Printf(`INSERT INTO exhibitions (asset_id, slot_id, host_profile_id, occupier_uid, occupier_star_id, start_time, expire_at, created_at, updated_at) VALUES (%d, %d, %d, %d, %d, %d, %d, %d, %d), (%d, %d, %d, %d, %d, %d, %d, %d, %d) ON CONFLICT (asset_id) DO UPDATE SET slot_id = EXCLUDED.slot_id, expire_at = EXCLUDED.expire_at; `, asset1ID, slot1ID, hostProfile1ID, user1ID, star1ID, now, expireAt, now, now, asset2ID, slot2ID, hostProfile1ID, user1ID, star1ID, now, expireAt, now, now) fmt.Println() // 用户2 fmt.Println("-- ========================================") fmt.Println("-- 用户2:创建用户、粉丝档案、展位、资产、展品") fmt.Println("-- ========================================") // 1. 插入用户 fmt.Printf(`INSERT INTO users (id, mobile, password_hash, is_active, created_at, updated_at) VALUES (%d, '%s', '%s', true, %d, %d) ON CONFLICT (mobile) DO UPDATE SET password_hash = EXCLUDED.password_hash; `, user2ID, user2Mobile, passwordHash, now, now) fmt.Println() // 2. 插入粉丝档案 fmt.Printf(`INSERT INTO fan_profiles (user_id, star_id, nickname, level, times, social, experience, coin_balance, crystal_balance, tags, starbook_limit, slot_limit, assets_count, is_active, created_at, updated_at) VALUES (%d, %d, '%s', 1, 1, 0, 0, 0, 1000, '[]'::jsonb, 3, 3, 2, true, %d, %d) ON CONFLICT (user_id, star_id) DO UPDATE SET nickname = EXCLUDED.nickname, crystal_balance = EXCLUDED.crystal_balance; `, user2ID, star2ID, user2Nickname, now, now) fmt.Println() // 3. 插入展位(3个,全部已解锁) for i := 1; i <= 3; i++ { slotID := int64(2000 + i) // slot_id: 2001, 2002, 2003 fmt.Printf(`INSERT INTO booth_slots (slot_id, host_profile_id, user_id, star_id, slot_index, visibility, is_enabled, unlock_type, unlock_value, created_at, updated_at) VALUES (%d, %d, %d, %d, %d, 'public', true, 'free', 0, %d, %d) ON CONFLICT (host_profile_id, slot_index) DO UPDATE SET is_enabled = EXCLUDED.is_enabled; `, slotID, hostProfile2ID, user2ID, star2ID, i, now, now) } fmt.Println() // 4. 插入资产(用户2的2个资产) fmt.Printf(`INSERT INTO assets (id, owner_uid, star_id, name, cover_url, material_url, description, rarity, tags, visibility, status, tx_hash, block_number, like_count, created_at, updated_at, minted_at, is_active) VALUES (%d, %d, %d, '测试藏品1-用户2', 'https://top-fans-test.oss-cn-shanghai.aliyuncs.com/asset/%d/%d/covers/%d.png', NULL, '用户2的第一个藏品', 1, '[]'::jsonb, 'public', 1, '0x3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d', 12345680, 12, %d, %d, %d, true), (%d, %d, %d, '测试藏品2-用户2', 'https://top-fans-test.oss-cn-shanghai.aliyuncs.com/asset/%d/%d/covers/%d.png', NULL, '用户2的第二个藏品', 2, '[]'::jsonb, 'public', 1, '0x4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e', 12345681, 15, %d, %d, %d, true) ON CONFLICT (id) DO NOTHING; `, asset3ID, user2ID, star2ID, user2ID, star2ID, asset3ID, now, now, now, asset4ID, user2ID, star2ID, user2ID, star2ID, asset4ID, now, now, now) fmt.Println() // 5. 插入展品展示(用户2的展位1和展位2放置了展品) slot3ID := int64(2001) slot4ID := int64(2002) fmt.Printf(`INSERT INTO exhibitions (asset_id, slot_id, host_profile_id, occupier_uid, occupier_star_id, start_time, expire_at, created_at, updated_at) VALUES (%d, %d, %d, %d, %d, %d, %d, %d, %d), (%d, %d, %d, %d, %d, %d, %d, %d, %d) ON CONFLICT (asset_id) DO UPDATE SET slot_id = EXCLUDED.slot_id, expire_at = EXCLUDED.expire_at; `, asset3ID, slot3ID, hostProfile2ID, user2ID, star2ID, now, expireAt, now, now, asset4ID, slot4ID, hostProfile2ID, user2ID, star2ID, now, expireAt, now, now) fmt.Println() fmt.Println("-- ========================================") fmt.Println("-- 测试账号信息") fmt.Println("-- ========================================") fmt.Printf("-- 用户1: mobile=%s, password=%s, user_id=%d, star_id=%d, gallery_owner_id=%d\n", user1Mobile, password, user1ID, star1ID, hostProfile1ID) fmt.Printf("-- 展位: slot_id=1001(有展品), 1002(有展品), 1003(空)\n") fmt.Printf("-- 资产: asset_id=%d, %d\n", asset1ID, asset2ID) fmt.Println() fmt.Printf("-- 用户2: mobile=%s, password=%s, user_id=%d, star_id=%d, gallery_owner_id=%d\n", user2Mobile, password, user2ID, star2ID, hostProfile2ID) fmt.Printf("-- 展位: slot_id=2001(有展品), 2002(有展品), 2003(空)\n") fmt.Printf("-- 资产: asset_id=%d, %d\n", asset3ID, asset4ID) fmt.Println() fmt.Println("-- 测试接口:") fmt.Printf("-- GET /api/v1/galleries/%d (查看用户1的展馆)\n", user1ID) fmt.Printf("-- GET /api/v1/galleries/%d (查看用户2的展馆)\n", user2ID) fmt.Println() }