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