EnergyEfficiencyManagement/Assets/Zion/Scripts/UIView/ExecuteSimulationView.cs

920 lines
34 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;
using System.Collections.Generic;
using UnityEngine;
using SK.Framework;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Linq;
using System;
using TMPro;
using System.Data;
using System.IO;
using OfficeOpenXml;
using System.Text;
using UnityEditor;
/// <summary>
/// 执行流程仿真
/// </summary>
public class ExecuteSimulationView : UIView
{
public Variables variables;
public List<Button> leftBtns = new List<Button>();
[System.Serializable]
public class ButtonData
{
public Sprite normalSprite;
public Sprite selectedSprite;
}
[SerializeField] private List<ButtonData> buttonData = new List<ButtonData>();
private Dictionary<Button, ButtonData> buttonDictionary = new Dictionary<Button, ButtonData>();
private Button _currentSelectedButton;
public List<GameObject> panels = new List<GameObject>();
// 存储所有Item的RectTransform便于索引查找
private List<RectTransform> itemTransforms = new List<RectTransform>();
// 运行时状态
private RectTransform draggedItem; // 当前被拖拽的Item
private GameObject placeholder; // 占位符对象
private int startDragIndex; // 开始拖拽时Item的索引
[Header("数据与测试")]
[Tooltip("示例数据列表实际项目中应替换为您的数据模型List")]
[SerializeField] private List<GameObject> dataList = new List<GameObject>();
//打字动画协程句柄,防止重复打字导致打字动画卡顿问题
private Coroutine typingCoroutine;
//打字动画速度,单位:秒/字符
private float typingSpeed = 0.05f;
//延时隐藏时间
private float hideAlarm = 3f;
private DataRecordSheet dataRecordSheet;
public List<BreakdownTaskItem> breakdownTaskItems = new List<BreakdownTaskItem>();
protected override void OnInit(IViewData data)
{
base.OnInit(data);
variables.Set<ExecuteSimulationView>("my_executeSimulation", this);
breakdownTaskItems.Clear();
breakdownTaskItems.Add(variables.Get<RectTransform>("子任务").GetComponent<BreakdownTaskItem>());
PanelInit();
PanelBtnsInit();
itemTransforms.Clear();
}
#region Tab页面切换
/// <summary>
/// Tab页初始化
/// </summary>
private void PanelInit()
{
if (!leftBtns.Count.Equals(panels.Count))
{
ShowWarming($"按钮和面板数量{leftBtns.Count}_{panels.Count}不匹配!");
return;
}
HideAllPanels();
InitLeftBtns();
SetSelectedButton(leftBtns[0]);
if (panels.Count > 0)
panels[0].Activate();
GetTaskList();
}
/// <summary>
/// 隐藏所有面板信息
/// </summary>
private void HideAllPanels()
{
foreach (var panel in panels)
{
if (panel != null)
panel.Deactivate();
}
}
/// <summary>
/// Tab页点击初始化
/// </summary>
/// <param name="index"></param>
private void OnPanelBtnClick(int index)
{
if (index < 0 || index >= panels.Count)
return;
HideAllPanels();
panels[index].Activate();
}
void InitLeftBtns()
{
// 初始化字典
for (int i = 0; i < leftBtns.Count; i++)
{
buttonDictionary[leftBtns[i]] = buttonData[i];
// 设置初始状态
Image img = leftBtns[i].GetComponent<Image>();
if (img != null)
{
img.sprite = buttonData[i].normalSprite;
}
// 添加点击事件
int index = i; // 闭包需要
leftBtns[i].onClick.AddListener(() => OnButtonSelected(leftBtns[index], index));
}
// 设置默认选中
if (leftBtns.Count > 0)
{
SetSelectedButton(leftBtns[0]);
}
}
private void OnButtonSelected(Button selectedButton, int index)
{
if (_currentSelectedButton == selectedButton) return;
// 取消上一个按钮的选中
if (_currentSelectedButton != null && buttonDictionary.ContainsKey(_currentSelectedButton))
{
Image prevImg = _currentSelectedButton.GetComponent<Image>();
if (prevImg != null)
{
prevImg.sprite = buttonDictionary[_currentSelectedButton].normalSprite;
}
}
HideAllPanels();
panels[index].Activate();
// 设置新按钮的选中
SetSelectedButton(selectedButton);
}
public void SetSelectedButton(Button button)
{
if (!buttonDictionary.ContainsKey(button))
{
Debug.LogWarning($"按钮 {button.name} 不在管理列表中");
return;
}
_currentSelectedButton = button;
Image img = button.GetComponent<Image>();
if (img != null)
{
img.sprite = buttonDictionary[button].selectedSprite;
}
}
#endregion
/// <summary>
/// 页面按钮点击初始化
/// </summary>
private void PanelBtnsInit()
{
variables.Get<Button>("关闭界面").onClick.AddListener(() =>
{
breakdownTaskItems.Clear();
Unload();
Load<HighEnergyConsumptionSTView>();
});
variables.Get<Button>("确认承接").onClick.AddListener(() =>
{
variables.Get<InputField>("起始日期").interactable = false;
variables.Get<InputField>("起始日期").GetComponent<EventTrigger>().triggers.Clear();
variables.Get<Button>("起始日期按钮").interactable = false;
variables.Get<InputField>("终止日期").interactable = false;
variables.Get<InputField>("终止日期").GetComponent<EventTrigger>().triggers.Clear();
variables.Get<Button>("终止日期按钮").interactable = false;
variables.Get<Button>("确认承接").interactable = false;
});
variables.Get<Button>("新增").onClick.AddListener(() =>
{
AddItemToScrollView(variables.Get<RectTransform>("子任务"), variables.Get<RectTransform>("子任务Content"));
//AddItemToScrollView(variables.Get<RectTransform>("准备工作子任务"), variables.Get<RectTransform>("准备工作Content"));
});
variables.Get<Button>("保存").onClick.AddListener(() =>
{
if (breakdownTaskItems.Where(a => a.timeInput.text.IsNullOrEmpty()).ToList().Count > 0
|| breakdownTaskItems.Where(a => a.nameInput.text.IsNullOrEmpty()).ToList().Count > 0
)
{
ShowWarming($"子任务名称或预计耗时未填写!");
}
else
{
variables.Get<Button>("新增").interactable = false;
variables.Get<Button>("保存").interactable = false;
float sum = 0;
for (int i = 0; i < breakdownTaskItems.Count; i++)
{
breakdownTaskItems[i].DisabledAll();
if (!breakdownTaskItems[i].timeInput.text.IsNullOrEmpty())
sum += float.Parse(breakdownTaskItems[i].timeInput.text);
}
variables.Get<Text>("总耗时").text = $"总耗时:{sum}天";
AddItemToTaskList();
AddItemToMaterialsList();
}
});
variables.Get<Button>("导出Excel").onClick.AddListener(() =>
{
ExportToExcel();
});
variables.Get<Button>("保存数据").onClick.AddListener(() =>
{
SaveDataRecordSheet();
});
variables.Get<Button>("保存报告").onClick.AddListener(() =>
{
SaveReport();
});
variables.Get<Button>("上传附件").onClick.AddListener(() =>
{
UploadFile();
});
variables.Get<Button>("导出PDF").onClick.AddListener(() =>
{
ExportPDF();
});
}
/// <summary>
/// 承接任务
/// </summary>
private void GetTaskList()
{
variables.Get<Text>("任务名称").text = UIUtils.Instance.ProjectName;
variables.Get<Text>("任务ID").text = UIUtils.Instance.GetUuid();
variables.Get<Text>("负责人").text = UIUtils.Instance.ProjectServiceTarget;
}
#region ScrollView部分
/// <summary>
/// 向滚动视图添加子项。
/// </summary>
/// <param name="item"></param>
/// <param name="scrollViewContent"></param>
private void AddItemToScrollView(RectTransform item, RectTransform scrollViewContent)
{
GameObject newItem = Instantiate(item.gameObject, scrollViewContent.transform);
newItem.Activate();
//AdjustContentLength(scrollViewContent);
if (newItem.GetComponent<BreakdownTaskItem>() != null)
{
BreakdownTaskItem breakdownTaskItem = newItem.GetComponent<BreakdownTaskItem>();
breakdownTaskItem.InitData();
breakdownTaskItems.Add(breakdownTaskItem);
Refresh();
}
}
/// <summary>
/// 添加子项到任务清单
/// </summary>
/// <param name="item"></param>
/// <param name="scrollViewContent"></param>
private void AddItemToTaskList()
{
BubbleSortList();
for (int i = 0; i < breakdownTaskItems.Count; i++)
{
GameObject newItem = Instantiate(variables.Get<RectTransform>("准备工作子任务").gameObject,
variables.Get<RectTransform>("准备工作Content").transform);
newItem.Activate();
newItem.transform.Find("顺序").GetComponent<Text>().text = (breakdownTaskItems[i].index + 1).ToString();
newItem.transform.Find("子任务名称输入框").GetComponent<InputField>().text = breakdownTaskItems[i].nameInput.text;
newItem.transform.Find("预计耗时输入框").GetComponent<InputField>().text = breakdownTaskItems[i].timeInput.text;
}
//AdjustContentLength(variables.Get<RectTransform>("准备工作Content"));
}
/// <summary>
/// 准备工作面板-添加物料准备清单
/// </summary>
private void AddItemToMaterialsList()
{
InventoryData inventoryData = JsonManager.LoadData<InventoryData>("BillofMaterials");
for (int i = 0; i < inventoryData.inventory.Count; i++)
{
GameObject newItem = Instantiate(variables.Get<RectTransform>("物料").gameObject,
variables.Get<RectTransform>("物料Content").transform);
newItem.Activate();
newItem.transform.Find("名称").GetComponent<Text>().text =$"名称:{inventoryData.inventory[i].type}";
newItem.transform.Find("数量").GetComponent<Text>().text = $"数量:{inventoryData.inventory[i].remaining}";
}
}
void BubbleSortList()
{
for (int i = 0; i < breakdownTaskItems.Count - 1; i++)
{
for (int j = 0; j < breakdownTaskItems.Count - 1 - i; j++)
{
if (breakdownTaskItems[j].index > breakdownTaskItems[j + 1].index)
{
BreakdownTaskItem temp = breakdownTaskItems[j];
breakdownTaskItems[j] = breakdownTaskItems[j + 1];
breakdownTaskItems[j + 1] = temp;
}
}
}
}
/// <summary>
/// 调整内容长度以适应子项数量和布局设置。
/// 计算内容长度,以便在滚动视图中正确显示所有子项。
/// </summary>
/// <param name="contentRect"></param>
private void AdjustContentLength(RectTransform contentRect)
{
GridLayoutGroup gridLayout = contentRect.GetComponent<GridLayoutGroup>();
int childCount = contentRect.childCount;
if (childCount == 0) return;
Vector2 cellSize = gridLayout.cellSize;
Vector2 spacing = gridLayout.spacing;
GridLayoutGroup.Constraint constraint = gridLayout.constraint;
int constraintCount = gridLayout.constraintCount;
GridLayoutGroup.Axis startAxis = gridLayout.startAxis;
int rows = 1;
int columns = 1;
// 根据Grid Layout Group设置计算行和列
if (startAxis == GridLayoutGroup.Axis.Vertical) // 垂直排列
{
switch (constraint)
{
case GridLayoutGroup.Constraint.FixedColumnCount:
columns = constraintCount;
rows = Mathf.CeilToInt((float)childCount / columns);
break;
case GridLayoutGroup.Constraint.FixedRowCount:
rows = constraintCount;
columns = Mathf.CeilToInt((float)childCount / rows);
break;
case GridLayoutGroup.Constraint.Flexible: // Flexible模式
float contentWidth = contentRect.rect.width;
if (contentWidth > 0)
{
columns = Mathf.FloorToInt((contentWidth + spacing.x) / (cellSize.x + spacing.x));
if (columns < 1) columns = 1;
rows = Mathf.CeilToInt((float)childCount / columns);
}
else
{
columns = 1;
rows = childCount;
}
break;
}
}
else // 水平排列
{
switch (constraint)
{
case GridLayoutGroup.Constraint.FixedColumnCount:
columns = constraintCount;
rows = Mathf.CeilToInt((float)childCount / columns);
break;
case GridLayoutGroup.Constraint.FixedRowCount:
rows = constraintCount;
columns = Mathf.CeilToInt((float)childCount / rows);
break;
case GridLayoutGroup.Constraint.Flexible: // Flexible模式
float contentHeight = contentRect.rect.height;
if (contentHeight > 0)
{
rows = Mathf.FloorToInt((contentHeight + spacing.y) / (cellSize.y + spacing.y));
if (rows < 1) rows = 1;
columns = Mathf.CeilToInt((float)childCount / rows);
}
else
{
rows = 1;
columns = childCount;
}
break;
}
}
// 计算所需Content尺寸
float requiredWidth = columns * cellSize.x + Mathf.Max(0, columns - 1) * spacing.x;
float requiredHeight = rows * cellSize.y + Mathf.Max(0, rows - 1) * spacing.y;
// 更新Content大小
contentRect.sizeDelta = new Vector2(requiredWidth, requiredHeight);
}
/*
/// <summary>
/// 【核心方法】为实例化好的Item GameObject 绑定拖拽功能。
/// 在您自己的实例化代码中在Instantiate之后调用此方法。
/// </summary>
/// <param name="itemRectTransform">Item的RectTransform组件</param>
/// <param name="index">该Item在列表中的初始索引</param>
public void SetupDraggableItem(RectTransform itemRectTransform, int index, RectTransform content, GridLayoutGroup gridLayoutGroup)
{
if (itemRectTransform == null) return;
// 确保Item有CanvasGroup组件用于在拖拽时屏蔽射线检测
CanvasGroup cg = itemRectTransform.gameObject.GetComponent<CanvasGroup>();
if (cg == null) cg = itemRectTransform.gameObject.AddComponent<CanvasGroup>();
// 添加或获取EventTrigger组件
EventTrigger eventTrigger = itemRectTransform.gameObject.GetComponent<EventTrigger>();
if (eventTrigger == null) eventTrigger = itemRectTransform.gameObject.AddComponent<EventTrigger>();
// 清除旧的事件(避免重复绑定),然后添加三个必要的事件监听
eventTrigger.triggers.Clear();
// 1. 开始拖拽事件
EventTrigger.Entry beginDragEntry = new EventTrigger.Entry();
beginDragEntry.eventID = EventTriggerType.BeginDrag;
beginDragEntry.callback.AddListener((data) => { OnBeginDrag(itemRectTransform, index, content); });
eventTrigger.triggers.Add(beginDragEntry);
// 2. 拖拽中事件
EventTrigger.Entry dragEntry = new EventTrigger.Entry();
dragEntry.eventID = EventTriggerType.Drag;
dragEntry.callback.AddListener((data) => { OnDrag(content); });
eventTrigger.triggers.Add(dragEntry);
// 3. 结束拖拽事件
EventTrigger.Entry endDragEntry = new EventTrigger.Entry();
endDragEntry.eventID = EventTriggerType.EndDrag;
endDragEntry.callback.AddListener((data) => { OnEndDrag(itemRectTransform, content, gridLayoutGroup); });
eventTrigger.triggers.Add(endDragEntry);
// 将Item添加到跟踪列表
if (!itemTransforms.Contains(itemRectTransform))
{
itemTransforms.Add(itemRectTransform);
}
}
// --- 事件处理函数 ---
private void OnBeginDrag(RectTransform item, int index, RectTransform content)
{
draggedItem = item;
startDragIndex = index;
Debug.Log($"开始拖拽: {item.name}, 起始索引: {startDragIndex}");
// 1. 创建占位符保持原Item的尺寸
placeholder = new GameObject("Placeholder");
placeholder.transform.SetParent(content, false);
LayoutElement le = placeholder.AddComponent<LayoutElement>();
le.preferredWidth = item.sizeDelta.x;
le.preferredHeight = item.sizeDelta.y;
// 将占位符放在被拖拽Item原来的位置
placeholder.transform.SetSiblingIndex(startDragIndex);
// 2. 使被拖拽Item暂时脱离布局控制并置于顶层
item.SetParent(content.parent.parent, true); // 通常设为Canvas或ScrollView的父级
item.GetComponent<CanvasGroup>().blocksRaycasts = false; // 禁止接收射线,防止事件冲突
}
private void OnDrag(RectTransform content)
{
if (draggedItem == null || placeholder == null) return;
// 1. 让被拖拽的Item跟随鼠标/触摸位置
RectTransformUtility.ScreenPointToWorldPointInRectangle(
content,
Input.mousePosition,
null,
out Vector3 worldPoint
);
draggedItem.position = worldPoint;
// 2. 计算并更新占位符的新位置(决定插入点)
// 该方法适用于垂直布局。对于水平布局需比较X轴位置。
int newSiblingIndex = content.childCount; // 默认放在最后
for (int i = 0; i < content.childCount; i++)
{
// 跳过占位符自己
if (content.GetChild(i) == placeholder.transform) continue;
// 比较Y坐标从上到下递减的布局。可根据您的布局方向调整比较逻辑。
if (draggedItem.position.y > content.GetChild(i).position.y)
{
newSiblingIndex = i;
// 一个小调整:如果从下往上拖,索引需要修正
if (placeholder.transform.GetSiblingIndex() < newSiblingIndex)
{
newSiblingIndex--;
}
break;
}
}
// 应用新的位置索引
placeholder.transform.SetSiblingIndex(newSiblingIndex);
}
private void OnEndDrag(RectTransform item, RectTransform content, GridLayoutGroup contentLayoutGroup)
{
if (draggedItem == null || placeholder == null) return;
// 1. 恢复被拖拽Item的状态
item.SetParent(content, true);
// 将Item放到占位符所在的位置
item.SetSiblingIndex(placeholder.transform.GetSiblingIndex());
item.GetComponent<CanvasGroup>().blocksRaycasts = true; // 恢复交互
// 2. 销毁占位符
Destroy(placeholder);
placeholder = null;
// 3. 计算新的数据索引并更新数据列表
int endDragIndex = item.GetSiblingIndex();
UpdateDataOrder(startDragIndex, endDragIndex);
// 4. 可选:强制布局组件立即重新计算,避免视觉延迟
if (contentLayoutGroup != null)
{
LayoutRebuilder.ForceRebuildLayoutImmediate(content);
}
// 5. 更新itemTransforms列表的顺序以匹配新的UI顺序
RefreshItemTransformList(content);
Debug.Log($"拖拽结束。Item从索引 {startDragIndex} 移动到 {endDragIndex}");
Debug.Log("当前数据顺序: " + string.Join(", ", dataList));
draggedItem = null;
}
/// <summary>
/// 更新底层数据列表的顺序以匹配UI变化。
/// 这是整个拖拽排序功能的核心确保数据与UI同步。
/// </summary>
private void UpdateDataOrder(int fromIndex, int toIndex)
{
if (fromIndex == toIndex) return;
if (fromIndex < 0 || fromIndex >= dataList.Count) return;
if (toIndex < 0 || toIndex >= dataList.Count) return;
// 移动数据
GameObject movedData = dataList[fromIndex];
dataList.RemoveAt(fromIndex);
dataList.Insert(toIndex, movedData);
// 这里可以触发一个自定义事件,通知其他游戏系统数据顺序已改变
// OnDataOrderChanged?.Invoke(dataList);
}
/// <summary>
/// 根据Content下Item当前的顺序刷新itemTransforms列表。
/// </summary>
private void RefreshItemTransformList(RectTransform content)
{
itemTransforms.Clear();
foreach (Transform child in content)
{
RectTransform rt = child.GetComponent<RectTransform>();
if (rt != null && !child.name.Contains("Placeholder")) // 排除占位符
{
itemTransforms.Add(rt);
}
}
}*/
#endregion
/// <summary>
/// 导出Excel
/// </summary>
private void ExportToExcel()
{
string defaultFileName = $"{""}_{DateTime.Now:yyyyMMdd_HHmmss}.xlsx";
string outputPath = EditorUtility.SaveFilePanel("保存Excel文件", "", defaultFileName, "xlsx");
if (!string.IsNullOrEmpty(outputPath))
{
FileInfo file = new FileInfo(outputPath);
ExcelPackage package = new ExcelPackage(file);
ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("sheet1");
worksheet.Cells[1, 1, 1, 4].Merge = true;
worksheet.Cells[1, 1].Value = "任务清单";
worksheet.Cells[1, 1].Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center;
worksheet.Cells[1, 1].Style.Font.Bold = true;
for (int i = 1; i <= breakdownTaskItems.Count; i++)
{
Debug.Log(i);
worksheet.Cells[$"A{i*2}:A{i*2+1}"].Merge = true;
worksheet.Cells[$"A{i*2}:A{i*2+1}"].Style.VerticalAlignment = OfficeOpenXml.Style.ExcelVerticalAlignment.Center;
worksheet.Cells[$"A{i*2}:A{i*2+1}"].Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center;
worksheet.Cells[$"A{i*2}:A{i*2+1}"].Value = i;
worksheet.Cells[$"B{i*2}"].Value = "子任务名称";
worksheet.Cells[$"B{i*2+1}"].Value ="预计耗时(天)";
worksheet.Cells[$"C{i*2}"].Value = breakdownTaskItems[i-1].nameInput.text;
worksheet.Cells[$"C{i*2+1}"].Value =breakdownTaskItems[i-1].timeInput.text;
}
int row = (breakdownTaskItems.Count*2+2);
worksheet.Cells[row, 1, row, 4].Merge = true;
worksheet.Cells[row, 1].Value = "诊断方案";
worksheet.Cells[row, 1].Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center;
worksheet.Cells[row, 1].Style.Font.Bold = true;
row++;
worksheet.Cells[row, 1, row, 4].Merge = true;
worksheet.Cells[row, 1].Value = variables.Get<Dropdown>("诊断方案").options[variables.Get<Dropdown>("诊断方案").value].text;
row++;
worksheet.Cells[row, 1, row, 4].Merge = true;
worksheet.Cells[row, 1].Value = "物料准备清单";
worksheet.Cells[row, 1].Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center;
worksheet.Cells[row, 1].Style.Font.Bold = true;
row++;
for (int i = 0; i < variables.Get<RectTransform>("物料准备清单").transform.childCount; i++)
{
worksheet.Cells[$"A{row}:A{row+1}"].Merge = true;
worksheet.Cells[$"A{row}:A{row+1}"].Style.VerticalAlignment = OfficeOpenXml.Style.ExcelVerticalAlignment.Center;
worksheet.Cells[$"A{row}:A{row + 1}"].Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center;
worksheet.Cells[$"A{row}:A{row + 1}"].Value = i;
worksheet.Cells[$"B{row}"].Value = variables.Get<RectTransform>("物料准备清单").GetComponentsInChildren<Text>()[0].text;
worksheet.Cells[$"B{row+1}"].Value = variables.Get<RectTransform>("物料准备清单").GetComponentsInChildren<Text>()[1].text;
row++;
}
worksheet.Cells.AutoFitColumns();
package.Save();
Debug.Log("导出Excel成功");
}
}
/// <summary>
/// 保存数据记录表
/// </summary>
private void SaveDataRecordSheet()
{
if (!UIUtils.Instance.IsInputCorrect(variables.Get<InputField>("运行时长")) ||
!UIUtils.Instance.IsInputCorrect(variables.Get<InputField>("当前能耗")) ||
!UIUtils.Instance.IsInputCorrect(variables.Get<InputField>("功率")) ||
!UIUtils.Instance.IsInputCorrect(variables.Get<InputField>("温度")))
{
ShowWarming("有数据未记录"); return;
}
dataRecordSheet = new DataRecordSheet
{
Model = variables.Get<Dropdown>("设备型号").options[variables.Get<Dropdown>("设备型号").value].text,
RuntimeDuration = float.Parse(variables.Get<InputField>("运行时长").text),
CurrentEnergyConsumption = float.Parse(variables.Get<InputField>("当前能耗").text),
Power = float.Parse(variables.Get<InputField>("功率").text),
Temperature = float.Parse(variables.Get<InputField>("温度").text)
};
variables.Get<Button>("保存数据").interactable = false;
variables.Get<Dropdown>("设备型号").interactable = false;
variables.Get<InputField>("运行时长").interactable = false;
variables.Get<InputField>("当前能耗").interactable = false;
variables.Get<InputField>("功率").interactable = false;
variables.Get<InputField>("温度").interactable = false;
}
/// <summary>
/// 保存报告
/// </summary>
private void SaveReport()
{
variables.Get<InputField>("设备现状输入框").interactable = false;
variables.Get<InputField>("数据对比输入框").interactable = false;
variables.Get<InputField>("问题清单输入框").interactable = false;
variables.Get<InputField>("节能方案输入框").interactable = false;
variables.Get<Button>("上传附件").interactable = false;
//variables.Get<Button>("导出PDF").interactable = false;
//-------------------------------------------------------------
variables.Get<InputField>("设备现状输入框-解读").text = variables.Get<InputField>("设备现状输入框").text;
variables.Get<InputField>("数据对比输入框-解读").text = variables.Get<InputField>("数据对比输入框").text;
variables.Get<InputField>("问题清单输入框-解读").text = variables.Get<InputField>("问题清单输入框").text;
variables.Get<InputField>("节能方案输入框-解读").text = variables.Get<InputField>("节能方案输入框").text;
Transform attachmentContainer = variables.Get<RectTransform>("附件展示框-解读");
foreach (var item in variables.Get<RectTransform>("附件展示框").GetComponentsInChildren<AttachmentItem>())
{
GameObject attachmentGO = Instantiate(item.gameObject, attachmentContainer);
AttachmentItem attachmentItem = attachmentGO.GetComponent<AttachmentItem>();
attachmentItem.Initialize(item.filePath, FileUploadManager.Instance.GetFileIcon(item.filePath), OnAttachmentRemoved);
attachmentItem.removeButton.gameObject.SetActive(false);
}
//variables.Get<InputField>("上传附件-解读").interactable = false;
}
/// <summary>
/// 上传附件
/// </summary>
private void UploadFile()
{
// 使用FileUploadManager选择文件
FileUploadManager.Instance.SelectAndUploadFile((filePath) =>
{
if (!string.IsNullOrEmpty(filePath))
{
// 获取文件图标
Sprite fileIcon = FileUploadManager.Instance.GetFileIcon(filePath);
// 创建附件项
CreateAttachmentItem(filePath, fileIcon);
}
});
}
/// <summary>
/// 导出PDF
/// </summary>
private void ExportPDF()
{
string title = "能效诊断报告";
string content = $@"
设备现状
{variables.Get<InputField>("").text}
{variables.Get<InputField>("数据对比输入框").text}
{variables.Get<InputField>("问题清单输入框").text}
{variables.Get<InputField>("节能方案输入框").text}
";
// 执行PDF导出
PdfExportManager.Instance.SelectAndExportPdf(title, content, (success, message) =>
{
Debug.Log($"PDF导出测试结果: {message}");
});
}
/// <summary>
/// 创建附件项
/// </summary>
/// <param name="filePath">文件路径</param>
/// <param name="fileIcon">文件图标</param>
private void CreateAttachmentItem(string filePath, Sprite fileIcon)
{
// 获取附件容器
Transform attachmentContainer = variables.Get<RectTransform>("附件展示框");
if (attachmentContainer == null)
{
Debug.LogError("未找到附件容器请确保UI中存在名为'附件展示框'的Transform");
return;
}
// 查找AttachmentItem预制件
GameObject attachmentPrefab = Resources.Load<GameObject>("Prefabs/AttachmentItem");
if (attachmentPrefab == null)
{
Debug.LogError("未找到预制体路径");
}
else
{
// 实例化预制件
GameObject attachmentGO = Instantiate(attachmentPrefab, attachmentContainer);
AttachmentItem attachmentItem = attachmentGO.GetComponent<AttachmentItem>();
if (attachmentItem == null)
{
attachmentItem = attachmentGO.AddComponent<AttachmentItem>();
// 创建UI元素
}
LayoutRebuilder.ForceRebuildLayoutImmediate(variables.Get<ScrollRect>("报告生成").content);
// 初始化附件项
attachmentItem.Initialize(filePath, fileIcon, OnAttachmentRemoved);
variables.Get<ScrollRect>("报告生成").verticalNormalizedPosition = 0;
Canvas.ForceUpdateCanvases();
PdfExportManager.Instance.AddAttachment(filePath);
}
}
/// <summary>
/// 附件移除回调
/// </summary>
/// <param name="attachmentItem">被移除的附件项</param>
private void OnAttachmentRemoved(AttachmentItem attachmentItem)
{
if (attachmentItem != null)
{
PdfExportManager.Instance.RemoveAttachment(attachmentItem.filePath);
Destroy(attachmentItem.gameObject);
}
}
public void Refresh()
{
if (breakdownTaskItems.Count == 0) return;
for (int i = 0; i < breakdownTaskItems.Count; i++)
{
int index = i;
//breakdownTaskItems[i].SetCurrentIndex =index;
breakdownTaskItems[i].Refresh();
}
}
#region
/// <summary>
/// 显示警告信息
/// </summary>
/// <param name="warmingText"></param>
public void ShowWarming(string warmingText)
{
if (string.IsNullOrEmpty(warmingText.Trim())) return;
if (!variables.Get<RectTransform>("警告").gameObject.activeSelf)
variables.Get<RectTransform>("警告").gameObject.Activate();
// 快速完成打字
if (typingCoroutine != null)
StopCoroutine(typingCoroutine);
//开启打字效果
typingCoroutine = StartCoroutine(TypeText(warmingText));
}
/// <summary>
/// 打字效果协程,逐个字符显示文本。
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
private IEnumerator TypeText(string text)
{
variables.Get<Text>("警告文本").text = "";
foreach (char letter in text.ToCharArray())
{
variables.Get<Text>("警告文本").text += letter;
yield return new WaitForSeconds(typingSpeed);
}
yield return new WaitForSeconds(hideAlarm);
variables.Get<RectTransform>("警告").gameObject.SetActive(false);
}
#endregion
}
/// <summary>
/// 数据记录表
/// </summary>
public class DataRecordSheet
{
/// <summary>
/// 型号
/// </summary>
public string Model { get; set; }
/// <summary>
/// 运行时长
/// </summary>
public float RuntimeDuration { get; set; }
/// <summary>
/// 当前能耗
/// </summary>
public float CurrentEnergyConsumption { get; set; }
/// <summary>
/// 功率
/// </summary>
public float Power { get; set; }
/// <summary>
/// 温度
/// </summary>
public float Temperature { get; set; }
}