using System.Collections; using System.Collections.Generic; using Unity.VisualScripting; using UnityEngine; using UnityEngine.UI; using AFeijia.UI; using TMPro; using System; using System.IO; using UnityEditor; using Newtonsoft.Json; public class TrainingManager : UITool { public static TrainingManager Instance; /// /// 已选择的选项 /// Key:设备信息(名称或者id);Value:选项信息(选项图片id) /// [Manual] public static Dictionary SelectedDeviceOption = new Dictionary(); /// /// 当前选中的设备 /// [Manual] public string CurrentDevice; /// /// 选择对应模型标题 /// public RectTransform SelectModelTittle; /// /// 提交按钮 /// public Button TrainingSubmit; /// /// 训练成绩返回按钮 /// public Button TrainingScoreBack; /// /// 当前是否停留在成绩页面 /// [Manual] public bool IsScorePage; /// /// 事件值 /// public TextMeshProUGUI TimeValue; /// /// 正确值 /// public TextMeshProUGUI CorretValue; /// /// 错误值 /// public TextMeshProUGUI WrongValue; #region 练习UI /// /// 练习设备选项容器 /// public RectTransform TrainingOptionsContent; /// /// 练习设备选项预制体 /// [Manual] public TrainingDeviceItem TrainingDeviceItemPrefab; /// /// 练习设备选项列表 /// [Manual] public List TrainingDeviceItemList = new List(); /// /// 练习结果容器 /// public RectTransform TrainingScoreContent; /// /// 练习结果预制体 /// [Manual] public TrainingScoreItem TrainingScoreItemPrefab; /// /// 训练结果项列表 /// [Manual] public List TrainingScoreItemList = new List(); #endregion #region 练习界面 /// /// 练习选项界面 /// public RectTransform TrainingOptions; /// /// 练习分数界面 /// public RectTransform TrainingScore; #endregion #region 考核模式 /// /// 考核模式部分UI元素 /// public RectTransform ExaminationElements; /// /// 交卷 /// public Button ExaminationSubmit; /// /// 剩余时间 /// public TextMeshProUGUI RemainingTime; /// /// 总时间(秒) /// [Manual] public int TotalSeconds = 60; /// /// 计时器协程 /// [Manual] private Coroutine TimerCoroutine; /// /// 退出计时 /// public TextMeshProUGUI TimerClock; /// /// 计时提示文本 /// public TextMeshProUGUI TimerQuit; /// /// 考试结束标题 /// public TextMeshProUGUI ExamEndTittle; /// /// 圆环 /// public Image ClockRing; /// /// 考核退出界面 /// public RectTransform ExaminationQuit; #endregion public bool IsTutorial; protected override void Awake() { base.Awake(); Instance = this; } private void Start() { TrainingSubmit.onClick.AddListener(OnTrainingSubmit); TrainingScoreBack.onClick.AddListener(OnTrainingBack); ExaminationSubmit.onClick.AddListener(() => { OnExaminationSubmit(true); }); #region 本地无数据测试 Debug.Log("本地测试生成练习选项"); TrainingDeviceItemPrefab = Resources.Load("Prefabs/UI/TrainingDeviceItem"); //for (int i = 0; i < 30; i++) //{ // var inst = Instantiate(TrainingDeviceItemPrefab, TrainingOptionsContent); // inst.Init(new TrainingDeviceData { id = i.ToString() }); // TrainingDeviceItemList.Add(inst); //} #endregion InterfaceManager.GetLocalFiles(Application.streamingAssetsPath + "/结构认知图", (_files) => { for (int i = 0; i < _files.Count; i++) { var _directory = Path.GetFileNameWithoutExtension(_files[i].DirectoryName); if (!PictureDic.ContainsKey(_directory)) { PictureDic.Add(_directory, new List() { _files[i].FullName }); } else { PictureDic[_directory].Add(_files[i].FullName); } } }); } #region 训练模式内容 /// /// 提交训练结果 /// private void OnTrainingSubmit() { //隐藏设备列表 CanvasMain.Instance.DeviceListRoot.gameObject.SetActive(false); //隐藏设备选项 TrainingOptions.gameObject.SetActive(false); //展示练习结果 TrainingScore.gameObject.SetActive(true); //隐藏提交按钮 TrainingSubmit.gameObject.SetActive(false); //隐藏标题 SelectModelTittle.gameObject.SetActive(false); //根据设备列表数据和选择内容生成练习结果 int trueCount = 0; int falseCount = 0; if (TrainingScoreItemPrefab == null) TrainingScoreItemPrefab = Resources.Load("Prefabs/UI/TrainingScoreItem"); for (int i = 0; i < DeviceItem.DeviceItemsList.Count; i++) { var inst = Instantiate(TrainingScoreItemPrefab, TrainingScoreContent); var istrue = inst.Init(i + 1, DeviceItem.DeviceItemsList[i].DevicesItemData); if (istrue) trueCount++; else falseCount++; TrainingScoreItemList.Add(inst); } MainCoroutine.Instance.StopTimer(); //计算时间、得分数量、错误数量 TimeValue.text = MainCoroutine.Instance.cost_time; CorretValue.text = trueCount + "题"; WrongValue.text = falseCount + "题"; } /// /// 训练结果返回 /// private void OnTrainingBack() { //显示设备列表 CanvasMain.Instance.DeviceListRoot.gameObject.SetActive(true); //隐藏设备选项 TrainingOptions.gameObject.SetActive(true); //展示练习结果 TrainingScore.gameObject.SetActive(false); //显示提交按钮 TrainingSubmit.gameObject.SetActive(true); //显示标题 SelectModelTittle.gameObject.SetActive(true); //清空上次训练选项 SelectedDeviceOption.Clear(); //清除已选中的状态 if (TrainingDeviceItem.SelectedItem != null) { TrainingDeviceItem.SelectedItem.SetSelectStatus(selected: false, force: true); } //清除上一次的训练结果 for (int i = 0; i < TrainingScoreItemList.Count; i++) { Destroy(TrainingScoreItemList[i].gameObject); } TrainingScoreItemList.Clear(); } #endregion #region 公共 /// /// 当前设备改变 /// /// public static void ChangeDevice(DeviceItem _device_item) { Instance.CurrentDevice = _device_item.DevicesItemData.dev_name; //当设备改变时,先清除已选中的状态 if (TrainingDeviceItem.SelectedItem != null) { TrainingDeviceItem.SelectedItem.SetSelectStatus(selected: false, force: true); } if (!SelectedDeviceOption.ContainsKey(_device_item.DevicesItemData.dev_name)) { SelectedDeviceOption.Add(_device_item.DevicesItemData.dev_name, ""); } else { var selected = TrainingDeviceItem.TrainingDeviceItemList.Find(x => x.TrainingDeviceData.id.Equals(SelectedDeviceOption[_device_item.DevicesItemData.dev_name])); if (selected != null) { selected.SetSelectStatus(selected: true, force: true); } } Instance.Init(_device_item); } /// /// 更新选项值 /// public void UpdateSelectItem(string _selected_id) { SelectedDeviceOption[CurrentDevice] = _selected_id; } #endregion #region 考核模式内容 /// /// 切换考核模式 /// public void SwitchExaminationMode() { //改变界面元素 TrainingSubmit.gameObject.SetActive(false); ExaminationElements.gameObject.SetActive(true); //开始倒计时 TimerCoroutine = StartCoroutine(Timer(OnExaminationSubmit)); //StartCoroutine() } /// /// 交卷 /// /// 是否进行二次确认 private void OnExaminationSubmit(bool tips) { if (tips) { //二次确认 TipsPanel.Instance.Tips("提示", "确定要交卷吗?", (submit) => { if (submit) { //显示正在提交面板 TipsPanel.Instance.WaitingSubmit(true); try { //手动交卷确认时,停止倒计时 StopCoroutine(TimerCoroutine); //提交成绩 OnSubmitScore((_error, _data) => { TipsPanel.Instance.WaitingSubmit(false); if (!string.IsNullOrEmpty(_error)) { TipsPanel.Instance.ForceTips("ERROR_1", _error, (submit) => { }); } else { //隐藏其他 //设备列表 CanvasMain.Instance.DeviceListRoot.gameObject.SetActive(false); //设备选项 TrainingOptions.gameObject.SetActive(false); //提交按钮、考核倒计时 ExaminationElements.gameObject.SetActive(false); _submited = true; //倒计时并退出 ExaminationQuit.gameObject.SetActive(true); StartCoroutine(ExitTimer(() => { Debug.Log("退出!"); Application.Quit(); })); } }); } catch (Exception ex) { Debug.LogException(ex); TipsPanel.Instance.WaitingSubmit(false); TipsPanel.Instance.ForceTips("ERROR_2", ex.ToString(), (submit) => { }); } } else { } }); } else { //显示正在提交面板 TipsPanel.Instance.WaitingSubmit(true); TipsPanel.Instance.WaitingText("考试时间到,正在自动交卷..."); try { //提交成绩 OnSubmitScore((_error, _data) => { TipsPanel.Instance.WaitingSubmit(false); if (!string.IsNullOrEmpty(_error)) { TipsPanel.Instance.ForceTips("ERROR", _error, (submit) => { }); } else { //隐藏其他 //设备列表 CanvasMain.Instance.DeviceListRoot.gameObject.SetActive(false); //设备选项 TrainingOptions.gameObject.SetActive(false); //提交按钮、考核倒计时 ExaminationElements.gameObject.SetActive(false); _submited = true; //倒计时并退出 ExaminationQuit.gameObject.SetActive(true); //变更标题 ExamEndTittle.text = "考试时间到,已自动交卷,请离开考场"; StartCoroutine(ExitTimer(() => { Debug.Log("退出!"); Application.Quit(); })); } }); } catch (Exception ex) { Debug.LogException(ex); TipsPanel.Instance.WaitingSubmit(false); TipsPanel.Instance.ForceTips("ERROR_2", ex.ToString(), (submit) => { }); } } } /// /// 考试总花费的时间 /// int cost_time = 0; /// /// 考核总时间倒计时 /// /// /// private IEnumerator Timer(Action callback) { int t = (int)GameInit.InfoIni.user_time * 60; while (t > 0) { RemainingTime.text = string.Format("{0:D2}:{1:D2}:{2:D2}", t / 3600, t % 3600 / 60, t % 3600 % 60); t--; cost_time++; yield return new WaitForSeconds(1); } //考试限时结束,自动交卷 Debug.Log("考试限时结束,自动交卷"); callback?.Invoke(false); } /// /// 自动退出倒计时 /// /// /// private IEnumerator ExitTimer(Action callback) { yield return new WaitUntil(() => _submited == true); int t = 10; float c = 0; TimerClock.text = t.ToString(); TimerQuit.text = t + "秒后自动退出系统"; while (t > 0) { c++; if (c == 10) { t--; c = 0; TimerClock.text = t.ToString(); TimerQuit.text = t + "秒后自动退出系统"; } ClockRing.fillAmount -= 0.01f; yield return new WaitForSeconds(0.1f); } yield return new WaitForSeconds(0.5f); callback?.Invoke(); } #endregion #region 读取信息 /// /// Key:设备名称;Value:图片地址列表 /// public Dictionary> PictureDic = new Dictionary>(); /// /// Key:图片地址;Value:精灵 /// public Dictionary Sprites = new Dictionary(); /// /// 初始化 /// /// public void Init(DeviceItem _device_item) { if (_device_item == null) { return; } if (PictureDic.ContainsKey(_device_item.DevicesItemData.dev_name)) { var _pics = PictureDic[_device_item.DevicesItemData.dev_name]; for (int i = 0; i < _pics.Count; i++) { var _id = Path.GetFileNameWithoutExtension(_pics[i]); TrainingDeviceItem _inst; if (TrainingDeviceItemList.Count > i) { _inst = TrainingDeviceItemList[i]; } else { _inst = Instantiate(TrainingDeviceItemPrefab, TrainingOptionsContent); TrainingDeviceItemList.Add(_inst); } if (Sprites.ContainsKey(_pics[i])) { var _uuid = System.Guid.NewGuid().ToString(); var _sprite = Sprites[_pics[i]]; _inst.Init(new TrainingDeviceData { id = _id, uuid = _uuid }, _sprite); _inst.gameObject.SetActive(true); } else { var _url = _pics[i]; StartCoroutine(InterfaceManager.GetSprite(_url, (_sp) => { Sprites.Add(_url, _sp); _inst.Init(new TrainingDeviceData { id = _id }, _sp); _inst.gameObject.SetActive(true); })); } } if (_pics.Count < TrainingDeviceItemList.Count) { for (int i = _pics.Count; i < TrainingDeviceItemList.Count; i++) { TrainingDeviceItemList[i].gameObject.SetActive(false); } } } else { Debug.Log($"[{_device_item.DevicesItemData.dev_name}]不存在!"); } } //是否完成提交 bool _submited = false; /// /// 提交当前内容 /// /// private void OnSubmitScore(Action _callback) { var _post_url = InterfaceManager.IpAddress + InterfaceManager.API_DIC["SUBMIT"]; List stepListItems = new List(); for (int i = 0; i < CanvasMain.Instance.ExamContents.Count; i++) { StepListItem _step = new StepListItem(); _step.stepName = CanvasMain.Instance.ExamContents[i].step; _step.testPoint = CanvasMain.Instance.ExamContents[i].point; DeviceItem device = DeviceItem.DeviceItemsList.Find(x => x.DevicesItemData.dev_name == CanvasMain.Instance.ExamContents[i].device); _step.score = SelectedDeviceOption.ContainsKey(CanvasMain.Instance.ExamContents[i].device) ? (SelectedDeviceOption[CanvasMain.Instance.ExamContents[i].device] == device.DevicesItemData.pic_id ? float.Parse(CanvasMain.Instance.ExamContents[i].score) : 0) : 0; stepListItems.Add(_step); _step.setScore = float.Parse(CanvasMain.Instance.ExamContents[i].score); } ScoreInfo _score_info = new ScoreInfo() { userName = GameInit.InfoIni.user_name, userId = GameInit.InfoIni.user_id, examId = GameInit.InfoIni.exam_id, classId = GameInit.InfoIni.class_id, useTime = cost_time.ToString(), examClassId = GameInit.InfoIni.exam_class_id, stepList = stepListItems }; var _json_str = JsonConvert.SerializeObject(_score_info); StartCoroutine(InterfaceManager.Post(_post_url, _json_str, _callback)); } #endregion }