580 lines
21 KiB
C#
580 lines
21 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using DefaultNamespace.ProcessMode;
|
||
using Framework.Manager;
|
||
using MotionFramework;
|
||
using TMPro;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
using ProcessMode = DefaultNamespace.ProcessMode.ProcessMode;
|
||
|
||
namespace Zion.Scripts.ERP.库存物资查询报表
|
||
{
|
||
public class LedgerTransferPostingManager : MonoBehaviour
|
||
{
|
||
public TMP_InputField[] batchs; //批次输入框数组
|
||
public TMP_InputField[] materialCodes; // 物料编码输入框数组
|
||
public TMP_InputField[] storageLocations; // 库存地点输入框数组
|
||
public TMP_InputField[] factories; // 工厂输入框数组
|
||
public TMP_InputField[] movementReasons; // 移动原因输入框数组
|
||
public TMP_InputField[] quantities; // 数量输入框数组
|
||
|
||
public TMP_Dropdown quantitiesDropdown;
|
||
public TMP_Dropdown quantitiesDropdown2;
|
||
|
||
|
||
public Button queryButton;
|
||
public Button jianchaButton;
|
||
public TMP_Text titleText;
|
||
|
||
public bool onlyFirst = false;
|
||
public AutoHideScript autoHideScript;
|
||
|
||
// 输入顺序验证相关变量
|
||
private bool isMaterialCodeCompleted = false; // 物料编码是否完成
|
||
private bool isStorageLocationCompleted = false; // 库存地点是否完成
|
||
private bool isFactoryCompleted = false; // 工厂是否完成
|
||
private bool isInputOrderValid = true; // 输入顺序是否有效
|
||
|
||
// 模式管理相关变量
|
||
private ProcessMode _cachedCurrentMode; // 缓存的当前模式
|
||
|
||
/// <summary>
|
||
/// 获取当前是否为教学模式
|
||
/// </summary>
|
||
private bool IsTeachingMode => _cachedCurrentMode == ProcessMode.教学模式;
|
||
|
||
private void Start()
|
||
{
|
||
queryButton.onClick.AddListener(() => OnQueryButtonClicked());
|
||
jianchaButton.onClick.AddListener(delegate
|
||
{
|
||
autoHideScript.ShowObject("已检查");
|
||
TutorialGuideManager.Instance.TriggerNextGuide(jianchaButton.name);
|
||
});
|
||
|
||
// 初始化输入验证系统
|
||
InitializeInputValidation();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 初始化下拉框默认选择
|
||
/// </summary>
|
||
private void InitializeDropdowns()
|
||
{
|
||
// 初始化quantitiesDropdown默认选择第一个选项
|
||
if (quantitiesDropdown != null && quantitiesDropdown.options.Count > 0)
|
||
{
|
||
quantitiesDropdown.value = 0;
|
||
Debug.Log($"quantitiesDropdown默认选择: {quantitiesDropdown.options[0].text}");
|
||
}
|
||
else
|
||
{
|
||
Debug.LogWarning("quantitiesDropdown为null或没有选项");
|
||
}
|
||
|
||
// 初始化quantitiesDropdown2默认选择第一个选项
|
||
if (quantitiesDropdown2 != null && quantitiesDropdown2.options.Count > 0)
|
||
{
|
||
quantitiesDropdown2.value = 0;
|
||
Debug.Log($"quantitiesDropdown2默认选择: {quantitiesDropdown2.options[0].text}");
|
||
}
|
||
else
|
||
{
|
||
Debug.LogWarning("quantitiesDropdown2为null或没有选项");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 初始化输入验证系统
|
||
/// </summary>
|
||
private void InitializeInputValidation()
|
||
{
|
||
// 缓存当前模式
|
||
CacheCurrentMode();
|
||
|
||
// 为所有输入框添加值变化监听
|
||
AddInputFieldListeners();
|
||
|
||
// 初始化输入框状态
|
||
UpdateInputFieldStates();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 缓存当前模式
|
||
/// </summary>
|
||
private void CacheCurrentMode()
|
||
{
|
||
try
|
||
{
|
||
var processManager = MotionEngine.GetModule<ProcessManager>();
|
||
if (processManager != null)
|
||
{
|
||
_cachedCurrentMode = processManager._currentMode;
|
||
Debug.Log($"缓存当前模式: {_cachedCurrentMode}");
|
||
}
|
||
else
|
||
{
|
||
Debug.LogWarning("ProcessManager未找到,使用默认模式");
|
||
_cachedCurrentMode = ProcessMode.练习模式; // 默认模式
|
||
}
|
||
}
|
||
catch (System.Exception ex)
|
||
{
|
||
Debug.LogError($"获取当前模式时发生错误: {ex.Message}");
|
||
_cachedCurrentMode = ProcessMode.练习模式; // 默认模式
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 为所有输入框添加值变化监听
|
||
/// </summary>
|
||
private void AddInputFieldListeners()
|
||
{
|
||
// 为物料编码输入框添加监听
|
||
foreach (var inputField in materialCodes)
|
||
{
|
||
inputField.onValueChanged.AddListener((value) => OnMaterialCodeChanged(value));
|
||
}
|
||
|
||
// 为库存地点输入框添加监听
|
||
foreach (var inputField in storageLocations)
|
||
{
|
||
inputField.onValueChanged.AddListener((value) => OnStorageLocationChanged(value));
|
||
}
|
||
|
||
// 为工厂输入框添加监听
|
||
foreach (var inputField in factories)
|
||
{
|
||
inputField.onValueChanged.AddListener((value) => OnFactoryChanged(value));
|
||
}
|
||
|
||
// 为批次输入框添加监听(包括焦点控制)
|
||
foreach (var inputField in batchs)
|
||
{
|
||
inputField.onValueChanged.AddListener((value) => OnBatchChanged(value));
|
||
|
||
// 在教学模式下添加焦点控制
|
||
if (IsTeachingMode)
|
||
{
|
||
inputField.onSelect.AddListener((value) => OnBatchFieldSelected(inputField));
|
||
}
|
||
}
|
||
|
||
// 为移动原因输入框添加监听
|
||
foreach (var inputField in movementReasons)
|
||
{
|
||
inputField.onValueChanged.AddListener((value) => OnMovementReasonChanged(value));
|
||
}
|
||
|
||
// 为数量输入框添加监听
|
||
foreach (var inputField in quantities)
|
||
{
|
||
inputField.onValueChanged.AddListener((value) => OnQuantityChanged(value));
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新输入框状态,根据前置条件启用/禁用输入框
|
||
/// </summary>
|
||
private void UpdateInputFieldStates()
|
||
{
|
||
// 物料编码输入框始终可用
|
||
SetInputFieldsInteractable(materialCodes, true);
|
||
|
||
// 库存地点输入框:允许用户开始输入流程,不要求物料编码完全完成
|
||
SetInputFieldsInteractable(storageLocations, true);
|
||
|
||
// 工厂输入框:允许用户开始输入流程,不要求库存地点完全完成
|
||
SetInputFieldsInteractable(factories, true);
|
||
|
||
// 批次输入框:在教学模式下,只有在物料编码、库存地点、工厂都完成后才可用
|
||
bool canInputBatch = true; // 默认允许输入
|
||
if (IsTeachingMode)
|
||
{
|
||
canInputBatch = isMaterialCodeCompleted && isStorageLocationCompleted && isFactoryCompleted;
|
||
}
|
||
|
||
// 调试日志:检查批次输入框数组状态
|
||
Debug.Log($"批次输入框控制 - 教学模式: {IsTeachingMode}, 可输入: {canInputBatch}, 批次输入框数量: {batchs?.Length ?? 0}");
|
||
|
||
SetInputFieldsInteractable(batchs, canInputBatch, true); // 批次输入框需要特殊处理
|
||
|
||
// 移动原因输入框:始终可用
|
||
SetInputFieldsInteractable(movementReasons, true);
|
||
|
||
// 数量输入框:始终可用
|
||
SetInputFieldsInteractable(quantities, true);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置输入框数组的交互状态
|
||
/// </summary>
|
||
/// <param name="inputFields">输入框数组</param>
|
||
/// <param name="interactable">是否可交互</param>
|
||
/// <param name="isBatchField">是否为批次输入框(需要特殊处理)</param>
|
||
private void SetInputFieldsInteractable(TMP_InputField[] inputFields, bool interactable, bool isBatchField = false)
|
||
{
|
||
if (inputFields == null)
|
||
{
|
||
Debug.LogWarning("输入框数组为null");
|
||
return;
|
||
}
|
||
|
||
int processedCount = 0;
|
||
|
||
if (!onlyFirst)
|
||
{
|
||
foreach (var inputField in inputFields)
|
||
{
|
||
if (inputField != null)
|
||
{
|
||
inputField.interactable = interactable;
|
||
processedCount++;
|
||
|
||
// 在教学模式下,对批次输入框进行特殊处理
|
||
if (IsTeachingMode && isBatchField)
|
||
{
|
||
// 使用readOnly属性完全阻止输入
|
||
inputField.readOnly = !interactable;
|
||
}
|
||
else if (isBatchField)
|
||
{
|
||
// 非教学模式下,批次输入框正常可用
|
||
inputField.readOnly = false;
|
||
}
|
||
|
||
// 添加视觉反馈:禁用时变灰
|
||
var colors = inputField.colors;
|
||
// colors.normalColor = interactable ? Color.white : Color.gray;
|
||
inputField.colors = colors;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
TMP_InputField inputField = inputFields[0];
|
||
|
||
if (inputField != null)
|
||
{
|
||
inputField.interactable = interactable;
|
||
processedCount++;
|
||
|
||
// 在教学模式下,对批次输入框进行特殊处理
|
||
if (IsTeachingMode && isBatchField)
|
||
{
|
||
// 使用readOnly属性完全阻止输入
|
||
inputField.readOnly = !interactable;
|
||
}
|
||
else if (isBatchField)
|
||
{
|
||
// 非教学模式下,批次输入框正常可用
|
||
inputField.readOnly = false;
|
||
}
|
||
|
||
// 添加视觉反馈:禁用时变灰
|
||
var colors = inputField.colors;
|
||
// colors.normalColor = interactable ? Color.white : Color.gray;
|
||
inputField.colors = colors;
|
||
}
|
||
}
|
||
|
||
// 调试日志:显示处理的输入框数量
|
||
if (isBatchField)
|
||
{
|
||
Debug.Log($"批次输入框处理完成 - 总数: {inputFields.Length}, 已处理: {processedCount}, 可交互: {interactable}");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 检查输入框数组中是否有任何输入框被填写
|
||
/// </summary>
|
||
/// <param name="inputFields">输入框数组</param>
|
||
/// <returns>是否有输入框被填写</returns>
|
||
private bool IsAnyInputFieldFilled(TMP_InputField[] inputFields)
|
||
{
|
||
foreach (var inputField in inputFields)
|
||
{
|
||
if (inputField != null && !string.IsNullOrEmpty(inputField.text.Trim()))
|
||
{
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 智能检查输入框是否完成(根据onlyFirst决定检查范围)
|
||
/// </summary>
|
||
/// <param name="inputFields">输入框数组</param>
|
||
/// <returns>输入框是否完成</returns>
|
||
private bool IsInputFieldCompleted(TMP_InputField[] inputFields)
|
||
{
|
||
if (inputFields == null || inputFields.Length == 0)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
if (onlyFirst)
|
||
{
|
||
// 只检查第一个输入框
|
||
return inputFields[0] != null && !string.IsNullOrEmpty(inputFields[0].text.Trim());
|
||
}
|
||
else
|
||
{
|
||
// 检查所有输入框
|
||
return IsAnyInputFieldFilled(inputFields);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 物料编码输入变化事件处理
|
||
/// </summary>
|
||
/// <param name="value">输入值</param>
|
||
private void OnMaterialCodeChanged(string value)
|
||
{
|
||
// 检查物料编码是否完成(根据onlyFirst决定检查范围)
|
||
isMaterialCodeCompleted = IsInputFieldCompleted(materialCodes);
|
||
|
||
// 更新输入框状态
|
||
UpdateInputFieldStates();
|
||
|
||
Debug.Log($"物料编码状态更新: {isMaterialCodeCompleted} (onlyFirst: {onlyFirst})");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 库存地点输入变化事件处理
|
||
/// </summary>
|
||
/// <param name="value">输入值</param>
|
||
private void OnStorageLocationChanged(string value)
|
||
{
|
||
// 检查库存地点是否完成(根据onlyFirst决定检查范围)
|
||
isStorageLocationCompleted = IsInputFieldCompleted(storageLocations);
|
||
|
||
// 更新输入框状态
|
||
UpdateInputFieldStates();
|
||
|
||
Debug.Log($"库存地点状态更新: {isStorageLocationCompleted} (onlyFirst: {onlyFirst})");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 工厂输入变化事件处理
|
||
/// </summary>
|
||
/// <param name="value">输入值</param>
|
||
private void OnFactoryChanged(string value)
|
||
{
|
||
// 检查工厂是否完成(根据onlyFirst决定检查范围)
|
||
isFactoryCompleted = IsInputFieldCompleted(factories);
|
||
|
||
// 更新输入框状态
|
||
UpdateInputFieldStates();
|
||
|
||
Debug.Log($"工厂状态更新: {isFactoryCompleted} (onlyFirst: {onlyFirst})");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 批次输入变化事件处理
|
||
/// </summary>
|
||
/// <param name="value">输入值</param>
|
||
private void OnBatchChanged(string value)
|
||
{
|
||
// 验证输入顺序:只有在物料编码、库存地点、工厂都完成后才能输入批次
|
||
if (!string.IsNullOrEmpty(value.Trim()) && !(isMaterialCodeCompleted && isStorageLocationCompleted && isFactoryCompleted))
|
||
{
|
||
// 输入顺序错误,清空批次输入并提示
|
||
foreach (var batch in batchs)
|
||
{
|
||
if (batch.text == value)
|
||
{
|
||
batch.text = "";
|
||
break;
|
||
}
|
||
}
|
||
|
||
// 显示错误提示
|
||
ShowInputOrderError("请先完成物料编码、库存地点、工厂的输入,再输入批次号");
|
||
isInputOrderValid = false;
|
||
return;
|
||
}
|
||
|
||
isInputOrderValid = true;
|
||
|
||
// 更新输入框状态
|
||
UpdateInputFieldStates();
|
||
|
||
Debug.Log($"批次输入验证: 顺序有效 = {isInputOrderValid}");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 批次输入框获得焦点事件处理(教学模式专用)
|
||
/// </summary>
|
||
/// <param name="inputField">获得焦点的输入框</param>
|
||
private void OnBatchFieldSelected(TMP_InputField inputField)
|
||
{
|
||
// 检查前置条件是否满足
|
||
if (!(isMaterialCodeCompleted && isStorageLocationCompleted && isFactoryCompleted))
|
||
{
|
||
// 前置条件不满足,立即取消焦点
|
||
inputField.DeactivateInputField();
|
||
|
||
// 显示提示信息
|
||
ShowInputOrderError("请先完成物料编码、库存地点、工厂的输入,再输入批次号");
|
||
|
||
Debug.Log("教学模式:批次输入框焦点被阻止,前置条件未满足");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 移动原因输入变化事件处理
|
||
/// </summary>
|
||
/// <param name="value">输入值</param>
|
||
private void OnMovementReasonChanged(string value)
|
||
{
|
||
// 更新输入框状态
|
||
UpdateInputFieldStates();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 数量输入变化事件处理
|
||
/// </summary>
|
||
/// <param name="value">输入值</param>
|
||
private void OnQuantityChanged(string value)
|
||
{
|
||
// 更新输入框状态
|
||
UpdateInputFieldStates();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 显示输入顺序错误提示
|
||
/// </summary>
|
||
/// <param name="message">错误消息</param>
|
||
private void ShowInputOrderError(string message)
|
||
{
|
||
// 使用现有的AutoHideScript显示错误提示
|
||
if (autoHideScript != null)
|
||
{
|
||
autoHideScript.ShowObject(message);
|
||
}
|
||
|
||
Debug.LogWarning($"输入顺序错误: {message}");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 验证输入顺序是否有效
|
||
/// </summary>
|
||
/// <returns>输入顺序是否有效</returns>
|
||
private bool ValidateInputOrder()
|
||
{
|
||
// 检查是否所有必需的字段都按顺序完成
|
||
bool materialCodeValid = isMaterialCodeCompleted;
|
||
bool storageLocationValid = isStorageLocationCompleted && materialCodeValid;
|
||
bool factoryValid = isFactoryCompleted && storageLocationValid;
|
||
bool batchValid = IsAnyInputFieldFilled(batchs) && factoryValid;
|
||
bool movementReasonValid = IsAnyInputFieldFilled(movementReasons) && batchValid;
|
||
bool quantityValid = IsAnyInputFieldFilled(quantities) && movementReasonValid;
|
||
|
||
return materialCodeValid && storageLocationValid && factoryValid && batchValid && movementReasonValid && quantityValid;
|
||
}
|
||
|
||
private void OnQueryButtonClicked()
|
||
{
|
||
// 首先验证输入顺序
|
||
if (!ValidateInputOrder())
|
||
{
|
||
ShowInputOrderError("请按照正确顺序输入:物料编码 → 库存地点 → 工厂 → 批次 → 移动原因 → 数量");
|
||
return;
|
||
}
|
||
|
||
List<string> parameters = new List<string>();
|
||
// 添加两个下拉框的选中值
|
||
parameters.Add(quantitiesDropdown.options[quantitiesDropdown.value].text);
|
||
parameters.Add(quantitiesDropdown2.options[quantitiesDropdown2.value].text);
|
||
|
||
if (onlyFirst)
|
||
{
|
||
// 只添加每个数组的第一个输入框的值
|
||
if (materialCodes.Length > 0) parameters.Add(materialCodes[0].text);
|
||
if (storageLocations.Length > 0) parameters.Add(storageLocations[0].text);
|
||
if (factories.Length > 0) parameters.Add(factories[0].text);
|
||
if (movementReasons.Length > 0) parameters.Add(movementReasons[0].text);
|
||
if (batchs.Length > 0) parameters.Add(batchs[0].text);
|
||
if (quantities.Length > 0) parameters.Add(quantities[0].text);
|
||
}
|
||
else
|
||
{
|
||
foreach (var code in materialCodes)
|
||
{
|
||
parameters.Add(code.text);
|
||
}
|
||
|
||
foreach (var location in storageLocations)
|
||
{
|
||
parameters.Add(location.text);
|
||
}
|
||
|
||
foreach (var factory in factories)
|
||
{
|
||
parameters.Add(factory.text);
|
||
}
|
||
|
||
foreach (var reason in movementReasons)
|
||
{
|
||
parameters.Add(reason.text);
|
||
}
|
||
|
||
// 添加所有输入框的值
|
||
foreach (var batch in batchs)
|
||
{
|
||
parameters.Add(batch.text);
|
||
}
|
||
|
||
foreach (var quantity in quantities)
|
||
{
|
||
parameters.Add(quantity.text);
|
||
}
|
||
}
|
||
|
||
if (MotionEngine.GetModule<ProcessManager>().HandleClick(parameters))
|
||
{
|
||
onlyFirst = true;
|
||
Debug.Log("查询成功");
|
||
titleText.text = "物料凭证 500004650 已过账";
|
||
autoHideScript.ShowObject("已过账");
|
||
// 清空所有输入框的内容
|
||
foreach (var batch in batchs)
|
||
{
|
||
batch.text = "";
|
||
}
|
||
|
||
foreach (var code in materialCodes)
|
||
{
|
||
code.text = "";
|
||
}
|
||
|
||
foreach (var location in storageLocations)
|
||
{
|
||
location.text = "";
|
||
}
|
||
|
||
foreach (var factory in factories)
|
||
{
|
||
factory.text = "";
|
||
}
|
||
|
||
foreach (var reason in movementReasons)
|
||
{
|
||
reason.text = "";
|
||
}
|
||
|
||
foreach (var quantity in quantities)
|
||
{
|
||
quantity.text = "";
|
||
}
|
||
|
||
InitializeDropdowns();
|
||
TutorialGuideManager.Instance.TriggerNextGuide(queryButton.name);
|
||
}
|
||
}
|
||
}
|
||
} |