using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Threading.Tasks; using Cysharp.Threading.Tasks; using DefaultNamespace; using DefaultNamespace.ProcessMode; using Framework.Manager; using Framework.Scripts.Runtime.Engine.Engine.Camera; using Framework.Scripts.Runtime.Engine.Scene; using Framework.Tools; using UnityEngine; // 引入Motion框架相关命名空间 using MotionFramework; using MotionFramework.Console; using MotionFramework.Event; using MotionFramework.Scripts.Runtime.Engine.Engine.Network.WebRequest; using MotionFramework.Utility; using Newtonsoft.Json; using SGUnitySDK; using SGUnitySDK.Etys; using SGUnitySDK.Services.SGStartParams; using UnityEditor; using Zion.ERP.Inventory; using Time = OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime.Time; namespace Framework.Dto { public class InventoryReversalVoucherAnalyzer { public string formselection; } } // 定义三个状态枚举 enum MaterialOperationType { 入库, 出库, 未知 } /// /// 游戏启动器类,负责初始化和管理游戏的核心模块 /// public class GameLauncher : MonoBehaviour { /// /// 在编辑器下是否模拟运行,默认为true /// [Tooltip("在编辑器下模拟运行")] public bool SimulationOnEditor = true; /// /// 是否使用离线模式 /// [Tooltip("是否使用离线模式")] public bool UseOfflineMode = false; /// /// 描述框 /// public GameObject topic; ProcessMode processMode; public string examName; string quantity = string.Empty; public static GameLauncher Instance; public string localtarge; public SGUConfig SguConfig; public SGAppStartMode SGAppStartMode; public string json; public OfflineConfig OfflineConfig; public string show; /// /// Unity生命周期方法,在游戏对象初始化时调用 /// void Awake() { Instance = this; // 初始化开发者控制台 DeveloperConsole.Initialize(); // 初始化Motion框架,并设置日志处理回调 MotionEngine.Initialize(this, HandleMotionFrameworkLog); } /// /// Unity生命周期方法,在游戏开始时调用 /// void Start() { // 创建并初始化游戏所需的核心模块 CreateGameModules(); } /// /// Unity生命周期方法,每帧更新时调用 /// void Update() { // 更新Motion框架状态 MotionEngine.Update(); } /// /// Unity生命周期方法,用于绘制GUI界面 /// void OnGUI() { // 注释掉的代码:根据是否在编辑器或调试版本中绘制控制台 DeveloperConsole.Draw(); } public string renwushu; /// /// 创建并初始化游戏所需的核心模块 /// private void CreateGameModules() { //创建API MotionEngine.CreateModule(); // 创建事件管理器 MotionEngine.CreateModule(); // 创建全局数据存储 MotionEngine.CreateModule(); // 创建流程管理器 MotionEngine.CreateModule(); // 创建场景管理器 MotionEngine.CreateModule(); // 创建网络请求管理器 MotionEngine.CreateModule(); MotionEngine.GetModule().Initialize(); SguConfig = new SGUConfig(); // SGUSdk.GetInstance().InitSDK(SguConfig); // SGAppStartMode = SGUSdk.GetInstance().GetAppStartMode(); // // // if (SGAppStartMode.examId > 0) //考试 // { // } // else if (SGAppStartMode.examId > 0) //练习 // { // } UnityEngine.SceneManagement.SceneManager.LoadScene("GameMain"); // if (UseOfflineMode) // { // InitializeOfflineMode(); // } // else // { // InitializeOnlineMode(); // } } /// /// 初始化离线模式 /// public void InitializeOfflineMode() { try { // 简化的离线配置,只需要题目名称和模式 string examNames = ""; // 默认题目名称 string mode = ""; // 默认教学模式,"3"为考核模式 string time = ""; // 默认考试时间60分钟 // MotionEngine.GetModule().bigName = "物资配送履约跟踪表维护"; // 尝试从配置文件读取,如果失败则使用默认值 try { for (int i = 0; i < 8; i++) { MaterialCheckInfo info = new MaterialCheckInfo(); info.Question = "物料" + (i + 1).ToString() + "物资品类是否一致"; info.CorrectAnswer = "一致"; info.MaterialNumber = "8"; MotionEngine.GetModule().materialCheckInfoList.Add(info); } // 只读取需要的字段 if (!string.IsNullOrEmpty(OfflineConfig.ExamName)) examNames = OfflineConfig.ExamName; if (!string.IsNullOrEmpty(OfflineConfig.Mode)) mode = OfflineConfig.Mode; if (!string.IsNullOrEmpty(OfflineConfig.Time)) time = OfflineConfig.Time; } catch (Exception configEx) { Debug.LogWarning($"读取离线配置文件失败,使用默认值: {configEx.Message}"); } object obj = JsonConvert.DeserializeObject("{\"formselection\":\"库存物资报表1\"}"); Debug.Log($"已反序列化为InventoryReversalVoucherAnalyzer: {JsonConvert.SerializeObject(obj)}"); Framework.Dto.InventoryReversalVoucherAnalyzer inventoryReversalVoucherAnalyzer1 = obj as Framework.Dto.InventoryReversalVoucherAnalyzer; Debug.Log($"系统入库冲销凭证分析月份: {inventoryReversalVoucherAnalyzer1.formselection}"); MotionEngine.GetModule().materialTaskObj = obj; // 设置考试信息(使用默认值) MotionEngine.GetModule().ExamInfo = new ExamInfo { PaperId = "offline_paper_001", AppID = "offline_app_001", ExamRoomId = "offline_room_001", StudentId = "offline_student_001", GroupId = "offline_group_001", BatchId = "offline_batch_001", Token = "offline_token_001", EncodedStr = "offline_encoded_001", CourseId = "offline_course_001", IpAddress = "127.0.0.1", Time = time }; // 设置流程模式 processMode = mode == "3" ? ProcessMode.考核模式 : ProcessMode.教学模式; Debug.Log($"离线模式初始化 - 题目名称: {examNames}, 模式: {processMode}, 时间: {time}分钟"); MotionEngine.GetModule().ExamName = examNames; examName = examNames; // 检查流程配置文件是否存在 string processConfigPath = Application.streamingAssetsPath + "/DataConfig/" + examNames + ".json"; Debug.Log(processConfigPath); if (!System.IO.File.Exists(processConfigPath)) { Debug.LogError($"流程配置文件不存在: {processConfigPath}"); return; } MotionEngine.GetModule().SetTaskBook(show); NewJsonRoot newJsonRoot = JsonConvert.DeserializeObject(json); MotionEngine.GetModule().ExamName = examNames; MotionEngine.GetModule().SetTaskBook(renwushu); Debug.Log(JsonConvert.SerializeObject(newJsonRoot.detailsList[0].stepList)); // 初始化流程 MotionEngine.GetModule().InitializeFirstStep( JsonConvert.SerializeObject(newJsonRoot.detailsList[0].stepList), processMode, topic); // 设置步骤 FileComponent.SetProcessSteps(JsonConvert.DeserializeObject>(JsonConvert.SerializeObject(newJsonRoot.detailsList[0].stepList))); // 加载场景并初始化引导 LoadSceneAndContinueAsync("仓库Main").Forget(); } catch (Exception ex) { Debug.LogError($"离线模式初始化失败: {ex.Message}"); } } /// /// 初始化在线模式 /// public void InitializeOnlineMode() { Debug.Log(Application.streamingAssetsPath + "/info.ini"); // 定义包含考试信息的URL参数字符串 string input = System.IO.File.ReadAllText(Application.streamingAssetsPath + "/info.ini"); // string input = "tz20001://227,111,118,12488,3,1371478298231570432,eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6ImQ4OTM3NDY0LWVjMWItNDQ5NC1hYmFlLTBlZmMxYjRjYWMwMiJ9.ccF3kM0BMoigrc6xj8eudQpfq7uy4TsDKVlryjyliHfZN3anmdCEnGRsRgK0z0yDKlpAtI6KzOKHsZSXjv_tPg,test1214,null,172.16.1.117:8083,60"; // 将输入字符串按逗号分割成数组 string[] parts = input.Split(','); // 从分割后的数组中提取并处理各个参数 string paperId = parts[0].Split("://")[1]; // 提取试卷ID string appID = parts[0].Split("://")[0]; string examRoomId = parts[1]; // 提取考场ID string studentId = parts[2]; // 提取学生ID string groupId = parts[3]; // 提取分组ID string mode = parts[4]; // 提取模式参数 string batchId = parts[5]; // 提取批次ID string token = parts[6]; // 提取认证token string encodedStr = parts[7]; // 提取编码字符串 string courseId = "1"; //科目ID string ipAddress = parts[9]; // 提取IP地址 string time = parts[10].Replace("'|", ""); // 提取时间戳并清理特殊字符 Debug.LogError(mode); if (mode == "3") { processMode = ProcessMode.考核模式; } else if (mode == "4") { processMode = ProcessMode.课程预览; } else if (mode == "5") { processMode = ProcessMode.考试预览; } else { processMode = ProcessMode.教学模式; } // // 根据模式参数设置ProcessMode // processMode = mode == "3" ? ProcessMode.考核模式 : ProcessMode.教学模式; // processMode = mode == "4" ? ProcessMode.课程预览 : processMode; // processMode = mode == "5" ? ProcessMode.考试预览 : processMode; Debug.Log($"流程模式: {processMode}"); // 输出解析后的数据用于调试 Debug.Log($"试卷 ID: {paperId}"); Debug.Log($"AppID : {appID}"); Debug.Log($"考场 ID: {examRoomId}"); Debug.Log($"学生 ID: {studentId}"); Debug.Log($"分组 ID: {groupId}"); Debug.Log($"模式: {mode}"); Debug.Log($"批次 ID: {batchId}"); Debug.Log($"Token: {token}"); Debug.Log($"编码的字符串: {encodedStr}"); Debug.Log($"CourseId ID: {courseId}"); Debug.Log($"IP 地址: {ipAddress}"); Debug.Log($"时间: {time}"); // 将解析的数据存储到全局数据存储中 MotionEngine.GetModule().ExamInfo = new ExamInfo { PaperId = paperId, AppID = appID, ExamRoomId = examRoomId, StudentId = studentId, GroupId = groupId, BatchId = batchId, Token = token, EncodedStr = encodedStr, CourseId = courseId, IpAddress = ipAddress, Time = time }; //GetTaskDataAsync(); // 将GetTaskDataAsync改为返回UniTask GetTaskDataAsync().ContinueWith(() => { // 使用UniTask加载场景 LoadSceneAndContinueAsync("仓库Main").Forget(); }).Forget(); } /// /// 使用UniTask异步加载场景并等待加载完成后继续执行 /// private async UniTask LoadSceneAndContinueAsync(string sceneName) { // 加载场景 UnityEngine.SceneManagement.SceneManager.LoadScene(sceneName); // 等待场景完全加载 await UniTask.WaitUntil(() => UnityEngine.SceneManagement.SceneManager.GetSceneByName(sceneName).isLoaded); // 场景加载完成后,检查是否需要初始化教程 if (processMode == ProcessMode.教学模式 || processMode == ProcessMode.课程预览) { topic.SetActive(true); TutorialGuideManager.Instance.InitializeGuideObjects(examName); TutorialGuideManager.Instance.StartGuide(); } } /// /// 异步获取任务数据并初始化流程,返回UniTask以便等待完成 /// private async UniTask GetTaskDataAsync() { // string url = string.Empty; // // if (processMode == ProcessMode.教学模式) // { // url = ApiUrls.TransitInventory.GetLearningTest; // } // else if (processMode == ProcessMode.课程预览) // { // url = ApiUrls.TransitInventory.GetLearningTestIsView; // } // else // { // url = ApiUrls.TransitInventory.GetProSimulationExaminationQueryById; // } // // //processMode = ProcessMode.教学模式; // Debug.Log(url); // // 发送网络请求获取任务数据,使用全局存储中的token进行认证 // string jsonText = await MotionEngine.GetModule().GetTextAsync( // url: url, // token: MotionEngine.GetModule().ExamInfo.Token); // // 输出原始JSON数据用于调试 // Debug.Log(jsonText); // 将JSON数据反序列化为API响应对象 var response = JsonConvert.DeserializeObject>(json); Debug.Log(JsonConvert.SerializeObject(response)); Debug.Log("试卷名称:" + response.Data.small); // 输出任务书和流程信息用于调试 Debug.Log("任务书--->" + JsonConvert.SerializeObject(response.Data.shows)); if (processMode == ProcessMode.教学模式 || processMode == ProcessMode.课程预览) { examName = response.Data.small; } else { examName = response.Data.small; //examName = response.Data.examName; } MotionEngine.GetModule().ExamName = examName; MotionEngine.GetModule().ExamData = response; // 解析并保存任务书信息到GlobalDataStorage if (!string.IsNullOrEmpty(response.Data.shows)) { Debug.Log("开始解析任务书信息..."); Debug.Log("任务书:+" + response.Data.shows); MotionEngine.GetModule().SetTaskBook(response.Data.shows); Debug.Log("任务书信息解析并保存完成"); } else { Debug.LogWarning("任务书信息为空,跳过解析"); } // ========== 新增:根据 big 字段的中文描述动态解析 task 字段 ========== object obj = null; // 用于存储反序列化后的对象 string bigType = response.Data.big; string taskJson = response.Data.task != null ? response.Data.task.ToString() : null; Debug.Log($"big类型(中文): {bigType}"); Debug.Log($"原始task内容: {taskJson}"); if (!string.IsNullOrEmpty(bigType) && !string.IsNullOrEmpty(taskJson)) { //存储大类 MotionEngine.GetModule().bigName = bigType; switch (bigType) { case "采购物资入库": // PurchaseMaterialInbound obj = JsonConvert.DeserializeObject(taskJson); Debug.Log($"已反序列化为PurchaseMaterialInbound: {JsonConvert.SerializeObject(obj)}"); Framework.Dto.PurchaseMaterialInbound purchaseMaterialInbound = obj as Framework.Dto.PurchaseMaterialInbound; Debug.Log($"采购物资入库数量: {purchaseMaterialInbound.quantity}"); Debug.Log($"采购物资入库名称: {purchaseMaterialInbound.materialName}"); Debug.Log($"采购物资入库编码: {purchaseMaterialInbound.code}"); Debug.Log($"采购物资入库描述: {purchaseMaterialInbound.description}"); Debug.Log($"采购物资入库位置: {purchaseMaterialInbound.location}"); quantity = purchaseMaterialInbound.quantity.ToString(); localtarge = purchaseMaterialInbound.storageBin; break; case "调拨物资入库": // TransferMaterialInbound obj = JsonConvert.DeserializeObject(taskJson); Debug.Log($"已反序列化为TransferMaterialInbound: {JsonConvert.SerializeObject(obj)}"); Framework.Dto.TransferMaterialInbound transferMaterialInbound = obj as Framework.Dto.TransferMaterialInbound; Debug.Log($"调拨物资入库数量: {transferMaterialInbound.quantity}"); Debug.Log($"调拨物资入库名称: {transferMaterialInbound.materialName}"); quantity = transferMaterialInbound.quantity.ToString(); localtarge = transferMaterialInbound.storageBin; break; case "退料物资入库": // ReturnMaterialInbound obj = JsonConvert.DeserializeObject(taskJson); Debug.Log($"已反序列化为ReturnMaterialInbound: {JsonConvert.SerializeObject(obj)}"); Framework.Dto.ReturnMaterialInbound returnMaterialInbound = obj as Framework.Dto.ReturnMaterialInbound; Debug.Log($"退料物资入库数量: {returnMaterialInbound.quantity}"); Debug.Log($"退料物资入库名称: {returnMaterialInbound.materialName}"); quantity = returnMaterialInbound.quantity.ToString(); localtarge = returnMaterialInbound.storageBin; break; case "代保管物资入库": // CustodyMaterialInbound obj = JsonConvert.DeserializeObject(taskJson); Debug.Log($"已反序列化为CustodyMaterialInbound: {JsonConvert.SerializeObject(obj)}"); Framework.Dto.CustodyMaterialInbound custodyMaterialInbound = obj as Framework.Dto.CustodyMaterialInbound; Debug.Log($"代保管物资入库数量: {custodyMaterialInbound.quantity}"); Debug.Log($"代保管物资入库名称: {custodyMaterialInbound.materialName}"); quantity = custodyMaterialInbound.quantity.ToString(); localtarge = custodyMaterialInbound.storageBin; break; case "代保管物资出库": // CustodyMaterialOutbound obj = JsonConvert.DeserializeObject(taskJson); Debug.Log($"已反序列化为CustodyMaterialOutbound: {JsonConvert.SerializeObject(obj)}"); Framework.Dto.CustodyMaterialOutbound custodyMaterialOutbound = obj as Framework.Dto.CustodyMaterialOutbound; Debug.Log($"代保管物资出库数量: {custodyMaterialOutbound.quantity}"); Debug.Log($"代保管物资出库名称: {custodyMaterialOutbound.materialName}"); quantity = custodyMaterialOutbound.quantity.ToString(); break; case "调拨物资出库": // TransferMaterialOutbound obj = JsonConvert.DeserializeObject(taskJson); Debug.Log($"已反序列化为TransferMaterialOutbound: {JsonConvert.SerializeObject(obj)}"); Framework.Dto.TransferMaterialOutbound transferMaterialOutbound = obj as Framework.Dto.TransferMaterialOutbound; Debug.Log($"调拨物资出库数量: {transferMaterialOutbound.quantity}"); Debug.Log($"调拨物资出库名称: {transferMaterialOutbound.materialName}"); quantity = transferMaterialOutbound.quantity.ToString(); break; case "废旧物资入库": // ScrapMaterialInbound obj = JsonConvert.DeserializeObject(taskJson); Debug.Log($"已反序列化为ScrapMaterialInbound: {JsonConvert.SerializeObject(obj)}"); Framework.Dto.ScrapMaterialInbound scrapMaterialInbound = obj as Framework.Dto.ScrapMaterialInbound; Debug.Log($"废旧物资入库数量: {scrapMaterialInbound.quantity}"); Debug.Log($"废旧物资入库名称: {scrapMaterialInbound.materialName}"); quantity = scrapMaterialInbound.quantity.ToString(); localtarge = scrapMaterialInbound.storageBin; break; case "借用物资出库": // BorrowMaterialOutbound obj = JsonConvert.DeserializeObject(taskJson); Debug.Log($"已反序列化为BorrowMaterialOutbound: {JsonConvert.SerializeObject(obj)}"); Framework.Dto.BorrowMaterialOutbound borrowMaterialOutbound = obj as Framework.Dto.BorrowMaterialOutbound; Debug.Log($"借用物资出库数量: {borrowMaterialOutbound.quantity}"); Debug.Log($"借用物资出库名称: {borrowMaterialOutbound.materialName}"); quantity = borrowMaterialOutbound.quantity.ToString(); break; case "借用物资入库": // BorrowMaterialInbound obj = JsonConvert.DeserializeObject(taskJson); Debug.Log($"已反序列化为BorrowMaterialInbound: {JsonConvert.SerializeObject(obj)}"); Framework.Dto.BorrowMaterialInbound borrowMaterialInbound = obj as Framework.Dto.BorrowMaterialInbound; Debug.Log($"借用物资入库数量: {borrowMaterialInbound.quantity}"); Debug.Log($"借用物资入库名称: {borrowMaterialInbound.materialName}"); quantity = borrowMaterialInbound.quantity.ToString(); break; case "项目领用出库": // ProjectUseMaterialOutbound obj = JsonConvert.DeserializeObject(taskJson); Debug.Log($"已反序列化为ProjectUseMaterialOutbound: {JsonConvert.SerializeObject(obj)}"); Framework.Dto.ProjectUseMaterialOutbound projectUseMaterialOutbound = obj as Framework.Dto.ProjectUseMaterialOutbound; Debug.Log($"项目领用出库数量: {projectUseMaterialOutbound.quantity}"); Debug.Log($"项目领用出库名称: {projectUseMaterialOutbound.materialName}"); quantity = projectUseMaterialOutbound.quantity.ToString(); break; case "库存物资报废": // InventoryMaterialScrap obj = JsonConvert.DeserializeObject(taskJson); Debug.Log($"已反序列化为InventoryMaterialScrap: {JsonConvert.SerializeObject(obj)}"); Framework.Dto.InventoryMaterialScrap inventoryMaterialScrap = obj as Framework.Dto.InventoryMaterialScrap; Debug.Log($"库存物资报废数量: {inventoryMaterialScrap.quantity}"); Debug.Log($"库存物资报废名称: {inventoryMaterialScrap.materialName}"); quantity = inventoryMaterialScrap.quantity.ToString(); break; case "凭证分析": // InventoryReversalVoucherAnalyzer obj = JsonConvert.DeserializeObject(taskJson); Debug.Log($"已反序列化为InventoryReversalVoucherAnalyzer: {JsonConvert.SerializeObject(obj)}"); Framework.Dto.InventoryReversalVoucherAnalyzer inventoryReversalVoucherAnalyzer = obj as Framework.Dto.InventoryReversalVoucherAnalyzer; Debug.Log($"系统入库冲销凭证分析月份: {inventoryReversalVoucherAnalyzer.formselection}"); break; case "库存分析": // InventoryReversalVoucherAnalyzer obj = JsonConvert.DeserializeObject(taskJson); Debug.Log($"已反序列化为InventoryReversalVoucherAnalyzer: {JsonConvert.SerializeObject(obj)}"); Framework.Dto.InventoryReversalVoucherAnalyzer inventoryReversalVoucherAnalyzer1 = obj as Framework.Dto.InventoryReversalVoucherAnalyzer; Debug.Log($"系统入库冲销凭证分析月份: {inventoryReversalVoucherAnalyzer1.formselection}"); break; case "履约跟踪": obj = JsonConvert.DeserializeObject(taskJson); Debug.Log($"已反序列化为InventoryReversalVoucherAnalyzer: {JsonConvert.SerializeObject(obj)}"); inventoryReversalVoucherAnalyzer = obj as Framework.Dto.InventoryReversalVoucherAnalyzer; Debug.Log($"履约跟踪: {inventoryReversalVoucherAnalyzer.formselection}"); break; default: obj = JsonConvert.DeserializeObject(taskJson); Debug.Log($"已反序列化为InventoryReversalVoucherAnalyzer: {JsonConvert.SerializeObject(obj)}"); Framework.Dto.InventoryReversalVoucherAnalyzer inventoryReversalVoucherAnalyzer2 = obj as Framework.Dto.InventoryReversalVoucherAnalyzer; Debug.Log($"系统入库冲销凭证分析月份: {inventoryReversalVoucherAnalyzer2.formselection}"); break; } MotionEngine.GetModule().materialTaskObj = obj; } else { Debug.LogWarning($"big或task字段为空,无法进行反序列化"); } // ========== 新增结束 ========== string jsonString = null; if (response.Data.updateStep != null) { Debug.Log("有修改过的流程--->" + JsonConvert.SerializeObject(response.Data.updateStep)); jsonString = response.Data.updateStep; } else { Debug.Log("没有修改过的流程--->" + JsonConvert.SerializeObject(response.Data.oldStep)); jsonString = response.Data.oldStep; } // if (processMode == ProcessMode.课程预览 || processMode == ProcessMode.考试预览) // { // jsonString = System.IO.File.ReadAllText(Application.streamingAssetsPath + "/DataConfig/" + examName + ".json"); // } string updatedJsonString = string.Empty; // if (processMode == ProcessMode.考核模式 || processMode == ProcessMode.考试预览) // { // Debug.Log(jsonString); // // // 更新JSON中的JudgmentQuestions字段值 // Debug.Log("开始更新JSON配置中的字段值..."); // updatedJsonString = MotionEngine.GetModule().UpdateJsonWithTaskBookValues(jsonString); // } // else // { // updatedJsonString = jsonString; // } updatedJsonString = MotionEngine.GetModule().UpdateJsonWithTaskBookValues(jsonString); // // Debug.Log($"JSON更新完成,原始: {jsonString}"); // string s = $"D:\\{DateTime.Now:yyyy-MM-dd HH:mm:ss}.txt"; // File.CreateText(s); // File.WriteAllText(s,jsonString); Debug.Log($"JSON更新完成,更新后的: {updatedJsonString}"); //加载数量的,判断外观物体 // List materialCheckInfoList =MaterialCheckHelper.GetMaterialAppearanceCheckDetails(System.IO.File.ReadAllText("D:\\BaiduNetdiskDownload\\TaizhouWarehousePhaseII (2)\\Assets\\StreamingAssets\\DataConfig/1KV电缆终端到货验收入库.json")); List materialCheckInfoList = MaterialCheckHelper.GetMaterialAppearanceCheckDetails(updatedJsonString); // 新增:检查并更新物资数量相关的正确答案 updatedJsonString = UpdateMaterialQuantityAnswers(updatedJsonString); MotionEngine.GetModule().materialCheckInfoList = materialCheckInfoList; Debug.Log(JsonConvert.SerializeObject(materialCheckInfoList)); Debug.Log("使用更新后的JSON配置加载物资检查信息"); // 初始化流程管理器,设置流程模式 MotionEngine.GetModule().InitializeFirstStep( updatedJsonString, processMode, topic); //设置步骤 FileComponent.SetProcessSteps(JsonConvert.DeserializeObject>( updatedJsonString)); } /// /// 处理Motion框架的日志输出 /// /// 日志级别 /// 日志内容 private void HandleMotionFrameworkLog(ELogLevel logLevel, string log) { // 根据不同的日志级别进行相应的处理 if (logLevel == ELogLevel.Log) { // 普通日志输出 UnityEngine.Debug.Log(log); } else if (logLevel == ELogLevel.Error) { // 错误日志输出 UnityEngine.Debug.LogError(log); } else if (logLevel == ELogLevel.Warning) { // 警告日志输出 UnityEngine.Debug.LogWarning(log); } else if (logLevel == ELogLevel.Exception) { // 异常日志输出 UnityEngine.Debug.LogError(log); } else { // 未知日志级别抛出异常 throw new NotImplementedException($"{logLevel}"); } } /// /// 检查并更新物资数量相关的正确答案 /// /// 流程配置的JSON字符串 /// 修改后的JSON字符串 private string UpdateMaterialQuantityAnswers(string jsonString) { try { Debug.Log("开始检查并更新物资数量相关的正确答案..."); // 检查输入参数 if (string.IsNullOrEmpty(jsonString)) { Debug.LogWarning("JSON字符串为空,跳过数量更新"); return jsonString; } // 获取收入数量 Debug.Log($"从任务书获取的收入数量: {quantity}"); if (string.IsNullOrEmpty(quantity)) { Debug.LogWarning("收入数量为空,跳过数量更新"); return jsonString; } // 解析JSON字符串 var jsonArray = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonString); if (jsonArray == null) { Debug.LogWarning("JSON解析失败,跳过数量更新"); return jsonString; } int updatedCount = 0; int totalSteps = 0; int totalActions = 0; int actionsWithQuestions = 0; int actionsWithoutQuestions = 0; // 根据题目名称判断类型(入库/出库/未知) MaterialOperationType operationType; if (examName.Contains("入库")) { operationType = MaterialOperationType.入库; } else if (examName.Contains("出库")) { operationType = MaterialOperationType.出库; } else { operationType = MaterialOperationType.未知; } Debug.Log($" 【题目类型】{operationType} (基于题目名称: {examName})"); // 遍历所有步骤 foreach (var step in jsonArray) { if (step == null) continue; totalSteps++; string stepDescription = step["StepDescription"]?.ToString() ?? "未知步骤"; Debug.Log($"【步骤 {totalSteps}】{stepDescription}"); var actions = step["Actions"] as Newtonsoft.Json.Linq.JArray; if (actions == null) { Debug.Log($" 【警告】步骤 {stepDescription} 没有Actions字段或Actions为null"); continue; } totalActions += actions.Count; // 遍历所有动作 foreach (var action in actions) { if (action == null) continue; string actionTitle = action["Title"]?.ToString() ?? "未知动作"; var judgmentQuestions = action["JudgmentQuestions"] as Newtonsoft.Json.Linq.JArray; if (judgmentQuestions == null) { actionsWithoutQuestions++; // Debug.Log($" 【跳过】{actionTitle} - 无判断题 (JudgmentQuestions: null)"); continue; } actionsWithQuestions++; //Debug.Log($" 【动作】{actionTitle} - 包含 {judgmentQuestions.Count} 个判断题"); // 遍历所有判断题 foreach (var question in judgmentQuestions) { if (question == null) continue; var questionText = question["Question"]?.ToString(); var correctAnswer = question["CorrectAnswer"]; if (string.IsNullOrEmpty(questionText) || correctAnswer == null) { Debug.Log($" 【警告】跳过无效问题: Question={questionText}, CorrectAnswer={correctAnswer}"); continue; } // 根据题目类型设置不同的数量字段匹配规则 bool shouldUpdate = false; string updateReason = ""; switch (operationType) { case MaterialOperationType.入库: // 入库逻辑:匹配物资数量、收入数量、结存数量 if (questionText.Contains("物资数量") || questionText.Contains("收入数量") || questionText.Contains("结存数量") || questionText == "数量" || questionText.Contains("交接数量") || questionText.Contains("上下架数量")) { shouldUpdate = true; updateReason = "入库数量字段"; } else if (questionText.Contains("发出数量")) { if (question["CorrectAnswer"].ToString() != "") { string oldAnswer = correctAnswer.ToString(); question["CorrectAnswer"] = "0"; Debug.Log($" 【发出数量更新】问题: {questionText}"); Debug.Log($" 【发出数量更新】更新前答案: {oldAnswer} -> 更新后答案: 0"); updatedCount++; } else { Debug.Log(correctAnswer.ToString() + "目标题目答案为空 不更新"); } } else if (questionText.Contains("目标仓位")) { if (question["CorrectAnswer"].ToString() != "") { string oldAnswer = correctAnswer.ToString(); question["CorrectAnswer"] = localtarge; Debug.Log($" 【目标仓位更新】问题: {questionText}"); Debug.Log($" 【目标仓位更新】更新前答案: {oldAnswer} -> 更新后答案: {localtarge}"); updatedCount++; } else { Debug.Log(correctAnswer.ToString() + "目标题目答案为空 不更新"); } } else if (questionText.Equals("物料") || questionText.Contains("物料描述")) { if (question["CorrectAnswer"].ToString() != "") { string oldAnswer = correctAnswer.ToString(); question["CorrectAnswer"] = MotionEngine.GetModule().GetMaterialDescription(); Debug.Log($" 【物料更新】问题: {questionText}"); Debug.Log($" 【物料更新】更新前答案: {oldAnswer} -> 更新后答案: {question["CorrectAnswer"]}"); updatedCount++; } else { Debug.Log(correctAnswer.ToString() + "目标题目答案为空 不更新"); } } else if (questionText.Equals("仓库号")) { if (question["CorrectAnswer"].ToString() != "") { string oldAnswer = correctAnswer.ToString(); question["CorrectAnswer"] = MotionEngine.GetModule().GetCangKuHao(); Debug.Log($" 【仓库号更新】问题: {questionText}"); Debug.Log($" 【仓库号更新】更新前答案: {oldAnswer} -> 更新后答案: {question["CorrectAnswer"]}"); updatedCount++; } else { Debug.Log(correctAnswer.ToString() + "目标题目答案为空 不更新"); } } else if (questionText.Contains("工厂")) { if (question["CorrectAnswer"].ToString() != "") { string oldAnswer = correctAnswer.ToString(); question["CorrectAnswer"] = MotionEngine.GetModule().GetFactoryCode(); Debug.Log($" 【工厂更新】问题: {questionText}"); Debug.Log($" 【工厂更新】更新前答案: {oldAnswer} -> 更新后答案: {question["CorrectAnswer"]}"); updatedCount++; } else { Debug.Log(correctAnswer.ToString() + "目标题目答案为空 不更新"); } } else if (questionText.Contains("批次")) { if (question["CorrectAnswer"].ToString() != "") { string oldAnswer = correctAnswer.ToString(); question["CorrectAnswer"] = MotionEngine.GetModule().GetBatchNumber(); Debug.Log($" 【批次更新】问题: {questionText}"); Debug.Log($" 【批次更新】更新前答案: {oldAnswer} -> 更新后答案: {question["CorrectAnswer"]}"); updatedCount++; } else { Debug.Log(correctAnswer.ToString() + "目标题目答案为空 不更新"); } } else if (questionText.Contains("上架仓位")) { if (question["CorrectAnswer"].ToString() != "") { string oldAnswer = correctAnswer.ToString(); question["CorrectAnswer"] = localtarge; Debug.Log($" 【目标仓位更新】问题: {questionText}"); Debug.Log($" 【目标仓位更新】更新前答案: {oldAnswer} -> 更新后答案: {localtarge}"); updatedCount++; } else { Debug.Log(correctAnswer.ToString() + "目标题目答案为空 不更新"); } } else if (questionText.Contains("物料编码")) { if (question["CorrectAnswer"].ToString() != "") { string oldAnswer = correctAnswer.ToString(); question["CorrectAnswer"] = MotionEngine.GetModule().GetMaterialCode(); Debug.Log($" 【批次更新】问题: {questionText}"); Debug.Log($" 【批次更新】更新前答案: {oldAnswer} -> 更新后答案: {question["CorrectAnswer"]}"); updatedCount++; } else { Debug.Log(correctAnswer.ToString() + "目标题目答案为空 不更新"); } } break; case MaterialOperationType.出库: // 出库逻辑:匹配物资数量、发出数量 if (questionText.Contains("物资数量") || questionText.Contains("发出数量") || questionText.Contains("下架数量") || questionText == "数量") { shouldUpdate = true; updateReason = "出库数量字段"; } else if (questionText.Contains("收入数量") || questionText.Contains("结存数量")) { string oldAnswer = correctAnswer.ToString(); question["CorrectAnswer"] = "0"; Debug.Log($" 【数量更新】问题: {questionText}"); Debug.Log($" 【数量更新】更新前答案: {oldAnswer} -> 更新后答案: 0"); updatedCount++; } break; case MaterialOperationType.未知: // 未知类型:通用匹配逻辑,根据关键词进行判断替换 if (questionText.Contains("物资数量") || questionText.Contains("收入数量") || questionText.Contains("发出数量") || questionText.Contains("结存数量") || questionText.Contains("交接数量") || questionText.Contains("下架数量") || questionText.Contains("过账起始时间") || questionText.Contains("过账结束时间") || questionText == "数量") { shouldUpdate = true; } break; } if (shouldUpdate) { // 记录更新前的值 string oldAnswer = correctAnswer.ToString(); // 更新正确答案为实际收入数量 question["CorrectAnswer"] = quantity; // 记录更新日志 Debug.Log($" 【数量更新】问题: {questionText}"); // Debug.Log($" 【数量更新】原因: {updateReason}"); Debug.Log($" 【数量更新】更新前答案: {oldAnswer} -> 更新后答案: {quantity}"); updatedCount++; } else { // Debug.Log($" 【跳过】问题: {questionText} (不包含相关数量关键词)"); } } } } // ========== 新增:物料检查流程题目过滤逻辑 ========== // 注意:此过滤逻辑在数量更新完成后执行,确保与原有数量更新逻辑完全兼容 // 过滤后的题目数量将根据实际物料数量动态调整,不影响数量字段的更新 Debug.Log("开始执行物料检查流程题目过滤..."); int filteredActionsCount = 0; int totalFilteredQuestions = 0; // 重新遍历JSON进行题目过滤 foreach (var step in jsonArray) { if (step == null) continue; var actions = step["Actions"] as Newtonsoft.Json.Linq.JArray; if (actions == null) continue; foreach (var action in actions) { if (action == null) continue; string actionTitle = action["Title"]?.ToString() ?? ""; bool isMaterialCheckProcess = false; switch (operationType) { case MaterialOperationType.入库: isMaterialCheckProcess = !string.IsNullOrEmpty(actionTitle) && actionTitle.Contains("物料") || actionTitle.Contains("检查") || actionTitle.Contains("核对"); break; case MaterialOperationType.出库: if (actionTitle != "物料核对") { isMaterialCheckProcess = !string.IsNullOrEmpty(actionTitle) && actionTitle.Contains("物料") || actionTitle.Contains("检查"); } break; } // // 检查是否为物料检查流程 // bool isMaterialCheckProcess = !string.IsNullOrEmpty(actionTitle) && // actionTitle.Contains("物料") || // actionTitle.Contains("检查")|| // actionTitle.Contains("核对"); if (isMaterialCheckProcess) { var judgmentQuestions = action["JudgmentQuestions"] as Newtonsoft.Json.Linq.JArray; if (judgmentQuestions != null && judgmentQuestions.Count > 0) { // 获取物料数量并计算最大题目数量 int materialCount = GetMaterialCountForFiltering(); int maxQuestionsToShow = materialCount * 3; // 每个物料3个题目,确保不超过实际题目数量 Debug.Log($"【物料检查过滤】检测到物料检查流程,标题:{actionTitle}"); Debug.Log($"【物料检查过滤】物料数量:{materialCount},最大显示题目数:{maxQuestionsToShow}"); // 如果题目数量超过限制,进行过滤 if (judgmentQuestions.Count > maxQuestionsToShow) { int originalCount = judgmentQuestions.Count; // 保留前N个题目,移除多余的题目 while (judgmentQuestions.Count > maxQuestionsToShow) { judgmentQuestions.RemoveAt(judgmentQuestions.Count - 1); } filteredActionsCount++; totalFilteredQuestions += (originalCount - maxQuestionsToShow); Debug.Log($"【物料检查过滤】动作 '{actionTitle}' 题目已过滤:{originalCount} -> {maxQuestionsToShow} (移除 {originalCount - maxQuestionsToShow} 个题目)"); } else { Debug.Log($"【物料检查过滤】动作 '{actionTitle}' 题目数量未超过限制,无需过滤:{judgmentQuestions.Count} <= {maxQuestionsToShow}"); } } } bool isMaterialCheckProcess1 = !string.IsNullOrEmpty(actionTitle) && actionTitle.Contains("码放"); if (isMaterialCheckProcess1) { var judgmentQuestions = action["JudgmentQuestions"] as Newtonsoft.Json.Linq.JArray; if (judgmentQuestions != null && judgmentQuestions.Count > 0) { // 获取物料数量并计算最大题目数量 int materialCount = GetMaterialCountForFiltering(); int maxQuestionsToShow = materialCount; // 每个物料3个题目,确保不超过实际题目数量 Debug.Log($"【物料检查过滤】检测到物料检查流程,标题:{actionTitle}"); Debug.Log($"【物料检查过滤】物料数量:{materialCount},最大显示题目数:{maxQuestionsToShow}"); // 如果题目数量超过限制,进行过滤 if (judgmentQuestions.Count > maxQuestionsToShow) { int originalCount = judgmentQuestions.Count; // 保留前N个题目,移除多余的题目 while (judgmentQuestions.Count > maxQuestionsToShow) { judgmentQuestions.RemoveAt(judgmentQuestions.Count - 1); } filteredActionsCount++; totalFilteredQuestions += (originalCount - maxQuestionsToShow); Debug.Log($"【物料检查过滤】动作 '{actionTitle}' 题目已过滤:{originalCount} -> {maxQuestionsToShow} (移除 {originalCount - maxQuestionsToShow} 个题目)"); } else { Debug.Log($"【物料检查过滤】动作 '{actionTitle}' 题目数量未超过限制,无需过滤:{judgmentQuestions.Count} <= {maxQuestionsToShow}"); } } } } } Debug.Log($"【物料检查过滤】过滤完成!共处理 {filteredActionsCount} 个动作,总共移除 {totalFilteredQuestions} 个题目"); // 添加详细的过滤结果日志 if (filteredActionsCount > 0) { Debug.Log($"【框架消息】【物料检查过滤】成功过滤 {filteredActionsCount} 个物料检查动作"); Debug.Log($"【框架消息】【物料检查过滤】总共移除 {totalFilteredQuestions} 个超出物料数量的题目"); Debug.Log($"【框架消息】【物料检查过滤】过滤后的题目数量将根据实际物料数量动态调整"); } else { Debug.Log($"【框架消息】【物料检查过滤】未发现需要过滤的物料检查动作"); } // ========== 物料检查流程题目过滤逻辑结束 ========== // 输出统计信息 Debug.Log("=== 物资数量更新统计信息 ==="); Debug.Log($"总步骤数: {totalSteps}"); Debug.Log($"总动作数: {totalActions}"); Debug.Log($"包含判断题的动作数: {actionsWithQuestions}"); Debug.Log($"无判断题的动作数: {actionsWithoutQuestions}"); Debug.Log($"更新的问题数: {updatedCount}"); Debug.Log($"物资数量更新完成!"); // 返回修改后的JSON字符串 string updatedJsonString = JsonConvert.SerializeObject(jsonArray, Formatting.Indented); Debug.Log($"返回修改后的JSON字符串,长度: {updatedJsonString.Length}"); return updatedJsonString; } catch (Exception ex) { Debug.LogError($"更新物资数量答案时发生错误: {ex.Message}"); Debug.LogError($"错误堆栈: {ex.StackTrace}"); // 发生错误时返回原始字符串 return jsonString; } } /// /// 获取用于题目过滤的物料数量 /// /// 物料数量,如果获取失败则返回默认值1 private int GetMaterialCountForFiltering() { try { // 检查quantity字段是否为空 if (string.IsNullOrEmpty(quantity)) { Debug.LogWarning("【物料数量获取】quantity 为空,使用默认物料数量1"); return 1; } // 尝试解析quantity为整数 if (int.TryParse(quantity, out int materialCount)) { Debug.Log($"【物料数量获取】成功获取物料数量:{materialCount}"); return materialCount; } else { Debug.LogWarning($"【物料数量获取】无法解析 quantity:{quantity},使用默认物料数量1"); return 1; } } catch (System.Exception ex) { Debug.LogError($"【物料数量获取】获取物料数量时发生异常:{ex.Message}"); return 1; } } } /// /// 离线模式配置类 /// [Serializable] public class OfflineConfig { public string PaperId { get; set; } public string AppID { get; set; } public string ExamRoomId { get; set; } public string StudentId { get; set; } public string GroupId { get; set; } public string Mode { get; set; } public string BatchId { get; set; } public string Token { get; set; } public string EncodedStr { get; set; } public string CourseId { get; set; } public string IpAddress { get; set; } public string Time { get; set; } public string ExamName { get; set; } }