Tz2/Assets/Framework/Manager/GlobalDataStorage.cs

673 lines
26 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 MotionFramework;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using UnityEngine;
namespace DefaultNamespace
{
/// <summary>
/// 任务书信息类,用于存储解析后的任务书字段数据
/// 完全动态,不预定义任何固定字段
/// </summary>
[System.Serializable]
public class TaskBookInfo
{
/// <summary>
/// 字段映射字典,存储所有解析出的字段名和对应值
/// </summary>
public Dictionary<string, string> FieldMap { get; set; } = new Dictionary<string, string>();
/// <summary>
/// 原始任务书字符串
/// </summary>
public string OriginalText { get; set; } = string.Empty;
/// <summary>
/// 根据字段名获取对应的值
/// </summary>
/// <param name="fieldName">字段名称</param>
/// <returns>对应的值,如果不存在则返回空字符串</returns>
public string GetValue(string fieldName)
{
return FieldMap.TryGetValue(fieldName, out string value) ? value : string.Empty;
}
/// <summary>
/// 检查是否包含指定字段
/// </summary>
/// <param name="fieldName">字段名称</param>
/// <returns>是否包含该字段</returns>
public bool HasField(string fieldName)
{
return FieldMap.ContainsKey(fieldName);
}
/// <summary>
/// 获取所有字段名
/// </summary>
/// <returns>字段名集合</returns>
public IEnumerable<string> GetAllFieldNames()
{
return FieldMap.Keys;
}
/// <summary>
/// 获取所有字段和值的键值对
/// </summary>
/// <returns>所有字段的键值对</returns>
public IEnumerable<KeyValuePair<string, string>> GetAllFields()
{
return FieldMap;
}
/// <summary>
/// 清空所有字段数据
/// </summary>
public void Clear()
{
FieldMap.Clear();
OriginalText = string.Empty;
}
}
/// <summary>
/// 用于存储全局的考试相关信息以及其他可能的全局数据。
/// </summary>
public class GlobalDataStorage : ModuleSingleton<GlobalDataStorage>, IModule
{
/// <summary>
/// Info文件前端传过来的
/// </summary>
public ExamInfo ExamInfo = new ExamInfo();
/// <summary>
/// Info文件前端传过来的
/// </summary>
public string ExamName { get; set; }
public ApiResponse<ExamData> ExamData;
/// <summary>
/// 任务书信息,存储解析后的任务书字段数据
/// </summary>
public TaskBookInfo TaskBook { get; set; } = new TaskBookInfo();
/// <summary>
/// 任务书信息,存储解析后的任务书字段数据
/// </summary>
public object materialTaskObj = null;
/// <summary>
/// 大类题目
/// </summary>
public string bigName;
public List<MaterialCheckInfo> materialCheckInfoList = new List<MaterialCheckInfo>();
/// <summary>
/// 获取任务书
/// </summary>
/// <returns></returns>
public string GetTaskBook()
{
return TaskBook.OriginalText;
}
/// <summary>
/// 根据字段名获取任务书中的值
/// </summary>
/// <param name="fieldName">字段名称</param>
/// <returns>对应的值,如果不存在则返回空字符串</returns>
public string GetTaskBookValue(string fieldName)
{
return TaskBook.GetValue(fieldName);
}
/// <summary>
/// 检查任务书是否包含指定字段
/// </summary>
/// <param name="fieldName">字段名称</param>
/// <returns>是否包含该字段</returns>
public bool HasTaskBookField(string fieldName)
{
return TaskBook.HasField(fieldName);
}
/// <summary>
/// 获取物料编码
/// </summary>
/// <returns>物料编码</returns>
public string GetMaterialCode()
{
return GetTaskBookValue("物料编码");
}
/// <summary>
/// 获取物料描述
/// </summary>
/// <returns>物料描述</returns>
public string GetMaterialDescription()
{
return GetTaskBookValue("物料描述");
}
/// <summary>
/// 获取工厂代码
/// </summary>
/// <returns>工厂代码</returns>
public string GetFactoryCode()
{
return GetTaskBookValue("工厂代码");
}
/// <summary>
/// 获取批次号
/// </summary>
/// <returns>批次号</returns>
public string GetBatchNumber()
{
return GetTaskBookValue("批次");
}
/// <summary>
/// 获取收入数量
/// </summary>
/// <returns>收入数量</returns>
public string GetIncomeQuantity()
{
return GetTaskBookValue("收入数量");
}
/// <summary>
/// 获取台数(从"已将X台"中提取的数字)
/// </summary>
/// <returns>台数</returns>
public string GetQuantity()
{
return GetTaskBookValue("台");
}
/// <summary>
/// 获取日期
/// </summary>
/// <returns>日期</returns>
public string GetDate()
{
return GetTaskBookValue("日期");
}
/// <summary>
/// 获取货物交接单号
/// </summary>
/// <returns>货物交接单号</returns>
public string GetHandoverDocument()
{
return GetTaskBookValue("货物交接单");
}
/// <summary>
/// 获取过账日期前
/// </summary>
/// <returns>过账日期前</returns>
public string GetPostingDateBefore()
{
return GetTaskBookValue("过账日期前");
}
/// <summary>
/// 获取过账日期后
/// </summary>
/// <returns>过账日期后</returns>
public string GetPostingDateAfter()
{
return GetTaskBookValue("过账日期后");
}
/// <summary>
/// 获取仓库号
/// </summary>
/// <returns>过账日期后</returns>
public string GetCangKuHao()
{
return GetTaskBookValue("仓库号");
}
/// <summary>
/// 获取仓位信息
/// </summary>
/// <returns>仓位信息如F01-010101</returns>
public string GetShelfPosition()
{
// 优先获取货架区信息
string shelfArea = GetTaskBookValue("货架区");
if (!string.IsNullOrEmpty(shelfArea))
{
return shelfArea;
}
// 其次获取仓位信息
string position = GetTaskBookValue("仓位");
if (!string.IsNullOrEmpty(position))
{
return position;
}
// 最后获取仓位号信息
string positionNumber = GetTaskBookValue("仓位号");
if (!string.IsNullOrEmpty(positionNumber))
{
return positionNumber;
}
return string.Empty;
}
/// <summary>
/// 智能字段映射字典,处理字段名的模糊匹配
/// </summary>
private readonly Dictionary<string, string> _fieldMapping = new Dictionary<string, string>
{
// 完全匹配
{"物料编码", "物料编码"},
{"物料描述", "物料描述"},
{"工厂代码", "工厂代码"},
{"批次", "批次"},
{"库存地点", "库存地点"},
{"库管员", "库管员"},
{"仓库主管", "仓库主管"},
{"物资公司签字", "物资公司签字"},
{"单位签收人", "单位签收人"},
{"供应商交付人", "供应商交付人"},
{"发货方", "发货方"},
{"收货方", "收货方"},
{"收入数量", "收入数量"},
{"结存数量", "结存数量"},
{"发出数量", "发出数量"},
{"期初库存数量", "期初库存数量"},
{"台", "台"},
{"套", "套"},
{"组", "组"},
{"米", "米"},
{"千米", "千米"},
{"只", "只"},
{"片", "片"},
{"付", "付"},
{"日期", "日期"},
{"货物交接单", "货物交接单"},
{"过账起始时间", "过账起始时间"},
{"过账结束时间", "过账结束时间"},
// {"货架区", "货架区"},
// {"仓位", "仓位"},
// {"仓位号", "仓位号"},
// 模糊匹配
{"批次号", "批次"},
{"物料编号", "物料编码"},
{"物资编码", "物料编码"},
{"物资描述", "物料描述"},
{"工厂编号", "工厂代码"},
{"库存位置", "库存地点"},
{"仓库管理员", "库管员"},
{"仓库负责人", "仓库主管"},
{"物资公司负责人", "物资公司签字"},
{"签收人", "单位签收人"},
{"交付人", "供应商交付人"},
{"发货人", "发货方"},
{"收货人", "收货方"},
{"入库数量", "收入数量"},
{"库存数量", "结存数量"},
{"出库数量", "发出数量"},
{"初始库存", "期初库存数量"},
{"已交付数量", "台"},
{"交付台数", "台"},
{"交接单号", "货物交接单"},
{"过账开始日期", "过账日期前"},
{"过账结束日期", "过账日期后"},
{"过账日期开始", "过账日期前"},
{"过账日期结束", "过账日期后"},
{"货架位置", "货架区"},
{"存储位置", "仓位"},
{"位置编号", "仓位号"},
{"上架仓位", "上架仓位"},
{"仓库号", "仓库号"},
};
/// <summary>
/// 根据字段名获取对应的任务书值,支持模糊匹配
/// </summary>
/// <param name="fieldName">字段名称</param>
/// <returns>对应的值,如果不存在则返回空字符串</returns>
public string GetTaskBookValueByMapping(string fieldName)
{
// Debug.Log($"尝试获取字段值: {fieldName}");
// 首先尝试直接匹配
if (_fieldMapping.ContainsKey(fieldName))
{
string mappedField = _fieldMapping[fieldName];
string value = GetTaskBookValue(mappedField);
Debug.Log($"字段映射成功: {fieldName} -> {mappedField} = {value}");
return value;
}
// 如果没有找到映射,尝试直接获取
string directValue = GetTaskBookValue(fieldName);
Debug.Log($"直接获取字段值: {fieldName} = {directValue}");
return directValue;
}
/// <summary>
/// 更新JSON字符串中的JudgmentQuestions字段值
/// </summary>
/// <param name="jsonString">原始JSON字符串</param>
/// <returns>更新后的JSON字符串</returns>
public string UpdateJsonWithTaskBookValues(string jsonString)
{
// 输入参数验证
if (string.IsNullOrEmpty(jsonString))
{
Debug.LogWarning("JSON字符串为空无法更新");
return jsonString;
}
try
{
Debug.Log("开始更新JSON中的JudgmentQuestions字段值...");
// 解析JSON
JArray jsonArray = JArray.Parse(jsonString);
// 验证JSON数组是否为空
if (jsonArray == null || jsonArray.Count == 0)
{
Debug.LogWarning("JSON数组为空或无效无法更新");
return jsonString;
}
int updatedCount = 0;
// 遍历所有步骤
foreach (JObject step in jsonArray)
{
// 验证步骤对象是否有效
if (step == null) continue;
// 检查步骤是否包含Actions数组
if (step["Actions"] != null && step["Actions"] is JArray actions)
{
// 验证Actions数组是否为空
if (actions.Count == 0) continue;
// 遍历所有动作
foreach (JObject action in actions)
{
// 验证动作对象是否有效
if (action == null) continue;
// 检查动作是否包含JudgmentQuestions且不为null
if (action["JudgmentQuestions"] != null && action["JudgmentQuestions"] is JArray judgmentQuestions)
{
// 验证判断题数组是否为空
if (judgmentQuestions.Count == 0) continue;
// 遍历所有判断题
foreach (JObject question in judgmentQuestions)
{
// 验证问题对象是否有效
if (question == null) continue;
// 安全地获取问题文本和正确答案
if (question["Question"] != null && question["CorrectAnswer"] != null)
{
string questionText = question["Question"].ToString();
string currentAnswer = question["CorrectAnswer"].ToString();
// 验证问题文本和答案是否为空
if (string.IsNullOrEmpty(questionText) || string.IsNullOrEmpty(currentAnswer))
{
Debug.LogWarning($"跳过无效的问题或答案: Question='{questionText}', Answer='{currentAnswer}'");
continue;
}
// 获取对应的任务书值
string taskBookValue = GetTaskBookValueByMapping(questionText);
if (!string.IsNullOrEmpty(taskBookValue))
{
// 更新CorrectAnswer
question["CorrectAnswer"] = taskBookValue;
updatedCount++;
Debug.Log($"更新字段: {questionText} = {taskBookValue} (原值: {currentAnswer})");
}
else
{
// Debug.Log($"未找到字段对应的任务书值: {questionText}");
}
}
}
}
}
}
}
string updatedJson = jsonArray.ToString(Formatting.None);
Debug.Log($"JSON更新完成共更新了 {updatedCount} 个字段");
return updatedJson;
}
catch (System.Exception ex)
{
Debug.LogError($"更新JSON时发生错误: {ex.Message}");
Debug.LogError($"错误堆栈: {ex.StackTrace}");
return jsonString; // 返回原始字符串
}
}
/// <summary>
/// 设置任务书信息
/// </summary>
/// <param name="taskBookText">任务书原始文本</param>
public void SetTaskBook(string taskBookText)
{
TaskBook.Clear();
TaskBook.OriginalText = taskBookText;
ParseTaskBook(taskBookText);
}
/// <summary>
/// 解析任务书文本,智能提取各种字段信息
/// </summary>
/// <param name="taskBookText">任务书文本</param>
private void ParseTaskBook(string taskBookText)
{
if (string.IsNullOrEmpty(taskBookText))
{
Debug.LogWarning("任务书文本为空,无法解析");
return;
}
Debug.Log("开始智能解析任务书文本...");
// 定义字段匹配模式
var fieldPatterns = new Dictionary<string, string>
{
// 物料相关信息
{"物料编码", @"物料编码[:]\s*([A-Za-z0-9]+)"},
{"物料描述", @"([^]+)|物料描述[:]\s*([^,。;:,.;:\n\r]+?)"},
// 工厂和批次信息
{"工厂代码", @"工厂代码[:]?\s*([A-Za-z0-9*]+)"},
{"批次", @"批次[:]?\s*([A-Za-z0-9]+)"},
// 库存地点
{"库存地点", @"库存地点[:]\s*[^]*([A-Za-z0-9]+)"},
// 人员信息
{"库管员", @"库管员[:]\s*([^,。;:,.;:]+)"},
{"仓库主管", @"仓库主管[:]\s*([^,。;:,.;:]+)"},
{"物资公司签字", @"物资公司签字[:]\s*([^,。;:,.;:]+)"},
{"单位签收人", @"单位签收人[:]\s*([^,。;:,.;:]+)"},
{"供应商交付人", @"供应商交付人[:]\s*([^,。;:,.;:]+)"},
{"发货方", @"发货方[:]\s*([^,。;:,.;:]+)"},
{"收货方", @"收货方[:]\s*([^,。;:,.;:]+)"},
// 数量信息
{"收入数量", @"收入数量[:]\s*(\d+)"},
{"结存数量", @"结存数量[:]\s*(\d+)"},
{"发出数量", @"发出数量[:]\s*(\d+)"},
{"期初库存数量", @"期初库存数量[:]\s*(\d+)"},
{"台", @"已将(\d+)台"},
{"套", @"已将(\d+)套"},
{"组", @"已将(\d+)组"},
{"米", @"已将(\d+)米"},
{"千米", @"已将(\d+)千米"},
{"只", @"已将(\d+)只"},
{"片", @"已将(\d+)片"},
{"付", @"已将(\d+)付"},
// 日期信息
{"日期", @"日期[为]?\s*(\d{4}\.\d{2}\.\d{2})"},
{"过账起始时间", @"过账日期前[:]\s*(\d{4}\.\d{2}月\.\d{2})"},
{"过账结束时间", @"过账日期后[:]\s*(\d{4}\.\d{2}月\.\d{2})"},
// 单据信息
{"货物交接单", @"货物交接单[:]\s*([A-Za-z0-9]+)"},
{"仓库号", @"仓库号[:]?\s*([A-Za-z0-9]+)"},
// //仓位号
// {"货架区", @"货架区[:]\s*([A-Za-z0-9\-]+)"},
// {"仓位", @"仓位[:]\s*([A-Za-z0-9\-]+)"},
// {"仓位号", @"仓位号[:]\s*([A-Za-z0-9\-]+)"},
// 复合格式解析 - 支持"货架区F01-010101仓位"等格式
// {"上架仓位", @"货架区([A-Za-z0-9\-]+)仓位"},
// 直接匹配仓位编号格式 F01-010101
{"上架仓位", @"([A-Z][0-9]{2}-[0-9]{6})"},
};
int parsedFieldsCount = 0;
// 遍历所有字段模式进行匹配
foreach (var pattern in fieldPatterns)
{
string fieldName = pattern.Key;
string regexPattern = pattern.Value;
try
{
System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(regexPattern);
System.Text.RegularExpressions.Match match = regex.Match(taskBookText);
if (match.Success && match.Groups.Count >= 2)
{
string value = string.Empty;
// 特殊处理物料描述字段,支持两种格式的合并正则
if (fieldName == "物料描述")
{
// 检查第一个捕获组(括号格式)
if (match.Groups[1].Success && !string.IsNullOrEmpty(match.Groups[1].Value.Trim()))
{
value = match.Groups[1].Value.Trim();
Debug.Log($"成功解析字段: [物料描述] = {value} (括号格式)");
// 如果括号格式解析成功,再次解析物料描述
int materialDescIndex = value.IndexOf("物料描述:");
if (materialDescIndex >= 0)
{
string materialDescValue = value.Substring(materialDescIndex + 4); // 跳过"物料描述:"
materialDescValue = CleanValue(materialDescValue);
if (!string.IsNullOrEmpty(materialDescValue))
{
value = materialDescValue;
Debug.Log($"成功解析字段: [物料描述] = {value} (从括号格式中再次解析)");
}
}
}
// 检查第二个捕获组(冒号格式)
else if (match.Groups[2].Success && !string.IsNullOrEmpty(match.Groups[2].Value.Trim()))
{
value = match.Groups[2].Value.Trim();
Debug.Log($"成功解析字段: [物料描述] = {value} (冒号格式)");
}
}
else
{
value = match.Groups[1].Value.Trim();
}
// 清理值中的多余字符
value = CleanValue(value);
if (!string.IsNullOrEmpty(value))
{
TaskBook.FieldMap[fieldName] = value;
if (fieldName != "物料描述") // 物料描述已经在上面打印过日志了
{
Debug.Log($"成功解析字段: [{fieldName}] = {value}");
}
parsedFieldsCount++;
}
}
else
{
Debug.Log($"未找到字段: {fieldName}");
}
}
catch (System.Exception ex)
{
Debug.LogError($"解析字段 {fieldName} 时发生错误: {ex.Message}");
}
}
Debug.Log($"任务书解析完成,共成功解析出 {parsedFieldsCount} 个字段");
Debug.Log($"解析出的字段列表: {string.Join(", ", TaskBook.FieldMap.Keys)}");
}
/// <summary>
/// 清理值中的多余字符
/// </summary>
/// <param name="value">原始值</param>
/// <returns>清理后的值</returns>
private string CleanValue(string value)
{
if (string.IsNullOrEmpty(value))
return value;
// 移除开头和结尾的标点符号和空格
value = value.Trim('', '。', '', '', ',', '.', ';', ':', ' ', '\t', '\n', '\r');
// 处理日期格式中的"月"字符,将其替换为"."
// 例如2024.12月.01 -> 2024.12.01
value = value.Replace("月", ".");
// 清理重复的点号
while (value.Contains(".."))
{
value = value.Replace("..", ".");
}
return value;
}
//
public void OnCreate(object createParam)
{
}
public void OnUpdate()
{
}
public void OnDestroy()
{
}
public void OnGUI()
{
}
}
}