From f97275cb54531408feb0dd66c58e56f5ac39b398 Mon Sep 17 00:00:00 2001 From: xinian Date: Mon, 27 Apr 2026 00:51:28 +0800 Subject: [PATCH] 1 --- help/base_sys_user_role去重.sql | 17 +- help/约束类.sql | 237 +++++++++++++++++++-- modules/config/model/cdk.go | 2 +- modules/config/model/fight_rule.go | 2 +- modules/config/model/peak_tianxuan.go | 4 +- modules/config/model/peak_tianxuan_vote.go | 4 +- modules/config/model/server_show.go | 4 +- modules/config/model/shop.go | 2 +- modules/config/model/sign.go | 6 +- modules/config/model/spt.go | 2 +- modules/config/model/tower_110.go | 2 +- modules/player/model/info.go | 2 +- 12 files changed, 250 insertions(+), 34 deletions(-) diff --git a/help/base_sys_user_role去重.sql b/help/base_sys_user_role去重.sql index 74cd0ac7..ad54066d 100644 --- a/help/base_sys_user_role去重.sql +++ b/help/base_sys_user_role去重.sql @@ -1,5 +1,6 @@ -- base_sys_user_role 角色授权去重 --- 保留每组 userId + roleId 中 id 最小的一条,删除其余重复记录 +-- 只处理未软删除的有效授权;软删除历史记录不参与去重和唯一约束 +-- 保留每组有效 userId + roleId 中 id 最小的一条,删除其余重复记录 -- 1. 执行前查看重复数据 SELECT @@ -9,6 +10,7 @@ SELECT MIN(id) AS keep_id, ARRAY_AGG(id ORDER BY id) AS ids FROM base_sys_user_role +WHERE deleted_at IS NULL GROUP BY "userId", "roleId" HAVING COUNT(*) > 1 ORDER BY cnt DESC, "userId", "roleId"; @@ -18,6 +20,8 @@ DELETE FROM base_sys_user_role a USING base_sys_user_role b WHERE a."userId" = b."userId" AND a."roleId" = b."roleId" + AND a.deleted_at IS NULL + AND b.deleted_at IS NULL AND a.id > b.id; -- 3. 执行后复查,应返回 0 行 @@ -26,5 +30,16 @@ SELECT "roleId", COUNT(*) AS cnt FROM base_sys_user_role +WHERE deleted_at IS NULL GROUP BY "userId", "roleId" HAVING COUNT(*) > 1; + +-- 4. 建议约束:只限制未软删除授权唯一,允许历史软删除授权保留 +ALTER TABLE base_sys_user_role +DROP CONSTRAINT IF EXISTS uk_base_sys_user_role_user_role; + +DROP INDEX IF EXISTS uk_base_sys_user_role_user_role; + +CREATE UNIQUE INDEX IF NOT EXISTS uk_base_sys_user_role_user_role +ON base_sys_user_role ("userId", "roleId") +WHERE deleted_at IS NULL; diff --git a/help/约束类.sql b/help/约束类.sql index d947de69..7bc3562b 100644 --- a/help/约束类.sql +++ b/help/约束类.sql @@ -1,53 +1,254 @@ +-- 唯一约束修复 +-- 规则:所有带 deleted_at 的业务唯一约束,只约束未软删除记录。 + -- 玩家+物品+VIP状态 联合唯一 ALTER TABLE player_item -ADD CONSTRAINT uk_player_item_player_item_vip -UNIQUE (player_id, item_id, is_vip); +DROP CONSTRAINT IF EXISTS uk_player_item_player_item_vip; +DROP INDEX IF EXISTS uk_player_item_player_item_vip; + +CREATE UNIQUE INDEX IF NOT EXISTS uk_player_item_player_item_vip +ON player_item (player_id, item_id, is_vip) +WHERE deleted_at IS NULL; -- 玩家+挖矿 联合唯一 -CREATE UNIQUE INDEX uk_talk_player ON player_talk (talk_id, player_id); +ALTER TABLE player_talk +DROP CONSTRAINT IF EXISTS uk_talk_player; +DROP INDEX IF EXISTS uk_talk_player; + +CREATE UNIQUE INDEX IF NOT EXISTS uk_talk_player +ON player_talk (talk_id, player_id) +WHERE deleted_at IS NULL; -- 玩家+任务 联合唯一 -CREATE UNIQUE INDEX uk_player_task ON player_task (player_id, task_id); +ALTER TABLE player_task +DROP CONSTRAINT IF EXISTS uk_player_task; +DROP INDEX IF EXISTS uk_player_task; + +CREATE UNIQUE INDEX IF NOT EXISTS uk_player_task +ON player_task (player_id, task_id) +WHERE deleted_at IS NULL; + + -- 玩家+称号 联合唯一 -CREATE UNIQUE INDEX uk_player_title ON player_title (player_id, is_vip) WHERE deleted_at IS NULL; +ALTER TABLE player_title +DROP CONSTRAINT IF EXISTS uk_player_title; +DROP INDEX IF EXISTS uk_player_title; + +CREATE UNIQUE INDEX IF NOT EXISTS uk_player_title +ON player_title (player_id, is_vip) +WHERE deleted_at IS NULL; + -- 玩家+精灵 联合唯一 -CREATE UNIQUE INDEX uk_player_pet ON player_pet (player_id, is_vip, catch_time) WHERE deleted_at IS NULL; +ALTER TABLE player_pet +DROP CONSTRAINT IF EXISTS uk_player_pet; +DROP INDEX IF EXISTS uk_player_pet; + +CREATE UNIQUE INDEX IF NOT EXISTS uk_player_pet +ON player_pet (player_id, is_vip, catch_time) +WHERE deleted_at IS NULL; + -- 玩家+CDK 联合唯一 -CREATE UNIQUE INDEX uk_player_cdk_log +ALTER TABLE player_cdk_log +DROP CONSTRAINT IF EXISTS uk_player_cdk_log; +DROP INDEX IF EXISTS uk_player_cdk_log; + +CREATE UNIQUE INDEX IF NOT EXISTS uk_player_cdk_log ON player_cdk_log (player_id, code_id, is_vip) WHERE deleted_at IS NULL; - + -- 玩家孵蛋 联合唯一 - CREATE UNIQUE INDEX uk_player_egg -ON player_egg (player_id, is_vip) +ALTER TABLE player_egg +DROP CONSTRAINT IF EXISTS uk_player_egg; +DROP INDEX IF EXISTS uk_player_egg; + +CREATE UNIQUE INDEX IF NOT EXISTS uk_player_egg +ON player_egg (player_id, is_vip) WHERE deleted_at IS NULL; ----PVP索引 -CREATE UNIQUE INDEX uk_player_pvp + +-- PVP索引 +ALTER TABLE player_pvp +DROP CONSTRAINT IF EXISTS uk_player_pvp; +DROP INDEX IF EXISTS uk_player_pvp; + +CREATE UNIQUE INDEX IF NOT EXISTS uk_player_pvp ON player_pvp (player_id, season) WHERE deleted_at IS NULL; ---签到 -CREATE UNIQUE INDEX uk_player_sign_in_log + +-- 签到 +ALTER TABLE player_sign_in_log +DROP CONSTRAINT IF EXISTS uk_player_sign_in_log; +DROP INDEX IF EXISTS uk_player_sign_in_log; + +CREATE UNIQUE INDEX IF NOT EXISTS uk_player_sign_in_log ON player_sign_in_log (player_id, sign_in_id, is_vip) WHERE deleted_at IS NULL; ---房间索引 -CREATE UNIQUE INDEX uk_player_room_house + + +-- 房间索引 +ALTER TABLE player_room_house +DROP CONSTRAINT IF EXISTS uk_player_room_house; +DROP INDEX IF EXISTS uk_player_room_house; + +CREATE UNIQUE INDEX IF NOT EXISTS uk_player_room_house ON player_room_house (player_id, is_vip) WHERE deleted_at IS NULL; + -- 集市权限角色 联合唯一 --- 先清理历史重复授权,保留每组 userId + roleId 中 id 最小的一条 +-- 先清理有效重复授权,保留每组 userId + roleId 中 id 最小的一条。 DELETE FROM base_sys_user_role a USING base_sys_user_role b WHERE a."userId" = b."userId" AND a."roleId" = b."roleId" + AND a.deleted_at IS NULL + AND b.deleted_at IS NULL AND a.id > b.id; +ALTER TABLE base_sys_user_role +DROP CONSTRAINT IF EXISTS uk_base_sys_user_role_user_role; +DROP INDEX IF EXISTS uk_base_sys_user_role_user_role; + CREATE UNIQUE INDEX IF NOT EXISTS uk_base_sys_user_role_user_role -ON base_sys_user_role ("userId", "roleId"); +ON base_sys_user_role ("userId", "roleId") +WHERE deleted_at IS NULL; + + +-- CDK配置 编号唯一 +ALTER TABLE config_gift_cdk +DROP CONSTRAINT IF EXISTS idx_config_gift_cdk_cdk_code; +DROP INDEX IF EXISTS idx_config_gift_cdk_cdk_code; + +CREATE UNIQUE INDEX IF NOT EXISTS idx_config_gift_cdk_cdk_code +ON config_gift_cdk (cdk_code) +WHERE deleted_at IS NULL; + + +-- 战斗规则 规则索引唯一 +ALTER TABLE config_fight_rule +DROP CONSTRAINT IF EXISTS idx_rule_idx; +DROP INDEX IF EXISTS idx_rule_idx; + +CREATE UNIQUE INDEX IF NOT EXISTS idx_rule_idx +ON config_fight_rule (rule_idx) +WHERE deleted_at IS NULL; + + +-- 天选配置 玩家+精灵唯一 +ALTER TABLE config_peak_tianxuan +DROP CONSTRAINT IF EXISTS idx_peak_tianxuan_player_pet; +DROP INDEX IF EXISTS idx_peak_tianxuan_player_pet; + +CREATE UNIQUE INDEX IF NOT EXISTS idx_peak_tianxuan_player_pet +ON config_peak_tianxuan (player_id, pet_id) +WHERE deleted_at IS NULL; + + +-- 天选投票 周期+玩家唯一 +ALTER TABLE config_peak_tianxuan_vote +DROP CONSTRAINT IF EXISTS idx_peak_tianxuan_vote_week_player; +DROP INDEX IF EXISTS idx_peak_tianxuan_vote_week_player; + +CREATE UNIQUE INDEX IF NOT EXISTS idx_peak_tianxuan_vote_week_player +ON config_peak_tianxuan_vote (week_index, player_id) +WHERE deleted_at IS NULL; + + +-- 服务器冠名 同服同属主唯一 +ALTER TABLE server_show +DROP CONSTRAINT IF EXISTS idx_server_show_server_owner; +DROP INDEX IF EXISTS idx_server_show_server_owner; + +CREATE UNIQUE INDEX IF NOT EXISTS idx_server_show_server_owner +ON server_show (server_id, owner) +WHERE deleted_at IS NULL; + + +-- 商店 商品ID唯一 +ALTER TABLE config_shop +DROP CONSTRAINT IF EXISTS idx_config_shop_product_id; +DROP INDEX IF EXISTS idx_config_shop_product_id; + +CREATE UNIQUE INDEX IF NOT EXISTS idx_config_shop_product_id +ON config_shop (product_id) +WHERE deleted_at IS NULL; + + +-- 签到配置 签到类别+阶段唯一 +ALTER TABLE config_sign_in +DROP CONSTRAINT IF EXISTS idx_sign_type_stage; +DROP INDEX IF EXISTS idx_sign_type_stage; + +CREATE UNIQUE INDEX IF NOT EXISTS idx_sign_type_stage +ON config_sign_in (sign_type, stage_days) +WHERE deleted_at IS NULL; + + +-- 签到配置 CDK唯一 +ALTER TABLE config_sign_in +DROP CONSTRAINT IF EXISTS idx_config_sign_in_cdk_id; +DROP INDEX IF EXISTS idx_config_sign_in_cdk_id; + +CREATE UNIQUE INDEX IF NOT EXISTS idx_config_sign_in_cdk_id +ON config_sign_in (cdk_id) +WHERE deleted_at IS NULL; + + +-- SPT配置 任务ID唯一 +ALTER TABLE config_spt +DROP CONSTRAINT IF EXISTS idx_config_spt_task_id; +DROP INDEX IF EXISTS idx_config_spt_task_id; + +CREATE UNIQUE INDEX IF NOT EXISTS idx_config_spt_task_id +ON config_spt (task_id) +WHERE deleted_at IS NULL; + + +-- 爬塔配置 层级唯一 +ALTER TABLE config_tower_1 +DROP CONSTRAINT IF EXISTS idx_config_tower_1_tower_level; +DROP INDEX IF EXISTS idx_config_tower_1_tower_level; + +CREATE UNIQUE INDEX IF NOT EXISTS idx_config_tower_1_tower_level +ON config_tower_1 (tower_level) +WHERE deleted_at IS NULL; + +ALTER TABLE config_tower_110 +DROP CONSTRAINT IF EXISTS idx_config_tower_110_tower_level; +DROP INDEX IF EXISTS idx_config_tower_110_tower_level; + +CREATE UNIQUE INDEX IF NOT EXISTS idx_config_tower_110_tower_level +ON config_tower_110 (tower_level) +WHERE deleted_at IS NULL; + +ALTER TABLE config_tower_500 +DROP CONSTRAINT IF EXISTS idx_config_tower_500_tower_level; +DROP INDEX IF EXISTS idx_config_tower_500_tower_level; + +CREATE UNIQUE INDEX IF NOT EXISTS idx_config_tower_500_tower_level +ON config_tower_500 (tower_level) +WHERE deleted_at IS NULL; + +ALTER TABLE config_tower_600 +DROP CONSTRAINT IF EXISTS idx_config_tower_600_tower_level; +DROP INDEX IF EXISTS idx_config_tower_600_tower_level; + +CREATE UNIQUE INDEX IF NOT EXISTS idx_config_tower_600_tower_level +ON config_tower_600 (tower_level) +WHERE deleted_at IS NULL; + + +-- 玩家信息 角色ID唯一 +ALTER TABLE player_info +DROP CONSTRAINT IF EXISTS idx_player_info_player_id; +DROP INDEX IF EXISTS idx_player_info_player_id; + +CREATE UNIQUE INDEX IF NOT EXISTS idx_player_info_player_id +ON player_info (player_id) +WHERE deleted_at IS NULL; diff --git a/modules/config/model/cdk.go b/modules/config/model/cdk.go index e9112ab1..f04c820d 100644 --- a/modules/config/model/cdk.go +++ b/modules/config/model/cdk.go @@ -15,7 +15,7 @@ type CDKConfig struct { *cool.Model // 核心字段 - CDKCode string `gorm:"not null;size:16;uniqueIndex;comment:'CDK编号(唯一标识,用于玩家兑换)'" json:"cdk_code" description:"CDK编号"` + CDKCode string `gorm:"not null;size:16;uniqueIndex:idx_config_gift_cdk_cdk_code,where:deleted_at IS NULL;comment:'CDK编号(唯一标识,用于玩家兑换)'" json:"cdk_code" description:"CDK编号"` Type uint32 `gorm:"column:type;not null;default:0;comment:'CDK类型:0普通奖励,1服务器冠名'" json:"type" description:"CDK类型"` //cdk可兑换次数,where不等于0 diff --git a/modules/config/model/fight_rule.go b/modules/config/model/fight_rule.go index 4f73ded4..abc43ed1 100644 --- a/modules/config/model/fight_rule.go +++ b/modules/config/model/fight_rule.go @@ -12,7 +12,7 @@ const TableNameFightRule = "config_fight_rule" type FightRule struct { *cool.Model // 嵌入基础Model(包含主键、创建/更新时间等通用字段) - RuleIdx uint32 `gorm:"not null;uniqueIndex:idx_rule_idx;comment:'规则索引(300-316)'" json:"rule_idx"` + RuleIdx uint32 `gorm:"not null;uniqueIndex:idx_rule_idx,where:deleted_at IS NULL;comment:'规则索引(300-316)'" json:"rule_idx"` Args []int `gorm:"type:jsonb;comment:'规则参数(JSON数组,对应RuleBase.args)'" json:"args"` Desc string `gorm:"type:varchar(255);default:'';comment:'规则描述'" json:"desc"` } diff --git a/modules/config/model/peak_tianxuan.go b/modules/config/model/peak_tianxuan.go index b3f02799..984baae5 100644 --- a/modules/config/model/peak_tianxuan.go +++ b/modules/config/model/peak_tianxuan.go @@ -11,9 +11,9 @@ const ( type PeakTianxuan struct { *BaseConfig - PlayerID uint32 `gorm:"not null;index:idx_peak_tianxuan_player;uniqueIndex:idx_peak_tianxuan_player_pet;comment:'所属玩家ID'" json:"player_id"` + PlayerID uint32 `gorm:"not null;index:idx_peak_tianxuan_player;uniqueIndex:idx_peak_tianxuan_player_pet,where:deleted_at IS NULL;comment:'所属玩家ID'" json:"player_id"` DisplayOrder uint32 `gorm:"not null;default:0;comment:'展示顺序'" json:"display_order"` - PetID uint32 `gorm:"not null;uniqueIndex:idx_peak_tianxuan_player_pet;comment:'天选精灵ID'" json:"pet_id"` + PetID uint32 `gorm:"not null;uniqueIndex:idx_peak_tianxuan_player_pet,where:deleted_at IS NULL;comment:'天选精灵ID'" json:"pet_id"` PresetName string `gorm:"type:varchar(64);not null;default:'';comment:'预设显示名'" json:"preset_name"` Level uint32 `gorm:"not null;default:100;comment:'预设等级'" json:"level"` Nature uint32 `gorm:"not null;default:0;comment:'预设性格'" json:"nature"` diff --git a/modules/config/model/peak_tianxuan_vote.go b/modules/config/model/peak_tianxuan_vote.go index c7e600a5..0c9aaaaa 100644 --- a/modules/config/model/peak_tianxuan_vote.go +++ b/modules/config/model/peak_tianxuan_vote.go @@ -11,8 +11,8 @@ const ( type PeakTianxuanVote struct { *cool.Model - WeekIndex uint32 `gorm:"not null;uniqueIndex:idx_peak_tianxuan_vote_week_player;index:idx_peak_tianxuan_vote_week_pet;comment:'周序号'" json:"week_index"` - PlayerID uint32 `gorm:"not null;uniqueIndex:idx_peak_tianxuan_vote_week_player;comment:'投票玩家ID'" json:"player_id"` + WeekIndex uint32 `gorm:"not null;uniqueIndex:idx_peak_tianxuan_vote_week_player,where:deleted_at IS NULL;index:idx_peak_tianxuan_vote_week_pet;comment:'周序号'" json:"week_index"` + PlayerID uint32 `gorm:"not null;uniqueIndex:idx_peak_tianxuan_vote_week_player,where:deleted_at IS NULL;comment:'投票玩家ID'" json:"player_id"` PetID uint32 `gorm:"not null;index:idx_peak_tianxuan_vote_week_pet;comment:'投票精灵ID'" json:"pet_id"` } diff --git a/modules/config/model/server_show.go b/modules/config/model/server_show.go index ddc20536..f5a014a3 100644 --- a/modules/config/model/server_show.go +++ b/modules/config/model/server_show.go @@ -10,9 +10,9 @@ const TableNameServerShow = "server_show" // ServerShow 绑定服务器展示信息(冠名、属主、到期时间)。 type ServerShow struct { *cool.Model - ServerID uint32 `gorm:"column:server_id;comment:'服务器ID';index:idx_server_show_server_id;uniqueIndex:idx_server_show_server_owner" json:"server_id"` + ServerID uint32 `gorm:"column:server_id;comment:'服务器ID';index:idx_server_show_server_id;uniqueIndex:idx_server_show_server_owner,where:deleted_at IS NULL" json:"server_id"` Name string `gorm:"comment:'服务器展示名'" json:"name"` - Owner uint32 `gorm:"comment:'服务器属主';uniqueIndex:idx_server_show_server_owner" json:"owner"` + Owner uint32 `gorm:"comment:'服务器属主';uniqueIndex:idx_server_show_server_owner,where:deleted_at IS NULL" json:"owner"` ExpireTime time.Time `gorm:"column:expire_time;default:0;comment:'展示到期时间'" json:"expire_time"` } diff --git a/modules/config/model/shop.go b/modules/config/model/shop.go index a4d8b815..1d74ca5a 100644 --- a/modules/config/model/shop.go +++ b/modules/config/model/shop.go @@ -17,7 +17,7 @@ type ShopConfig struct { ProductType uint32 `gorm:"not null;default:0;comment:'商品类型'" json:"product_type" description:"商品类型"` //商品ID - ProductID int64 `gorm:"not null;uniqueIndex;comment:'商品ID'" json:"product_id" description:"商品ID"` + ProductID int64 `gorm:"not null;uniqueIndex:idx_config_shop_product_id,where:deleted_at IS NULL;comment:'商品ID'" json:"product_id" description:"商品ID"` // 价格信息 -1代表不允许购买,0表示不支持购买 SeerdouPrice int32 `gorm:"not null;default:0;comment:'骄阳豆价格'" json:"seerdou_price" description:"骄阳豆价格"` diff --git a/modules/config/model/sign.go b/modules/config/model/sign.go index f708da02..d98e3238 100644 --- a/modules/config/model/sign.go +++ b/modules/config/model/sign.go @@ -12,9 +12,9 @@ const ( // SignIn 签到阶段配置表。 type SignIn struct { *BaseConfig - SignType uint32 `gorm:"not null;default:1;uniqueIndex:idx_sign_type_stage;comment:'签到类别(1-累计 2-连续)'" json:"sign_type"` - StageDays uint32 `gorm:"not null;default:1;uniqueIndex:idx_sign_type_stage;comment:'签到阶段天数(0/1/3/7/14/30)'" json:"stage_days"` - CdkID uint32 `gorm:"not null;uniqueIndex;comment:'绑定的CDK配置ID'" json:"cdk_id"` + SignType uint32 `gorm:"not null;default:1;uniqueIndex:idx_sign_type_stage,where:deleted_at IS NULL;comment:'签到类别(1-累计 2-连续)'" json:"sign_type"` + StageDays uint32 `gorm:"not null;default:1;uniqueIndex:idx_sign_type_stage,where:deleted_at IS NULL;comment:'签到阶段天数(0/1/3/7/14/30)'" json:"stage_days"` + CdkID uint32 `gorm:"not null;uniqueIndex:idx_config_sign_in_cdk_id,where:deleted_at IS NULL;comment:'绑定的CDK配置ID'" json:"cdk_id"` } func (*SignIn) TableName() string { diff --git a/modules/config/model/spt.go b/modules/config/model/spt.go index c3a97e9d..4e5d0f6f 100644 --- a/modules/config/model/spt.go +++ b/modules/config/model/spt.go @@ -10,7 +10,7 @@ const ( type SptConfig struct { *BaseConfig - TaskID uint32 `gorm:"not null;uniqueIndex;comment:'SPT任务ID'" json:"task_id" description:"SPT任务ID"` + TaskID uint32 `gorm:"not null;uniqueIndex:idx_config_spt_task_id,where:deleted_at IS NULL;comment:'SPT任务ID'" json:"task_id" description:"SPT任务ID"` Title string `gorm:"type:varchar(64);not null;default:'';comment:'SPT名字'" json:"title" description:"SPT名字"` PetID uint32 `gorm:"not null;default:0;comment:'SPT精灵ID'" json:"pet_id" description:"SPT精灵ID"` Online int32 `gorm:"not null;default:1;comment:'是否开放(1开放/0未开放)'" json:"online" description:"是否开放"` diff --git a/modules/config/model/tower_110.go b/modules/config/model/tower_110.go index 5c4fe1c0..fbb1a8cc 100644 --- a/modules/config/model/tower_110.go +++ b/modules/config/model/tower_110.go @@ -14,7 +14,7 @@ const ( type BaseTowerConfig struct { *BaseConfig Name string `gorm:"type:varchar(100);default:'';comment:'name'" json:"name" description:"name"` - TowerLevel uint32 `gorm:"not null;default:0;uniqueIndex;comment:'tower level'" json:"tower_level"` + TowerLevel uint32 `gorm:"not null;default:0;uniqueIndex:,where:deleted_at IS NULL;comment:'tower level'" json:"tower_level"` BossIds []uint32 `gorm:"type:jsonb;comment:'boss ids'" json:"boss_ids"` } diff --git a/modules/player/model/info.go b/modules/player/model/info.go index cb5fe8e7..906e4310 100644 --- a/modules/player/model/info.go +++ b/modules/player/model/info.go @@ -13,7 +13,7 @@ const TableNamePlayerInfo = "player_info" type Player struct { *cool.Model - PlayerID uint64 `gorm:"not null;uniqueIndex;index:idx_pet_by_player_id;comment:'所属玩家ID'" json:"player_id"` + PlayerID uint64 `gorm:"not null;uniqueIndex:idx_player_info_player_id,where:deleted_at IS NULL;index:idx_pet_by_player_id;comment:'所属玩家ID'" json:"player_id"` LastResetTime *gtime.Time `struc:"skip" json:"last_reset_time"` // 重置时间,比如电池和每日任务 WeekLastResetTime *gtime.Time `struc:"skip" json:"week_last_reset_time"` Data PlayerInfo `gorm:"type:jsonb;not null;comment:'全部数据'" json:"data"`