285 lines
9.7 KiB
C#
285 lines
9.7 KiB
C#
using Newtonsoft.Json;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
namespace Samkwang
|
|
{
|
|
public class Panel_ProductionProgress : UIPopupBase
|
|
{
|
|
private string dataOrder;
|
|
|
|
public Dictionary<int, UI_StatusContent> statusContents = new Dictionary<int, UI_StatusContent>();
|
|
private List<CompleteInfo> cachedSortedCompleteInfos = new List<CompleteInfo>();
|
|
private UI_StatusContent prf_statusContent;
|
|
public RectTransform Content;
|
|
public RectTransform Image_Loading;
|
|
public Button Button_Close;
|
|
public TextMeshProUGUI CurrentDate;
|
|
public TextMeshProUGUI CurrentTime;
|
|
|
|
public int statusItemsCount;
|
|
private int currentContentIndex;
|
|
private bool isChangedData;
|
|
|
|
public float changeDataTime;
|
|
public float fadeTime;
|
|
|
|
public Action<string> onClose;
|
|
|
|
public void Init()
|
|
{
|
|
dataOrder = Resources.Load<TextAsset>("DataOrder").text;
|
|
|
|
var textDict = transform.GetChildComponentsByName<TextMeshProUGUI>();
|
|
var buttonDict = transform.GetChildComponentsByName<Button>();
|
|
var rectDict = transform.GetChildComponentsByName<RectTransform>();
|
|
|
|
CurrentDate = textDict.GetOrNull(nameof(CurrentDate));
|
|
CurrentTime = textDict.GetOrNull(nameof(CurrentTime));
|
|
Content = rectDict.GetOrNull(nameof(Content));
|
|
Image_Loading = rectDict.GetOrNull(nameof(Image_Loading));
|
|
Button_Close = buttonDict.GetOrNull(nameof(Button_Close));
|
|
|
|
prf_statusContent = Resources.Load<UI_StatusContent>("Prefabs/UI/UI_StatusContent");
|
|
Button_Close.onClick.AddListener(Close);
|
|
SetDate();
|
|
|
|
Image_Loading.gameObject.SetActive(true);
|
|
Close();
|
|
}
|
|
public void Update()
|
|
{
|
|
SetTime();
|
|
}
|
|
public override void Open()
|
|
{
|
|
gameObject.SetActive(true);
|
|
gameObject.transform.SetAsLastSibling();
|
|
|
|
StopAllCoroutines();
|
|
StartCoroutine(ScaleUp());
|
|
|
|
if (statusContents.Count <= 0)
|
|
{
|
|
isChangedData = false;
|
|
return;
|
|
}
|
|
|
|
StartCoroutine(ChageStatusContent());
|
|
}
|
|
public override void Close()
|
|
{
|
|
onClose?.Invoke("ProductionProgress");
|
|
gameObject.SetActive(false);
|
|
gameObject.transform.localScale = Vector3.zero;
|
|
ResetStatusContentOrder();
|
|
isChangedData = false;
|
|
}
|
|
private IEnumerator ChageStatusContent()
|
|
{
|
|
isChangedData = true;
|
|
|
|
currentContentIndex = 0;
|
|
|
|
statusContents[currentContentIndex].gameObject.transform.SetAsFirstSibling();
|
|
currentContentIndex++;
|
|
|
|
var wfs = new WaitForSeconds(changeDataTime);
|
|
while (true)
|
|
{
|
|
yield return wfs;
|
|
|
|
if (currentContentIndex >= statusContents.Values.Count)
|
|
{
|
|
currentContentIndex = 0;
|
|
}
|
|
|
|
statusContents[currentContentIndex].gameObject.transform.SetAsFirstSibling();
|
|
currentContentIndex++;
|
|
}
|
|
}
|
|
private void ResetStatusContentOrder()
|
|
{
|
|
foreach (var statusContent in statusContents.Values)
|
|
{
|
|
statusContent.gameObject.transform.SetAsFirstSibling();
|
|
}
|
|
}
|
|
|
|
public void SetProductionStatus(List<CompleteInfo> machineInfos)
|
|
{
|
|
Image_Loading.gameObject.SetActive(false);
|
|
|
|
var sortMachineInfos = SortListByWorknm(machineInfos);
|
|
cachedSortedCompleteInfos = sortMachineInfos;
|
|
var splitCompleteInfo = SplitArray(sortMachineInfos, statusItemsCount);
|
|
SetProductionContent(splitCompleteInfo);
|
|
}
|
|
public void SetProductionStatus(List<OneHourInfo> oneHourInfos)
|
|
{
|
|
var alignedOneHourInfos = AlignOneHourInfoToCompleteInfo(oneHourInfos);
|
|
|
|
var splitOneHourInfo = SplitArray(alignedOneHourInfos, statusItemsCount);
|
|
SetProductionContent(splitOneHourInfo);
|
|
}
|
|
|
|
private List<OneHourInfo> AlignOneHourInfoToCompleteInfo(List<OneHourInfo> oneHourInfos)
|
|
{
|
|
if (cachedSortedCompleteInfos == null || cachedSortedCompleteInfos.Count == 0)
|
|
{
|
|
return new List<OneHourInfo>();
|
|
}
|
|
|
|
var oneHourMap = new Dictionary<string, OneHourInfo>();
|
|
foreach (var info in oneHourInfos)
|
|
{
|
|
if (!string.IsNullOrEmpty(info.wordno) && !oneHourMap.ContainsKey(info.wordno))
|
|
{
|
|
oneHourMap.Add(info.wordno, info);
|
|
}
|
|
}
|
|
|
|
var resultList = new List<OneHourInfo>();
|
|
|
|
foreach (var completeInfo in cachedSortedCompleteInfos)
|
|
{
|
|
if (!string.IsNullOrEmpty(completeInfo.wordno) &&
|
|
oneHourMap.TryGetValue(completeInfo.wordno, out var matchedOneHour))
|
|
{
|
|
// UI_StatusContent는 딕셔너리 키를 worknm으로 쓰고 있음.
|
|
// 매칭된 OneHourInfo의 이름을 CompleteInfo의 이름(UI 키값)으로 덮어씌워야 UI가 찾을 수 있음.
|
|
matchedOneHour.worknm = completeInfo.worknm;
|
|
|
|
resultList.Add(matchedOneHour);
|
|
}
|
|
else
|
|
{
|
|
// 매칭 실패: 데이터가 없어도 자리는 차지해야 함 (null 추가)
|
|
// 그래야 15번째 설비가 2페이지(인덱스상 뒤쪽)로 밀려날 수 있음.
|
|
resultList.Add(null);
|
|
}
|
|
}
|
|
|
|
return resultList;
|
|
}
|
|
public List<CompleteInfo> SortListByWorknm(List<CompleteInfo> machineInfos)
|
|
{
|
|
var workcdOrder = JsonConvert.DeserializeObject<List<string>>(dataOrder);
|
|
var orderMap = workcdOrder.Select((workcd, index) => new { workcd, index }).ToDictionary(x => x.workcd, x => x.index);
|
|
|
|
return machineInfos.Where(field => orderMap.ContainsKey(field.worknm)).OrderBy(field => orderMap[field.worknm]).ToList();
|
|
}
|
|
|
|
public void SetProductionContent(List<List<CompleteInfo>> splitCompleteInfo)
|
|
{
|
|
for (int i = 0; i < splitCompleteInfo.Count; i++)
|
|
{
|
|
if (!statusContents.ContainsKey(i))
|
|
{
|
|
var statusContent = Instantiate(prf_statusContent, Content);
|
|
statusContent.Init();
|
|
statusContent.SetProductionStatusItem(splitCompleteInfo[i]);
|
|
statusContents.Add(i, statusContent);
|
|
}
|
|
else
|
|
{
|
|
statusContents[i].SetProductionStatusItem(splitCompleteInfo[i]);
|
|
}
|
|
}
|
|
|
|
if (!isChangedData && gameObject.activeSelf)
|
|
{
|
|
StopAllCoroutines();
|
|
StartCoroutine(ChageStatusContent());
|
|
}
|
|
}
|
|
public void SetProductionContent(List<List<OneHourInfo>> splitOneHourInfos)
|
|
{
|
|
for (int i = 0; i < splitOneHourInfos.Count; i++)
|
|
{
|
|
if (statusContents.ContainsKey(i))
|
|
{
|
|
statusContents[i].SetProductionStatusItem(splitOneHourInfos[i]);
|
|
}
|
|
}
|
|
|
|
if (!isChangedData && gameObject.activeSelf)
|
|
{
|
|
StopAllCoroutines();
|
|
StartCoroutine(ChageStatusContent());
|
|
}
|
|
}
|
|
private List<List<CompleteInfo>> SplitArray(List<CompleteInfo> machineInfos, int groupSize)
|
|
{
|
|
List<List<CompleteInfo>> result = new List<List<CompleteInfo>>();
|
|
int totalGroups = Mathf.CeilToInt(machineInfos.Count / (float)groupSize);
|
|
|
|
for (int i = 0; i < totalGroups; i++)
|
|
{
|
|
int startIndex = i * groupSize;
|
|
int endIndex = Mathf.Min(startIndex + groupSize, machineInfos.Count);
|
|
|
|
List<CompleteInfo> group = new List<CompleteInfo>();
|
|
for (int j = startIndex; j < endIndex; j++)
|
|
{
|
|
group.Add(machineInfos[j]);
|
|
}
|
|
|
|
result.Add(group);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
private List<List<OneHourInfo>> SplitArray(List<OneHourInfo> machineInfos, int groupSize)
|
|
{
|
|
List<List<OneHourInfo>> result = new List<List<OneHourInfo>>();
|
|
int totalGroups = Mathf.CeilToInt(machineInfos.Count / (float)groupSize);
|
|
|
|
for (int i = 0; i < totalGroups; i++)
|
|
{
|
|
int startIndex = i * groupSize;
|
|
int endIndex = Mathf.Min(startIndex + groupSize, machineInfos.Count);
|
|
|
|
List<OneHourInfo> group = new List<OneHourInfo>();
|
|
for (int j = startIndex; j < endIndex; j++)
|
|
{
|
|
group.Add(machineInfos[j]);
|
|
}
|
|
|
|
result.Add(group);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
public void SetDate()
|
|
{
|
|
CurrentDate.text = DateTime.Now.ToString("yyyy-MM-dd");
|
|
}
|
|
public void SetTime()
|
|
{
|
|
CurrentTime.text = DateTime.Now.ToString("HH:mm");
|
|
}
|
|
IEnumerator ScaleUp()
|
|
{
|
|
float timer = 0f;
|
|
float percent = 0f;
|
|
|
|
while (percent < 1)
|
|
{
|
|
timer += Time.deltaTime;
|
|
percent = timer / fadeTime;
|
|
transform.localScale = Vector3.Lerp(transform.localScale, Vector3.one, percent);
|
|
|
|
yield return null;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|