Design_SubModule/Scripts/Editor/Design_Tools/LimitedTimeEvent/CatTrickConstEditor.cs
2026-03-27 15:12:55 +08:00

257 lines
9.1 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;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using OfficeOpenXml;
using UnityEditor;
using UnityEngine;
using Debug = UnityEngine.Debug;
namespace DesignTools.LimitedTimeEvent
{
/// <summary>
/// 小猫戏法限时事件常量配置工具
/// 读取 Docs/config/LimitedTimeEvent.xlsx 的 Const Sheet仅编辑指定 Key 的 Value。
/// </summary>
public class CatTrickConstEditor : BaseDesignToolEditor
{
private const string LIMITED_TIME_EVENT_EXCEL_NAME = "LimitedTimeEvent.xlsx";
private const string CONST_SHEET_NAME = "Const";
private const int HEADER_ROW = 1;
private const int DATA_START_ROW = 3;
private const string KEY_CONSUME_ENERGY = "CatTrick_ConsumeEnergy";
private const string KEY_REWARD_DIAMOND = "CatTrick_RewardDiamond";
private const string LABEL_CONSUME_ENERGY = "小猫戏法每次获得钻石需要消耗的体力";
private const string LABEL_REWARD_DIAMOND = "每次领取的钻石数量";
private readonly List<CatTrickConstItem> constItems = new List<CatTrickConstItem>();
private int keyColumnIndex = -1;
private int valueColumnIndex = -1;
[MenuItem("策划工具/限时事件/小猫戏法")]
public static void ShowWindow()
{
CatTrickConstEditor window = GetWindow<CatTrickConstEditor>("小猫戏法");
window.minSize = window.GetMinWindowSize();
window.Show();
}
protected override string GetDocsPathPrefKey()
{
return "CatTrickConstEditor_DocsPath";
}
protected override string GetWindowTitle()
{
return "小猫戏法配置工具";
}
protected override Vector2 GetMinWindowSize()
{
return new Vector2(760, 420);
}
protected override void LoadConfigData()
{
LoadConstSheet();
}
protected override void DrawDataEditor()
{
EditorGUILayout.BeginVertical("box");
EditorGUILayout.HelpBox("仅会写回 LimitedTimeEvent.xlsx 的 Const Sheet并且只修改 CatTrick_ConsumeEnergy 与 CatTrick_RewardDiamond 两个 Key 的 Value。", MessageType.Info);
EditorGUILayout.EndVertical();
EditorGUILayout.Space(6);
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
foreach (CatTrickConstItem item in constItems)
{
DrawConstItem(item);
EditorGUILayout.Space(4);
}
EditorGUILayout.EndScrollView();
}
protected override void SaveDataToExcel()
{
SaveConstSheet();
}
private void LoadConstSheet()
{
constItems.Clear();
keyColumnIndex = -1;
valueColumnIndex = -1;
string excelPath = GetDocsConfigFilePath(LIMITED_TIME_EVENT_EXCEL_NAME);
if (!File.Exists(excelPath))
{
throw new FileNotFoundException($"未找到 {LIMITED_TIME_EVENT_EXCEL_NAME}", excelPath);
}
using (ExcelPackage package = new ExcelPackage(new FileInfo(excelPath)))
{
ExcelWorksheet worksheet = package.Workbook.Worksheets[CONST_SHEET_NAME];
if (worksheet == null)
{
throw new Exception($"{LIMITED_TIME_EVENT_EXCEL_NAME} 中未找到 Sheet: {CONST_SHEET_NAME}");
}
if (worksheet.Dimension == null)
{
throw new Exception($"{LIMITED_TIME_EVENT_EXCEL_NAME}/{CONST_SHEET_NAME} 没有可读取的数据");
}
keyColumnIndex = FindColumnIndex(worksheet, "Key");
valueColumnIndex = FindColumnIndex(worksheet, "Value");
if (keyColumnIndex < 0 || valueColumnIndex < 0)
{
throw new Exception($"{LIMITED_TIME_EVENT_EXCEL_NAME}/{CONST_SHEET_NAME} 表结构不正确,缺少 Key 或 Value 列");
}
int rowCount = worksheet.Dimension.End.Row;
for (int row = DATA_START_ROW; row <= rowCount; row++)
{
string key = worksheet.Cells[row, keyColumnIndex].Text.Trim();
if (string.IsNullOrEmpty(key))
{
continue;
}
if (key != KEY_CONSUME_ENERGY && key != KEY_REWARD_DIAMOND)
{
continue;
}
string valueText = worksheet.Cells[row, valueColumnIndex].Text.Trim();
if (!int.TryParse(valueText, out int value))
{
throw new Exception($"{CONST_SHEET_NAME} Sheet 第 {row} 行 Key={key} 的 Value 不是有效整数:{valueText}");
}
constItems.Add(new CatTrickConstItem
{
Key = key,
Value = value,
RowIndex = row
});
}
}
string[] missingKeys = new[] { KEY_CONSUME_ENERGY, KEY_REWARD_DIAMOND }
.Where(targetKey => constItems.All(item => item.Key != targetKey))
.ToArray();
if (missingKeys.Length > 0)
{
throw new Exception($"{CONST_SHEET_NAME} Sheet 缺少以下 Key{string.Join("", missingKeys)}");
}
constItems.Sort((left, right) => string.CompareOrdinal(left.Key, right.Key));
Debug.Log($"小猫戏法配置读取完成,共加载 {constItems.Count} 条数据");
}
private void DrawConstItem(CatTrickConstItem item)
{
EditorGUILayout.BeginVertical("box");
EditorGUILayout.LabelField(GetDisplayName(item.Key), EditorStyles.boldLabel);
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Value", GUILayout.Width(60));
item.Value = EditorGUILayout.IntField(item.Value, GUILayout.Width(180));
GUILayout.FlexibleSpace();
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
GUILayout.Space(4);
EditorGUILayout.LabelField($"Excel 行号:{item.RowIndex}", EditorStyles.miniLabel);
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndVertical();
}
private void SaveConstSheet()
{
if (constItems.Count == 0)
{
EditorUtility.DisplayDialog("提示", "当前没有可保存的数据,请先加载配置。", "确定");
return;
}
string excelPath = GetDocsConfigFilePath(LIMITED_TIME_EVENT_EXCEL_NAME);
if (!File.Exists(excelPath))
{
EditorUtility.DisplayDialog("错误", $"未找到文件:{excelPath}", "确定");
return;
}
try
{
using (ExcelPackage package = new ExcelPackage(new FileInfo(excelPath)))
{
ExcelWorksheet worksheet = package.Workbook.Worksheets[CONST_SHEET_NAME];
if (worksheet == null)
{
EditorUtility.DisplayDialog("错误", $"未找到 Sheet: {CONST_SHEET_NAME}", "确定");
return;
}
foreach (CatTrickConstItem item in constItems)
{
worksheet.Cells[item.RowIndex, valueColumnIndex].Value = item.Value;
}
package.Save();
}
EditorUtility.DisplayDialog("成功", "小猫戏法配置已保存到 Excel", "确定");
Debug.Log("小猫戏法配置保存成功");
}
catch (Exception e)
{
EditorUtility.DisplayDialog("错误", $"保存失败: {e.Message}", "确定");
Debug.LogError($"保存小猫戏法配置失败: {e}");
}
}
private int FindColumnIndex(ExcelWorksheet worksheet, string columnName)
{
int columnCount = worksheet.Dimension?.End.Column ?? 0;
for (int col = 1; col <= columnCount; col++)
{
if (string.Equals(worksheet.Cells[HEADER_ROW, col].Text.Trim(), columnName, StringComparison.OrdinalIgnoreCase))
{
return col;
}
}
return -1;
}
private string GetDisplayName(string key)
{
switch (key)
{
case KEY_CONSUME_ENERGY:
return LABEL_CONSUME_ENERGY;
case KEY_REWARD_DIAMOND:
return LABEL_REWARD_DIAMOND;
default:
return key;
}
}
[Serializable]
private class CatTrickConstItem
{
public string Key;
public int Value;
public int RowIndex;
}
}
}