Design_SubModule/Scripts/Editor/Design_Tools/MigrateIconFormatTool.cs
2026-04-14 17:30:13 +08:00

171 lines
6.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;
using OfficeOpenXml;
using ArtResource;
namespace DesignTools
{
/// <summary>
/// 一次性工具:将 Emoji.xlsx / Face.xlsx / Avatar.xlsx 的 Icon 字段从 ArtItemData.Id 迁移为 ArtItemData.Name
/// 使用完毕后可删除此文件
/// </summary>
public static class MigrateIconFormatTool
{
private static readonly string[] SO_SEARCH_PATHS = new[]
{
"Assets/Art_SubModule/Art_SO",
"Assets/Art_SubModule/Art_SO/Collections"
};
private struct MigrationTarget
{
public string ExcelName;
public string SheetName;
public string SOTableName;
}
private static readonly MigrationTarget[] Targets = new[]
{
new MigrationTarget { ExcelName = "Emoji.xlsx", SheetName = "Emoji", SOTableName = "EmojiResource" },
new MigrationTarget { ExcelName = "Face.xlsx", SheetName = "Face", SOTableName = "HeadResource" },
new MigrationTarget { ExcelName = "Avatar.xlsx", SheetName = "Avatar", SOTableName = "HeadFrameResource" },
};
[MenuItem("策划工具/一次性迁移/Icon格式 ID→Name (Emoji+Face+Avatar)")]
public static void Execute()
{
// 1. 选择 Docs/config 目录
string configDir = EditorUtility.OpenFolderPanel("选择 Docs/config 目录(包含 Emoji.xlsx、Face.xlsx、Avatar.xlsx", "", "");
if (string.IsNullOrEmpty(configDir)) return;
// 2. 加载所有 ArtTableSO
var allArtTables = new List<ArtTableSO>();
foreach (string searchPath in SO_SEARCH_PATHS)
{
string[] guids = AssetDatabase.FindAssets("t:ArtTableSO", new[] { searchPath });
foreach (string guid in guids)
{
string path = AssetDatabase.GUIDToAssetPath(guid);
var so = AssetDatabase.LoadAssetAtPath<ArtTableSO>(path);
if (so != null && !allArtTables.Any(x => x.TableName == so.TableName))
allArtTables.Add(so);
}
}
if (allArtTables.Count == 0)
{
EditorUtility.DisplayDialog("错误", "未找到任何 ArtTableSO 资源", "确定");
return;
}
int totalMigrated = 0;
int totalSkipped = 0;
int totalErrors = 0;
var allMessages = new List<string>();
foreach (var target in Targets)
{
string excelPath = Path.Combine(configDir, target.ExcelName);
if (!File.Exists(excelPath))
{
allMessages.Add($"[{target.ExcelName}] 文件不存在,跳过");
continue;
}
var tableSO = allArtTables.FirstOrDefault(x => x.TableName == target.SOTableName);
if (tableSO == null)
{
allMessages.Add($"[{target.ExcelName}] 未找到 ArtTableSO: {target.SOTableName},跳过");
totalErrors++;
continue;
}
// 备份
string backupPath = excelPath + ".bak";
File.Copy(excelPath, backupPath, true);
int migrated = 0, skipped = 0, errors = 0;
using (var package = new ExcelPackage(new FileInfo(excelPath)))
{
var ws = package.Workbook.Worksheets[target.SheetName];
if (ws == null)
{
allMessages.Add($"[{target.ExcelName}] 未找到 Sheet: {target.SheetName},跳过");
totalErrors++;
continue;
}
// 找 Icon 列和 Id 列
int iconCol = -1, idCol = -1;
int colCount = ws.Dimension?.Columns ?? 0;
for (int c = 1; c <= colCount; c++)
{
string h = ws.Cells[1, c].Text;
if (h == "Icon") iconCol = c;
else if (h == "Id") idCol = c;
}
if (iconCol < 0)
{
allMessages.Add($"[{target.ExcelName}] 未找到 Icon 列,跳过");
totalErrors++;
continue;
}
int rowCount = ws.Dimension?.Rows ?? 0;
for (int row = 3; row <= rowCount; row++)
{
string iconText = ws.Cells[row, iconCol].Text.Trim();
if (string.IsNullOrEmpty(iconText))
{
continue;
}
// 判断是否是旧格式(纯数字)
if (!int.TryParse(iconText, out int artItemId))
{
// 已经是Name格式
skipped++;
continue;
}
string rowId = idCol > 0 ? ws.Cells[row, idCol].Text : row.ToString();
var artItem = tableSO.Items.FirstOrDefault(x => x.Id == artItemId);
if (artItem == null)
{
errors++;
allMessages.Add($"[{target.ExcelName}] Row {row} Id={rowId}: {target.SOTableName} 中无 ArtItemId={artItemId}");
continue;
}
ws.Cells[row, iconCol].Value = artItem.Name;
migrated++;
}
package.Save();
}
totalMigrated += migrated;
totalSkipped += skipped;
totalErrors += errors;
allMessages.Add($"[{target.ExcelName}] 成功: {migrated}, 跳过: {skipped}, 错误: {errors} (备份: {backupPath})");
}
// 报告
string msg = $"Icon 迁移完成!\n\n" +
$"总计成功: {totalMigrated} 条\n" +
$"已是新格式(跳过): {totalSkipped} 条\n" +
$"错误: {totalErrors} 条\n\n" +
string.Join("\n", allMessages);
EditorUtility.DisplayDialog("迁移结果", msg, "确定");
Debug.Log(msg);
}
}
}