unityzgy/Assets/Scripts/UIScripts/Teacher/TeacherMainPanel.cs
ayuan9957 a9e03f6ac0 feat: 维修科目步骤描述多语言支持 + LocalizeOperateMsg修复
- 创建维修案例1/2的英/法/俄翻译版XML文件
- TeacherMainPanel: 根据语言选择对应翻译版XML下发
- StudentSub3Panel: 所有InjectOperateMsg改为InjectOperateMsgLocalized
- StudentOperateRecorder: 新增InjectOperateMsgLocalizedWithTime方法
- LocalizationManager: 修复LocalizeOperateMsg双重格式化bug
- LocalizationManager: 新增维修步骤模板/拆卸/安装翻译条目
2026-07-16 11:36:18 +08:00

641 lines
24 KiB
C#

using Public.File;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Video;
using XFramework;
using XFramework.Objects;
public class TeacherMainPanel : BasePanel
{
const string panelName = "Panel_TeacherMain";
Dropdown dropdownState;
Dropdown dropdownSubject;
Dropdown dropdownRepairSubject;
Dropdown dropdownWeather;
Button playAudio;
Button quitButton;
Button enterLook;
Button sendSubject;
Button stop;
Button selectFile;
Button editorFile;
Button newFile;
Button creatGroup;
Button removeGroup;
Button addGroup;
Button setGroupMaster;
PromptTextCtrl promptText_SetGroup;
GroupManager groupManager;
string selectFilePath;
Text filePath;
Text fileDetail;
Text text_stuCount;
Toggle continuous;//连续科目
StudentContentCtrl contentCtrl;
PromptTextCtrl sendSubPro;//发送科目提示
PromptTextCtrl sendStopPro;//结束任务提示
PromptTextCtrl lookStudentPro;//观察学员按钮提示
PromptTextCtrl editorPro;//编辑文件按钮提示
PromptTextCtrl newFilePro;//新建文件按钮提示
VideoController videoPlayer;
Dictionary<string, OnlineStudent> selectStudent = new Dictionary<string, OnlineStudent>();//处于选中状态的学员数据
RecordBase selectRecord;
public TeacherMainPanel() : base(new UIType(panelName))
{
}
protected override void InitEvent()
{
dropdownState = ActivePanel.Find("Dropdown_模式").GetComponent<Dropdown>();
dropdownSubject = ActivePanel.Find("Dropdown_kemu").GetComponent<Dropdown>();
dropdownRepairSubject = ActivePanel.Find("Dropdown_维修科目出现").GetComponent<Dropdown>();
dropdownWeather = ActivePanel.Find("Dropdown_weather").GetComponent<Dropdown>();
playAudio = ActivePanel.Find("Button_playAudio").GetComponent<Button>();
quitButton = ActivePanel.Find("Button_exit").GetComponent<Button>();
enterLook = ActivePanel.Find("Button_look").GetComponent<Button>();
sendSubject = ActivePanel.Find("Button_send").GetComponent<Button>();
selectFile = ActivePanel.Find("Button_SelectFile").GetComponent<Button>();
editorFile = ActivePanel.Find("Button_eidtorFile").GetComponent<Button>();
newFile = ActivePanel.Find("Button_newFile").GetComponent<Button>();
stop = ActivePanel.Find("Button_finishSub").GetComponent<Button>();
continuous = ActivePanel.Find("Toggle_lianxu").GetComponent<Toggle>();
videoPlayer = ActivePanel.Find("VideoPlayPanel").GetComponent<VideoController>();
contentCtrl = ActivePanel.GetComponentInChildren<StudentContentCtrl>();
contentCtrl.AddListener(ShowStudentCount);
groupManager = new GroupManager(contentCtrl);
creatGroup = ActivePanel.FindChildTrans("Button_creatGroup").GetComponent<Button>();
removeGroup = ActivePanel.FindChildTrans("Button_removeGroup").GetComponent<Button>();
addGroup = ActivePanel.FindChildTrans("Button_addGroup").GetComponent<Button>();
setGroupMaster = ActivePanel.FindChildTrans("Button_setMaster").GetComponent<Button>();
editorPro = ActivePanel.FindChildTrans("Text_editorPro").GetComponent<PromptTextCtrl>();
sendSubPro = ActivePanel.FindChildTrans("Text_sendSubPrompt").GetComponent<PromptTextCtrl>();
sendStopPro = sendSubject.GetComponentInChildren<PromptTextCtrl>();
lookStudentPro = enterLook.GetComponentInChildren<PromptTextCtrl>();
newFilePro = newFile.GetComponentInChildren<PromptTextCtrl>();
filePath = ActivePanel.FindChildTrans("Text_MsgPath").GetComponent<Text>();
fileDetail = ActivePanel.FindChildTrans("Text_MsgDetail").GetComponent<Text>();
text_stuCount = ActivePanel.FindChildTrans("Text_studentsCount").GetComponent<Text>();
promptText_SetGroup = ActivePanel.FindChildTrans("PormptText_setGroup").GetComponent<PromptTextCtrl>();
LocalizationManager.SetFormatted(text_stuCount, "当前登录学员:{0},训练中:{1},考核中:{2},等待中:{3}", 0, 0, 0, 0);//初始化人员数量
dropdownWeather.options.Clear();
dropdownWeather.options.Add(new Dropdown.OptionData(LocalizationManager.Get("选择天气")));
string[] weathers = DBManager.Instance.GetABNames(ABType.);
for (int i = 0; i < weathers.Length; i++)
{
dropdownWeather.options.Add(new Dropdown.OptionData(weathers[i]));
}
dropdownState.onValueChanged.AddListener(StateValueChange);
dropdownSubject.onValueChanged.AddListener(SubjectValueChange);
dropdownRepairSubject.onValueChanged.AddListener(RepairValueChange);
playAudio.onClick.AddListener(PlayRepairVideo);
quitButton.onClick.AddListener(SignOut);
enterLook.onClick.AddListener(LookStudent);
sendSubject.onClick.AddListener(SendSubject);
selectFile.onClick.AddListener(SelectFile);
editorFile.onClick.AddListener(EditorFile);
newFile.onClick.AddListener(NewFile);
stop.onClick.AddListener(StopLearn);
creatGroup.onClick.AddListener(() => {
string error = groupManager.CreatGroup(GetStuList());
ShowSetGroupError(error);
});
removeGroup.onClick.AddListener(() => {
string error = groupManager.RemoveGroup(GetStuList());
ShowSetGroupError(error);
});
setGroupMaster.onClick.AddListener(() => {
string error = groupManager.SetMaster(GetStuList());
ShowSetGroupError(error);
});
dropdownRepairSubject.gameObject.SetActive(false);
continuous.gameObject.SetActive(false);
playAudio.gameObject.SetActive(false);
videoPlayer.gameObject.SetActive(false);
foreach (var item in MasterLoginManager.Instance.onlineStudents)
{
StudentLogin(item.Key, item.Value.user);
}
OnboardManager.Instance.onboardDic = DBManager.Instance.GetOnBoardEquip();
//SubjectValueChange(2);
dropdownState.value = 1;
dropdownWeather.value = 1;
dropdownSubject.value = 2;
}
public override void OnStart()
{
base.OnStart();
EventCenter.Instance.AddEventListener<OnlineStudent, bool>("StudentSelectToggle", SelectStudent);
EventCenter.Instance.AddEventListener<string, string>("StudentLoginOn", StudentLogin);//
EventCenter.Instance.AddEventListener<string>("StudentQuit", StudentQuit);//
EventCenter.Instance.AddEventListener<string, NetSubStage>("ChangeStudentStage", ChangeStudentStage);
//TCPManager.Instance.RegisterConnCloseEvent(StudentConnectChanged);//GameMain监听
EventCenter.Instance.AddEventListener<string, LearnState>("ChangeLearnState", ChangeLearnState);
}
public override void OnDestroy(bool isDestroy = false)
{
base.OnDestroy(isDestroy);
EventCenter.Instance.RemoveEnvetListener<OnlineStudent, bool>("StudentSelectToggle", SelectStudent);
EventCenter.Instance.RemoveEnvetListener<string, string>("StudentLoginOn", StudentLogin);
EventCenter.Instance.RemoveEnvetListener<string>("StudentQuit", StudentQuit);
EventCenter.Instance.RemoveEnvetListener<string, LearnState>("ChangeLearnState", ChangeLearnState);
//TCPManager.Instance.RemoveCloseEnvet(StudentConnectChanged);
}
//接收网络消息弹出学员面板
public override void Change(object newData)
{
PopResultWindow(newData);
}
//下达结束科目指令
private void StopLearn()
{
if (selectStudent.Count == 0)
{
sendStopPro.SetPrompt(LocalizationManager.Get("未选择待结束席位!"), Color.red, 3f);
return;
}
foreach (var item in selectStudent)
{
if (item.Value.state != LearnState.waiting)
{
TCPManager.Instance.SendEndCommand(item.Value.ip);
}
}
}
//学员登陆
private void StudentLogin(string ip, string user)
{
OnlineStudent newStu = new OnlineStudent();
newStu.ip = ip;
newStu.user = user;
newStu.state = LearnState.waiting;
contentCtrl.AddStudent(newStu);
}
/// <summary>
/// 客户端网络连接状态发生变化
/// </summary>
private void StudentConnectChanged(string ip,bool value)
{
if(!value)
{
StudentQuit(ip);
}
}
//学员退出登录/断开网络连接
private void StudentQuit(string ip)
{
if (selectStudent.ContainsKey(ip))
selectStudent.Remove(ip);
contentCtrl.RemoveStudent(ip);
}
//学员端返回等待场景时调用 当前仅会返回wating 返回其他值可能有误
private void ChangeLearnState(string ip, LearnState state)
{
ChangeLearnState(ip, "", state);
}
//学员学习状态变化
private void ChangeLearnState(string ip, string subName, LearnState state)
{
contentCtrl.ChangeStudentState(ip, subName, state);
if (selectStudent.ContainsKey(ip))
selectStudent[ip].state = state;
}
//学员学习阶段发生变化
private void ChangeStudentStage(string ip, NetSubStage stage)
{
contentCtrl.ChangeStudentStage(ip, stage);
if (selectStudent.ContainsKey(ip))
selectStudent[ip].subStage = stage;
}
//增加或减少当前选中的学员
void SelectStudent(OnlineStudent student, bool isSelect)
{
if (isSelect)
{
selectStudent.Add(student.ip, student);
}
else
{
selectStudent.Remove(student.ip);
}
}
//选择科目 科目发生变化时 清空想定文件选择和读取的记录 避免出现选择科目 和发送数据不符合的情况
void SubjectValueChange(int value)
{
switch (value)
{
case 1://科目1
continuous.gameObject.SetActive(true);
dropdownRepairSubject.gameObject.SetActive(false);
playAudio.gameObject.SetActive(false);
selectFile.interactable = true;
newFile.interactable = true;
editorFile.interactable = true;
break;
case 2://科目2
continuous.gameObject.SetActive(false);
dropdownRepairSubject.gameObject.SetActive(false);
playAudio.gameObject.SetActive(false);
selectFile.interactable = true;
newFile.interactable = true;
editorFile.interactable = true;
break;
case 3://科目3
dropdownRepairSubject.gameObject.SetActive(true);
continuous.gameObject.SetActive(false);
selectFile.interactable = false;
newFile.interactable = false;
editorFile.interactable = false;
if (dropdownRepairSubject.value != 0 && dropdownState.value==1)
{
playAudio.gameObject.SetActive(true);
}
break;
default://未选择科目
dropdownRepairSubject.gameObject.SetActive(false);
continuous.gameObject.SetActive(false);
selectFile.interactable = false;
newFile.interactable = false;
editorFile.interactable = false;
break;
}
selectRecord = null;
fileDetail.text = "";
selectFilePath = "";//切换科目时清空当前选择的文件 避免误操作
ShowFilePath();
}
//选择模式
void StateValueChange(int value)
{
if (value == 1 && dropdownRepairSubject.gameObject.activeSelf && dropdownRepairSubject.value != 0)
playAudio.gameObject.SetActive(true);
else
playAudio.gameObject.SetActive(false);
}
//选择维修科目 训练模式
void RepairValueChange(int value)
{
if (dropdownState.value == 1)
playAudio.gameObject.SetActive(true);
}
//播放维修视频
void PlayRepairVideo()
{
switch (dropdownRepairSubject.value)
{
case 1:
case 2:
//videoPlayer.gameObject.SetActive(true);
//videoPlayer.url = Application.streamingAssetsPath + "/Video/案例" + dropdownRepairSubject.value.ToString() + ".mp4";
string videoPath = StreamingAssetsManager.GetPath($"案例{dropdownRepairSubject.value.ToString()}_Video");
videoPlayer.PlayVideo(videoPath);
break;
default:
videoPlayer.CloseVideo();
break;
}
}
//退出登录
void SignOut()
{
Pop();
Push(new DaoHangPanel());
}
//学员导调
private void LookStudent()
{
if (selectStudent.Count != 1)
{
lookStudentPro.SetPrompt(LocalizationManager.Get("请选择单个席位进行导调!"), Color.red, 3f);
return;
}
OnlineStudent[] onlineStudents = new OnlineStudent[1] ;
selectStudent.Values.CopyTo(onlineStudents,0);
//if (student.state == LearnState.waiting)
//{
// lookStudentPro.SetPrompt("当前席位尚未开始学习!", Color.red, 3f);
// return;
//}
//else
if(onlineStudents[0].subStage!= NetSubStage.)//编队行军连贯训练科目时 可以导调 其他科目无需导调
{
lookStudentPro.SetPrompt(LocalizationManager.Get("行军中的席位可进行导调!"), Color.red, 3f);
return;
}
Push(new AdjustingPanel()).Change(onlineStudents[0]);
TCPManager.Instance.SendAdjusting(onlineStudents[0].ip,true);
}
private void ShowSetGroupError(string error)
{
if (error != null)
promptText_SetGroup.SetPrompt(error, Color.red, 2f);
}
//下发科目
private void SendSubject()
{
if (selectStudent.Count == 0)
{
sendSubPro.SetPrompt(LocalizationManager.Get("请选择席位!"), Color.red, 3f);
return;
}
if (dropdownState.value == 0)
{
sendSubPro.SetPrompt(LocalizationManager.Get("请选择训练模式!"), Color.red, 3f);
return;
}
if (selectRecord == null && dropdownSubject.value != 3)
{
sendSubPro.SetPrompt(LocalizationManager.Get("请选择想定文件!"), Color.red, 3f);
return;
}
if (dropdownSubject.value == 3 && dropdownState.value == 1)
{
sendSubPro.SetPrompt(LocalizationManager.Get("维修科目训练模式无需发送科目!"), Color.red, 3f);
return;
}
if (dropdownSubject.value == 3 && dropdownRepairSubject.value == 0)
{
sendSubPro.SetPrompt(LocalizationManager.Get("请选择维修案例!"), Color.red, 3f);
return;
}
List<int> groupNumbers = new List<int>();//梳理选中学员中 覆盖到的分组编号
List<OnlineStudent> soloStudent = new List<OnlineStudent>();
foreach (var item in selectStudent)
{
if (item.Value.state != LearnState.waiting)
{
sendSubPro.SetPrompt(LocalizationManager.Get("选择席位正在训练中,无法重复下发科目!"), Color.red, 3f);
return;
}
int gN = item.Value.groupNumber;
if (gN != -1)
{
if (!groupNumbers.Contains(gN))//不重复记录分组编号
groupNumbers.Add(gN);
}
else
{
soloStudent.Add(item.Value);//添加进入单人训练队列
}
}
if (groupNumbers.Count > 0)//存在分组训练学员
{
if (dropdownSubject.value == 1)//编队行军科目无法编队训练
{
sendSubPro.SetPrompt(LocalizationManager.Get("编队行军科目不支持协同训练!"), Color.red, 3f);
return;
}
for (int i = 0; i < groupNumbers.Count; i++)
{
SendGroupSub(groupManager.GetGroupStudents(groupNumbers[i]),groupNumbers[i]);
}
}
SendSub(soloStudent);//发送单人训练科目
}
//发送分组协同训练科目 梳理组员信息
private void SendGroupSub(List<OnlineStudent> groupStudents,int number)
{
NetLearnGroup groupMsg = new NetLearnGroup();
groupMsg.groupNumber = number;
for (int i = 0; i < groupStudents.Count; i++)
{
groupMsg.allStudents.Add(new SyncUser( groupStudents[i].ip,groupStudents[i].user));
if (groupStudents[i].isMaster)
groupMsg.masterIP = groupStudents[i].ip;
}
SendSub(groupStudents, groupMsg);
}
//下发训练科目 分组下发时设置分组信息
private void SendSub(List<OnlineStudent> studentsList,NetLearnGroup netGroupLearn = null)
{
foreach (var item in studentsList)
{
NetSubNameEnum subNameEnum = (NetSubNameEnum)dropdownSubject.value;
switch (subNameEnum)
{
case NetSubNameEnum.:
NetSub1Msg netSub1Msg = new NetSub1Msg();
netSub1Msg.recordClass = (SubRecordClass)selectRecord;
netSub1Msg.state = dropdownState.value;
netSub1Msg.weather = dropdownWeather.captionText.text;
netSub1Msg.isContinuity = continuous.isOn;
netSub1Msg.onboardGO = OnboardManager.Instance.onboardDic;
TCPManager.Instance.SendSubject(item.ip, subNameEnum, netSub1Msg);
break;
case NetSubNameEnum.:
NetSub2Msg netSub2Msg = new NetSub2Msg();
netSub2Msg.recordClass = (Sub2RecordClass)selectRecord;
netSub2Msg.state = dropdownState.value;
netSub2Msg.weather = dropdownWeather.captionText.text;
netSub2Msg.onboardGO = OnboardManager.Instance.onboardDic;
netSub2Msg.groupLearn = netGroupLearn;
TCPManager.Instance.SendSubject(item.ip, subNameEnum, netSub2Msg);
break;
case NetSubNameEnum.:
NetSub3Msg netSub3Msg = new NetSub3Msg();
netSub3Msg.caseName = $"案例{dropdownRepairSubject.value}";
netSub3Msg.weather = dropdownWeather.captionText.text;
netSub3Msg.groupLearn = netGroupLearn;
string langSuffix = "";
switch ((int)LocalizationManager.Language)
{
case 1: langSuffix = "_en"; break;
case 2: langSuffix = "_fr"; break;
case 3: langSuffix = "_ru"; break;
}
string xmlPath = Application.streamingAssetsPath + $"/XML/装备维修/维修{netSub3Msg.caseName}{langSuffix}.xml";
if (!System.IO.File.Exists(xmlPath))
xmlPath = Application.streamingAssetsPath + $"/XML/装备维修/维修{netSub3Msg.caseName}.xml";
netSub3Msg.fixLinks = (List<FixLink>)XmlHelper.DeserializeObject(xmlPath, typeof(List<FixLink>));//根据科目获取当前维修案例配置文件
TCPManager.Instance.SendSubject(item.ip, subNameEnum, netSub3Msg);
break;
default:
break;
}
ChangeLearnState(item.ip, dropdownSubject.captionText.text, (LearnState)(dropdownState.value));//改变学员当前的状态
}
sendSubPro.SetPrompt(LocalizationManager.Format("{0}科目成功下发!", dropdownSubject.captionText.text), Color.green, 3f);
}
//选择文件
void SelectFile()
{
string openFile = "";
if (dropdownSubject.value == 1)
openFile = Application.streamingAssetsPath + "/XML/编队行军";
else if (dropdownSubject.value == 2)
openFile = Application.streamingAssetsPath + "/XML/修理所展开";
string windowGetPath = OpenWindow.GetFilePath("选择想定文件", openFile, "想定文件(*.xml)\0*.xml\0");
if (windowGetPath != null)
{
selectFilePath = windowGetPath;
ShowFilePath();
LoadXMLFile(selectFilePath);
ShowFile();
}
}
private void ShowFilePath()
{
this.filePath.text = selectFilePath;
}
//编辑文件
private void EditorFile()
{
if (string.IsNullOrEmpty(selectFilePath))
{
editorPro.SetPrompt(LocalizationManager.Get("未选择想定文件!"), Color.red, 3f);
return;
}
BasePanel basePanel;
if (selectRecord.subName == NetSubNameEnum.)
{
basePanel= Push(new Subject1EditorCtrl());
}
else
basePanel= Push(new Subject2EditorCtrl());
basePanel.Change(selectRecord);
//basePanel.Change("InjectFilePath",);
//EventCenter.Instance.EventTrigger<RecordBase>("EditorFile", selectRecord);
}
//新建文件
private void NewFile()
{
if (dropdownSubject.value == 0 || dropdownSubject.value == 3)
{
newFilePro.SetPrompt(LocalizationManager.Get("未选择有效科目!"), Color.red, 3f);
return;
}
// EventCenter.Instance.EventTrigger<string>("CreatFile", dropdownSubject.value == 1 ? "Sub1" : "Sub2");
if (dropdownSubject.value == 1)
Push(new Subject1EditorCtrl());
else
Push(new Subject2EditorCtrl());
//ChangeNextPanel(null);
}
//加载文件
private void LoadXMLFile(string filePath)
{
if (filePath.Contains("编队行军"))
{
selectRecord = XmlHelper.DeserializeObject(filePath, typeof(SubRecordClass)) as RecordBase;
}
else if (filePath.Contains("修理所展开"))
{
selectRecord = XmlHelper.DeserializeObject(filePath, typeof(Sub2RecordClass)) as RecordBase;
}
else
selectRecord = null;
}
//显示文件概要信息
private void ShowFile()
{
fileDetail.text = selectRecord.fileIntr;
}
//弹出学员成绩面板
private void PopResultWindow(object result)
{
ResultMsgToUI resultMsg = result as ResultMsgToUI;
GameObject newWindow=null;
switch (resultMsg.resultMsg.subName)
{
case NetSubNameEnum.:
case NetSubNameEnum.:
newWindow = ResourcesCreater.InstantiatePrefab("Window_评估界面1", ActivePanel);//弹出成绩面板1
break;
case NetSubNameEnum.:
newWindow = ResourcesCreater.InstantiatePrefab("Windwo_装备维修评估界面", ActivePanel);//弹出成绩面板2
break;
}
if (newWindow != null)
{
newWindow.GetComponent<RectTransform>().anchoredPosition = new Vector2(0, 20);//初始化面板位置
newWindow.GetComponent<AppraiseWindowBase>().SetResultMsg(resultMsg.resultMsg, contentCtrl.GetStudentMsg(resultMsg.ip));//注入面板显示数据
//contentCtrl.ChangeStudentState(resultMsg.ip, "", LearnState.waiting);//更新传回成绩的学员状态为等待中
}
else
{
Debug.LogError("评估面板弹出失败");
}
}
//显示学员数量
private void ShowStudentCount(Vector3Int vector3Int)
{
LocalizationManager.SetFormatted(text_stuCount, "当前登录学员:{0},训练中:{1},考核中:{2},等待中:{3}", vector3Int.x + vector3Int.y + vector3Int.z, vector3Int.y, vector3Int.z, vector3Int.x);
}
//获取选中学员的数据
private List<OnlineStudent> GetStuList()
{
List<OnlineStudent> selectStu = new List<OnlineStudent>();
foreach (var item in selectStudent)
{
selectStu.Add(item.Value);
}
return selectStu;
}
}