10 changed files with 290 additions and 12 deletions
@ -0,0 +1,18 @@ |
|||||
|
using SqlSugar; |
||||
|
|
||||
|
namespace Build_God_Api.DB |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 角色装备槽位(武器/防具/饰品各一条记录,未穿时 EquipmentInstanceId 为空)
|
||||
|
/// </summary>
|
||||
|
public class CharacterEquippedSlot : BaseEntity |
||||
|
{ |
||||
|
public int CharacterId { get; set; } |
||||
|
|
||||
|
/// <summary>武器、防具、饰品</summary>
|
||||
|
public EquipmentType Slot { get; set; } |
||||
|
|
||||
|
[SugarColumn(IsNullable = true)] |
||||
|
public int? EquipmentInstanceId { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,25 @@ |
|||||
|
-- 装备实例与穿戴槽:CharacterBagId -> CharacterId(PostgreSQL) |
||||
|
-- 仅用于「已有库且表上仍存在 CharacterBagId 列」的升级;全新库由 SqlSugar CodeFirst 建表即可,不要执行本脚本。 |
||||
|
-- 若执行时报错列不存在,说明已迁过或为新库,请跳过。 |
||||
|
|
||||
|
-- EquipmentInstance |
||||
|
ALTER TABLE "EquipmentInstance" ADD COLUMN IF NOT EXISTS "CharacterId" integer; |
||||
|
|
||||
|
UPDATE "EquipmentInstance" ei |
||||
|
SET "CharacterId" = cb."CharacterId" |
||||
|
FROM "CharacterBag" cb |
||||
|
WHERE ei."CharacterBagId" IS NOT NULL |
||||
|
AND cb."Id" = ei."CharacterBagId"; |
||||
|
|
||||
|
ALTER TABLE "EquipmentInstance" DROP COLUMN IF EXISTS "CharacterBagId"; |
||||
|
|
||||
|
-- CharacterEquippedSlot |
||||
|
ALTER TABLE "CharacterEquippedSlot" ADD COLUMN IF NOT EXISTS "CharacterId" integer; |
||||
|
|
||||
|
UPDATE "CharacterEquippedSlot" s |
||||
|
SET "CharacterId" = cb."CharacterId" |
||||
|
FROM "CharacterBag" cb |
||||
|
WHERE s."CharacterBagId" IS NOT NULL |
||||
|
AND cb."Id" = s."CharacterBagId"; |
||||
|
|
||||
|
ALTER TABLE "CharacterEquippedSlot" DROP COLUMN IF EXISTS "CharacterBagId"; |
||||
@ -0,0 +1,51 @@ |
|||||
|
using Build_God_Api.DB; |
||||
|
using SqlSugar; |
||||
|
|
||||
|
namespace Build_God_Api.Services.Game |
||||
|
{ |
||||
|
/// <summary>装备槽位表读写(供属性计算与 BagService 共用,避免重复逻辑)</summary>
|
||||
|
public static class CharacterEquippedSlotQueries |
||||
|
{ |
||||
|
private static readonly EquipmentType[] AllSlots = |
||||
|
[EquipmentType.Weapon, EquipmentType.Armor, EquipmentType.Accessory]; |
||||
|
|
||||
|
public static async Task EnsureSlotsAsync(ISqlSugarClient db, int characterId) |
||||
|
{ |
||||
|
var existing = await db.Queryable<CharacterEquippedSlot>() |
||||
|
.Where(x => x.CharacterId == characterId) |
||||
|
.Select(x => x.Slot) |
||||
|
.ToListAsync(); |
||||
|
|
||||
|
var toInsert = new List<CharacterEquippedSlot>(); |
||||
|
foreach (var slot in AllSlots) |
||||
|
{ |
||||
|
if (existing.Contains(slot)) continue; |
||||
|
toInsert.Add(new CharacterEquippedSlot |
||||
|
{ |
||||
|
CharacterId = characterId, |
||||
|
Slot = slot, |
||||
|
EquipmentInstanceId = null |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
if (toInsert.Count > 0) |
||||
|
await db.Insertable(toInsert).ExecuteCommandAsync(); |
||||
|
} |
||||
|
|
||||
|
public static async Task<List<int>> GetEquippedEquipmentInstanceIdsAsync(ISqlSugarClient db, int characterId) |
||||
|
{ |
||||
|
var ids = await db.Queryable<CharacterEquippedSlot>() |
||||
|
.Where(x => x.CharacterId == characterId && x.EquipmentInstanceId != null) |
||||
|
.Select(x => x.EquipmentInstanceId!.Value) |
||||
|
.ToListAsync(); |
||||
|
|
||||
|
return ids; |
||||
|
} |
||||
|
|
||||
|
public static Task ClearSlotReferencesToInstanceAsync(ISqlSugarClient db, int characterId, int equipmentInstanceId) => |
||||
|
db.Updateable<CharacterEquippedSlot>() |
||||
|
.SetColumns(x => new CharacterEquippedSlot { EquipmentInstanceId = null, UpdatedOn = DateTime.UtcNow }) |
||||
|
.Where(x => x.CharacterId == characterId && x.EquipmentInstanceId == equipmentInstanceId) |
||||
|
.ExecuteCommandAsync(); |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue