chore: initial commit
This commit is contained in:
428
Interface_WebAPI/SlMesDbIterface/WebAPI/AGV/AGV_BusinessLogic.cs
Normal file
428
Interface_WebAPI/SlMesDbIterface/WebAPI/AGV/AGV_BusinessLogic.cs
Normal file
@@ -0,0 +1,428 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Configuration;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using ExternalDataSync;
|
||||
using MesServerWork;
|
||||
using MisDataSaveDate;
|
||||
using System.Net.Http;
|
||||
using System.Web.Http;
|
||||
using MisDataSaveDate.MOM;
|
||||
using System.Data.SqlClient;
|
||||
using static MisDataSaveDate.Helper.ApiLogHelper;
|
||||
using MisDataSaveDate.Helper;
|
||||
using WebApi;
|
||||
using System.Security.Policy;
|
||||
using System.Data;
|
||||
using MisDataFunDll;
|
||||
using System.Reflection.Emit;
|
||||
|
||||
namespace MisDataSaveDate
|
||||
{
|
||||
/// <summary>
|
||||
/// AGV业务处理类
|
||||
/// </summary>
|
||||
public class AGV_BusinessLogic
|
||||
{
|
||||
static string agvBaseUrl = ConfigurationManager.AppSettings["AGV_BaseUrl"];
|
||||
|
||||
/// <summary>
|
||||
/// 处理AGV进入请求业务逻辑
|
||||
/// </summary>
|
||||
/// <param name="url">接口URL</param>
|
||||
/// <param name="jobj">AGV请求数据</param>
|
||||
/// <returns>处理结果</returns>
|
||||
public static string ProcessAGVEnterRequest(string url, [FromBody] JObject jobj)
|
||||
{
|
||||
var result = new AGV_Response();
|
||||
result.code = "0";
|
||||
result.message = "";
|
||||
result.reqCode = "";
|
||||
string errorMessage = "";
|
||||
|
||||
if (jobj == null)
|
||||
{
|
||||
result.code = "1";
|
||||
result.message = "参数格式不正确!";
|
||||
result.reqCode = "";
|
||||
string retString1 = JsonConvert.SerializeObject(result);
|
||||
SaveMesLog("AGV进入请求", "参数格式不正确!", MesLogType.ERROR);
|
||||
MyLog4Net.MyLogHelper.Info("AGV请求进入接口res:", retString1);
|
||||
return retString1;
|
||||
}
|
||||
|
||||
string str = jobj.ToString();
|
||||
//存储请求日志
|
||||
SaveLog_Interface_Request(url, 2, str, out int AID);
|
||||
|
||||
try
|
||||
{
|
||||
// 解析AGV请求内容
|
||||
AGV_EnterRequest enterRequest = JsonConvert.DeserializeObject<AGV_EnterRequest>(str);
|
||||
|
||||
// 必填字段校验
|
||||
if (string.IsNullOrWhiteSpace(enterRequest.reqCode))
|
||||
{
|
||||
throw new Exception("请求编号(reqCode)不能为空");
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(enterRequest.reqTime))
|
||||
{
|
||||
throw new Exception("请求时间戳(reqTime)不能为空");
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(enterRequest.currentPositionCode))
|
||||
{
|
||||
throw new Exception("当前位置编号(currentPositionCode)不能为空");
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(enterRequest.method))
|
||||
{
|
||||
throw new Exception("方法名(method)不能为空");
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(enterRequest.robotCode))
|
||||
{
|
||||
throw new Exception("AGV编号(robotCode)不能为空");
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(enterRequest.taskCode))
|
||||
{
|
||||
throw new Exception("任务编号(taskCode)不能为空");
|
||||
}
|
||||
|
||||
string method = enterRequest.method.Trim().ToLower();
|
||||
if (method != "apply" && method != "release" && method != "lower" && method != "raise")
|
||||
{
|
||||
throw new Exception($"不支持的method:{enterRequest.method}");
|
||||
}
|
||||
|
||||
//enterRequest.currentPositionCode = RemoveTrailingZero(enterRequest.currentPositionCode);
|
||||
|
||||
// 调用存储过程保存AGV请求数据
|
||||
var param = new SqlParameter[] {
|
||||
new SqlParameter("@reqCode", enterRequest.reqCode ?? ""),
|
||||
new SqlParameter("@reqTime", enterRequest.reqTime ?? ""),
|
||||
new SqlParameter("@cooX", enterRequest.cooX ?? ""),
|
||||
new SqlParameter("@cooY", enterRequest.cooY ?? ""),
|
||||
new SqlParameter("@currentPositionCode", enterRequest.currentPositionCode ?? ""),
|
||||
new SqlParameter("@data", ""),// enterRequest.data ??
|
||||
new SqlParameter("@mapCode", enterRequest.mapCode ?? ""),
|
||||
new SqlParameter("@mapDataCode", enterRequest.mapDataCode ?? ""),
|
||||
new SqlParameter("@stgBinCode", enterRequest.stgBinCode ?? ""),
|
||||
new SqlParameter("@method", method),
|
||||
new SqlParameter("@podCode", enterRequest.podCode ?? ""),
|
||||
new SqlParameter("@podDir", enterRequest.podDir ?? ""),
|
||||
new SqlParameter("@materialLot", enterRequest.materialLot ?? ""),
|
||||
new SqlParameter("@robotCode", enterRequest.robotCode ?? ""),
|
||||
new SqlParameter("@taskCode", enterRequest.taskCode ?? ""),
|
||||
new SqlParameter("@wbCode", enterRequest.wbCode ?? ""),
|
||||
new SqlParameter("@ctnrCode", enterRequest.ctnrCode ?? ""),
|
||||
new SqlParameter("@ctnrType", enterRequest.ctnrType ?? ""),
|
||||
new SqlParameter("@roadWayCode", enterRequest.roadWayCode ?? ""),
|
||||
new SqlParameter("@seq", enterRequest.seq ?? ""),
|
||||
new SqlParameter("@eqpCode", enterRequest.eqpCode ?? "")
|
||||
};
|
||||
|
||||
// 这里定义AGV返回的位置 - 从currentPositionCode获取并去掉尾部_1后缀
|
||||
string OpCode = "";
|
||||
try
|
||||
{
|
||||
// 从请求的currentPositionCode字段获取位置码
|
||||
string currentPositionCode = enterRequest.currentPositionCode?.ToString() ?? "";
|
||||
if (!string.IsNullOrEmpty(currentPositionCode))
|
||||
{
|
||||
// 去掉尾部的_1后缀,保留前面的库位号
|
||||
int lastUnderscoreIndex = currentPositionCode.LastIndexOf('_');
|
||||
if (lastUnderscoreIndex > 0)
|
||||
{
|
||||
OpCode = currentPositionCode.Substring(0, lastUnderscoreIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果没有下划线,直接使用原值
|
||||
OpCode = currentPositionCode;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果从currentPositionCode获取不到,使用wbCode作为备用
|
||||
if (string.IsNullOrEmpty(OpCode))
|
||||
{
|
||||
OpCode = enterRequest.wbCode?.ToString() ?? "";
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 解析失败时使用wbCode作为备用
|
||||
OpCode = enterRequest.wbCode?.ToString() ?? "";
|
||||
SaveMesLog("AGV进入请求", $"解析currentPositionCode失败,使用wbCode作为备用:{ex.Message}", MesLogType.WARNING);
|
||||
}
|
||||
|
||||
// 跟新Moby表 AGV进入离开、下降举升状态
|
||||
MisDataFun.Location_MIS_MOBY_Insert(OpCode, method, "1");
|
||||
|
||||
// 执行存储过程
|
||||
DataLinkMesWork2.DataAccess2.ExecuteStoredProcedure("AGV_光栅请求记录_增加", ref param, out errorMessage);
|
||||
|
||||
switch (method)
|
||||
{
|
||||
case "apply":
|
||||
MisDataFun.Location_MIS_MOBY_Insert(OpCode, "inReq", enterRequest.reqCode);
|
||||
MisDataFun.Location_MIS_MOBY_Insert(OpCode, "inTask", enterRequest.taskCode);
|
||||
MisDataFun.Rrunning_AGV_Arrive(OpCode); // 磨合AGV到达
|
||||
MIS_BASE.WritePLC(301, OpCode, true); // 请求进入
|
||||
SaveMesLog(OpCode, $"AGV请求进入成功:工位{OpCode}", MesLogType.INFO);
|
||||
break;
|
||||
case "release": // 离开在收到后反馈回去 发给PLC
|
||||
MisDataFun.Location_MIS_MOBY_Insert(OpCode, "outReq", enterRequest.reqCode);
|
||||
MisDataFun.Location_MIS_MOBY_Insert(OpCode, "outTask", enterRequest.taskCode);
|
||||
MisDataFun.Rrunning_AGV_Leave(OpCode); // 磨合AGV离开
|
||||
// 读取一下上一个请求进入的工件编号~~~ 然后传过去 找对应的
|
||||
//bool agvOutResult = PassAgvInOut(OpCode, "", "release"); // 通知AGV可以离开
|
||||
//if (!agvOutResult)
|
||||
//{
|
||||
// errorMessage = $"AGV离开通知失败:工位{OpCode}";
|
||||
// SaveMesLog("AGV进入请求", errorMessage, "error");
|
||||
//}
|
||||
SaveMesLog(OpCode, $"AGV离开通知成功:工位{OpCode}", MesLogType.INFO);
|
||||
MIS_BASE.WritePLC(301, OpCode, false); // 请求进入
|
||||
// AGV已离开 - 通知PLC
|
||||
MIS_BASE.WritePLC(303, OpCode, true);
|
||||
MIS_BASE.WritePLC(302, OpCode, false); // 托盘到位 器具放置完毕 请求扫描器具码
|
||||
MisDataFun.Location_MIS_MOBY_Insert(OpCode, "AllowAGVLeave", "1");
|
||||
break;
|
||||
case "lower":
|
||||
MisDataFun.Location_MIS_MOBY_Insert(OpCode, "lowerReq", enterRequest.reqCode);
|
||||
MisDataFun.Location_MIS_MOBY_Insert(OpCode, "lowerTask", enterRequest.taskCode);
|
||||
MisDataFun.Location_MIS_MOBY_Insert(OpCode, "当前状态", "AGV请求下降");
|
||||
MisDataFun.Location_MIS_MOBY_Insert(OpCode, "备注", $"lowerReq={enterRequest.reqCode};lowerTask={enterRequest.taskCode}");
|
||||
MIS_BASE.WritePLC(500, OpCode, true); // AGV请求下降
|
||||
SaveMesLog(OpCode, $"AGV请求下降成功:工位{OpCode}", MesLogType.INFO);
|
||||
break;
|
||||
case "raise":
|
||||
MisDataFun.Location_MIS_MOBY_Insert(OpCode, "raiseReq", enterRequest.reqCode);
|
||||
MisDataFun.Location_MIS_MOBY_Insert(OpCode, "raiseTask", enterRequest.taskCode);
|
||||
MisDataFun.Location_MIS_MOBY_Insert(OpCode, "当前状态", "AGV请求举升");
|
||||
MisDataFun.Location_MIS_MOBY_Insert(OpCode, "备注", $"raiseReq={enterRequest.reqCode};raiseTask={enterRequest.taskCode}");
|
||||
MIS_BASE.WritePLC(501, OpCode, true); // AGV请求举升
|
||||
SaveMesLog(OpCode, $"AGV请求举升成功:工位{OpCode}", MesLogType.INFO);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (!string.IsNullOrEmpty(errorMessage))
|
||||
{
|
||||
result.code = "500";
|
||||
result.message = "AGV请求处理失败";
|
||||
result.reqCode = enterRequest.reqCode;
|
||||
SaveMesLog("AGV进入请求", errorMessage, MesLogType.ERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.code = "0";
|
||||
result.message = "";
|
||||
result.reqCode = enterRequest.reqCode;
|
||||
}
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
// 记录错误日志
|
||||
SaveMesLog("AGV进入请求", err.Message, MesLogType.ERROR);
|
||||
|
||||
result.code = "1";
|
||||
result.message = err.Message;
|
||||
|
||||
// 尝试从请求中获取reqCode
|
||||
try
|
||||
{
|
||||
AGV_EnterRequest tempRequest = JsonConvert.DeserializeObject<AGV_EnterRequest>(str);
|
||||
result.reqCode = tempRequest?.reqCode ?? "";
|
||||
}
|
||||
catch
|
||||
{
|
||||
result.reqCode = "";
|
||||
}
|
||||
}
|
||||
|
||||
string retString = JsonConvert.SerializeObject(result);
|
||||
// 存储响应日志
|
||||
SaveLog_Interface_Response(retString, AID);
|
||||
MyLog4Net.MyLogHelper.Info("AGV请求进入接口res:", retString);
|
||||
return retString;
|
||||
}
|
||||
|
||||
public static string RemoveTrailingZero(string input)
|
||||
{
|
||||
if (input != null && input.Contains("-0") && input.Length >= 3)
|
||||
{
|
||||
int dashIndex = input.LastIndexOf("-0");
|
||||
if (dashIndex > 0 && dashIndex == input.Length - 3) // 确保是最后的-0x格式
|
||||
{
|
||||
return input.Remove(dashIndex + 1, 1); // 去掉"-0"中的0
|
||||
}
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送AGV任务继续执行请求(允许进入、离开、下降或举升)
|
||||
/// </summary>
|
||||
/// <param name="opName">工位号</param>
|
||||
/// <param name="engineID">工件编号</param>
|
||||
/// <param name="type">任务类型</param>
|
||||
/// <returns>操作是否成功</returns>
|
||||
public static bool PassAgvInOut(string opName, string engineID, string type)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 其实没有用 engineID 这玩意正常本工位获取不到
|
||||
|
||||
// 调用存储过程获取AGV任务数据
|
||||
var param = new SqlParameter[] {
|
||||
new SqlParameter("@opName", opName),
|
||||
new SqlParameter("@engineID", engineID),
|
||||
new SqlParameter("@type", type)
|
||||
};
|
||||
DataLinkMesWork2.DataAccess2.ExecuteStoredProcedure("AGV_允许进入离开_查询", ref param, out DataTable dtResult, out string errMessage);
|
||||
|
||||
if (dtResult == null || dtResult.Rows.Count == 0)
|
||||
{
|
||||
SaveMesLog(opName, $"获取AGV任务数据失败:工位号={opName}, 工件编号={engineID}, 任务类型={type}, 错误信息={errMessage}", MesLogType.ERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 从数据库获取请求编号和任务号
|
||||
string reqCode = dtResult.Rows[0]["reqCode"].ToString();
|
||||
string taskCode = dtResult.Rows[0]["taskCode"].ToString();
|
||||
|
||||
// 构造AGV反馈请求对象
|
||||
AGV_FeedbackRequest agvFeedbackRequest = new AGV_FeedbackRequest()
|
||||
{
|
||||
reqCode = reqCode,
|
||||
taskCode = taskCode
|
||||
};
|
||||
|
||||
// 获取AGV接口地址并发送请求
|
||||
string interfaceUrl = agvBaseUrl.TrimEnd('/') + "/rcms/services/rest/hikRpcService/continueTask";
|
||||
string jsonStr = JsonConvert.SerializeObject(agvFeedbackRequest);
|
||||
|
||||
//存储请求日志
|
||||
SaveLog_Interface_Request(interfaceUrl, 1, jsonStr, out int AID);
|
||||
|
||||
string resultStr = "";
|
||||
try
|
||||
{
|
||||
resultStr = Post.Post_Auto(interfaceUrl, jsonStr);
|
||||
}
|
||||
catch (Exception httpEx)
|
||||
{
|
||||
SaveMesLog(opName, $"AGV接口HTTP请求异常:工位号={opName}, 工件编号={engineID}, 任务类型={type}, 异常信息={httpEx.Message}", MesLogType.ERROR);
|
||||
// 存储响应日志
|
||||
SaveLog_Interface_Response($"HTTP请求异常:{httpEx.Message}", AID);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 存储响应日志
|
||||
SaveLog_Interface_Response(resultStr, AID);
|
||||
|
||||
// 解析响应结果
|
||||
if (string.IsNullOrWhiteSpace(resultStr))
|
||||
{
|
||||
SaveMesLog(opName, "AGV接口返回空响应", MesLogType.ERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查是否为Post.Post_Auto返回的错误格式
|
||||
try
|
||||
{
|
||||
JObject tempResult = JsonConvert.DeserializeObject<JObject>(resultStr);
|
||||
if (tempResult != null && tempResult["code"] != null && tempResult["code"].ToString() == "500")
|
||||
{
|
||||
string errorMsg = tempResult["message"]?.ToString() ?? "HTTP请求异常";
|
||||
SaveMesLog(opName, $"AGV接口HTTP异常:工位号={opName}, 工件编号={engineID}, 任务类型={type}, 错误信息={errorMsg}", MesLogType.ERROR);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 如果不是标准JSON格式,继续后续处理
|
||||
}
|
||||
|
||||
AGV_Response result = JsonConvert.DeserializeObject<AGV_Response>(resultStr);
|
||||
if (result == null)
|
||||
{
|
||||
SaveMesLog(opName, "AGV接口返回数据格式错误", MesLogType.ERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查AGV返回码
|
||||
string code = result.code?.ToString();
|
||||
if (code != "0")
|
||||
{
|
||||
string message = result.message?.ToString() ?? "未知错误";
|
||||
SaveMesLog(opName, $"允许AGV光栅请求失败:工位号={opName}, 工件编号={engineID}, 任务类型={type}, code={code}, message={message}", MesLogType.ERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 请求成功后调用存储过程更新送料状态
|
||||
var updateParam = new SqlParameter[] {
|
||||
new SqlParameter("@opName", opName),
|
||||
new SqlParameter("@engineID", engineID),
|
||||
new SqlParameter("@reqCode", reqCode),
|
||||
new SqlParameter("@taskCode", taskCode)
|
||||
};
|
||||
DataLinkMesWork2.DataAccess2.ExecuteStoredProcedure("AGV_光栅请求记录_允许", ref updateParam, out string updateErrMessage);
|
||||
|
||||
if (!string.IsNullOrEmpty(updateErrMessage))
|
||||
{
|
||||
SaveMesLog(opName, $"允许AGV光栅请求失败:工位号={opName}, 工件编号={engineID}, 任务类型={type}, 异常信息={updateErrMessage}", MesLogType.ERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// 根据任务类型进行后续操作
|
||||
if (type == "apply")
|
||||
{
|
||||
// AGV已进入
|
||||
MisDataFun.Location_MIS_MOBY_Insert(opName, "AllowAGVEnter", "1");
|
||||
}
|
||||
else if (type == "release")
|
||||
{
|
||||
// AGV已离开 - 通知PLC
|
||||
MIS_BASE.WritePLC(301, opName, false); // 请求进入
|
||||
MIS_BASE.WritePLC(303, opName, true);
|
||||
MisDataFun.Location_MIS_MOBY_Insert(opName, "AllowAGVLeave", "1");
|
||||
}
|
||||
else if (type == "lower")
|
||||
{
|
||||
// AGV允许下降
|
||||
MIS_BASE.WritePLC(500, opName, false); // AGV请求下降
|
||||
MisDataFun.Location_MIS_MOBY_Insert(opName, "AllowAGVLower", "1");
|
||||
MisDataFun.Location_MIS_MOBY_Insert(opName, "当前状态", "允许AGV下降");
|
||||
}
|
||||
else if (type == "raise")
|
||||
{
|
||||
// AGV允许举升
|
||||
MIS_BASE.WritePLC(501, opName, false); // AGV请求举升
|
||||
MisDataFun.Location_MIS_MOBY_Insert(opName, "AllowAGVRaise", "1");
|
||||
MisDataFun.Location_MIS_MOBY_Insert(opName, "当前状态", "允许AGV举升");
|
||||
}
|
||||
|
||||
SaveMesLog(opName, $"允许AGV光栅请求成功:工件编号={engineID}, 请求编号={reqCode}, 任务号={taskCode}, 工位号={opName}, 任务类型={type}", MesLogType.INFO);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SaveMesLog(opName, $"允许AGV光栅请求失败:工位号={opName}, 工件编号={engineID}, 任务类型={type}, 异常信息={ex.Message}", MesLogType.ERROR);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
164
Interface_WebAPI/SlMesDbIterface/WebAPI/AGV/AGV_Models.cs
Normal file
164
Interface_WebAPI/SlMesDbIterface/WebAPI/AGV/AGV_Models.cs
Normal file
@@ -0,0 +1,164 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace MisDataSaveDate
|
||||
{
|
||||
/// <summary>
|
||||
/// AGV进入请求实体类
|
||||
/// </summary>
|
||||
public class AGV_EnterRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 请求编号,每个请求都要一个唯一编号,同一个请求重复提交,使用同一编号
|
||||
/// </summary>
|
||||
public string reqCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 请求时间戳,格式: "yyyy-MM-dd HH:mm:ss"
|
||||
/// </summary>
|
||||
public string reqTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 地码 X 坐标(mm):任务完成时有值
|
||||
/// </summary>
|
||||
public string cooX { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 地码 Y 坐标(mm):任务完成时有值
|
||||
/// </summary>
|
||||
public string cooY { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前位置编号
|
||||
/// </summary>
|
||||
public string currentPositionCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 自定义字段,不超过2000个字符
|
||||
/// </summary>
|
||||
public object data { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 地图编号
|
||||
/// </summary>
|
||||
public string mapCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 地码编号:任务完成时有值
|
||||
/// </summary>
|
||||
public string mapDataCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 仓位编号:叉车与CTU任务时有值
|
||||
/// </summary>
|
||||
public string stgBinCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 方法名, apply: 申请进入;release:申请离开
|
||||
/// </summary>
|
||||
public string method { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 货架编号:背货架时有值
|
||||
/// </summary>
|
||||
public string podCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// "180","0","90","-90" 分别对应地图的"左","右","上","下":任务完成时有值
|
||||
/// </summary>
|
||||
public string podDir { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 物料编号
|
||||
/// </summary>
|
||||
public string materialLot { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// AGV编号(同 agvCode)
|
||||
/// </summary>
|
||||
public string robotCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前任务单号
|
||||
/// </summary>
|
||||
public string taskCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 工作位,与RCS-2000端配置的位置名称一致。任务完成时有值,与生成任务单接口中的wbCode一致
|
||||
/// </summary>
|
||||
public string wbCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 容器编号
|
||||
/// </summary>
|
||||
public string ctnrCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 容器类型
|
||||
/// </summary>
|
||||
public string ctnrType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 巷道编号
|
||||
/// </summary>
|
||||
public string roadWayCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 巷道内顺序号,巷道尾是0,到巷道头依次递增1
|
||||
/// </summary>
|
||||
public string seq { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 设备编号,如梳齿式工作站、输送线等,一般使用于CTU场景。系统根据仓位定位到关联的设备编号
|
||||
/// </summary>
|
||||
public string eqpCode { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// AGV请求反馈实体类
|
||||
/// </summary>
|
||||
public class AGV_FeedbackRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 请求编号
|
||||
/// </summary>
|
||||
public string reqCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 任务单号
|
||||
/// </summary>
|
||||
public string taskCode { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// AGV接口通用响应类
|
||||
/// </summary>
|
||||
public class AGV_Response
|
||||
{
|
||||
/// <summary>
|
||||
/// 返回码 "0"表示成功
|
||||
/// </summary>
|
||||
public string code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回消息
|
||||
/// </summary>
|
||||
public string message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 请求编号
|
||||
/// </summary>
|
||||
public string reqCode { get; set; }
|
||||
|
||||
public AGV_Response()
|
||||
{
|
||||
code = "0";
|
||||
message = "成功";
|
||||
reqCode = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Configuration;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using MisDataSaveDate;
|
||||
using System.Web.Http;
|
||||
using static MisDataSaveDate.Helper.ApiLogHelper;
|
||||
using MisDataSaveDate.Helper;
|
||||
|
||||
namespace MisDataSaveDate
|
||||
{
|
||||
/// <summary>
|
||||
/// 西开 AGV 业务处理类
|
||||
/// 处理 AGV -> MES 的接收请求
|
||||
/// </summary>
|
||||
public class ZZAGV_BusinessLogic
|
||||
{
|
||||
/// <summary>
|
||||
/// 处理状态更新请求(到达/离开)
|
||||
/// </summary>
|
||||
/// <param name="url">接口URL</param>
|
||||
/// <param name="jobj">请求数据</param>
|
||||
/// <returns>处理结果 JSON 字符串</returns>
|
||||
public static string ProcessStatusUpdate(string url, [FromBody] JObject jobj)
|
||||
{
|
||||
var result = ZZAGV_Response.Success();
|
||||
string str = jobj?.ToString() ?? "";
|
||||
|
||||
// 存储请求日志
|
||||
SaveLog_Interface_Request(url, 2, str, out int AID);
|
||||
|
||||
try
|
||||
{
|
||||
if (jobj == null)
|
||||
{
|
||||
throw new Exception("请求参数不能为空");
|
||||
}
|
||||
|
||||
ZZAGV_StatusUpdateRequest request = JsonConvert.DeserializeObject<ZZAGV_StatusUpdateRequest>(str);
|
||||
|
||||
// 参数校验
|
||||
if (string.IsNullOrWhiteSpace(request.position))
|
||||
{
|
||||
throw new Exception("工位编号(position)不能为空");
|
||||
}
|
||||
|
||||
string typeDesc = request.type == 1 ? "到达" : (request.type == 2 ? "离开" : "未知");
|
||||
SaveMesLog("ZZAGV_StatusUpdate", $"AGV状态更新:工位={request.position}, 类型={typeDesc}, AGV={request.agvid}, 物料={request.materialCode}", MesLogType.INFO);
|
||||
|
||||
// TODO: 后续业务逻辑在此添加
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result = ZZAGV_Response.Fail(1, ex.Message);
|
||||
SaveMesLog("ZZAGV_StatusUpdate", $"处理异常:{ex.Message}", MesLogType.ERROR);
|
||||
}
|
||||
|
||||
string retString = JsonConvert.SerializeObject(result);
|
||||
SaveLog_Interface_Response(retString, AID);
|
||||
return retString;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理动作完成请求(举升/下降)
|
||||
/// </summary>
|
||||
/// <param name="url">接口URL</param>
|
||||
/// <param name="jobj">请求数据</param>
|
||||
/// <returns>处理结果 JSON 字符串</returns>
|
||||
public static string ProcessActionComplete(string url, [FromBody] JObject jobj)
|
||||
{
|
||||
var result = ZZAGV_Response.Success();
|
||||
string str = jobj?.ToString() ?? "";
|
||||
|
||||
// 存储请求日志
|
||||
SaveLog_Interface_Request(url, 2, str, out int AID);
|
||||
|
||||
try
|
||||
{
|
||||
if (jobj == null)
|
||||
{
|
||||
throw new Exception("请求参数不能为空");
|
||||
}
|
||||
|
||||
ZZAGV_ActionCompleteRequest request = JsonConvert.DeserializeObject<ZZAGV_ActionCompleteRequest>(str);
|
||||
|
||||
// 参数校验
|
||||
if (string.IsNullOrWhiteSpace(request.position))
|
||||
{
|
||||
throw new Exception("工位编号(position)不能为空");
|
||||
}
|
||||
|
||||
string typeDesc = request.type == 1 ? "举升完成" : (request.type == 2 ? "下降完成" : "未知");
|
||||
SaveMesLog("ZZAGV_ActionComplete", $"AGV动作完成:工位={request.position}, 类型={typeDesc}", MesLogType.INFO);
|
||||
|
||||
// TODO: 后续业务逻辑在此添加
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result = ZZAGV_Response.Fail(1, ex.Message);
|
||||
SaveMesLog("ZZAGV_ActionComplete", $"处理异常:{ex.Message}", MesLogType.ERROR);
|
||||
}
|
||||
|
||||
string retString = JsonConvert.SerializeObject(result);
|
||||
SaveLog_Interface_Response(retString, AID);
|
||||
return retString;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理故障/报警推送请求
|
||||
/// </summary>
|
||||
/// <param name="url">接口URL</param>
|
||||
/// <param name="jobj">请求数据</param>
|
||||
/// <returns>处理结果 JSON 字符串</returns>
|
||||
public static string ProcessAlarmPush(string url, [FromBody] JObject jobj)
|
||||
{
|
||||
var result = ZZAGV_Response.Success();
|
||||
string str = jobj?.ToString() ?? "";
|
||||
|
||||
// 存储请求日志
|
||||
SaveLog_Interface_Request(url, 2, str, out int AID);
|
||||
|
||||
try
|
||||
{
|
||||
if (jobj == null)
|
||||
{
|
||||
throw new Exception("请求参数不能为空");
|
||||
}
|
||||
|
||||
ZZAGV_AlarmPushRequest request = JsonConvert.DeserializeObject<ZZAGV_AlarmPushRequest>(str);
|
||||
|
||||
string typeDesc = request.type == 1 ? "AGV故障" : (request.type == 2 ? "区域故障" : "未知");
|
||||
SaveMesLog("ZZAGV_AlarmPush", $"AGV故障推送:类型={typeDesc}, AGV={request.agvNo}, 故障码={request.errorCode}, 信息={request.errorMsg}", MesLogType.WARNING);
|
||||
|
||||
// TODO: 后续业务逻辑在此添加
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result = ZZAGV_Response.Fail(1, ex.Message);
|
||||
SaveMesLog("ZZAGV_AlarmPush", $"处理异常:{ex.Message}", MesLogType.ERROR);
|
||||
}
|
||||
|
||||
string retString = JsonConvert.SerializeObject(result);
|
||||
SaveLog_Interface_Response(retString, AID);
|
||||
return retString;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理任务执行结果请求
|
||||
/// </summary>
|
||||
/// <param name="url">接口URL</param>
|
||||
/// <param name="jobj">请求数据</param>
|
||||
/// <returns>处理结果 JSON 字符串</returns>
|
||||
public static string ProcessTaskResult(string url, [FromBody] JObject jobj)
|
||||
{
|
||||
var result = ZZAGV_Response.Success();
|
||||
string str = jobj?.ToString() ?? "";
|
||||
|
||||
// 存储请求日志
|
||||
SaveLog_Interface_Request(url, 2, str, out int AID);
|
||||
|
||||
try
|
||||
{
|
||||
if (jobj == null)
|
||||
{
|
||||
throw new Exception("请求参数不能为空");
|
||||
}
|
||||
|
||||
ZZAGV_TaskResultRequest request = JsonConvert.DeserializeObject<ZZAGV_TaskResultRequest>(str);
|
||||
|
||||
// 参数校验
|
||||
if (string.IsNullOrWhiteSpace(request.requestTaskId))
|
||||
{
|
||||
throw new Exception("任务ID(requestTaskId)不能为空");
|
||||
}
|
||||
|
||||
string statusDesc = request.status == "success" ? "成功" : "失败";
|
||||
SaveMesLog("ZZAGV_TaskResult", $"AGV任务结果:任务ID={request.requestTaskId}, 状态={statusDesc}, AGV={request.agvNo}, 消息={request.message}", MesLogType.INFO);
|
||||
|
||||
// TODO: 后续业务逻辑在此添加
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result = ZZAGV_Response.Fail(1, ex.Message);
|
||||
SaveMesLog("ZZAGV_TaskResult", $"处理异常:{ex.Message}", MesLogType.ERROR);
|
||||
}
|
||||
|
||||
string retString = JsonConvert.SerializeObject(result);
|
||||
SaveLog_Interface_Response(retString, AID);
|
||||
return retString;
|
||||
}
|
||||
}
|
||||
}
|
||||
221
Interface_WebAPI/SlMesDbIterface/WebAPI/AGV/ZZAGV_Models.cs
Normal file
221
Interface_WebAPI/SlMesDbIterface/WebAPI/AGV/ZZAGV_Models.cs
Normal file
@@ -0,0 +1,221 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MisDataSaveDate
|
||||
{
|
||||
#region AGV -> MES 接收请求模型
|
||||
|
||||
/// <summary>
|
||||
/// 状态更新请求(到达/离开)
|
||||
/// AGV 到达或离开工位时通知 MES
|
||||
/// </summary>
|
||||
public class ZZAGV_StatusUpdateRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 工位编号
|
||||
/// </summary>
|
||||
public string position { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 类型:1-到达,2-离开
|
||||
/// </summary>
|
||||
public int type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 物料编码/产品编码
|
||||
/// </summary>
|
||||
public string materialCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// AGV车号
|
||||
/// </summary>
|
||||
public string agvid { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 动作完成请求(举升/下降)
|
||||
/// AGV 完成托盘举升或下降动作后通知 MES
|
||||
/// </summary>
|
||||
public class ZZAGV_ActionCompleteRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 工位编号
|
||||
/// </summary>
|
||||
public string position { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 类型:1-举升完成,2-下降完成
|
||||
/// </summary>
|
||||
public int type { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 故障/报警推送请求
|
||||
/// AGV 上报故障或区域故障
|
||||
/// </summary>
|
||||
public class ZZAGV_AlarmPushRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// AGV车号
|
||||
/// </summary>
|
||||
public string agvNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 故障代码
|
||||
/// </summary>
|
||||
public string errorCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 故障信息
|
||||
/// </summary>
|
||||
public string errorMsg { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 故障类型:1-AGV故障,2-区域故障
|
||||
/// </summary>
|
||||
public int type { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 任务执行结果请求
|
||||
/// AGV 告知 MES 任务是否执行成功
|
||||
/// </summary>
|
||||
public class ZZAGV_TaskResultRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 任务唯一ID(与下发任务时的 requestTaskId 对应)
|
||||
/// </summary>
|
||||
public string requestTaskId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 执行状态:success-成功,fail-失败
|
||||
/// </summary>
|
||||
public string status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// AGV车号
|
||||
/// </summary>
|
||||
public string agvNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 失败原因(成功时为空)
|
||||
/// </summary>
|
||||
public string message { get; set; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region MES -> AGV 发送请求模型
|
||||
|
||||
/// <summary>
|
||||
/// 下发任务请求
|
||||
/// MES 给 AGV 下发搬运任务
|
||||
/// </summary>
|
||||
public class ZZAGV_AddTaskRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 任务唯一ID(由 MES 生成)
|
||||
/// </summary>
|
||||
public string requestTaskId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 抬货点/取货位置
|
||||
/// </summary>
|
||||
public string startPosition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 卸货点/目标位置
|
||||
/// </summary>
|
||||
public string endPosition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 产品编码/物料编码
|
||||
/// </summary>
|
||||
public string materialCode { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 放行请求
|
||||
/// MES 告知 AGV 可以离开当前位置
|
||||
/// </summary>
|
||||
public class ZZAGV_AllowLeaveRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 请求ID
|
||||
/// </summary>
|
||||
public string requestId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前位置编号
|
||||
/// </summary>
|
||||
public string position { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 放行标志(固定为1)
|
||||
/// </summary>
|
||||
public int allowLeave { get; set; } = 1;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 通用响应模型
|
||||
|
||||
/// <summary>
|
||||
/// 西开 AGV 接口通用响应
|
||||
/// </summary>
|
||||
public class ZZAGV_Response
|
||||
{
|
||||
/// <summary>
|
||||
/// 返回码:0-成功,其他-失败
|
||||
/// </summary>
|
||||
public int code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回描述信息
|
||||
/// </summary>
|
||||
public string desc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否成功
|
||||
/// </summary>
|
||||
public bool success { get; set; }
|
||||
|
||||
public ZZAGV_Response()
|
||||
{
|
||||
code = 0;
|
||||
desc = "成功";
|
||||
success = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置成功响应
|
||||
/// </summary>
|
||||
public static ZZAGV_Response Success(string desc = "成功")
|
||||
{
|
||||
return new ZZAGV_Response
|
||||
{
|
||||
code = 0,
|
||||
desc = desc,
|
||||
success = true
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置失败响应
|
||||
/// </summary>
|
||||
public static ZZAGV_Response Fail(int code, string desc)
|
||||
{
|
||||
return new ZZAGV_Response
|
||||
{
|
||||
code = code,
|
||||
desc = desc,
|
||||
success = false
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using System.Web.Http;
|
||||
using System.Collections.Concurrent;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Threading;
|
||||
using System.Net;
|
||||
using System.Net.Http.Headers;
|
||||
using System.IO;
|
||||
using MisDataSaveDate;
|
||||
|
||||
namespace MisDataSaveDate
|
||||
{
|
||||
/// <summary>
|
||||
/// AGV接口控制器
|
||||
/// </summary>
|
||||
public class AGVController : ApiController
|
||||
{
|
||||
readonly string headUrl = "agv/";
|
||||
|
||||
/// <summary>
|
||||
/// AGV请求进入离开、下降举升接口(接收方)
|
||||
/// 接收AGV的进入、离开、下降、举升请求并存储到数据库
|
||||
/// </summary>
|
||||
/// <param name="jobj">AGV请求数据</param>
|
||||
/// <returns>处理结果</returns>
|
||||
[HttpPost]
|
||||
[Route("agv/agvReqInOut")]
|
||||
public HttpResponseMessage agvReqInOut([FromBody] JObject jobj)
|
||||
{
|
||||
return new HttpResponseMessage
|
||||
{
|
||||
Content = new StringContent(AGV_BusinessLogic.ProcessAGVEnterRequest(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Web.Http;
|
||||
using ExternalDataSync.MOM;
|
||||
|
||||
namespace ExternalDataSync.WebAPI.Controller
|
||||
{
|
||||
public class CheckDataController : ApiController
|
||||
{
|
||||
private readonly string headUrl = "TestPlatform/";
|
||||
|
||||
[HttpPost]
|
||||
[Route("TestPlatform/OnlineCheckData")]
|
||||
public HttpResponseMessage OnlineCheckData([FromBody] JObject jobj)
|
||||
{
|
||||
var result = Other.OnlineCheckData(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj);
|
||||
return new HttpResponseMessage
|
||||
{
|
||||
Content = new StringContent(result, Encoding.GetEncoding("UTF-8"), "application/json")
|
||||
};
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("TestPlatform/OnlineStatusData")]
|
||||
public HttpResponseMessage OnlineStatusData([FromBody] JObject jobj)
|
||||
{
|
||||
var result = Other.OnlineStatusData(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj);
|
||||
return new HttpResponseMessage
|
||||
{
|
||||
Content = new StringContent(result, Encoding.GetEncoding("UTF-8"), "application/json")
|
||||
};
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("TestPlatform/OnlineDewPointResultData")]
|
||||
public HttpResponseMessage OnlineDewPointResultData([FromBody] JObject jobj)
|
||||
{
|
||||
var result = DewPointDataHandler.OnlineDewPointResultData(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj);
|
||||
return new HttpResponseMessage
|
||||
{
|
||||
Content = new StringContent(result, Encoding.GetEncoding("UTF-8"), "application/json")
|
||||
};
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("TestPlatform/OnlineDewPointTechnologyData")]
|
||||
public HttpResponseMessage OnlineDewPointTechnologyData([FromBody] JObject jobj)
|
||||
{
|
||||
var result = DewPointDataHandler.OnlineDewPointTechnologyData(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj);
|
||||
return new HttpResponseMessage
|
||||
{
|
||||
Content = new StringContent(result, Encoding.GetEncoding("UTF-8"), "application/json")
|
||||
};
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("TestPlatform/OnlineDewPointUseData")]
|
||||
public HttpResponseMessage OnlineDewPointUseData([FromBody] JObject jobj)
|
||||
{
|
||||
var result = DewPointDataHandler.OnlineDewPointUseData(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj);
|
||||
return new HttpResponseMessage
|
||||
{
|
||||
Content = new StringContent(result, Encoding.GetEncoding("UTF-8"), "application/json")
|
||||
};
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("TestPlatform/OnlineDewPointStatusData")]
|
||||
public HttpResponseMessage OnlineDewPointStatusData([FromBody] JObject jobj)
|
||||
{
|
||||
var result = DewPointDataHandler.OnlineDewPointStatusData(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj);
|
||||
return new HttpResponseMessage
|
||||
{
|
||||
Content = new StringContent(result, Encoding.GetEncoding("UTF-8"), "application/json")
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取位置待测试产品信息
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
[Route("TestPlatform/GetWaitCheckProductData")]
|
||||
public HttpResponseMessage GetWaitCheckProductData([FromBody] JObject jobj)
|
||||
{
|
||||
var result = Other.GetWaitCheckProductData(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj);
|
||||
return new HttpResponseMessage
|
||||
{
|
||||
Content = new StringContent(result, Encoding.GetEncoding("UTF-8"), "application/json")
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web.Http;
|
||||
using DataLinkMesWork2;
|
||||
|
||||
namespace WebApi
|
||||
{
|
||||
[RoutePrefix("api/checkimage")]
|
||||
public class CheckImageController : ApiController
|
||||
{
|
||||
private readonly string _defaultRoot = @"D:\\XDCheckImages";
|
||||
|
||||
public class ImageUploadRequest
|
||||
{
|
||||
public string ProductCode { get; set; }
|
||||
public string Remark { get; set; }
|
||||
public string ImageBase64 { get; set; }
|
||||
public string FileExt { get; set; }
|
||||
}
|
||||
|
||||
public class ImageDownloadRequest
|
||||
{
|
||||
public string Path { get; set; }
|
||||
}
|
||||
|
||||
private string GetRootPath()
|
||||
{
|
||||
string root = null;
|
||||
try
|
||||
{
|
||||
root = ConfigurationManager.AppSettings["XD_CheckImageRootPath"];
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(root))
|
||||
{
|
||||
root = _defaultRoot;
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
private string SanitizeForPath(string input)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input)) return string.Empty;
|
||||
char[] invalid = Path.GetInvalidFileNameChars();
|
||||
var value = input.Trim();
|
||||
foreach (var c in invalid)
|
||||
{
|
||||
value = value.Replace(c.ToString(), string.Empty);
|
||||
}
|
||||
value = value.Replace("/", string.Empty).Replace("\\", string.Empty);
|
||||
return value;
|
||||
}
|
||||
|
||||
private string GetExtensionFromRequest(ImageUploadRequest request)
|
||||
{
|
||||
string ext = ".jpg";
|
||||
if (request == null) return ext;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(request.FileExt))
|
||||
{
|
||||
ext = request.FileExt.Trim();
|
||||
if (!ext.StartsWith("."))
|
||||
{
|
||||
ext = "." + ext;
|
||||
}
|
||||
return ext;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(request.ImageBase64) &&
|
||||
request.ImageBase64.StartsWith("data:", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
try
|
||||
{
|
||||
var match = Regex.Match(request.ImageBase64, "^data:(?<mime>[^;]+);base64,", RegexOptions.IgnoreCase);
|
||||
if (match.Success)
|
||||
{
|
||||
var mime = match.Groups["mime"].Value.ToLowerInvariant();
|
||||
if (mime == "image/png") return ".png";
|
||||
if (mime == "image/gif") return ".gif";
|
||||
if (mime == "image/bmp") return ".bmp";
|
||||
if (mime == "image/webp") return ".webp";
|
||||
if (mime == "image/tiff" || mime == "image/tif") return ".tif";
|
||||
if (mime == "image/jpeg" || mime == "image/jpg") return ".jpg";
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
return ext;
|
||||
}
|
||||
|
||||
private string GetContentType(string fileName)
|
||||
{
|
||||
var extension = Path.GetExtension(fileName).ToLowerInvariant();
|
||||
if (extension == ".bmp") return "image/bmp";
|
||||
if (extension == ".jpg" || extension == ".jpeg") return "image/jpeg";
|
||||
if (extension == ".png") return "image/png";
|
||||
if (extension == ".gif") return "image/gif";
|
||||
if (extension == ".tiff" || extension == ".tif") return "image/tiff";
|
||||
if (extension == ".webp") return "image/webp";
|
||||
return "application/octet-stream";
|
||||
}
|
||||
|
||||
private bool IsPathSafe(string fullPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
var basePath = Path.GetFullPath(GetRootPath());
|
||||
var requestedPath = Path.GetFullPath(fullPath);
|
||||
return requestedPath.StartsWith(basePath, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("upload")]
|
||||
public IHttpActionResult Upload([FromBody] ImageUploadRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (request == null ||
|
||||
string.IsNullOrWhiteSpace(request.ProductCode) ||
|
||||
string.IsNullOrWhiteSpace(request.Remark) ||
|
||||
string.IsNullOrWhiteSpace(request.ImageBase64))
|
||||
{
|
||||
return Ok(new { success = false, message = "产品编号、备注和图片不能为空" });
|
||||
}
|
||||
|
||||
string productCode = SanitizeForPath(request.ProductCode);
|
||||
string remark = SanitizeForPath(request.Remark);
|
||||
if (string.IsNullOrEmpty(productCode))
|
||||
{
|
||||
return Ok(new { success = false, message = "产品编号无效" });
|
||||
}
|
||||
|
||||
string ext = GetExtensionFromRequest(request);
|
||||
string base64 = request.ImageBase64.Trim();
|
||||
int commaIndex = base64.IndexOf(',');
|
||||
if (base64.StartsWith("data:", StringComparison.OrdinalIgnoreCase) && commaIndex > 0)
|
||||
{
|
||||
base64 = base64.Substring(commaIndex + 1);
|
||||
}
|
||||
|
||||
byte[] bytes;
|
||||
try
|
||||
{
|
||||
bytes = Convert.FromBase64String(base64);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Ok(new { success = false, message = "图片数据格式错误" });
|
||||
}
|
||||
|
||||
var now = DateTime.Now;
|
||||
string datePart = now.ToString("yyyyMMdd");
|
||||
string timePart = now.ToString("HHmmss");
|
||||
|
||||
string fileName = string.Format("{0}-{1}-{2}{3}", timePart, productCode, remark, ext);
|
||||
string relativePath = string.Format("/{0}/{1}", datePart, fileName);
|
||||
|
||||
string root = GetRootPath();
|
||||
string directory = Path.Combine(root, datePart);
|
||||
if (!Directory.Exists(directory))
|
||||
{
|
||||
Directory.CreateDirectory(directory);
|
||||
}
|
||||
|
||||
string fullPath = Path.Combine(directory, fileName);
|
||||
|
||||
if (!IsPathSafe(fullPath))
|
||||
{
|
||||
return Ok(new { success = false, message = "目标路径不安全" });
|
||||
}
|
||||
|
||||
File.WriteAllBytes(fullPath, bytes);
|
||||
|
||||
string errorMessage;
|
||||
var sqlParameters = new SqlParameter[4];
|
||||
sqlParameters[0] = new SqlParameter("@产品编号", SqlDbType.NVarChar, 500) { Value = (object)request.ProductCode ?? DBNull.Value };
|
||||
sqlParameters[1] = new SqlParameter("@备注", SqlDbType.NVarChar, 500) { Value = (object)request.Remark ?? DBNull.Value };
|
||||
sqlParameters[2] = new SqlParameter("@图片路径", SqlDbType.NVarChar, 500) { Value = (object)relativePath ?? DBNull.Value };
|
||||
sqlParameters[3] = new SqlParameter("@图片名称", SqlDbType.NVarChar, 500) { Value = (object)fileName ?? DBNull.Value };
|
||||
|
||||
bool dbOk = DataAccess2.ExecuteStoredProcedure("XD_检测图片上传_增加", ref sqlParameters, out errorMessage);
|
||||
if (!dbOk)
|
||||
{
|
||||
return Ok(new { success = false, message = "图片已保存,但写入数据库失败:" + errorMessage });
|
||||
}
|
||||
|
||||
return Ok(new
|
||||
{
|
||||
success = true,
|
||||
message = "上传成功",
|
||||
data = new
|
||||
{
|
||||
产品编号 = request.ProductCode,
|
||||
备注 = request.Remark,
|
||||
图片路径 = relativePath,
|
||||
图片名称 = fileName
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Ok(new { success = false, message = "服务器错误:" + ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("download")]
|
||||
public IHttpActionResult Download([FromBody] ImageDownloadRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (request == null || string.IsNullOrWhiteSpace(request.Path))
|
||||
{
|
||||
return Ok(new { success = false, message = "文件路径不能为空" });
|
||||
}
|
||||
|
||||
string root = GetRootPath();
|
||||
string relative = request.Path.Replace("\\", "/").Trim();
|
||||
if (relative.StartsWith("/"))
|
||||
{
|
||||
relative = relative.Substring(1);
|
||||
}
|
||||
string fullPath = Path.Combine(root, relative.Replace('/', Path.DirectorySeparatorChar));
|
||||
|
||||
if (!IsPathSafe(fullPath) || !File.Exists(fullPath))
|
||||
{
|
||||
return Ok(new { success = false, message = "文件不存在" });
|
||||
}
|
||||
|
||||
var fileInfo = new FileInfo(fullPath);
|
||||
var contentType = GetContentType(fileInfo.Name);
|
||||
|
||||
var response = new HttpResponseMessage(HttpStatusCode.OK)
|
||||
{
|
||||
Content = new StreamContent(new FileStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
};
|
||||
response.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
|
||||
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("inline")
|
||||
{
|
||||
FileName = fileInfo.Name
|
||||
};
|
||||
|
||||
return ResponseMessage(response);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Ok(new { success = false, message = "下载文件失败:" + ex.Message });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,458 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Web.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using WinSCP;
|
||||
|
||||
namespace WebApi
|
||||
{
|
||||
[RoutePrefix("api/craftfile")]
|
||||
public class CraftFileController : ApiController
|
||||
{
|
||||
// 本地缓存根目录
|
||||
private readonly string _cacheRoot = @"D:\\CraftFilesCache";
|
||||
|
||||
private readonly string _sftpHost = "10.107.69.5";
|
||||
private readonly string _sftpUser = "root";
|
||||
private readonly string _sftpPassword = "XKYXmes@123!";
|
||||
|
||||
public class FileRequestDto
|
||||
{
|
||||
// 远程(SFTP)相对路径或绝对路径:如 /root/PLM-MES/.../xxx.pdf
|
||||
public string RelativePath { get; set; } = "";
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("browse")]
|
||||
public IHttpActionResult Browse([FromBody] FileRequestDto request)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (request == null || string.IsNullOrWhiteSpace(request.RelativePath))
|
||||
return Ok(new { success = false, message = "路径不能为空" });
|
||||
|
||||
EnsureCacheRoot();
|
||||
|
||||
var remotePath = NormalizeRemotePath(request.RelativePath);
|
||||
var localPath = ToLocalPath(remotePath);
|
||||
|
||||
var isFile = Path.HasExtension(remotePath);
|
||||
|
||||
if (isFile)
|
||||
{
|
||||
// 确保本地存在
|
||||
if (!System.IO.File.Exists(localPath))
|
||||
{
|
||||
var ok = DownloadFileFromSftp(remotePath, localPath, out string err);
|
||||
if (!ok) return Ok(new { success = false, message = $"下载失败: {err}" });
|
||||
}
|
||||
return GetFilePreviewLocal(localPath, remotePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 目录:优先读取本地,没有则读取远程目录结构
|
||||
if (Directory.Exists(localPath))
|
||||
{
|
||||
return GetDirectoryContentsLocal(localPath, remotePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetDirectoryContentsRemote(remotePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Ok(new { success = false, message = $"服务器错误: {ex.Message}" });
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("download")]
|
||||
public IHttpActionResult Download([FromBody] FileRequestDto request)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (request == null || string.IsNullOrWhiteSpace(request.RelativePath))
|
||||
return Ok(new { success = false, message = "文件路径不能为空" });
|
||||
|
||||
EnsureCacheRoot();
|
||||
|
||||
var remotePath = NormalizeRemotePath(request.RelativePath);
|
||||
var localPath = ToLocalPath(remotePath);
|
||||
|
||||
if (!Path.HasExtension(remotePath))
|
||||
return Ok(new { success = false, message = "请传入文件路径" });
|
||||
|
||||
if (!System.IO.File.Exists(localPath))
|
||||
{
|
||||
var ok = DownloadFileFromSftp(remotePath, localPath, out string err);
|
||||
if (!ok) return Ok(new { success = false, message = $"下载失败: {err}" });
|
||||
}
|
||||
|
||||
var fileInfo = new FileInfo(localPath);
|
||||
var contentType = GetContentType(fileInfo.Name);
|
||||
var response = new HttpResponseMessage(HttpStatusCode.OK)
|
||||
{
|
||||
Content = new StreamContent(new FileStream(localPath, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
};
|
||||
response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
|
||||
response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
|
||||
{
|
||||
FileName = fileInfo.Name
|
||||
};
|
||||
return ResponseMessage(response);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Ok(new { success = false, message = $"下载文件失败: {ex.Message}" });
|
||||
}
|
||||
}
|
||||
|
||||
// 新增:浏览器直接预览文件(支持PDF等),支持Range分块
|
||||
[HttpGet]
|
||||
[Route("preview")]
|
||||
public HttpResponseMessage Preview([FromUri] string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
{
|
||||
return Request.CreateResponse(HttpStatusCode.BadRequest, new { success = false, message = "文件路径不能为空" });
|
||||
}
|
||||
|
||||
EnsureCacheRoot();
|
||||
var remotePath = NormalizeRemotePath(path);
|
||||
var localPath = ToLocalPath(remotePath);
|
||||
|
||||
if (!Path.HasExtension(remotePath))
|
||||
{
|
||||
return Request.CreateResponse(HttpStatusCode.BadRequest, new { success = false, message = "请传入文件路径" });
|
||||
}
|
||||
|
||||
if (!System.IO.File.Exists(localPath))
|
||||
{
|
||||
var ok = DownloadFileFromSftp(remotePath, localPath, out string err);
|
||||
if (!ok)
|
||||
{
|
||||
return Request.CreateResponse(HttpStatusCode.InternalServerError, new { success = false, message = $"下载失败: {err}" });
|
||||
}
|
||||
}
|
||||
|
||||
var fileInfo = new FileInfo(localPath);
|
||||
var contentType = GetContentType(fileInfo.Name);
|
||||
var totalLength = fileInfo.Length;
|
||||
|
||||
var response = new HttpResponseMessage();
|
||||
var range = Request.Headers.Range;
|
||||
|
||||
var stream = new FileStream(localPath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
if (range != null && range.Ranges.Count > 0 && totalLength > 0)
|
||||
{
|
||||
// 处理 Range 请求
|
||||
var from = range.Ranges.First().From ?? 0;
|
||||
var to = range.Ranges.First().To ?? (totalLength - 1);
|
||||
if (to >= totalLength) to = totalLength - 1;
|
||||
var length = to - from + 1;
|
||||
stream.Seek(from, SeekOrigin.Begin);
|
||||
|
||||
response.StatusCode = HttpStatusCode.PartialContent;
|
||||
response.Content = new StreamContent(stream);
|
||||
response.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
|
||||
response.Content.Headers.ContentLength = length;
|
||||
response.Content.Headers.ContentRange = new ContentRangeHeaderValue(from, to, totalLength);
|
||||
response.Headers.AcceptRanges.Add("bytes");
|
||||
}
|
||||
else
|
||||
{
|
||||
// 全量流式
|
||||
response.StatusCode = HttpStatusCode.OK;
|
||||
response.Content = new StreamContent(stream);
|
||||
response.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
|
||||
response.Content.Headers.ContentLength = totalLength;
|
||||
response.Headers.AcceptRanges.Add("bytes");
|
||||
}
|
||||
|
||||
// inline 以支持浏览器内嵌预览
|
||||
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("inline")
|
||||
{
|
||||
FileName = fileInfo.Name
|
||||
};
|
||||
|
||||
// CORS 允许跨域及暴露必要头
|
||||
if (!response.Headers.Contains("Access-Control-Allow-Origin"))
|
||||
response.Headers.Add("Access-Control-Allow-Origin", "*");
|
||||
if (!response.Headers.Contains("Access-Control-Expose-Headers"))
|
||||
response.Headers.Add("Access-Control-Expose-Headers", "Accept-Ranges, Content-Range, Content-Length, Content-Type, Content-Disposition");
|
||||
|
||||
return response;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Request.CreateResponse(HttpStatusCode.InternalServerError, new { success = false, message = $"预览失败: {ex.Message}" });
|
||||
}
|
||||
}
|
||||
|
||||
private IHttpActionResult GetFilePreviewLocal(string localPath, string remotePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
var fileInfo = new FileInfo(localPath);
|
||||
var extension = fileInfo.Extension.ToLowerInvariant();
|
||||
var previewable = IsPreviewableFile(extension);
|
||||
var contentType = GetContentType(fileInfo.Name);
|
||||
|
||||
bool tooLarge = fileInfo.Length > 500 * 1024 * 1024; // 500MB限制
|
||||
string base64String = null;
|
||||
string dataUrl = null;
|
||||
bool canPreview = previewable && !tooLarge;
|
||||
if (canPreview)
|
||||
{
|
||||
var fileBytes = System.IO.File.ReadAllBytes(localPath);
|
||||
base64String = Convert.ToBase64String(fileBytes);
|
||||
dataUrl = $"data:{contentType};base64,{base64String}";
|
||||
}
|
||||
|
||||
var result = new
|
||||
{
|
||||
success = true,
|
||||
type = "file",
|
||||
path = remotePath,
|
||||
name = fileInfo.Name,
|
||||
size = fileInfo.Length,
|
||||
extension = fileInfo.Extension,
|
||||
contentType = contentType,
|
||||
isPreviewable = canPreview,
|
||||
base64Data = base64String,
|
||||
dataUrl = dataUrl,
|
||||
created = fileInfo.CreationTime,
|
||||
modified = fileInfo.LastWriteTime,
|
||||
message = tooLarge ? "文件过大,无法预览,可下载" : null
|
||||
};
|
||||
return Ok(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Ok(new { success = false, message = $"获取文件预览失败: {ex.Message}" });
|
||||
}
|
||||
}
|
||||
|
||||
private IHttpActionResult GetDirectoryContentsLocal(string localPath, string remotePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
var items = new List<object>();
|
||||
var directories = Directory.GetDirectories(localPath);
|
||||
foreach (var dir in directories)
|
||||
{
|
||||
var dirInfo = new DirectoryInfo(dir);
|
||||
var subPath = CombineRemotePath(remotePath, dirInfo.Name);
|
||||
items.Add(new
|
||||
{
|
||||
name = dirInfo.Name,
|
||||
type = "directory",
|
||||
path = subPath,
|
||||
created = dirInfo.CreationTime,
|
||||
modified = dirInfo.LastWriteTime,
|
||||
isPreviewable = false
|
||||
});
|
||||
}
|
||||
var files = Directory.GetFiles(localPath);
|
||||
foreach (var file in files)
|
||||
{
|
||||
var fileInfo = new FileInfo(file);
|
||||
var filePath = CombineRemotePath(remotePath, fileInfo.Name);
|
||||
var extension = fileInfo.Extension.ToLowerInvariant();
|
||||
items.Add(new
|
||||
{
|
||||
name = fileInfo.Name,
|
||||
type = "file",
|
||||
path = filePath,
|
||||
size = fileInfo.Length,
|
||||
extension = fileInfo.Extension,
|
||||
created = fileInfo.CreationTime,
|
||||
modified = fileInfo.LastWriteTime,
|
||||
isPreviewable = IsPreviewableFile(extension),
|
||||
contentType = GetContentType(fileInfo.Name)
|
||||
});
|
||||
}
|
||||
var result = new
|
||||
{
|
||||
success = true,
|
||||
type = "directory",
|
||||
path = remotePath,
|
||||
items = items.OrderBy(x => ((dynamic)x).type == "directory" ? 0 : 1)
|
||||
.ThenBy(x => ((dynamic)x).name)
|
||||
.ToList()
|
||||
};
|
||||
return Ok(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Ok(new { success = false, message = $"读取目录失败: {ex.Message}" });
|
||||
}
|
||||
}
|
||||
|
||||
private IHttpActionResult GetDirectoryContentsRemote(string remotePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var session = OpenSftp())
|
||||
{
|
||||
var dir = session.ListDirectory(remotePath);
|
||||
var items = new List<object>();
|
||||
|
||||
foreach (var subdir in dir.Files.Where(e => e.IsDirectory && e.Name != "." && e.Name != ".."))
|
||||
{
|
||||
var subPath = CombineRemotePath(remotePath, subdir.Name);
|
||||
items.Add(new
|
||||
{
|
||||
name = subdir.Name,
|
||||
type = "directory",
|
||||
path = subPath,
|
||||
created = subdir.LastWriteTime,
|
||||
modified = subdir.LastWriteTime,
|
||||
isPreviewable = false
|
||||
});
|
||||
}
|
||||
|
||||
foreach (var file in dir.Files.Where(e => !e.IsDirectory))
|
||||
{
|
||||
var filePath = CombineRemotePath(remotePath, file.Name);
|
||||
var extension = Path.GetExtension(file.Name).ToLowerInvariant();
|
||||
items.Add(new
|
||||
{
|
||||
name = file.Name,
|
||||
type = "file",
|
||||
path = filePath,
|
||||
size = file.Length,
|
||||
extension = Path.GetExtension(file.Name),
|
||||
created = file.LastWriteTime,
|
||||
modified = file.LastWriteTime,
|
||||
isPreviewable = IsPreviewableFile(extension),
|
||||
contentType = GetContentType(file.Name)
|
||||
});
|
||||
}
|
||||
|
||||
var result = new
|
||||
{
|
||||
success = true,
|
||||
type = "directory",
|
||||
path = remotePath,
|
||||
items = items.OrderBy(x => ((dynamic)x).type == "directory" ? 0 : 1)
|
||||
.ThenBy(x => ((dynamic)x).name)
|
||||
.ToList()
|
||||
};
|
||||
return Ok(result);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Ok(new { success = false, message = $"读取远程目录失败: {ex.Message}" });
|
||||
}
|
||||
}
|
||||
|
||||
private bool DownloadFileFromSftp(string remotePath, string localPath, out string error)
|
||||
{
|
||||
error = null;
|
||||
try
|
||||
{
|
||||
var localDir = Path.GetDirectoryName(localPath);
|
||||
if (!Directory.Exists(localDir)) Directory.CreateDirectory(localDir);
|
||||
|
||||
using (var session = OpenSftp())
|
||||
{
|
||||
var result = session.GetFiles(remotePath, localPath, false);
|
||||
result.Check();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
error = ex.Message;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private Session OpenSftp()
|
||||
{
|
||||
var options = new SessionOptions
|
||||
{
|
||||
Protocol = Protocol.Sftp,
|
||||
HostName = _sftpHost,
|
||||
UserName = _sftpUser,
|
||||
Password = _sftpPassword,
|
||||
SshHostKeyPolicy = SshHostKeyPolicy.GiveUpSecurityAndAcceptAny
|
||||
};
|
||||
var session = new Session();
|
||||
session.Open(options);
|
||||
return session;
|
||||
}
|
||||
|
||||
private void EnsureCacheRoot()
|
||||
{
|
||||
if (!Directory.Exists(_cacheRoot)) Directory.CreateDirectory(_cacheRoot);
|
||||
}
|
||||
|
||||
private string NormalizeRemotePath(string p)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(p)) return "/";
|
||||
var s = p.Trim();
|
||||
// 统一使用正斜杠
|
||||
s = s.Replace('\\', '/');
|
||||
return s;
|
||||
}
|
||||
|
||||
private string ToLocalPath(string remotePath)
|
||||
{
|
||||
// 去掉开头的 '/'
|
||||
var relative = remotePath.Trim().TrimStart('/');
|
||||
var localRelative = relative.Replace('/', Path.DirectorySeparatorChar);
|
||||
return Path.Combine(_cacheRoot, localRelative);
|
||||
}
|
||||
|
||||
private string CombineRemotePath(string basePath, string name)
|
||||
{
|
||||
if (string.IsNullOrEmpty(basePath) || basePath == "/") return $"/{name}";
|
||||
if (basePath.EndsWith("/")) return basePath + name;
|
||||
return basePath + "/" + name;
|
||||
}
|
||||
|
||||
private bool IsPreviewableFile(string extension)
|
||||
{
|
||||
var previewableExtensions = new[]
|
||||
{
|
||||
".bmp", ".jpg", ".jpeg", ".png", ".gif", ".tiff", ".tif", ".webp",
|
||||
".txt", ".json", ".xml", ".csv", ".log", ".md", ".pdf"
|
||||
};
|
||||
return previewableExtensions.Contains(extension);
|
||||
}
|
||||
|
||||
private string GetContentType(string fileName)
|
||||
{
|
||||
var extension = Path.GetExtension(fileName).ToLowerInvariant();
|
||||
if (extension == ".bmp") return "image/bmp";
|
||||
if (extension == ".jpg" || extension == ".jpeg") return "image/jpeg";
|
||||
if (extension == ".png") return "image/png";
|
||||
if (extension == ".gif") return "image/gif";
|
||||
if (extension == ".tiff" || extension == ".tif") return "image/tiff";
|
||||
if (extension == ".webp") return "image/webp";
|
||||
if (extension == ".pdf") return "application/pdf";
|
||||
if (extension == ".txt") return "text/plain";
|
||||
if (extension == ".json") return "application/json";
|
||||
if (extension == ".xml") return "application/xml";
|
||||
if (extension == ".csv") return "text/csv";
|
||||
if (extension == ".md") return "text/markdown";
|
||||
if (extension == ".log") return "text/plain";
|
||||
if (extension == ".zip") return "application/zip";
|
||||
if (extension == ".rar") return "application/x-rar-compressed";
|
||||
return "application/octet-stream";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,277 @@
|
||||
using System.Net.Http;
|
||||
using System.Net;
|
||||
using System.Web.Http;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System;
|
||||
|
||||
/////http://127.0.0.1:9981/api/file/browse
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
namespace WebApi
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[RoutePrefix("api/file")]
|
||||
public class IFileController : ApiController
|
||||
{
|
||||
// 基础路径配置
|
||||
private readonly string _basePath = @"D:\CameraImg";
|
||||
|
||||
/// <summary>
|
||||
/// 请求DTO
|
||||
/// </summary>
|
||||
public class FileRequestDto
|
||||
{
|
||||
public string RelativePath { get; set; } = "";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 浏览文件或文件夹,前端传相对路径,返回文件夹内容或文件流(图片等可预览)
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
[Route("browse")]
|
||||
public IHttpActionResult BrowsePath([FromBody] FileRequestDto request)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (request == null)
|
||||
request = new FileRequestDto();
|
||||
|
||||
if (string.IsNullOrEmpty(request.RelativePath) || request.RelativePath == "/")
|
||||
{
|
||||
request.RelativePath = "";
|
||||
}
|
||||
|
||||
string fullPath = Path.Combine(_basePath, request.RelativePath.Replace('/', Path.DirectorySeparatorChar));
|
||||
|
||||
if (!IsPathSafe(fullPath))
|
||||
{
|
||||
return Ok(new { success = false, message = "无效的路径" });
|
||||
}
|
||||
|
||||
if (!Directory.Exists(fullPath) && !System.IO.File.Exists(fullPath))
|
||||
{
|
||||
return Ok(new { success = false, message = "路径不存在" });
|
||||
}
|
||||
|
||||
if (System.IO.File.Exists(fullPath))
|
||||
{
|
||||
return GetFilePreview(fullPath, request.RelativePath);
|
||||
}
|
||||
|
||||
if (Directory.Exists(fullPath))
|
||||
{
|
||||
return GetDirectoryContents(fullPath, request.RelativePath);
|
||||
}
|
||||
|
||||
return Ok(new { success = false, message = "路径不存在" });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Ok(new { success = false, message = $"服务器错误: {ex.Message}" });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取文件预览数据(图片/文本base64,前端可直接预览)
|
||||
/// </summary>
|
||||
private IHttpActionResult GetFilePreview(string fullPath, string relativePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
var fileInfo = new FileInfo(fullPath);
|
||||
var extension = fileInfo.Extension.ToLowerInvariant();
|
||||
var previewable = IsPreviewableFile(extension);
|
||||
var contentType = GetContentType(fileInfo.Name);
|
||||
|
||||
bool tooLarge = fileInfo.Length > 10 * 1024 * 1024; // 10MB限制
|
||||
string base64String = null;
|
||||
string dataUrl = null;
|
||||
bool canPreview = previewable && !tooLarge;
|
||||
if (canPreview)
|
||||
{
|
||||
var fileBytes = System.IO.File.ReadAllBytes(fullPath);
|
||||
base64String = Convert.ToBase64String(fileBytes);
|
||||
dataUrl = $"data:{contentType};base64,{base64String}";
|
||||
}
|
||||
|
||||
var result = new
|
||||
{
|
||||
success = true,
|
||||
type = "file",
|
||||
path = relativePath,
|
||||
name = fileInfo.Name,
|
||||
size = fileInfo.Length,
|
||||
extension = fileInfo.Extension,
|
||||
contentType = contentType,
|
||||
isPreviewable = canPreview,
|
||||
base64Data = base64String,
|
||||
dataUrl = dataUrl,
|
||||
created = fileInfo.CreationTime,
|
||||
modified = fileInfo.LastWriteTime,
|
||||
message = tooLarge ? "文件过大,无法预览,可下载" : null
|
||||
};
|
||||
return Ok(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Ok(new { success = false, message = $"获取文件预览失败: {ex.Message}" });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断文件是否可预览
|
||||
/// </summary>
|
||||
private bool IsPreviewableFile(string extension)
|
||||
{
|
||||
var previewableExtensions = new[]
|
||||
{
|
||||
".bmp", ".jpg", ".jpeg", ".png", ".gif", ".tiff", ".tif", ".webp",
|
||||
".txt", ".json", ".xml", ".csv", ".log", ".md"
|
||||
};
|
||||
return previewableExtensions.Contains(extension);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 安全检查:确保路径在基础目录内,防止路径遍历攻击
|
||||
/// </summary>
|
||||
private bool IsPathSafe(string fullPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
var basePath = Path.GetFullPath(_basePath);
|
||||
var requestedPath = Path.GetFullPath(fullPath);
|
||||
return requestedPath.StartsWith(basePath, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据文件扩展名获取MIME类型(兼容C# 7.3)
|
||||
/// </summary>
|
||||
private string GetContentType(string fileName)
|
||||
{
|
||||
var extension = Path.GetExtension(fileName).ToLowerInvariant();
|
||||
if (extension == ".bmp") return "image/bmp";
|
||||
if (extension == ".jpg" || extension == ".jpeg") return "image/jpeg";
|
||||
if (extension == ".png") return "image/png";
|
||||
if (extension == ".gif") return "image/gif";
|
||||
if (extension == ".tiff" || extension == ".tif") return "image/tiff";
|
||||
if (extension == ".webp") return "image/webp";
|
||||
if (extension == ".pdf") return "application/pdf";
|
||||
if (extension == ".txt") return "text/plain";
|
||||
if (extension == ".json") return "application/json";
|
||||
if (extension == ".xml") return "application/xml";
|
||||
if (extension == ".csv") return "text/csv";
|
||||
if (extension == ".md") return "text/markdown";
|
||||
if (extension == ".log") return "text/plain";
|
||||
if (extension == ".zip") return "application/zip";
|
||||
if (extension == ".rar") return "application/x-rar-compressed";
|
||||
return "application/octet-stream";
|
||||
}
|
||||
|
||||
private IHttpActionResult GetDirectoryContents(string fullPath, string relativePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
var items = new List<object>();
|
||||
var directories = Directory.GetDirectories(fullPath);
|
||||
foreach (var dir in directories)
|
||||
{
|
||||
var dirInfo = new DirectoryInfo(dir);
|
||||
var subPath = string.IsNullOrEmpty(relativePath)
|
||||
? dirInfo.Name
|
||||
: $"{relativePath}/{dirInfo.Name}";
|
||||
items.Add(new
|
||||
{
|
||||
name = dirInfo.Name,
|
||||
type = "directory",
|
||||
path = subPath,
|
||||
created = dirInfo.CreationTime,
|
||||
modified = dirInfo.LastWriteTime,
|
||||
isPreviewable = false
|
||||
});
|
||||
}
|
||||
var files = Directory.GetFiles(fullPath);
|
||||
foreach (var file in files)
|
||||
{
|
||||
var fileInfo = new FileInfo(file);
|
||||
var filePath = string.IsNullOrEmpty(relativePath)
|
||||
? fileInfo.Name
|
||||
: $"{relativePath}/{fileInfo.Name}";
|
||||
var extension = fileInfo.Extension.ToLowerInvariant();
|
||||
items.Add(new
|
||||
{
|
||||
name = fileInfo.Name,
|
||||
type = "file",
|
||||
path = filePath,
|
||||
size = fileInfo.Length,
|
||||
extension = fileInfo.Extension,
|
||||
created = fileInfo.CreationTime,
|
||||
modified = fileInfo.LastWriteTime,
|
||||
isPreviewable = IsPreviewableFile(extension),
|
||||
contentType = GetContentType(fileInfo.Name)
|
||||
});
|
||||
}
|
||||
var result = new
|
||||
{
|
||||
success = true,
|
||||
type = "directory",
|
||||
path = relativePath,
|
||||
items = items.OrderBy(x => ((dynamic)x).type == "directory" ? 0 : 1)
|
||||
.ThenBy(x => ((dynamic)x).name)
|
||||
.ToList()
|
||||
};
|
||||
return Ok(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Ok(new { success = false, message = $"读取目录失败: {ex.Message}" });
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("download")]
|
||||
public IHttpActionResult DownloadFile([FromBody] FileRequestDto request)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (request == null || string.IsNullOrEmpty(request.RelativePath))
|
||||
return Ok(new { success = false, message = "文件路径不能为空" });
|
||||
|
||||
string fullPath = Path.Combine(_basePath, request.RelativePath.Replace('/', Path.DirectorySeparatorChar));
|
||||
if (!IsPathSafe(fullPath) || !System.IO.File.Exists(fullPath))
|
||||
return Ok(new { success = false, message = "文件不存在" });
|
||||
|
||||
var fileInfo = new FileInfo(fullPath);
|
||||
var contentType = GetContentType(fileInfo.Name);
|
||||
|
||||
var response = new HttpResponseMessage(HttpStatusCode.OK)
|
||||
{
|
||||
Content = new StreamContent(new FileStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
};
|
||||
response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
|
||||
response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
|
||||
{
|
||||
FileName = fileInfo.Name
|
||||
};
|
||||
return ResponseMessage(response);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Ok(new { success = false, message = $"下载文件失败: {ex.Message}" });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,252 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using System.Web.Http;
|
||||
using System.Collections.Concurrent;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Threading;
|
||||
using PLMTEST;
|
||||
using System.Net;
|
||||
using System.Net.Http.Headers;
|
||||
using System.IO;
|
||||
using MisDataSaveDate;
|
||||
|
||||
|
||||
/////http://127.0.0.1:9981/api/IOrder/InsertOrder
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
namespace WebApi
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class MomController : ApiController
|
||||
{
|
||||
readonly string headUrl = "/";
|
||||
|
||||
/// <summary>
|
||||
/// 工艺信息接口
|
||||
/// </summary>
|
||||
/// <param name="jobj"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[Route("ProcessInfo")]
|
||||
public HttpResponseMessage ProcessInfo([FromBody] JObject jobj)
|
||||
{
|
||||
return new HttpResponseMessage
|
||||
{
|
||||
Content = new StringContent(AnalysisMomMsg.ProcessInfo(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
|
||||
};
|
||||
}
|
||||
/// <summary>
|
||||
/// 生产任务接口
|
||||
/// </summary>
|
||||
/// <param name="jobj"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[Route("DispatchOrder")]
|
||||
public HttpResponseMessage DispatchOrder([FromBody] JObject jobj)
|
||||
{
|
||||
return new HttpResponseMessage
|
||||
{
|
||||
Content = new StringContent(AnalysisMomMsg.DispatchOrder(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
|
||||
};
|
||||
}
|
||||
/// <summary>
|
||||
/// 生产工单接口
|
||||
/// </summary>
|
||||
/// <param name="jobj"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[Route("ProductionOrder")]
|
||||
public HttpResponseMessage ProductionOrder([FromBody] JObject jobj)
|
||||
{
|
||||
return new HttpResponseMessage
|
||||
{
|
||||
Content = new StringContent(AnalysisMomMsg.ProductionOrder(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
|
||||
};
|
||||
}
|
||||
/// <summary>
|
||||
/// 员工信息下发接口
|
||||
/// </summary>
|
||||
/// <param name="jobj"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[Route("EmployeeSave")]
|
||||
public HttpResponseMessage EmployeeSave([FromBody] JObject jobj)
|
||||
{
|
||||
return new HttpResponseMessage
|
||||
{
|
||||
Content = new StringContent(AnalysisMomMsg.MES_To_AMS_Employee(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
|
||||
};
|
||||
}
|
||||
/// <summary>
|
||||
/// 生产组织信息下发
|
||||
/// </summary>
|
||||
/// <param name="jobj"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[Route("OrgInfoSave")]
|
||||
public HttpResponseMessage OrgInfoSave([FromBody] JObject jobj)
|
||||
{
|
||||
return new HttpResponseMessage
|
||||
{
|
||||
Content = new StringContent(AnalysisMomMsg.MES_To_AMS_OrgInfo(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
|
||||
};
|
||||
}
|
||||
/// <summary>
|
||||
/// 工作中心信息下发
|
||||
/// </summary>
|
||||
/// <param name="jobj"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[Route("WorkCenterSave")]
|
||||
public HttpResponseMessage WorkCenterSave([FromBody] JObject jobj)
|
||||
{
|
||||
return new HttpResponseMessage
|
||||
{
|
||||
Content = new StringContent(AnalysisMomMsg.MES_To_AMS_WorkCenterSave(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
|
||||
};
|
||||
}
|
||||
/// <summary>
|
||||
/// 物料信息下发
|
||||
/// </summary>
|
||||
/// <param name="jobj"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[Route("MaterialSave")]
|
||||
public HttpResponseMessage MaterialSave([FromBody] JObject jobj)
|
||||
{
|
||||
return new HttpResponseMessage
|
||||
{
|
||||
Content = new StringContent(AnalysisMomMsg.MES_To_AMS_MaterialSave(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
|
||||
};
|
||||
}
|
||||
/// <summary>
|
||||
/// 计量单位下发
|
||||
/// </summary>
|
||||
/// <param name="jobj"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[Route("UnitInfoSave")]
|
||||
public HttpResponseMessage UnitInfoSave([FromBody] JObject jobj)
|
||||
{
|
||||
return new HttpResponseMessage
|
||||
{
|
||||
Content = new StringContent(AnalysisMomMsg.MES_To_AMS_UnitInfoSave(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
|
||||
};
|
||||
}
|
||||
/// <summary>
|
||||
/// 员工排班信息下发
|
||||
/// </summary>
|
||||
/// <param name="jobj"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[Route("ShiftScheduleSave")]
|
||||
public HttpResponseMessage ShiftScheduleSave([FromBody] JObject jobj)
|
||||
{
|
||||
return new HttpResponseMessage
|
||||
{
|
||||
Content = new StringContent(AnalysisMomMsg.MES_To_AMS_ShiftScheduleSave(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
|
||||
};
|
||||
}
|
||||
/// <summary>
|
||||
/// 报警关闭
|
||||
/// </summary>
|
||||
/// <param name="jobj"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[Route("AlarmClosed")]
|
||||
public HttpResponseMessage AlarmClosed([FromBody] JObject jobj)
|
||||
{
|
||||
return new HttpResponseMessage
|
||||
{
|
||||
Content = new StringContent(AnalysisMomMsg.MES_To_AMS_AlarmClosed(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
|
||||
};
|
||||
}
|
||||
/// <summary>
|
||||
/// AGV送料交互接口
|
||||
/// </summary>
|
||||
/// <param name="jobj"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[Route("AGV_To_AMS_InterAction")]
|
||||
public HttpResponseMessage AGV_To_AMS_InterAction([FromBody] JObject jobj)
|
||||
{
|
||||
return new HttpResponseMessage
|
||||
{
|
||||
Content = new StringContent(AnalysisMomMsg.AGV_To_AMS_Interaction(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
|
||||
};
|
||||
}
|
||||
/// <summary>
|
||||
/// 缓存位置查询
|
||||
/// </summary>
|
||||
/// <param name="jobj"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[Route("LineSideStock")]
|
||||
public HttpResponseMessage LineSideStock([FromBody] JObject jobj)
|
||||
{
|
||||
return new HttpResponseMessage
|
||||
{
|
||||
Content = new StringContent(AnalysisMomMsg.AGV_To_AMS_LineSideStock(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
|
||||
};
|
||||
}
|
||||
/// <summary>
|
||||
/// 点检计划下发
|
||||
/// </summary>
|
||||
/// <param name="jobj"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[Route("InspectionPlan")]
|
||||
public HttpResponseMessage InspectionPlan([FromBody] JObject jobj)
|
||||
{
|
||||
return new HttpResponseMessage
|
||||
{
|
||||
Content = new StringContent(AnalysisMomMsg.InspectionPlan(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
|
||||
};
|
||||
}
|
||||
[HttpPost]
|
||||
[Route("QTTemplateInfo")]
|
||||
public HttpResponseMessage QTTemplateInfo([FromBody] JObject jobj)
|
||||
{
|
||||
return new HttpResponseMessage
|
||||
{
|
||||
Content = new StringContent(AnalysisMomMsg.QTItemTemplateInfo(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
|
||||
};
|
||||
}
|
||||
[HttpPost]
|
||||
[Route("QTStandardInfo")]
|
||||
public HttpResponseMessage QTStandardInfo([FromBody] JObject jobj)
|
||||
{
|
||||
return new HttpResponseMessage
|
||||
{
|
||||
Content = new StringContent(AnalysisMomMsg.QTStandardInfo(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
|
||||
};
|
||||
}
|
||||
/// <summary>
|
||||
/// 删除派工订单接口
|
||||
/// </summary>
|
||||
/// <param name="jobj"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[Route("DeleteDispatchOrder")]
|
||||
public HttpResponseMessage DeleteDispatchOrder([FromBody] JObject jobj)
|
||||
{
|
||||
return new HttpResponseMessage
|
||||
{
|
||||
Content = new StringContent(AnalysisMomMsg.DeleteDispatchOrder(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using System.Web.Http;
|
||||
using System.Collections.Concurrent;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Threading;
|
||||
using System.Net;
|
||||
using System.Net.Http.Headers;
|
||||
using System.IO;
|
||||
using MisDataSaveDate;
|
||||
using WebApi;
|
||||
|
||||
namespace MisDataSaveDate
|
||||
{
|
||||
/// <summary>
|
||||
/// AGV接口控制器
|
||||
/// </summary>
|
||||
public class WebController : ApiController
|
||||
{
|
||||
readonly string headUrl = "/";
|
||||
|
||||
/// <summary>
|
||||
/// AGV请求进入接口(接收方)
|
||||
/// 接收AGV的进入请求并存储到数据库
|
||||
/// </summary>
|
||||
/// <param name="jobj">AGV请求数据</param>
|
||||
/// <returns>处理结果</returns>
|
||||
[HttpPost]
|
||||
[Route("web/WEB_Request")]
|
||||
public HttpResponseMessage WEB_Request([FromBody] JObject jobj)
|
||||
{
|
||||
return new HttpResponseMessage
|
||||
{
|
||||
Content = new StringContent(WEB_BusinessLogic.WEB_Request(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// AGV请求进入接口(接收方)
|
||||
/// 接收AGV的进入请求并存储到数据库
|
||||
/// </summary>
|
||||
/// <param name="jobj">AGV请求数据</param>
|
||||
/// <returns>处理结果</returns>
|
||||
[HttpPost]
|
||||
[Route("web/WEB_SpotCheckResultUpload")]
|
||||
public HttpResponseMessage WEB_SpotCheckResultUpload([FromBody] SpotCheckResult request)
|
||||
{
|
||||
var result = new MsgResHeader<object>
|
||||
{
|
||||
code = 200,
|
||||
message = "",
|
||||
Data = null
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
if (request == null)
|
||||
{
|
||||
throw new Exception("请求体不能为空");
|
||||
}
|
||||
|
||||
var response = CALL_Inerface_DataHandle.CALL_Inerface_SpotCheckResultUpload(request);
|
||||
int.TryParse(response["code"]?.ToString() ?? "500", out int remoteCode);
|
||||
result.code = remoteCode;
|
||||
result.message = response["message"]?.ToString() ?? "";
|
||||
result.Data = response["data"];
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result.code = 500;
|
||||
result.message = ex.Message;
|
||||
}
|
||||
|
||||
return new HttpResponseMessage
|
||||
{
|
||||
Content = new StringContent(JsonConvert.SerializeObject(result), Encoding.GetEncoding("UTF-8"), "application/json")
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 磨合转序接口
|
||||
/// 调用AGV转序接口,成功后执行转序存储过程
|
||||
/// </summary>
|
||||
/// <param name="jobj">转序请求数据</param>
|
||||
/// <returns>处理结果</returns>
|
||||
[HttpPost]
|
||||
[Route("web/WEB_RunningInTransfer")]
|
||||
public HttpResponseMessage WEB_RunningInTransfer([FromBody] JObject jobj)
|
||||
{
|
||||
return new HttpResponseMessage
|
||||
{
|
||||
Content = new StringContent(WEB_BusinessLogic.WEB_RunningInTransfer(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 批量读取PLC点位值接口
|
||||
/// 前端传递TagTypeCodeID数组和工位号,返回对应点位的值
|
||||
/// </summary>
|
||||
/// <param name="jobj">请求数据,包含OpName和TagTypeCodeIDs数组</param>
|
||||
/// <returns>返回对应TagTypeCodeID的值列表</returns>
|
||||
[HttpPost]
|
||||
[Route("web/WEB_ReadPLCValues")]
|
||||
public HttpResponseMessage WEB_ReadPLCValues([FromBody] JObject jobj)
|
||||
{
|
||||
return new HttpResponseMessage
|
||||
{
|
||||
Content = new StringContent(WEB_BusinessLogic.WEB_ReadPLCValues(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入PLC接口
|
||||
/// 前端传递TagTypeCodeID、工位号和值,写入到PLC
|
||||
/// </summary>
|
||||
/// <param name="jobj">请求数据,包含TagTypeCodeID、OpName和TagValue</param>
|
||||
/// <returns>写入结果</returns>
|
||||
[HttpPost]
|
||||
[Route("web/WEB_WritePLC")]
|
||||
public HttpResponseMessage WEB_WritePLC([FromBody] JObject jobj)
|
||||
{
|
||||
return new HttpResponseMessage
|
||||
{
|
||||
Content = new StringContent(WEB_BusinessLogic.WEB_WritePLC(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
1962
Interface_WebAPI/SlMesDbIterface/WebAPI/FactoryMES/Analysis508Msg.cs
Normal file
1962
Interface_WebAPI/SlMesDbIterface/WebAPI/FactoryMES/Analysis508Msg.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,919 @@
|
||||
using DataLinkMesWork;
|
||||
using MesServerWork;
|
||||
using MisDataFunDll;
|
||||
using MisDataSaveDate.MOM;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NPOI.HSSF.Record.Chart;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Security.Policy;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static MisDataSaveDate.Helper.ApiLogHelper;
|
||||
using MisDataSaveDate.Helper;
|
||||
|
||||
|
||||
namespace WebApi
|
||||
{
|
||||
public class CALL_Inerface_DataHandle
|
||||
{
|
||||
/// <summary>
|
||||
/// 开工(工序)
|
||||
/// </summary>
|
||||
/// <param name="OpName"></param>
|
||||
/// <param name="EngineID"></param>
|
||||
/// <param name="OrderForm"></param>
|
||||
public static void CALL_Inerface_JobStart(string OpName, string EngineID, string OrderForm)
|
||||
{
|
||||
DataTable IsSendDT = MisDataFun.IOT_ReqData_UpLoad_IsSend(OpName, OrderForm, "完工");
|
||||
if (IsSendDT.Rows[0]["result"].ToString() != "1")
|
||||
{
|
||||
SaveMesLog("工序完工", IsSendDT.Rows[0]["msg"].ToString(), MesLogType.ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
//查询工单ID、任务ID、工序ID
|
||||
var param = new SqlParameter[] {
|
||||
new SqlParameter("@订单号",OrderForm),
|
||||
new SqlParameter("@工序号",OpName),
|
||||
new SqlParameter("@工件编号",EngineID)
|
||||
};
|
||||
DataLinkMesWork2.DataAccess2.ExecuteStoredProcedure("CallWebApi_FactoryMes_JobStart", ref param, out DataTable dt, out string errorMessage);
|
||||
|
||||
if (dt.Rows.Count > 0)
|
||||
{
|
||||
JobStart ReqEntity = new JobStart
|
||||
{
|
||||
//orderID = dt.Rows[0]["订单ID"].ToString(),
|
||||
taskID = dt.Rows[0]["任务ID"].ToString(),
|
||||
processId = dt.Rows[0]["工序ID"].ToString(),
|
||||
operationTime = DateTime.Now.ToString(),
|
||||
createTime = DateTime.Now.ToString(),
|
||||
lastModifiedTime = DateTime.Now.ToString(),
|
||||
operation = "1" //0取消,1开工
|
||||
};
|
||||
string lineType = ConfigurationManager.AppSettings["WebapiPostHeader_Systemcode"];
|
||||
if (lineType == "MES_ZHDQ_126GLKG") ReqEntity.operatorName = "AC09MES";
|
||||
if (lineType == "MES_ZHDQ_126DLQ") ReqEntity.operatorName = "AC06MES";
|
||||
if (lineType == "MES_ZHDQ_126ZZ") ReqEntity.operatorName = "AC11MES";
|
||||
if (OpName == "AC2401") ReqEntity.operatorName = "AC24MES";
|
||||
string InterfaceUrl = ConfigurationManager.AppSettings["CallWebApiUrl_ProcessJobStart"];
|
||||
|
||||
var result = CALL_Interface_WebAPI.CALL_WebApi_JobStart(InterfaceUrl, ReqEntity);
|
||||
//保存日志
|
||||
SaveLog_Interface_Request("CALL_WebApi_JobStart", 1, JsonConvert.SerializeObject(ReqEntity), out int AID);
|
||||
SaveLog_Interface_Response(result.ToString(), AID);
|
||||
|
||||
//当上报失败时,保存上报内容至缓存表
|
||||
bool reqIsOk = true;
|
||||
if (result["code"].ToString() != "200")
|
||||
{
|
||||
MisDataFun.CallWebApi_FactoryMes_NGRecordSave("CALL_WebApi_JobStart", AID, InterfaceUrl, JsonConvert.SerializeObject(ReqEntity), result.ToString());
|
||||
// 设置报工状态
|
||||
reqIsOk = false;
|
||||
SaveMesLog(OpName, $"工序开工上报失败:订单号={OrderForm}, 工件编号={EngineID}, 返回码={result["code"]}, 消息={result["message"]}", MesLogType.ERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
SaveMesLog(OpName, $"工序开工上报成功:订单号={OrderForm}, 工件编号={EngineID}", MesLogType.INFO);
|
||||
}
|
||||
// 保存报工状态
|
||||
MisDataFun.IOT_Data_UpLode_Res_Save(OpName, OrderForm, EngineID, "开工", reqIsOk, result.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
SaveLog_Interface_Request("CallWebApi_FactoryMes_JobStart", 1, $"查询记录数为0:订单号={OrderForm},工序号={OpName},产品流水号={EngineID}", out int AID);
|
||||
SaveMesLog(OpName, $"工序开工查询记录数为0:订单号={OrderForm}, 工件编号={EngineID}", MesLogType.WARNING);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 完工
|
||||
/// </summary>
|
||||
/// <param name="OpName"></param>
|
||||
/// <param name="EngineID"></param>
|
||||
/// <param name="OrderForm"></param>
|
||||
public static void CALL_Inerface_JobFinished(string OpName, string EngineID, string OrderForm)
|
||||
{
|
||||
DataTable IsSendDT = MisDataFun.IOT_ReqData_UpLoad_IsSend(OpName, OrderForm, "完工");
|
||||
if (IsSendDT.Rows[0]["result"].ToString() != "1")
|
||||
{
|
||||
SaveMesLog("工序完工", IsSendDT.Rows[0]["msg"].ToString(), MesLogType.ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
//查询工单ID、任务ID、工序ID
|
||||
var param = new SqlParameter[] {
|
||||
new SqlParameter("@订单号",OrderForm),
|
||||
new SqlParameter("@工序号",OpName),
|
||||
new SqlParameter("@工件编号",EngineID)
|
||||
};
|
||||
//DataAccess.ExecuteStoredProcedure("CallWebApi_FactoryMes_JobFinished", ref param, out DataSet ds);
|
||||
DataLinkMesWork2.DataAccess2.ExecuteStoredProcedure("CallWebApi_FactoryMes_JobFinished", ref param, out DataSet ds, out string errorMessage);
|
||||
//a.[订单ID],[任务ID],[工序ID],[工序名称],1 as 完工数量,@开工时间 as 开工时间,@结束时间 as 结束时间,@节拍 as 节拍,@操作时间 as 最后修改时间
|
||||
if (ds.Tables[0].Rows.Count > 0)
|
||||
{
|
||||
//1、工单信息
|
||||
DataRow orderRow = ds.Tables[0].Rows[0];
|
||||
JobFinished ReqEntity = new JobFinished
|
||||
{
|
||||
//orderID = orderRow["订单ID"].ToString(),
|
||||
taskID = orderRow["任务ID"].ToString(),
|
||||
processNo = orderRow["工序编号"].ToString(),
|
||||
beat = decimal.Parse(orderRow["节拍"].ToString()),
|
||||
finishedQuantity = 1.0M,//完工数量
|
||||
createTime = orderRow["开工时间"].ToString(),
|
||||
endTime = orderRow["结束时间"].ToString(),
|
||||
lastModifiedTime = DateTime.Now.ToString(),
|
||||
};
|
||||
//2、检验信息,根据质量数据和检验模板生成
|
||||
if (ds.Tables[1].Rows.Count > 0)
|
||||
{
|
||||
var qualityOK = ds.Tables[1].Rows[0]["是否合格"].ToString();
|
||||
var OKCount = qualityOK == "1" ? 1.0M : 0.0M;
|
||||
var NGCount = qualityOK == "1" ? 0.0M : 1.0M;
|
||||
|
||||
List<InspectionInfo> inspInfoList = new List<InspectionInfo>();
|
||||
InspectionInfo inspInfo = new InspectionInfo();
|
||||
string lineType = ConfigurationManager.AppSettings["WebapiPostHeader_Systemcode"];
|
||||
if (lineType == "MES_ZHDQ_126GLKG") inspInfo.inspector = "AC09MES";
|
||||
if (lineType == "MES_ZHDQ_126DLQ") inspInfo.inspector = "AC06MES";
|
||||
if (lineType == "MES_ZHDQ_126ZZ") inspInfo.inspector = "AC11MES";
|
||||
if (OpName == "AC2401") inspInfo.inspector = "AC24MES";
|
||||
inspInfo.qualifiedQuantity = OKCount;
|
||||
inspInfo.unqualifiedQuantity = NGCount;
|
||||
inspInfo.inspectionTime = DateTime.Now.ToString();
|
||||
|
||||
List<InspectionDetail> inspectionDetails = new List<InspectionDetail>();
|
||||
foreach (DataRow inspRow in ds.Tables[1].Rows)
|
||||
{
|
||||
InspectionDetail inspectionDetail = new InspectionDetail();
|
||||
var qualityOKStr = "";
|
||||
string TagValue = inspRow["TagValue"].ToString();
|
||||
if (inspRow["检测结果"].ToString() == "1") qualityOKStr = "合格";
|
||||
else qualityOKStr = inspRow["检测结果"].ToString() == "0" ? "未测量" : "不合格";
|
||||
|
||||
// 合格项目 使用 合格不合格
|
||||
if (inspRow["测量单位"]?.ToString() == "OK/NG")
|
||||
{
|
||||
switch (TagValue?.ToString())
|
||||
{
|
||||
case ("1"):
|
||||
TagValue = "合格";
|
||||
break;
|
||||
case ("2"):
|
||||
TagValue = "不合格";
|
||||
break;
|
||||
case ("0"):
|
||||
TagValue = "未测量";
|
||||
break;
|
||||
default:
|
||||
TagValue = "未知";
|
||||
break;
|
||||
}
|
||||
}
|
||||
//inspectionDetail.inspectionItemName = inspRow["质检项目名称"].ToString();
|
||||
inspectionDetail.inspectionItemName = inspRow["质检项目名称"].ToString();
|
||||
inspectionDetail.inspectionValue = TagValue;
|
||||
inspectionDetail.inspectionResult = qualityOKStr;
|
||||
inspectionDetail.upperLimitValue = Convert.ToDecimal(inspRow["上限值"]);
|
||||
inspectionDetail.lowerLimitValue = Convert.ToDecimal(inspRow["下限值"]);
|
||||
inspectionDetail.standardValue = Convert.ToDecimal(inspRow["理论值"]);
|
||||
inspectionDetail.upperLimitSymbol = inspRow["测量单位"].ToString();
|
||||
inspectionDetail.lowerLimitSymbol = inspRow["测量单位"].ToString();
|
||||
inspInfo.templetecode = inspRow["模板编号"].ToString();
|
||||
inspectionDetail.inspectionItemID = inspRow["检验项目ID"].ToString();
|
||||
inspectionDetail.inspectionItemNo = inspRow["检验项目编号"].ToString();
|
||||
inspectionDetails.Add(inspectionDetail);
|
||||
}
|
||||
inspInfo.inspectionDetails = inspectionDetails;
|
||||
inspInfoList.Add(inspInfo);
|
||||
ReqEntity.inspectionInfo = inspInfoList;
|
||||
}
|
||||
|
||||
List<MaterialInfo> materialInfoList = new List<MaterialInfo>();
|
||||
|
||||
//3、消耗物料信息
|
||||
if (ds.Tables[2].Rows.Count > 0)
|
||||
{
|
||||
foreach (DataRow MRow in ds.Tables[2].Rows)
|
||||
{
|
||||
MaterialInfo materialInfo = new MaterialInfo();
|
||||
materialInfo.consumedMaterialNo = MRow["物料编号"].ToString();
|
||||
materialInfo.type = "0";
|
||||
materialInfo.qty = decimal.Parse(MRow["数量"].ToString());
|
||||
materialInfo.batchNo = MRow["批次号"].ToString();
|
||||
materialInfoList.Add(materialInfo);
|
||||
}
|
||||
}
|
||||
|
||||
// 最后再记录一条产出
|
||||
MaterialInfo materialInfo2 = new MaterialInfo();
|
||||
materialInfo2.consumedMaterialNo = orderRow["产品编号"].ToString();
|
||||
materialInfo2.serialNo = EngineID;
|
||||
materialInfo2.type = "1";
|
||||
materialInfo2.qty = 1;
|
||||
materialInfo2.batchNo = "";
|
||||
materialInfoList.Add(materialInfo2);
|
||||
ReqEntity.materialInfo = materialInfoList;
|
||||
|
||||
//4、工时信息
|
||||
List<Workinghours> workinghoursList = new List<Workinghours>();
|
||||
Workinghours workinghours = new Workinghours();
|
||||
workinghours.workingHours = Math.Round(ReqEntity.beat / 3600, 2);//将秒换算成小时
|
||||
workinghours.quantity = 1.0M;
|
||||
workinghours.operation = "1";//默认1完工 0 取消完工 1 完工
|
||||
workinghoursList.Add(workinghours);
|
||||
ReqEntity.workinghours = workinghoursList;
|
||||
|
||||
string InterfaceUrl = ConfigurationManager.AppSettings["CallWebApiUrl_ProcessJobFinish"];
|
||||
var result = CALL_Interface_WebAPI.CALL_WebApi_JobFinished(InterfaceUrl, ReqEntity);
|
||||
SaveLog_Interface_Request("CALL_WebApi_JobFinish", 1, JsonConvert.SerializeObject(ReqEntity), out int AID);
|
||||
SaveLog_Interface_Response(result.ToString(), AID);
|
||||
bool reqIsOk = true;
|
||||
//当上报失败时,保存上报内容至缓存表
|
||||
if (result["code"].ToString() != "200")
|
||||
{
|
||||
MisDataFun.CallWebApi_FactoryMes_NGRecordSave("CALL_WebApi_JobFinished", AID, InterfaceUrl, JsonConvert.SerializeObject(ReqEntity), result.ToString());
|
||||
// 设置报工状态
|
||||
reqIsOk = false;
|
||||
SaveMesLog(OpName, $"工序完工上报失败:订单号={OrderForm}, 工件编号={EngineID}, 返回码={result["code"]}, 消息={result["message"]}", MesLogType.ERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
SaveMesLog(OpName, $"工序完工上报成功:订单号={OrderForm}, 工件编号={EngineID}", MesLogType.INFO);
|
||||
}
|
||||
// 保存报工状态
|
||||
MisDataFun.IOT_Data_UpLode_Res_Save(OpName, OrderForm, EngineID, "完工", reqIsOk, result.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
SaveLog_Interface_Request("CallWebApi_FactoryMes_JobFinish", 1, $"查询记录数为0:订单号={OrderForm},工序号={OpName},产品流水号={EngineID}", out int AID);
|
||||
SaveMesLog(OpName, $"工序完工查询记录数为0:订单号={OrderForm}, 工件编号={EngineID}", MesLogType.WARNING);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 产线报警信息上报
|
||||
/// </summary>
|
||||
/// <param name="OpName"></param>
|
||||
/// <param name="TagID"></param>
|
||||
/// <param name="alarmtype"></param>
|
||||
/// <param name="alarmContext"></param>
|
||||
public static void CALL_Inerface_DeviceAlarm(string OpName, string TagID, string alarmtype, string alarmContext)
|
||||
{
|
||||
MIS_BASE.Read_EngineGetOver_PLC(OpName, out bool isWorking);
|
||||
if (!isWorking) return; // 没有产品 则不上传数据
|
||||
|
||||
//查询工单ID、任务ID、工序ID
|
||||
var param = new SqlParameter[] {
|
||||
new SqlParameter("@工序号",OpName)
|
||||
};
|
||||
string orderID = "";
|
||||
string taskID = "";
|
||||
DataLinkMesWork2.DataAccess2.ExecuteStoredProcedure("CallWebApi_FactoryMes_DeviceAlarm", ref param, out DataTable dt, out string errMessage);
|
||||
if (dt.Rows.Count > 0)
|
||||
{
|
||||
orderID = dt.Rows[0]["订单ID"].ToString();
|
||||
taskID = dt.Rows[0]["任务ID"].ToString();
|
||||
}
|
||||
// 非工厂下发的订单产品,不上传报警
|
||||
if (string.IsNullOrEmpty(orderID) || string.IsNullOrEmpty(taskID)) return;
|
||||
|
||||
DeviceAlarm ReqEntity = new DeviceAlarm
|
||||
{
|
||||
id = Guid.NewGuid().ToString(),
|
||||
orderID = orderID,
|
||||
taskID = taskID,
|
||||
processNo = OpName,
|
||||
alarmCode = TagID,
|
||||
deviceInfo = alarmContext,
|
||||
exceptionInfo = alarmContext,
|
||||
exceptionType = alarmtype,
|
||||
createTime = DateTime.Now.ToString(),
|
||||
lastModifiedTime = DateTime.Now.ToString()
|
||||
};
|
||||
string InterfaceUrl = ConfigurationManager.AppSettings["CallWebApiUrl_AlarmInfoUpload"];
|
||||
var result = CALL_Interface_WebAPI.CALL_WebApi_DeviceAlarm(InterfaceUrl, ReqEntity);
|
||||
|
||||
SaveLog_Interface_Request("CALL_WebApi_DeviceAlarm", 1, JsonConvert.SerializeObject(ReqEntity), out int AID);
|
||||
SaveLog_Interface_Response(result.ToString(), AID);
|
||||
//当上报失败时,保存上报内容至缓存表
|
||||
if (result["code"].ToString() != "200")
|
||||
{
|
||||
MisDataFun.CallWebApi_FactoryMes_NGRecordSave("CALL_WebApi_DeviceAlarm", AID, InterfaceUrl, JsonConvert.SerializeObject(ReqEntity), result.ToString());
|
||||
SaveMesLog(OpName, $"设备报警上报失败:报警代码={TagID}, 报警内容={alarmContext}, 返回码={result["code"]}, 消息={result["message"]}", MesLogType.ERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
SaveMesLog(OpName, $"设备报警上报成功:报警代码={TagID}, 报警类型={alarmtype}", MesLogType.INFO);
|
||||
}
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 叫料、退料、退空、转序、下空、上空、点对点
|
||||
/// </summary>
|
||||
/// <param name="PositionCode"></param>
|
||||
/// <param name="deliveryType">1退托盘,2叫料,3送料,4转序,5下空,6上空,7点对点</param>
|
||||
/// <summary>
|
||||
/// 叫料、退料、退空、转序、下空、上空、点对点
|
||||
/// </summary>
|
||||
/// <param name="PositionCode"></param>
|
||||
/// <param name="deliveryType">1退托盘,2叫料,3送料,4转序,5下空,6上空,7点对点</param>
|
||||
public static bool CALL_Inerface_CallMaterial(string PositionCode, string deliveryType)
|
||||
{
|
||||
// 配送类型映射:1退托盘,2叫料,3送料,4转序,5下空,6上空,7点对点
|
||||
Dictionary<string, string> deliveryTypeMap = new Dictionary<string, string>
|
||||
{
|
||||
{ "1", "退托盘" },
|
||||
{ "2", "叫料" },
|
||||
{ "3", "送料" },
|
||||
{ "4", "转序" },
|
||||
{ "5", "下空" },
|
||||
{ "6", "上空" },
|
||||
{ "7", "点对点" }
|
||||
};
|
||||
string deliveryTypeName = deliveryTypeMap.ContainsKey(deliveryType) ? deliveryTypeMap[deliveryType] : "未知";
|
||||
|
||||
//查询工单ID、任务ID、工序ID
|
||||
var param = new SqlParameter[] {
|
||||
new SqlParameter("@位置号",PositionCode),
|
||||
new SqlParameter("@叫料类型",deliveryType)
|
||||
};
|
||||
DataLinkMesWork2.DataAccess2.ExecuteStoredProcedure("CallWebApi_FactoryMes_CallMaterial", ref param, out DataTable dt, out string errMessage);
|
||||
if (dt.Rows.Count > 0)
|
||||
{
|
||||
string containerNo = "";
|
||||
if (deliveryType == "1")
|
||||
{
|
||||
// 获取器具号(318)
|
||||
containerNo = MIS_BASE.ReadPLC(318, PositionCode).ToString();
|
||||
}
|
||||
|
||||
var callMaterialCode = Guid.NewGuid().ToString();
|
||||
MaterialSend ReqEntity = new MaterialSend
|
||||
{
|
||||
code = callMaterialCode,
|
||||
orderID = dt.Rows[0]["派工单ID"].ToString(),
|
||||
taskID = dt.Rows[0]["taskId"].ToString(),
|
||||
sequenceNo = dt.Rows[0]["顺序号"].ToString(),
|
||||
deliveryType = deliveryType,
|
||||
processStep = dt.Rows[0]["工序号"].ToString(),
|
||||
startLocation = (deliveryType == "1" || deliveryType == "3" || deliveryType == "4" || deliveryType == "5" || deliveryType == "7") ? PositionCode : "",
|
||||
endLocation = (deliveryType == "2" || deliveryType == "6") ? PositionCode : "",
|
||||
material = dt.Rows[0]["物料号"].ToString(),
|
||||
quantity = Convert.ToInt32(dt.Rows[0]["数量"]),
|
||||
trayNumber = containerNo, //dt.Rows[0]["托盘号"].ToString(),
|
||||
prodline = "", // 产线
|
||||
workstation = "",
|
||||
workshop = "",
|
||||
customerid = "",
|
||||
creator = "Auto",
|
||||
createTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
|
||||
lastModifiedTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
|
||||
};
|
||||
string InterfaceUrl = ConfigurationManager.AppSettings["CallWebApiUrl_CallMaterial"];
|
||||
SaveLog_Interface_Request("CallWebApiUrl_CallMaterial", 1, JsonConvert.SerializeObject(ReqEntity), out int AID);
|
||||
var result = CALL_Interface_WebAPI.CALL_WebApi_CallMaterial(InterfaceUrl, ReqEntity);
|
||||
SaveLog_Interface_Response(result.ToString(), AID);
|
||||
//当上报失败时,保存上报内容至缓存表
|
||||
if (result["code"].ToString() != "200")
|
||||
{
|
||||
var param1 = new SqlParameter[] {
|
||||
new SqlParameter("@接口名称","CallWebApiUrl_CallMaterial"),
|
||||
new SqlParameter("@接口地址",InterfaceUrl),
|
||||
new SqlParameter("@请求内容",JsonConvert.SerializeObject(ReqEntity)),
|
||||
new SqlParameter("@响应内容",result.ToString())
|
||||
};
|
||||
DataLinkMesWork2.DataAccess2.ExecuteStoredProcedure("CallWebApi_FactoryMes_NGRecordSave", ref param1, out string errMessage1);
|
||||
SaveMesLog(PositionCode, $"叫料上报失败:配送类型={deliveryType}({deliveryTypeName}), 起始位置={ReqEntity.startLocation}, 终点位置={ReqEntity.endLocation}, 物料号={ReqEntity.material}, 叫料任务号={callMaterialCode}, 返回码={result["code"]}, 消息={result["message"]}", MesLogType.ERROR);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
SaveMesLog(PositionCode, $"叫料上报成功:配送类型={deliveryType}({deliveryTypeName}), 起始位置={ReqEntity.startLocation}, 终点位置={ReqEntity.endLocation}, 物料号={ReqEntity.material}, 叫料任务号={callMaterialCode}", MesLogType.INFO);
|
||||
}
|
||||
MisDataFun.Location_MIS_MOBY_Insert(PositionCode, "器具号", ReqEntity.trayNumber);
|
||||
MisDataFun.Location_MIS_MOBY_Insert(PositionCode, "叫料任务号", callMaterialCode);
|
||||
MisDataFun.Location_MIS_MOBY_Insert(PositionCode, "派工单ID", dt.Rows[0]["派工单ID"].ToString());
|
||||
MisDataFun.Location_MIS_MOBY_Insert(PositionCode, "派工任务ID", dt.Rows[0]["taskId"].ToString());
|
||||
MisDataFun.Location_MIS_MOBY_Insert(PositionCode, "订单号", dt.Rows[0]["订单号"].ToString());
|
||||
|
||||
var param2 = new SqlParameter[] {
|
||||
new SqlParameter("@叫料任务号",ReqEntity.code),
|
||||
new SqlParameter("@派工单ID",ReqEntity.orderID),
|
||||
new SqlParameter("@派工任务ID",ReqEntity.taskID),
|
||||
new SqlParameter("@顺序号",ReqEntity.sequenceNo),
|
||||
new SqlParameter("@配送类型",ReqEntity.deliveryType),
|
||||
new SqlParameter("@工序",ReqEntity.processStep),
|
||||
new SqlParameter("@起始位置编号",ReqEntity.startLocation),
|
||||
new SqlParameter("@终点位置编号",ReqEntity.endLocation),
|
||||
new SqlParameter("@配送物料编码",ReqEntity.material),
|
||||
new SqlParameter("@配送数量",ReqEntity.quantity),
|
||||
new SqlParameter("@器具号",ReqEntity.trayNumber),
|
||||
new SqlParameter("@创建人编号",ReqEntity.creator),
|
||||
new SqlParameter("@创建时间",ReqEntity.createTime),
|
||||
new SqlParameter("@最后修改时间",ReqEntity.lastModifiedTime),
|
||||
};
|
||||
DataLinkMesWork2.DataAccess2.ExecuteStoredProcedure("MOM_生产任务_派工任务_叫料记录_增加", ref param2, out string errMessage2);
|
||||
}
|
||||
else
|
||||
{
|
||||
SaveLog_Interface_Request("CallWebApi_FactoryMes_DeviceAlarm", 1, $"查询记录数为0:工序号={PositionCode}", out int AID);
|
||||
SaveMesLog(PositionCode, $"叫料查询记录数为0:配送类型={deliveryType}({deliveryTypeName})", MesLogType.WARNING);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 物料配送确认
|
||||
/// </summary>
|
||||
/// <param name="PositionCode">位置号</param>
|
||||
/// <param name="containerNo">器具号</param>
|
||||
public static bool CALL_Inerface_MaterialConfirm(string PositionCode, string containerNo)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 调用存储过程获取叫料任务号和派工任务ID
|
||||
var param = new SqlParameter[] {
|
||||
new SqlParameter("@位置号", PositionCode),
|
||||
new SqlParameter("@器具号", containerNo)
|
||||
};
|
||||
|
||||
DataLinkMesWork2.DataAccess2.ExecuteStoredProcedure("MOM_生产任务_派工任务_叫料记录_到料确认", ref param, out DataTable dtResult, out string errMessage);
|
||||
|
||||
if (dtResult == null || dtResult.Rows.Count == 0)
|
||||
{
|
||||
SaveLog_Interface_Request("CallWebApiUrl_MaterialInfoConfirm", 0,
|
||||
$"获取叫料记录失败:位置号={PositionCode}, 器具号={containerNo}, 错误信息={errMessage}", out int errorAID);
|
||||
SaveMesLog(PositionCode, $"物料配送确认-获取叫料记录失败:器具号={containerNo}, 错误={errMessage}", MesLogType.ERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 获取存储过程返回的数据
|
||||
string tackcode = dtResult.Rows[0]["叫料任务号"].ToString();
|
||||
string taskID = dtResult.Rows[0]["派工任务ID"].ToString();
|
||||
|
||||
MaterialConfirm materialConfirm = new MaterialConfirm
|
||||
{
|
||||
tackcode = tackcode, // 从存储过程获取的配送任务号
|
||||
orderID = "", // 派工单ID
|
||||
taskID = taskID, // 从存储过程获取的派工任务ID
|
||||
processId = PositionCode, // 工序ID
|
||||
containerNo = containerNo // 器具号
|
||||
};
|
||||
|
||||
string InterfaceUrl = ConfigurationManager.AppSettings["CallWebApiUrl_MaterialInfoConfirm"];
|
||||
var result = CALL_Interface_WebAPI.CALL_WebApi_MaterialConfirm(InterfaceUrl, materialConfirm);
|
||||
SaveLog_Interface_Request("CallWebApiUrl_MaterialInfoConfirm", 1, JsonConvert.SerializeObject(materialConfirm), out int AID);
|
||||
SaveLog_Interface_Response(result.ToString(), AID);
|
||||
|
||||
//当上报失败时,保存上报内容至缓存表
|
||||
if (result["code"].ToString() != "200")
|
||||
{
|
||||
var param1 = new SqlParameter[] {
|
||||
new SqlParameter("@接口名称","CallWebApiUrl_MaterialInfoConfirm"),
|
||||
new SqlParameter("@接口地址",InterfaceUrl),
|
||||
new SqlParameter("@请求内容",JsonConvert.SerializeObject(materialConfirm)),
|
||||
new SqlParameter("@响应内容",result.ToString())
|
||||
};
|
||||
DataLinkMesWork2.DataAccess2.ExecuteStoredProcedure("CallWebApi_FactoryMes_NGRecordSave", ref param1, out string errMessage1);
|
||||
SaveMesLog(PositionCode, $"物料配送确认上报失败:器具号={containerNo}, 叫料任务号={tackcode}, 返回码={result["code"]}, 消息={result["message"]}", MesLogType.ERROR);
|
||||
return false;
|
||||
}
|
||||
SaveMesLog(PositionCode, $"物料配送确认上报成功:器具号={containerNo}, 叫料任务号={tackcode}", MesLogType.INFO);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SaveLog_Interface_Request("CallWebApiUrl_MaterialInfoConfirm", 0,
|
||||
$"物料配送确认异常:{ex.Message}", out int exceptionAID);
|
||||
SaveMesLog("MOM", $"物料配送确认异常:位置号={PositionCode}, 器具号={containerNo}, 异常={ex.Message}", MesLogType.ERROR);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 器具信息查询
|
||||
/// </summary>
|
||||
/// <param name="PositionCode">位置号</param>
|
||||
/// <param name="containerNo">托盘号</param>
|
||||
/// <returns>器具信息查询结果</returns>
|
||||
public static DeviceInfoResponse CALL_Inerface_DeviceInfoQuery(string PositionCode, string containerNo)
|
||||
{
|
||||
// 通过位置号查询任务号
|
||||
var param = new SqlParameter[] {
|
||||
new SqlParameter("@位置号",PositionCode)
|
||||
};
|
||||
DataLinkMesWork2.DataAccess2.ExecuteStoredProcedure("MOM_生产任务_派工任务_叫料记录_器具查询", ref param, out DataTable dt, out string errMessage);
|
||||
|
||||
if (dt.Rows.Count > 0)
|
||||
{
|
||||
string taskId = dt.Rows[0]["任务号"].ToString();
|
||||
|
||||
DeviceInfo deviceInfo = new DeviceInfo
|
||||
{
|
||||
id = taskId, // 使用查询出的任务号
|
||||
callcode = "",
|
||||
containerNo = containerNo
|
||||
};
|
||||
|
||||
string InterfaceUrl = ConfigurationManager.AppSettings["CallWebApiUrl_DeviceInfoQuery"];
|
||||
SaveLog_Interface_Request("CallWebApiUrl_DeviceInfoQuery", 1, JsonConvert.SerializeObject(deviceInfo), out int AID);
|
||||
var result = CALL_Interface_WebAPI.CALL_WebApi_DeviceInfoQuery(InterfaceUrl, deviceInfo);
|
||||
SaveLog_Interface_Response(result.ToString(), AID);
|
||||
|
||||
// 解析返回结果
|
||||
DeviceInfoResponse response = JsonConvert.DeserializeObject<DeviceInfoResponse>(result.ToString());
|
||||
|
||||
//当上报失败时,保存上报内容至缓存表
|
||||
if (result["code"].ToString() != "200")
|
||||
{
|
||||
var param1 = new SqlParameter[] {
|
||||
new SqlParameter("@接口名称","CallWebApiUrl_DeviceInfoQuery"),
|
||||
new SqlParameter("@接口地址",InterfaceUrl),
|
||||
new SqlParameter("@请求内容",JsonConvert.SerializeObject(deviceInfo)),
|
||||
new SqlParameter("@响应内容",result.ToString())
|
||||
};
|
||||
DataLinkMesWork2.DataAccess2.ExecuteStoredProcedure("CallWebApi_FactoryMes_NGRecordSave", ref param1, out string errMessage1);
|
||||
SaveMesLog(PositionCode, $"器具信息查询失败:位置号={PositionCode}, 器具号={containerNo}, 任务号={taskId}, 返回码={result["code"]}, 消息={result["message"]}", MesLogType.ERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
SaveMesLog(PositionCode, $"器具信息查询成功:位置号={PositionCode}, 器具号={containerNo}, 任务号={taskId}", MesLogType.INFO);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
else
|
||||
{
|
||||
SaveLog_Interface_Request("CALL_Inerface_DeviceInfoQuery", 1, $"查询记录数为0:位置号={PositionCode}", out int AID);
|
||||
|
||||
// 返回空结果
|
||||
return new DeviceInfoResponse
|
||||
{
|
||||
code = 404,
|
||||
message = $"查询记录数为0:位置号={PositionCode}",
|
||||
data = null
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 物料转序
|
||||
/// </summary>
|
||||
/// <param name="startPositionCode">起始位置编号</param>
|
||||
/// <param name="endPositionCode">终点位置编号</param>
|
||||
/// <param name="taskType">任务模板编号</param>
|
||||
/// <param name="dataid">派工任务id</param>
|
||||
/// <param name="moveTaskType">搬运类型:1:搬运容器,2:搬运货架</param>
|
||||
/// <param name="vehicleStatus">载具类型:0-空;1-满</param>
|
||||
/// <returns>返回调用结果 JObject,包含 code 和 message</returns>
|
||||
public static JObject CALL_Inerface_MaterialTransfer(string startPositionCode, string endPositionCode, string taskType = "211", string dataid = "", string moveTaskType = "2", string vehicleStatus = "1")
|
||||
{
|
||||
JObject response = new JObject();
|
||||
try
|
||||
{
|
||||
// 构建位置列表
|
||||
List<PositionInfo> positionList = new List<PositionInfo>
|
||||
{
|
||||
new PositionInfo
|
||||
{
|
||||
type = "00", // 工位
|
||||
positionCode = startPositionCode
|
||||
},
|
||||
new PositionInfo
|
||||
{
|
||||
type = "00", // 工位
|
||||
positionCode = endPositionCode
|
||||
}
|
||||
};
|
||||
|
||||
MaterialTransfer ReqEntity = new MaterialTransfer
|
||||
{
|
||||
reqCode = Guid.NewGuid().ToString(),
|
||||
reqTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
|
||||
clientCode = "126GIS",
|
||||
taskType = taskType,
|
||||
moveTaskType = moveTaskType,
|
||||
vehicleStatus = vehicleStatus,
|
||||
positionCodeList = positionList,
|
||||
dataid = dataid
|
||||
};
|
||||
|
||||
string InterfaceUrl = ConfigurationManager.AppSettings["CallWebApiUrl_MaterialTransfer"];
|
||||
SaveLog_Interface_Request("CALL_WebApi_MaterialTransfer", 1, JsonConvert.SerializeObject(ReqEntity), out int AID);
|
||||
var result = CALL_Interface_WebAPI.CALL_WebApi_MaterialTransfer(InterfaceUrl, ReqEntity);
|
||||
SaveLog_Interface_Response(result.ToString(), AID);
|
||||
|
||||
//当上报失败时,保存上报内容至缓存表
|
||||
if (result["code"].ToString() != "200")
|
||||
{
|
||||
var param1 = new SqlParameter[] {
|
||||
new SqlParameter("@接口名称","CALL_WebApi_MaterialTransfer"),
|
||||
new SqlParameter("@接口地址",InterfaceUrl),
|
||||
new SqlParameter("@请求内容",JsonConvert.SerializeObject(ReqEntity)),
|
||||
new SqlParameter("@响应内容",result.ToString())
|
||||
};
|
||||
DataLinkMesWork2.DataAccess2.ExecuteStoredProcedure("CallWebApi_FactoryMes_NGRecordSave", ref param1, out string errMessage1);
|
||||
|
||||
string errorMsg = result["message"]?.ToString() ?? "未知错误";
|
||||
SaveMesLog("MOM", $"物料转序上报失败:起点={startPositionCode}终点={endPositionCode}, 返回码={result["code"]}, 消息={errorMsg}", MesLogType.ERROR);
|
||||
|
||||
response["code"] = result["code"];
|
||||
response["message"] = errorMsg;
|
||||
}
|
||||
else
|
||||
{
|
||||
SaveMesLog("MOM", $"物料转序上报成功:起点={startPositionCode}终点={endPositionCode}", MesLogType.INFO);
|
||||
response["code"] = 200;
|
||||
response["message"] = "AGV调度成功";
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SaveLog_Interface_Request("CALL_WebApi_MaterialTransfer", 0,
|
||||
$"物料转序异常:{ex.Message}", out int exceptionAID);
|
||||
SaveMesLog("MOM", $"物料转序异常:起点={startPositionCode}终点={endPositionCode}, 异常={ex.Message}", MesLogType.ERROR);
|
||||
|
||||
response["code"] = 500;
|
||||
response["message"] = $"物料转序异常:{ex.Message}";
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 点检结果上传
|
||||
/// </summary>
|
||||
/// <param name="reqEntity">点检结果实体</param>
|
||||
/// <returns>工厂MES响应</returns>
|
||||
public static JObject CALL_Inerface_SpotCheckResultUpload(SpotCheckResult reqEntity)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (reqEntity == null)
|
||||
{
|
||||
SaveMesLog("MOM", "点检结果上传失败:点检结果不能为空", MesLogType.ERROR);
|
||||
throw new ArgumentNullException(nameof(reqEntity), "点检结果不能为空");
|
||||
}
|
||||
|
||||
if (reqEntity.ResultData == null || reqEntity.ResultData.Count == 0)
|
||||
{
|
||||
SaveMesLog("MOM", "点检结果上传失败:点检结果缺少明细数据", MesLogType.ERROR);
|
||||
throw new Exception("点检结果缺少明细数据");
|
||||
}
|
||||
|
||||
string interfaceUrl = ConfigurationManager.AppSettings["CallWebApiUrl_SpotCheckRecordCreate"];
|
||||
if (string.IsNullOrWhiteSpace(interfaceUrl))
|
||||
{
|
||||
SaveMesLog("MOM", "点检结果上传失败:未配置 CallWebApiUrl_SpotCheckRecordCreate", MesLogType.ERROR);
|
||||
throw new Exception("未配置 CallWebApiUrl_SpotCheckRecordCreate");
|
||||
}
|
||||
|
||||
string requestName = "CALL_WebApi_SpotCheckRecordCreate";
|
||||
string requestBody = JsonConvert.SerializeObject(reqEntity);
|
||||
SaveLog_Interface_Request(requestName, 1, requestBody, out int AID);
|
||||
|
||||
var result = CALL_Interface_WebAPI.CALL_WebApi_SpotCheckRecord(interfaceUrl, reqEntity);
|
||||
SaveLog_Interface_Response(result.ToString(), AID);
|
||||
|
||||
var codeToken = result["code"];
|
||||
if (codeToken == null || codeToken.ToString() != "200")
|
||||
{
|
||||
MisDataFun.CallWebApi_FactoryMes_NGRecordSave(requestName, AID, interfaceUrl, requestBody, result.ToString());
|
||||
|
||||
string errorMsg = result["message"]?.ToString() ?? "未知错误";
|
||||
string code = codeToken?.ToString() ?? "null";
|
||||
SaveMesLog("MOM", $"点检结果上报失败:返回码={code}, 消息={errorMsg}", MesLogType.ERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
SaveMesLog("MOM", "点检结果上报成功", MesLogType.INFO);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SaveMesLog("MOM", $"点检结果上传异常:{ex.Message}", MesLogType.ERROR);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
//#region 西开 AGV 发送方法 (MES -> AGV)
|
||||
|
||||
///// <summary>
|
||||
///// 下发任务给 AGV
|
||||
///// MES 调用 AGV 接口,下发搬运任务
|
||||
///// </summary>
|
||||
///// <param name="requestTaskId">任务唯一ID(由调用方生成,如 Guid)</param>
|
||||
///// <param name="startPosition">抬货点/取货位置</param>
|
||||
///// <param name="endPosition">卸货点/目标位置</param>
|
||||
///// <param name="materialCode">产品编码/物料编码</param>
|
||||
///// <returns>AGV 响应结果</returns>
|
||||
//public static JObject CALL_ZZAGV_AddTask(string requestTaskId, string startPosition, string endPosition, string materialCode)
|
||||
//{
|
||||
// JObject response = new JObject();
|
||||
// try
|
||||
// {
|
||||
// // 参数校验
|
||||
// if (string.IsNullOrWhiteSpace(requestTaskId))
|
||||
// {
|
||||
// requestTaskId = Guid.NewGuid().ToString();
|
||||
// }
|
||||
|
||||
// if (string.IsNullOrWhiteSpace(startPosition))
|
||||
// {
|
||||
// throw new ArgumentException("抬货点(startPosition)不能为空");
|
||||
// }
|
||||
|
||||
// if (string.IsNullOrWhiteSpace(endPosition))
|
||||
// {
|
||||
// throw new ArgumentException("卸货点(endPosition)不能为空");
|
||||
// }
|
||||
|
||||
// // 构建请求实体
|
||||
// var reqEntity = new MisDataSaveDate.ZZAGV_AddTaskRequest
|
||||
// {
|
||||
// requestTaskId = requestTaskId,
|
||||
// startPosition = startPosition,
|
||||
// endPosition = endPosition,
|
||||
// materialCode = materialCode ?? ""
|
||||
// };
|
||||
|
||||
// // 获取 AGV 接口地址
|
||||
// string baseUrl = ConfigurationManager.AppSettings["ZZAGV_BaseUrl"];
|
||||
// if (string.IsNullOrWhiteSpace(baseUrl))
|
||||
// {
|
||||
// throw new Exception("未配置 ZZAGV_BaseUrl");
|
||||
// }
|
||||
// string interfaceUrl = baseUrl.TrimEnd('/') + "/api/mes/AddTaskFromMes";
|
||||
|
||||
// string jsonStr = JsonConvert.SerializeObject(reqEntity);
|
||||
// SaveLog_Interface_Request("CALL_ZZAGV_AddTask", 1, jsonStr, out int AID);
|
||||
|
||||
// // 发送 HTTP 请求
|
||||
// string resultStr = "";
|
||||
// try
|
||||
// {
|
||||
// resultStr = WebApi.Post.Post_Auto(interfaceUrl, jsonStr);
|
||||
// }
|
||||
// catch (Exception httpEx)
|
||||
// {
|
||||
// SaveMesLog("ZZAGV", $"下发任务HTTP请求异常:起点={startPosition}, 终点={endPosition}, 异常={httpEx.Message}", MesLogType.ERROR);
|
||||
// SaveLog_Interface_Response($"HTTP请求异常:{httpEx.Message}", AID);
|
||||
// response["code"] = 500;
|
||||
// response["desc"] = $"HTTP请求异常:{httpEx.Message}";
|
||||
// response["success"] = false;
|
||||
// return response;
|
||||
// }
|
||||
|
||||
// SaveLog_Interface_Response(resultStr, AID);
|
||||
|
||||
// // 解析响应
|
||||
// if (string.IsNullOrWhiteSpace(resultStr))
|
||||
// {
|
||||
// SaveMesLog("ZZAGV", "下发任务失败:AGV返回空响应", MesLogType.ERROR);
|
||||
// response["code"] = 500;
|
||||
// response["desc"] = "AGV返回空响应";
|
||||
// response["success"] = false;
|
||||
// return response;
|
||||
// }
|
||||
|
||||
// response = JObject.Parse(resultStr);
|
||||
|
||||
// // 检查返回码
|
||||
// string code = response["code"]?.ToString();
|
||||
// if (code != "0")
|
||||
// {
|
||||
// string desc = response["desc"]?.ToString() ?? "未知错误";
|
||||
// SaveMesLog("ZZAGV", $"下发任务失败:任务ID={requestTaskId}, 起点={startPosition}, 终点={endPosition}, 返回码={code}, 消息={desc}", MesLogType.ERROR);
|
||||
|
||||
// // 保存失败记录
|
||||
// MisDataFun.CallWebApi_FactoryMes_NGRecordSave("CALL_ZZAGV_AddTask", AID, interfaceUrl, jsonStr, resultStr);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// SaveMesLog("ZZAGV", $"下发任务成功:任务ID={requestTaskId}, 起点={startPosition}, 终点={endPosition}", MesLogType.INFO);
|
||||
// }
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// SaveMesLog("ZZAGV", $"下发任务异常:{ex.Message}", MesLogType.ERROR);
|
||||
// response["code"] = 500;
|
||||
// response["desc"] = $"异常:{ex.Message}";
|
||||
// response["success"] = false;
|
||||
// }
|
||||
|
||||
// return response;
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// 放行 AGV
|
||||
///// MES 调用 AGV 接口,告知 AGV 可以离开当前位置
|
||||
///// </summary>
|
||||
///// <param name="requestId">请求ID</param>
|
||||
///// <param name="position">当前位置编号</param>
|
||||
///// <returns>AGV 响应结果</returns>
|
||||
//public static JObject CALL_ZZAGV_AllowLeave(string requestId, string position)
|
||||
//{
|
||||
// JObject response = new JObject();
|
||||
// try
|
||||
// {
|
||||
// // 参数校验
|
||||
// if (string.IsNullOrWhiteSpace(requestId))
|
||||
// {
|
||||
// requestId = Guid.NewGuid().ToString();
|
||||
// }
|
||||
|
||||
// if (string.IsNullOrWhiteSpace(position))
|
||||
// {
|
||||
// throw new ArgumentException("位置编号(position)不能为空");
|
||||
// }
|
||||
|
||||
// // 构建请求实体
|
||||
// var reqEntity = new MisDataSaveDate.ZZAGV_AllowLeaveRequest
|
||||
// {
|
||||
// requestId = requestId,
|
||||
// position = position,
|
||||
// allowLeave = 1
|
||||
// };
|
||||
|
||||
// // 获取 AGV 接口地址
|
||||
// string baseUrl = ConfigurationManager.AppSettings["ZZAGV_BaseUrl"];
|
||||
// if (string.IsNullOrWhiteSpace(baseUrl))
|
||||
// {
|
||||
// throw new Exception("未配置 ZZAGV_BaseUrl");
|
||||
// }
|
||||
// string interfaceUrl = baseUrl.TrimEnd('/') + "/api/mes/AllowLeave";
|
||||
|
||||
// string jsonStr = JsonConvert.SerializeObject(reqEntity);
|
||||
// SaveLog_Interface_Request("CALL_ZZAGV_AllowLeave", 1, jsonStr, out int AID);
|
||||
|
||||
// // 发送 HTTP 请求
|
||||
// string resultStr = "";
|
||||
// try
|
||||
// {
|
||||
// resultStr = WebApi.Post.Post_Auto(interfaceUrl, jsonStr);
|
||||
// }
|
||||
// catch (Exception httpEx)
|
||||
// {
|
||||
// SaveMesLog("ZZAGV", $"放行AGV HTTP请求异常:位置={position}, 异常={httpEx.Message}", MesLogType.ERROR);
|
||||
// SaveLog_Interface_Response($"HTTP请求异常:{httpEx.Message}", AID);
|
||||
// response["code"] = 500;
|
||||
// response["desc"] = $"HTTP请求异常:{httpEx.Message}";
|
||||
// response["success"] = false;
|
||||
// return response;
|
||||
// }
|
||||
|
||||
// SaveLog_Interface_Response(resultStr, AID);
|
||||
|
||||
// // 解析响应
|
||||
// if (string.IsNullOrWhiteSpace(resultStr))
|
||||
// {
|
||||
// SaveMesLog("ZZAGV", "放行AGV失败:AGV返回空响应", MesLogType.ERROR);
|
||||
// response["code"] = 500;
|
||||
// response["desc"] = "AGV返回空响应";
|
||||
// response["success"] = false;
|
||||
// return response;
|
||||
// }
|
||||
|
||||
// response = JObject.Parse(resultStr);
|
||||
|
||||
// // 检查返回码
|
||||
// string code = response["code"]?.ToString();
|
||||
// if (code != "0")
|
||||
// {
|
||||
// string desc = response["desc"]?.ToString() ?? "未知错误";
|
||||
// SaveMesLog("ZZAGV", $"放行AGV失败:请求ID={requestId}, 位置={position}, 返回码={code}, 消息={desc}", MesLogType.ERROR);
|
||||
|
||||
// // 保存失败记录
|
||||
// MisDataFun.CallWebApi_FactoryMes_NGRecordSave("CALL_ZZAGV_AllowLeave", AID, interfaceUrl, jsonStr, resultStr);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// SaveMesLog("ZZAGV", $"放行AGV成功:请求ID={requestId}, 位置={position}", MesLogType.INFO);
|
||||
// }
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// SaveMesLog("ZZAGV", $"放行AGV异常:{ex.Message}", MesLogType.ERROR);
|
||||
// response["code"] = 500;
|
||||
// response["desc"] = $"异常:{ex.Message}";
|
||||
// response["success"] = false;
|
||||
// }
|
||||
|
||||
// return response;
|
||||
//}
|
||||
|
||||
//#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using MisDataSaveDate.MOM;
|
||||
using Newtonsoft.Json;
|
||||
using System.Configuration;
|
||||
using ExternalDataSync;
|
||||
namespace WebApi
|
||||
{
|
||||
public class CALL_Interface_WebAPI
|
||||
{
|
||||
|
||||
public static JObject CALL_WebApi_CallMaterial(string InterfaceUrl, MaterialSend entity_send)
|
||||
{
|
||||
//string InterfaceUrl = ConfigurationManager.AppSettings["CallWebApiUrl_CallMaterial"];
|
||||
string bodydata = JsonConvert.SerializeObject(entity_send);
|
||||
return Post_WebAPI(InterfaceUrl, bodydata);
|
||||
}
|
||||
public static JObject CALL_WebApi_DeviceInfoQuery(string InterfaceUrl, DeviceInfo entity_send)
|
||||
{
|
||||
//string InterfaceUrl = ConfigurationManager.AppSettings["CallWebApiUrl_DeviceInfoQuery"];
|
||||
string bodydata = JsonConvert.SerializeObject(entity_send);
|
||||
return Post_WebAPI(InterfaceUrl, bodydata);
|
||||
}
|
||||
public static JObject CALL_WebApi_MaterialConfirm(string InterfaceUrl, MaterialConfirm entity_send)
|
||||
{
|
||||
//var InterfaceUrl = CallWebApiUrl_MaterialInfoConfirm;
|
||||
//string InterfaceUrl = ConfigurationManager.AppSettings["CallWebApiUrl_MaterialInfoConfirm"];
|
||||
string bodydata = JsonConvert.SerializeObject(entity_send);
|
||||
return Post_WebAPI(InterfaceUrl, bodydata);
|
||||
}
|
||||
public static JObject CALL_WebApi_JobStart(string InterfaceUrl, JobStart entity_send)
|
||||
{
|
||||
//string InterfaceUrl = ConfigurationManager.AppSettings["CallWebApiUrl_ProcessJobStart"];
|
||||
string bodydata = JsonConvert.SerializeObject(entity_send);
|
||||
return Post_WebAPI(InterfaceUrl, bodydata);
|
||||
}
|
||||
public static JObject CALL_WebApi_DeviceAlarm(string InterfaceUrl, DeviceAlarm entity_send)
|
||||
{
|
||||
//var InterfaceUrl = CallWebApiUrl_AlarmInfoUpload;
|
||||
//string InterfaceUrl = ConfigurationManager.AppSettings["CallWebApiUrl_AlarmInfoUpload"];
|
||||
string bodydata = JsonConvert.SerializeObject(entity_send);
|
||||
return Post_WebAPI(InterfaceUrl, bodydata);
|
||||
}
|
||||
public static JObject CALL_WebApi_JobFinished(string InterfaceUrl, JobFinished entity_send)
|
||||
{
|
||||
//var InterfaceUrl = CallWebApiUrl_ProcessJobFinish;
|
||||
//string InterfaceUrl = ConfigurationManager.AppSettings["CallWebApiUrl_ProcessJobFinish"];
|
||||
string bodydata = JsonConvert.SerializeObject(entity_send);
|
||||
return Post_WebAPI(InterfaceUrl, bodydata);
|
||||
}
|
||||
public static JObject CALL_WebApi_FinishedReport(TaskFinish entity_send)
|
||||
{
|
||||
//var InterfaceUrl = CallWebApiUrl_TaskFinishedReport;
|
||||
string InterfaceUrl = ConfigurationManager.AppSettings["CallWebApiUrl_TaskFinishedReport"];
|
||||
string bodydata = JsonConvert.SerializeObject(entity_send);
|
||||
return Post_WebAPI(InterfaceUrl, bodydata);
|
||||
}
|
||||
public static JObject CALL_WebApi_MaterialTransfer(string InterfaceUrl, MaterialTransfer entity_send)
|
||||
{
|
||||
//string InterfaceUrl = ConfigurationManager.AppSettings["CallWebApiUrl_MaterialTransfer"];
|
||||
string bodydata = JsonConvert.SerializeObject(entity_send);
|
||||
return Post_WebAPI(InterfaceUrl, bodydata);
|
||||
}
|
||||
public static JObject CALL_WebApi_SpotCheckRecord(string InterfaceUrl, SpotCheckResult entity_send)
|
||||
{
|
||||
string bodydata = JsonConvert.SerializeObject(entity_send);
|
||||
return Post_WebAPI(InterfaceUrl, bodydata);
|
||||
}
|
||||
public static JObject Post_WebAPI(string WebAPI_Url, string m_msg)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (StateVariable.online_Mes)
|
||||
{
|
||||
return JsonConvert.DeserializeObject<JObject>(WebApi.Post.Post_XK(WebAPI_Url, m_msg));
|
||||
}
|
||||
else
|
||||
{
|
||||
return JObject.Parse("{\"code\":404,\"离线工作模式,请求暂存。\":\"\",\"data\":{}}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new JObject { { "code", 500 }, { "Message", ex.Message }, { "data", new JObject() } };
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
145
Interface_WebAPI/SlMesDbIterface/WebAPI/Helper/ApiLogHelper.cs
Normal file
145
Interface_WebAPI/SlMesDbIterface/WebAPI/Helper/ApiLogHelper.cs
Normal file
@@ -0,0 +1,145 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MisDataSaveDate.Helper
|
||||
{
|
||||
/// <summary>
|
||||
/// MES系统日志类型枚举
|
||||
/// </summary>
|
||||
public enum MesLogType
|
||||
{
|
||||
/// <summary>
|
||||
/// 信息日志
|
||||
/// </summary>
|
||||
INFO,
|
||||
/// <summary>
|
||||
/// 警告日志
|
||||
/// </summary>
|
||||
WARNING,
|
||||
/// <summary>
|
||||
/// 错误日志
|
||||
/// </summary>
|
||||
ERROR
|
||||
}
|
||||
public class ApiLogHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 验证属性值是否有效
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="fieldName"></param>
|
||||
/// <param name="errorMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static bool ValidateProperty(object value, string fieldName, out string errorMessage)
|
||||
{
|
||||
if (value == null || value.ToString() == "")
|
||||
{
|
||||
errorMessage = $"参数{fieldName}值格式不正确";
|
||||
return false;
|
||||
}
|
||||
|
||||
errorMessage = string.Empty; // 无错误
|
||||
return true;
|
||||
}
|
||||
/// <summary>
|
||||
/// 非必填项Null值处理
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="fieldName"></param>
|
||||
/// <param name="errorMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static string VHandle(string value)
|
||||
{
|
||||
return value == null ? "" : value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="type">1. 主动调用接口 2. 被调用接口 </param>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="AID"></param>
|
||||
/// <param name="errorMessage"></param>
|
||||
public static void SaveLog_Interface_Request(string url, int type, string context, out int AID)
|
||||
{
|
||||
//存储日志
|
||||
var CreateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
|
||||
var param1 = new SqlParameter[] {
|
||||
new SqlParameter("@接口地址",url),
|
||||
new SqlParameter("@接口类型",type),
|
||||
new SqlParameter("@请求内容",context),
|
||||
new SqlParameter("@请求时间",CreateTime)
|
||||
};
|
||||
DataLinkMesWork2.DataAccess2.ExecuteStoredProcedure("接口_IOT接口交互日志_请求记录", ref param1, out DataTable dt, out string errorMessage);
|
||||
AID = int.Parse(dt.Rows[0][0].ToString());
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="AID"></param>
|
||||
public static void SaveLog_Interface_Response(string context, int AID)
|
||||
{
|
||||
//存储日志
|
||||
var CreateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
|
||||
//Event_MOM_Log_Insert,@创建时间,@内容
|
||||
var param1 = new SqlParameter[] {
|
||||
new SqlParameter("@响应时间",CreateTime),
|
||||
new SqlParameter("@响应内容",context),
|
||||
new SqlParameter("@AID",AID)
|
||||
};
|
||||
DataLinkMesWork2.DataAccess2.ExecuteStoredProcedure("接口_IOT接口交互日志_响应记录", ref param1, out string errorMessage);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 保存MES系统日志到数据库
|
||||
/// </summary>
|
||||
/// <param name="opName">工位号/模块名称</param>
|
||||
/// <param name="logText">日志内容</param>
|
||||
/// <param name="logType">日志类型:INFO/WARNING/ERROR</param>
|
||||
public static void SaveMesLog(string opName, string logText, MesLogType logType = MesLogType.INFO)
|
||||
{
|
||||
string logTypeStr = logType.ToString();
|
||||
var param1 = new SqlParameter[] {
|
||||
new SqlParameter("@工位号", opName),
|
||||
new SqlParameter("@日志类型", logTypeStr),
|
||||
new SqlParameter("@日志文本", logText),
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
DataLinkMesWork2.DataAccess2.ExecuteStoredProcedure("MES_系统日志_增加", ref param1, out DataTable dt, out string errorMessage);
|
||||
|
||||
// 同时记录到Log4Net
|
||||
if (logType == MesLogType.ERROR)
|
||||
{
|
||||
MyLog4Net.MyLogHelper.Error("MesLog", $"[{opName}] {logText}");
|
||||
}
|
||||
else if (logType == MesLogType.WARNING)
|
||||
{
|
||||
MyLog4Net.MyLogHelper.Error("MesLog", $"[{opName}] {logText}");
|
||||
}
|
||||
else
|
||||
{
|
||||
MyLog4Net.MyLogHelper.Info("MesLog", $"[{opName}] {logText}");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(errorMessage))
|
||||
{
|
||||
MyLog4Net.MyLogHelper.Error("SaveMesLog", $"保存日志到数据库失败:{errorMessage}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MyLog4Net.MyLogHelper.Error("SaveMesLog", $"保存日志异常:{ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
361
Interface_WebAPI/SlMesDbIterface/WebAPI/Other/CheckDate.cs
Normal file
361
Interface_WebAPI/SlMesDbIterface/WebAPI/Other/CheckDate.cs
Normal file
@@ -0,0 +1,361 @@
|
||||
using MisDataSaveDate;
|
||||
using MisDataSaveDate.MOM;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Http;
|
||||
using DataLinkMesWork2;
|
||||
using static MisDataSaveDate.Helper.ApiLogHelper;
|
||||
using MisDataFunDll;
|
||||
|
||||
namespace ExternalDataSync.MOM
|
||||
{
|
||||
public class Other
|
||||
{
|
||||
public static string OnlineCheckData(string url, [FromBody] JObject jobj)
|
||||
{
|
||||
var result = new OnlineCheckDataResponse();
|
||||
result.Code = "200";
|
||||
result.Message = "";
|
||||
result.MsgId = "";
|
||||
result.Data = "";
|
||||
|
||||
string errorMessage = string.Empty;
|
||||
|
||||
if (jobj == null)
|
||||
{
|
||||
result.Code = "500";
|
||||
result.Message = "参数格式不正确!";
|
||||
string retString1 = JsonConvert.SerializeObject(result);
|
||||
MyLog4Net.MyLogHelper.Info("接收检测数据_res", retString1);
|
||||
return retString1;
|
||||
}
|
||||
|
||||
string str = jobj.ToString();
|
||||
// 存储接口请求日志
|
||||
SaveLog_Interface_Request(url, 2, str, out int AID);
|
||||
|
||||
try
|
||||
{
|
||||
OnlineCheckData onlineCheckData = JsonConvert.DeserializeObject<OnlineCheckData>(str);
|
||||
if (onlineCheckData == null)
|
||||
{
|
||||
throw new Exception("请求体反序列化失败!");
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(onlineCheckData.MsgId))
|
||||
{
|
||||
throw new Exception("参数MsgId为空!");
|
||||
}
|
||||
// 设置响应的MsgId(带回请求编号)
|
||||
result.MsgId = onlineCheckData.MsgId;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(onlineCheckData.OpCode))
|
||||
{
|
||||
throw new Exception("参数OpCode为空!");
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(onlineCheckData.ProductionCode))
|
||||
{
|
||||
throw new Exception("参数ProductionCode为空!");
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(onlineCheckData.ScanTime))
|
||||
{
|
||||
throw new Exception("参数ScanTime为空!");
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(onlineCheckData.CheckPerson))
|
||||
{
|
||||
throw new Exception("参数CheckPerson为空!");
|
||||
}
|
||||
|
||||
string opName = onlineCheckData.OpCode;
|
||||
int idTagCf = 0;
|
||||
|
||||
SqlParameter[] paramIndex = new SqlParameter[8];
|
||||
paramIndex[0] = new SqlParameter("@EngineID", onlineCheckData.ProductionCode);
|
||||
paramIndex[1] = new SqlParameter("@工位号", opName);
|
||||
paramIndex[2] = new SqlParameter("@操作者工号", onlineCheckData.CheckPerson);
|
||||
paramIndex[3] = new SqlParameter("@扫码时间", onlineCheckData.ScanTime);
|
||||
paramIndex[4] = new SqlParameter("@合格标志", onlineCheckData.QualityMark);
|
||||
paramIndex[5] = new SqlParameter("@完成时间", onlineCheckData.EndTime);
|
||||
paramIndex[6] = new SqlParameter("@能耗", onlineCheckData.Powerused);
|
||||
paramIndex[7] = new SqlParameter("@Id_tagCF", SqlDbType.Int)
|
||||
{
|
||||
Direction = ParameterDirection.Output
|
||||
};
|
||||
|
||||
DataAccess2.ExecuteStoredProcedure("测量数据合格索引_增加_测试设备", ref paramIndex, out errorMessage);
|
||||
if (!string.IsNullOrEmpty(errorMessage))
|
||||
{
|
||||
throw new Exception(errorMessage);
|
||||
}
|
||||
|
||||
if (paramIndex[7].Value == null || paramIndex[7].Value == DBNull.Value)
|
||||
{
|
||||
throw new Exception("测量数据合格索引_增加_测试设备 未返回Id_tagCF!");
|
||||
}
|
||||
|
||||
idTagCf = Convert.ToInt32(paramIndex[7].Value);
|
||||
|
||||
List<OnlineCheckData_CheckData> detailList = onlineCheckData.CheckData ?? new List<OnlineCheckData_CheckData>();
|
||||
|
||||
foreach (var item in detailList)
|
||||
{
|
||||
var paramDetail = new SqlParameter[]
|
||||
{
|
||||
new SqlParameter("@Id_tagCF", idTagCf),
|
||||
new SqlParameter("@EngineID", onlineCheckData.ProductionCode),
|
||||
new SqlParameter("@TagID", item.CheckCode ?? string.Empty),
|
||||
new SqlParameter("@TagValue", item.CheckValue ?? string.Empty),
|
||||
new SqlParameter("@IsGoodBad", item.QualityMark),
|
||||
new SqlParameter("@工位号", opName),
|
||||
new SqlParameter("@理论值", item.StandardValue ?? string.Empty),
|
||||
new SqlParameter("@上限值", item.MaxValue ?? string.Empty),
|
||||
new SqlParameter("@下限值", item.MinValue ?? string.Empty),
|
||||
new SqlParameter("@测量项目", item.CheckName ?? string.Empty),
|
||||
new SqlParameter("@测量单位", item.Unit ?? string.Empty)
|
||||
};
|
||||
|
||||
DataAccess2.ExecuteStoredProcedure("测量数据合格_增加_测试设备", ref paramDetail, out errorMessage);
|
||||
if (!string.IsNullOrEmpty(errorMessage))
|
||||
{
|
||||
throw new Exception(errorMessage);
|
||||
}
|
||||
}
|
||||
// 存储到接口表里
|
||||
MisDataFun.SaveQualityInterfaceData(opName, onlineCheckData.ProductionCode);
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
result.Code = "500";
|
||||
result.Message = err.Message;
|
||||
}
|
||||
|
||||
string retString = JsonConvert.SerializeObject(result);
|
||||
SaveLog_Interface_Response(retString, AID);
|
||||
MyLog4Net.MyLogHelper.Info("接收检测数据_res", retString);
|
||||
return retString;
|
||||
}
|
||||
|
||||
public static string OnlineStatusData(string url, [FromBody] JObject jobj)
|
||||
{
|
||||
var result = new MsgResHeader<string>();
|
||||
result.code = 200;
|
||||
result.message = "";
|
||||
result.Data = "";
|
||||
|
||||
string errorMessage = string.Empty;
|
||||
|
||||
if (jobj == null)
|
||||
{
|
||||
result.code = 500;
|
||||
result.message = "参数格式不正确!";
|
||||
string retString1 = JsonConvert.SerializeObject(result);
|
||||
MyLog4Net.MyLogHelper.Info("接收设备状态数据_res", retString1);
|
||||
return retString1;
|
||||
}
|
||||
|
||||
string str = jobj.ToString();
|
||||
SaveLog_Interface_Request(url, 2, str, out int AID);
|
||||
|
||||
try
|
||||
{
|
||||
var statusData = JsonConvert.DeserializeObject<OnlineStatusData>(str);
|
||||
if (statusData == null)
|
||||
{
|
||||
throw new Exception("请求体反序列化失败!");
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(statusData.MsgId))
|
||||
{
|
||||
throw new Exception("参数MsgId为空!");
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(statusData.DeviceCode))
|
||||
{
|
||||
throw new Exception("参数DeviceCode为空!");
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(statusData.DataType))
|
||||
{
|
||||
throw new Exception("参数DataType为空!");
|
||||
}
|
||||
if (statusData.CheckData == null || statusData.CheckData.Count == 0)
|
||||
{
|
||||
throw new Exception("参数CheckData为空!");
|
||||
}
|
||||
|
||||
string dataType = statusData.DataType.ToUpper();
|
||||
|
||||
if (dataType == "STATUS")
|
||||
{
|
||||
// 设备运行状态监测 - 必填字段校验
|
||||
string deviceStatus = GetCheckDataValue(statusData.CheckData, "DeviceStatus");
|
||||
string statusTime = GetCheckDataValue(statusData.CheckData, "StatusTime");
|
||||
string statusCode = GetCheckDataValue(statusData.CheckData, "StatusCode");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(deviceStatus))
|
||||
{
|
||||
throw new Exception("设备状态(DeviceStatus)为必填项!");
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(statusTime))
|
||||
{
|
||||
throw new Exception("状态时间(StatusTime)为必填项!");
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(statusCode))
|
||||
{
|
||||
throw new Exception("状态代码(StatusCode)为必填项!");
|
||||
}
|
||||
|
||||
// 非必填字段
|
||||
string malfunctionCode = GetCheckDataValue(statusData.CheckData, "MalfunctionCode");
|
||||
string malfunctionName = GetCheckDataValue(statusData.CheckData, "MalfunctionName");
|
||||
string malfunctionExplain = GetCheckDataValue(statusData.CheckData, "Malfunctionexplain");
|
||||
string flag = GetCheckDataValue(statusData.CheckData, "Flag");
|
||||
string remark = GetCheckDataValue(statusData.CheckData, "Remark");
|
||||
string alarmRemove = GetCheckDataValue(statusData.CheckData, "alarmRemove");
|
||||
|
||||
var param = new SqlParameter[]
|
||||
{
|
||||
new SqlParameter("@DeviceCode", statusData.DeviceCode),
|
||||
new SqlParameter("@DeviceStatus", deviceStatus),
|
||||
new SqlParameter("@StatusTime", DateTime.Parse(statusTime)),
|
||||
new SqlParameter("@StatusCode", statusCode),
|
||||
new SqlParameter("@MalfunctionCode", string.IsNullOrWhiteSpace(malfunctionCode) ? (object)DBNull.Value : malfunctionCode),
|
||||
new SqlParameter("@MalfunctionName", string.IsNullOrWhiteSpace(malfunctionName) ? (object)DBNull.Value : malfunctionName),
|
||||
new SqlParameter("@Malfunctionexplain", string.IsNullOrWhiteSpace(malfunctionExplain) ? (object)DBNull.Value : malfunctionExplain),
|
||||
new SqlParameter("@Flag", string.IsNullOrWhiteSpace(flag) ? (object)DBNull.Value : flag),
|
||||
new SqlParameter("@Remark", string.IsNullOrWhiteSpace(remark) ? (object)DBNull.Value : remark),
|
||||
new SqlParameter("@alarmRemove", string.IsNullOrWhiteSpace(alarmRemove) ? (object)DBNull.Value : alarmRemove)
|
||||
};
|
||||
|
||||
DataAccess2.ExecuteStoredProcedure("EquipmentStatus_Backup_TestDeviceAdd", ref param, out errorMessage);
|
||||
if (!string.IsNullOrEmpty(errorMessage))
|
||||
{
|
||||
throw new Exception(errorMessage);
|
||||
}
|
||||
}
|
||||
else if (dataType == "USE")
|
||||
{
|
||||
// 设备使用情况记录 - 必填字段校验
|
||||
string workDate = GetCheckDataValue(statusData.CheckData, "WorkDate");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(workDate))
|
||||
{
|
||||
throw new Exception("工作日期(WorkDate)为必填项!");
|
||||
}
|
||||
|
||||
// 非必填字段
|
||||
string onhours = GetCheckDataValue(statusData.CheckData, "Onhours");
|
||||
string workhours = GetCheckDataValue(statusData.CheckData, "Workhours");
|
||||
string powerused = GetCheckDataValue(statusData.CheckData, "Powerused");
|
||||
string flag = GetCheckDataValue(statusData.CheckData, "Flag");
|
||||
|
||||
var param = new SqlParameter[]
|
||||
{
|
||||
new SqlParameter("@Device", statusData.DeviceCode),
|
||||
new SqlParameter("@WorkDate", DateTime.Parse(workDate)),
|
||||
new SqlParameter("@Onhours", string.IsNullOrWhiteSpace(onhours) ? (object)DBNull.Value : double.Parse(onhours)),
|
||||
new SqlParameter("@Workhours", string.IsNullOrWhiteSpace(workhours) ? (object)DBNull.Value : double.Parse(workhours)),
|
||||
new SqlParameter("@Powerused", string.IsNullOrWhiteSpace(powerused) ? (object)DBNull.Value : double.Parse(powerused)),
|
||||
new SqlParameter("@Flag", string.IsNullOrWhiteSpace(flag) ? (object)DBNull.Value : flag)
|
||||
};
|
||||
|
||||
DataAccess2.ExecuteStoredProcedure("EquipmentUse_Backup_TestDeviceAdd", ref param, out errorMessage);
|
||||
if (!string.IsNullOrEmpty(errorMessage))
|
||||
{
|
||||
throw new Exception(errorMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"DataType值不正确,只支持Status或Use,当前值:{statusData.DataType}");
|
||||
}
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
result.code = 500;
|
||||
result.message = err.Message;
|
||||
}
|
||||
|
||||
string retString = JsonConvert.SerializeObject(result);
|
||||
SaveLog_Interface_Response(retString, AID);
|
||||
MyLog4Net.MyLogHelper.Info("接收设备状态数据_res", retString);
|
||||
return retString;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从CheckData列表中获取指定StatuCode的StatuValue
|
||||
/// </summary>
|
||||
private static string GetCheckDataValue(List<OnlineStatusData_CheckData> checkDataList, string statuCode)
|
||||
{
|
||||
var item = checkDataList.FirstOrDefault(x => x.StatuCode?.Trim().Equals(statuCode, StringComparison.OrdinalIgnoreCase) == true);
|
||||
return item?.StatuValue ?? string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取位置待测试产品信息
|
||||
/// </summary>
|
||||
public static string GetWaitCheckProductData(string url, [FromBody] JObject jobj)
|
||||
{
|
||||
var result = new GetWaitCheckProductDataResponse();
|
||||
result.Code = "200";
|
||||
result.Message = "";
|
||||
result.MsgId = "";
|
||||
result.Data = new GetWaitCheckProductDataResult();
|
||||
|
||||
if (jobj == null)
|
||||
{
|
||||
result.Code = "500";
|
||||
result.Message = "参数格式不正确!";
|
||||
string retString1 = JsonConvert.SerializeObject(result);
|
||||
MyLog4Net.MyLogHelper.Info("获取待测产品信息_res", retString1);
|
||||
return retString1;
|
||||
}
|
||||
|
||||
string str = jobj.ToString();
|
||||
// 存储接口请求日志
|
||||
SaveLog_Interface_Request(url, 2, str, out int AID);
|
||||
|
||||
try
|
||||
{
|
||||
var requestData = JsonConvert.DeserializeObject<GetWaitCheckProductDataRequest>(str);
|
||||
if (requestData == null)
|
||||
{
|
||||
throw new Exception("请求体反序列化失败!");
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(requestData.MsgId))
|
||||
{
|
||||
throw new Exception("参数MsgId为空!");
|
||||
}
|
||||
// 设置响应的MsgId(带回请求编号)
|
||||
result.MsgId = requestData.MsgId;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(requestData.OpCode))
|
||||
{
|
||||
throw new Exception("参数OpCode为空!");
|
||||
}
|
||||
|
||||
// TODO: 后续实现查询待测产品逻辑
|
||||
// 目前固定返回无待测产品
|
||||
result.Data = new GetWaitCheckProductDataResult
|
||||
{
|
||||
ProductionCode = "",
|
||||
ProductModel = "",
|
||||
ProductModelCode = 0
|
||||
};
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
result.Code = "500";
|
||||
result.Message = err.Message;
|
||||
}
|
||||
|
||||
string retString = JsonConvert.SerializeObject(result);
|
||||
SaveLog_Interface_Response(retString, AID);
|
||||
MyLog4Net.MyLogHelper.Info("获取待测产品信息_res", retString);
|
||||
return retString;
|
||||
}
|
||||
}
|
||||
}
|
||||
527
Interface_WebAPI/SlMesDbIterface/WebAPI/Other/DewPointData.cs
Normal file
527
Interface_WebAPI/SlMesDbIterface/WebAPI/Other/DewPointData.cs
Normal file
@@ -0,0 +1,527 @@
|
||||
using DataLinkMesWork2;
|
||||
using MisDataFunDll;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using System.Globalization;
|
||||
using System.Web.Http;
|
||||
using static MisDataSaveDate.Helper.ApiLogHelper;
|
||||
|
||||
namespace ExternalDataSync.MOM
|
||||
{
|
||||
public static class DewPointDataHandler
|
||||
{
|
||||
private const string DefaultFlagValue = "0";
|
||||
|
||||
public static string OnlineDewPointResultData(string url, [FromBody] JObject jobj)
|
||||
{
|
||||
return ExecuteRequest<ResultDataRequest>(url, jobj, "接收露点仪测试结果数据", request =>
|
||||
{
|
||||
string msgId = RequireText(request.MsgId, "MsgId");
|
||||
string deviceCode = RequireText(request.DeviceCode, "DeviceCode");
|
||||
string testDateText = RequireText(request.TestDate, "TestDate");
|
||||
if (request.TestItems == null || request.TestItems.Count == 0)
|
||||
{
|
||||
throw new Exception("参数TestItems为空!");
|
||||
}
|
||||
|
||||
DateTime testDate = ParseDate(testDateText, "TestDate");
|
||||
DateTime? startTime = CombineDateAndTime(testDate, request.StartTime, "StartTime");
|
||||
DateTime? endTime = CombineDateAndTime(testDate, request.EndTime, "EndTime");
|
||||
DateTime actionTime = startTime ?? endTime ?? testDate;
|
||||
string serialNumber = CleanText(request.SectionNo);
|
||||
string userNumber = GetDefaultUser(request.UserNumber);
|
||||
int overallQualityMark = request.IsQualified == false ? 2 : 1;
|
||||
|
||||
int idTagCf = SaveMeasurementIndex(serialNumber, deviceCode, userNumber, actionTime, overallQualityMark);
|
||||
|
||||
foreach (MeasurementDetail detail in BuildResultDetails(request, overallQualityMark))
|
||||
{
|
||||
SaveMeasurementDetail(idTagCf, serialNumber, deviceCode, detail);
|
||||
}
|
||||
|
||||
SaveQualityInterfaceRecord(deviceCode, serialNumber);
|
||||
return msgId;
|
||||
});
|
||||
}
|
||||
|
||||
public static string OnlineDewPointTechnologyData(string url, [FromBody] JObject jobj)
|
||||
{
|
||||
return ExecuteRequest<TechnologyDataRequest>(url, jobj, "接收露点仪工艺采集数据", request =>
|
||||
{
|
||||
string msgId = RequireText(request.MsgId, "MsgId");
|
||||
string deviceCode = RequireText(request.DeviceCode, "DeviceCode");
|
||||
string serialNumber = CleanText(request.SerialNumber);
|
||||
string userNumber = GetDefaultUser(request.UserNumber);
|
||||
DateTime actionTime = ParseDateTimeOrNow(request.CreateTime, "CreateTime");
|
||||
|
||||
int idTagCf = SaveMeasurementIndex(serialNumber, deviceCode, userNumber, actionTime, 1);
|
||||
|
||||
foreach (MeasurementDetail detail in BuildTechnologyDetails(request))
|
||||
{
|
||||
SaveMeasurementDetail(idTagCf, serialNumber, deviceCode, detail);
|
||||
}
|
||||
|
||||
SaveQualityInterfaceRecord(deviceCode, serialNumber);
|
||||
return msgId;
|
||||
});
|
||||
}
|
||||
|
||||
public static string OnlineDewPointUseData(string url, [FromBody] JObject jobj)
|
||||
{
|
||||
return ExecuteRequest<EquipmentUseRequest>(url, jobj, "接收露点仪设备使用情况数据", request =>
|
||||
{
|
||||
string msgId = RequireText(request.MsgId, "MsgId");
|
||||
string deviceCode = RequireText(request.DeviceCode, "DeviceCode");
|
||||
DateTime testDate = ParseDate(RequireText(request.TestDate, "TestDate"), "TestDate");
|
||||
int? durationMinutes = ParseNullableInt(request.DurationMinutes, "DurationMinutes");
|
||||
|
||||
SqlParameter[] parameters = new SqlParameter[]
|
||||
{
|
||||
new SqlParameter("@Device", ToDbValue(deviceCode, 50)),
|
||||
new SqlParameter("@WorkDate", testDate.Date),
|
||||
new SqlParameter("@Onhours", durationMinutes.HasValue ? (object)durationMinutes.Value : DBNull.Value),
|
||||
new SqlParameter("@Workhours", durationMinutes.HasValue ? (object)durationMinutes.Value : DBNull.Value),
|
||||
new SqlParameter("@Powerused", DBNull.Value),
|
||||
new SqlParameter("@Flag", ToDbValue(CleanText(request.Flag2), 10, DefaultFlagValue))
|
||||
};
|
||||
|
||||
ExecuteStoredProcedureOrThrow("EquipmentUse_Backup_TestDeviceAdd", ref parameters);
|
||||
return msgId;
|
||||
});
|
||||
}
|
||||
|
||||
public static string OnlineDewPointStatusData(string url, [FromBody] JObject jobj)
|
||||
{
|
||||
return ExecuteRequest<EquipmentStatusRequest>(url, jobj, "接收露点仪设备状态数据", request =>
|
||||
{
|
||||
string msgId = RequireText(request.MsgId, "MsgId");
|
||||
string deviceCode = RequireText(request.DeviceCode, "DeviceCode");
|
||||
string status = RequireText(request.Status, "Status");
|
||||
string statusCode = RequireText(request.StatusCode, "StatusCode");
|
||||
DateTime statusTime = ParseDateTime(RequireText(request.StatusTime, "StatusTime"), "StatusTime");
|
||||
|
||||
SqlParameter[] parameters = new SqlParameter[]
|
||||
{
|
||||
new SqlParameter("@DeviceCode", ToDbValue(deviceCode, 20)),
|
||||
new SqlParameter("@DeviceStatus", ToDbValue(status, 10)),
|
||||
new SqlParameter("@StatusTime", statusTime),
|
||||
new SqlParameter("@StatusCode", ToDbValue(statusCode, 4)),
|
||||
new SqlParameter("@MalfunctionCode", ToNullableDbValue(request.FaultInfo == null ? string.Empty : request.FaultInfo.FaultCode, 4)),
|
||||
new SqlParameter("@MalfunctionName", ToNullableDbValue(request.FaultInfo == null ? string.Empty : request.FaultInfo.FaultName, 40)),
|
||||
new SqlParameter("@Malfunctionexplain", ToNullableDbValue(request.FaultInfo == null ? string.Empty : request.FaultInfo.FaultDescription, 40)),
|
||||
new SqlParameter("@Flag", ToDbValue(CleanText(request.Flag3), 1, DefaultFlagValue)),
|
||||
new SqlParameter("@Remark", DBNull.Value),
|
||||
new SqlParameter("@alarmRemove", DBNull.Value)
|
||||
};
|
||||
|
||||
ExecuteStoredProcedureOrThrow("EquipmentStatus_Backup_TestDeviceAdd", ref parameters);
|
||||
return msgId;
|
||||
});
|
||||
}
|
||||
|
||||
private static string ExecuteRequest<TRequest>(string url, JObject jobj, string logTitle, Func<TRequest, string> executor)
|
||||
{
|
||||
OnlineCheckDataResponse result = new OnlineCheckDataResponse
|
||||
{
|
||||
Code = "200",
|
||||
Message = "",
|
||||
MsgId = "",
|
||||
Data = ""
|
||||
};
|
||||
|
||||
if (jobj == null)
|
||||
{
|
||||
result.Code = "500";
|
||||
result.Message = "参数格式不正确!";
|
||||
string invalidText = JsonConvert.SerializeObject(result);
|
||||
MyLog4Net.MyLogHelper.Info(logTitle + "_res", invalidText);
|
||||
return invalidText;
|
||||
}
|
||||
|
||||
string requestText = jobj.ToString();
|
||||
SaveLog_Interface_Request(url, 2, requestText, out int aid);
|
||||
|
||||
try
|
||||
{
|
||||
TRequest request = JsonConvert.DeserializeObject<TRequest>(requestText);
|
||||
if (request == null)
|
||||
{
|
||||
throw new Exception("请求体反序列化失败!");
|
||||
}
|
||||
|
||||
result.MsgId = executor(request);
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
result.Code = "500";
|
||||
result.Message = err.Message;
|
||||
}
|
||||
|
||||
string responseText = JsonConvert.SerializeObject(result);
|
||||
SaveLog_Interface_Response(responseText, aid);
|
||||
MyLog4Net.MyLogHelper.Info(logTitle + "_res", responseText);
|
||||
return responseText;
|
||||
}
|
||||
|
||||
private static List<MeasurementDetail> BuildResultDetails(ResultDataRequest request, int overallQualityMark)
|
||||
{
|
||||
List<MeasurementDetail> details = new List<MeasurementDetail>();
|
||||
|
||||
for (int i = 0; i < request.TestItems.Count; i++)
|
||||
{
|
||||
ResultTestItem item = request.TestItems[i];
|
||||
if (item == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string itemName = RequireText(item.ItemName, "TestItems[" + i + "].ItemName");
|
||||
details.Add(new MeasurementDetail
|
||||
{
|
||||
TagId = itemName,
|
||||
MeasurementName = itemName,
|
||||
TagValue = GetTokenText(item.MeasuredValue),
|
||||
QualityMark = MapQualityMark(item.QualityMark, overallQualityMark),
|
||||
StandardValue = GetTokenText(item.SpecifiedValue),
|
||||
Unit = CleanText(item.Unit)
|
||||
});
|
||||
}
|
||||
|
||||
// Environment 暂时保留字段,但当前不参与入库。
|
||||
return details;
|
||||
}
|
||||
|
||||
private static List<MeasurementDetail> BuildTechnologyDetails(TechnologyDataRequest request)
|
||||
{
|
||||
List<MeasurementDetail> details = new List<MeasurementDetail>();
|
||||
|
||||
AddTechnologyDetail(details, "CheckData", request.CheckData);
|
||||
AddTechnologyDetail(details, "TechnologyData", request.TechnologyData);
|
||||
|
||||
if (details.Count == 0)
|
||||
{
|
||||
throw new Exception("参数CheckData和TechnologyData均为空!");
|
||||
}
|
||||
|
||||
return details;
|
||||
}
|
||||
|
||||
private static void AddTechnologyDetail(List<MeasurementDetail> details, string fieldName, string fieldValue)
|
||||
{
|
||||
string value = CleanText(fieldValue);
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
details.Add(new MeasurementDetail
|
||||
{
|
||||
TagId = fieldName,
|
||||
MeasurementName = fieldName,
|
||||
TagValue = value,
|
||||
QualityMark = 1,
|
||||
StandardValue = "",
|
||||
Unit = ""
|
||||
});
|
||||
}
|
||||
|
||||
private static int SaveMeasurementIndex(string serialNumber, string deviceCode, string userNumber, DateTime actionTime, int qualityMark)
|
||||
{
|
||||
SqlParameter[] parameters = new SqlParameter[]
|
||||
{
|
||||
new SqlParameter("@EngineID", ToNullableDbValue(serialNumber, 100)),
|
||||
new SqlParameter("@工位号", ToDbValue(deviceCode, 50)),
|
||||
new SqlParameter("@操作者工号", ToDbValue(userNumber, 50, "AUTO")),
|
||||
new SqlParameter("@扫码时间", actionTime),
|
||||
new SqlParameter("@合格标志", qualityMark),
|
||||
new SqlParameter("@Id_tagCF", SqlDbType.Int) { Direction = ParameterDirection.Output }
|
||||
};
|
||||
|
||||
ExecuteStoredProcedureOrThrow("测量数据合格索引_增加_测试设备", ref parameters);
|
||||
|
||||
if (parameters[5].Value == null || parameters[5].Value == DBNull.Value)
|
||||
{
|
||||
throw new Exception("测量数据合格索引_增加_测试设备 未返回Id_tagCF!");
|
||||
}
|
||||
|
||||
return Convert.ToInt32(parameters[5].Value);
|
||||
}
|
||||
|
||||
private static void SaveMeasurementDetail(int idTagCf, string serialNumber, string deviceCode, MeasurementDetail detail)
|
||||
{
|
||||
SqlParameter[] parameters = new SqlParameter[]
|
||||
{
|
||||
new SqlParameter("@Id_tagCF", idTagCf),
|
||||
new SqlParameter("@EngineID", ToNullableDbValue(serialNumber, 100)),
|
||||
new SqlParameter("@TagID", ToDbValue(detail.TagId, 50)),
|
||||
new SqlParameter("@TagValue", ToDbValue(detail.TagValue, 100)),
|
||||
new SqlParameter("@IsGoodBad", detail.QualityMark),
|
||||
new SqlParameter("@工位号", ToDbValue(deviceCode, 50)),
|
||||
new SqlParameter("@理论值", ToDbValue(detail.StandardValue, 50)),
|
||||
new SqlParameter("@上限值", ToDbValue(string.Empty, 50)),
|
||||
new SqlParameter("@下限值", ToDbValue(string.Empty, 50)),
|
||||
new SqlParameter("@测量项目", ToDbValue(detail.MeasurementName, 50)),
|
||||
new SqlParameter("@测量单位", ToDbValue(detail.Unit, 50))
|
||||
};
|
||||
|
||||
ExecuteStoredProcedureOrThrow("测量数据合格_增加_测试设备", ref parameters);
|
||||
}
|
||||
|
||||
private static void SaveQualityInterfaceRecord(string deviceCode, string serialNumber)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(deviceCode) && !string.IsNullOrWhiteSpace(serialNumber))
|
||||
{
|
||||
MisDataFun.SaveQualityInterfaceData(deviceCode, serialNumber);
|
||||
}
|
||||
}
|
||||
|
||||
private static int MapQualityMark(int? sourceQualityMark, int defaultQualityMark)
|
||||
{
|
||||
if (!sourceQualityMark.HasValue)
|
||||
{
|
||||
return defaultQualityMark;
|
||||
}
|
||||
|
||||
if (sourceQualityMark.Value == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (sourceQualityMark.Value == 1)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
return sourceQualityMark.Value;
|
||||
}
|
||||
|
||||
private static int? ParseNullableInt(JToken token, string fieldName)
|
||||
{
|
||||
string text = GetTokenText(token);
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (int.TryParse(text, NumberStyles.Integer, CultureInfo.InvariantCulture, out int result) ||
|
||||
int.TryParse(text, NumberStyles.Integer, CultureInfo.CurrentCulture, out result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
throw new Exception("参数" + fieldName + "格式不正确!");
|
||||
}
|
||||
|
||||
private static DateTime ParseDate(string text, string fieldName)
|
||||
{
|
||||
if (DateTime.TryParseExact(text, "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime result) ||
|
||||
DateTime.TryParse(text, CultureInfo.InvariantCulture, DateTimeStyles.None, out result) ||
|
||||
DateTime.TryParse(text, CultureInfo.CurrentCulture, DateTimeStyles.None, out result))
|
||||
{
|
||||
return result.Date;
|
||||
}
|
||||
|
||||
throw new Exception("参数" + fieldName + "格式不正确!");
|
||||
}
|
||||
|
||||
private static DateTime ParseDateTime(string text, string fieldName)
|
||||
{
|
||||
if (DateTime.TryParse(text, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime result) ||
|
||||
DateTime.TryParse(text, CultureInfo.CurrentCulture, DateTimeStyles.None, out result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
throw new Exception("参数" + fieldName + "格式不正确!");
|
||||
}
|
||||
|
||||
private static DateTime ParseDateTimeOrNow(string text, string fieldName)
|
||||
{
|
||||
string value = CleanText(text);
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
return DateTime.Now;
|
||||
}
|
||||
|
||||
return ParseDateTime(value, fieldName);
|
||||
}
|
||||
|
||||
private static DateTime? CombineDateAndTime(DateTime date, string timeText, string fieldName)
|
||||
{
|
||||
string text = CleanText(timeText);
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (TimeSpan.TryParse(text, CultureInfo.InvariantCulture, out TimeSpan timePart) ||
|
||||
TimeSpan.TryParse(text, CultureInfo.CurrentCulture, out timePart))
|
||||
{
|
||||
return date.Date.Add(timePart);
|
||||
}
|
||||
|
||||
throw new Exception("参数" + fieldName + "格式不正确!");
|
||||
}
|
||||
|
||||
private static string RequireText(string value, string fieldName)
|
||||
{
|
||||
string text = CleanText(value);
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
throw new Exception("参数" + fieldName + "为空!");
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
private static string RequireText(JToken value, string fieldName)
|
||||
{
|
||||
string text = GetTokenText(value);
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
throw new Exception("参数" + fieldName + "为空!");
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
private static string CleanText(string value)
|
||||
{
|
||||
return value == null ? string.Empty : value.Trim();
|
||||
}
|
||||
|
||||
private static string GetDefaultUser(string userNumber)
|
||||
{
|
||||
string value = CleanText(userNumber);
|
||||
return string.IsNullOrWhiteSpace(value) ? "AUTO" : value;
|
||||
}
|
||||
|
||||
private static string GetTokenText(JToken token)
|
||||
{
|
||||
return token == null || token.Type == JTokenType.Null ? string.Empty : token.ToString().Trim();
|
||||
}
|
||||
|
||||
private static object ToDbValue(string value, int maxLength)
|
||||
{
|
||||
return ToDbValue(value, maxLength, string.Empty);
|
||||
}
|
||||
|
||||
private static object ToDbValue(string value, int maxLength, string defaultValue)
|
||||
{
|
||||
string text = CleanText(value);
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
text = defaultValue ?? string.Empty;
|
||||
}
|
||||
|
||||
return text.Length > maxLength ? text.Substring(0, maxLength) : text;
|
||||
}
|
||||
|
||||
private static object ToNullableDbValue(string value, int maxLength)
|
||||
{
|
||||
string text = CleanText(value);
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
return DBNull.Value;
|
||||
}
|
||||
|
||||
return text.Length > maxLength ? text.Substring(0, maxLength) : text;
|
||||
}
|
||||
|
||||
private static void ExecuteStoredProcedureOrThrow(string procedureName, ref SqlParameter[] parameters)
|
||||
{
|
||||
DataAccess2.ExecuteStoredProcedure(procedureName, ref parameters, out string errorMessage);
|
||||
if (!string.IsNullOrWhiteSpace(errorMessage))
|
||||
{
|
||||
throw new Exception(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class ResultDataRequest
|
||||
{
|
||||
public string DeviceCode { get; set; } = string.Empty;
|
||||
public string EndTime { get; set; } = string.Empty;
|
||||
public ResultEnvironment Environment { get; set; } = new ResultEnvironment();
|
||||
public bool? IsQualified { get; set; }
|
||||
public JToken MsgId { get; set; }
|
||||
public JToken PowerUsed { get; set; }
|
||||
public string SectionNo { get; set; } = string.Empty;
|
||||
public string StartTime { get; set; } = string.Empty;
|
||||
public string TestDate { get; set; } = string.Empty;
|
||||
public List<ResultTestItem> TestItems { get; set; } = new List<ResultTestItem>();
|
||||
public string UserNumber { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
private sealed class ResultEnvironment
|
||||
{
|
||||
public JToken Humidity { get; set; }
|
||||
public JToken Temperature { get; set; }
|
||||
}
|
||||
|
||||
private sealed class ResultTestItem
|
||||
{
|
||||
public string ItemName { get; set; } = string.Empty;
|
||||
public JToken MeasuredValue { get; set; }
|
||||
public int? QualityMark { get; set; }
|
||||
public JToken SpecifiedValue { get; set; }
|
||||
public string Unit { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
private sealed class TechnologyDataRequest
|
||||
{
|
||||
public string CheckData { get; set; } = string.Empty;
|
||||
public string CreateTime { get; set; } = string.Empty;
|
||||
public string DeviceCode { get; set; } = string.Empty;
|
||||
public string Flag { get; set; } = string.Empty;
|
||||
public string MsgId { get; set; } = string.Empty;
|
||||
public string PowerUsed { get; set; } = string.Empty;
|
||||
public string SerialNumber { get; set; } = string.Empty;
|
||||
public string TechnologyData { get; set; } = string.Empty;
|
||||
public string UserNumber { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
private sealed class EquipmentUseRequest
|
||||
{
|
||||
public string CreateTime { get; set; } = string.Empty;
|
||||
public string DeviceCode { get; set; } = string.Empty;
|
||||
public JToken DurationMinutes { get; set; }
|
||||
public string Flag2 { get; set; } = string.Empty;
|
||||
public JToken MsgId { get; set; }
|
||||
public string StartTime { get; set; } = string.Empty;
|
||||
public string TestDate { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
private sealed class EquipmentStatusRequest
|
||||
{
|
||||
public string CreateTime { get; set; } = string.Empty;
|
||||
public string DeviceCode { get; set; } = string.Empty;
|
||||
public FaultInfo FaultInfo { get; set; } = new FaultInfo();
|
||||
public JToken MsgId { get; set; }
|
||||
public string Status { get; set; } = string.Empty;
|
||||
public string StatusCode { get; set; } = string.Empty;
|
||||
public string StatusTime { get; set; } = string.Empty;
|
||||
public string Flag3 { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
private sealed class FaultInfo
|
||||
{
|
||||
public string FaultCode { get; set; } = string.Empty;
|
||||
public string FaultDescription { get; set; } = string.Empty;
|
||||
public string FaultName { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
private sealed class MeasurementDetail
|
||||
{
|
||||
public string TagId { get; set; } = string.Empty;
|
||||
public string MeasurementName { get; set; } = string.Empty;
|
||||
public string TagValue { get; set; } = string.Empty;
|
||||
public int QualityMark { get; set; }
|
||||
public string StandardValue { get; set; } = string.Empty;
|
||||
public string Unit { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Interface_WebAPI/SlMesDbIterface/WebAPI/StateVariable.cs
Normal file
13
Interface_WebAPI/SlMesDbIterface/WebAPI/StateVariable.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ExternalDataSync
|
||||
{
|
||||
public static class StateVariable
|
||||
{
|
||||
public static bool online_Mes = true;
|
||||
}
|
||||
}
|
||||
411
Interface_WebAPI/SlMesDbIterface/WebAPI/WEB/WEB_BusinessLogic.cs
Normal file
411
Interface_WebAPI/SlMesDbIterface/WebAPI/WEB/WEB_BusinessLogic.cs
Normal file
@@ -0,0 +1,411 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Configuration;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using ExternalDataSync;
|
||||
using MesServerWork;
|
||||
using MisDataSaveDate;
|
||||
using System.Net.Http;
|
||||
using System.Web.Http;
|
||||
using MisDataSaveDate.MOM;
|
||||
using System.Data.SqlClient;
|
||||
using static MisDataSaveDate.Helper.ApiLogHelper;
|
||||
using WebApi;
|
||||
using System.Security.Policy;
|
||||
using System.Data;
|
||||
using MisDataFunDll;
|
||||
using System.Net;
|
||||
|
||||
namespace MisDataSaveDate
|
||||
{
|
||||
/// <summary>
|
||||
/// WEB业务处理类
|
||||
/// </summary>
|
||||
public class WEB_BusinessLogic
|
||||
{
|
||||
/// <summary>
|
||||
/// WEB端发来的请求
|
||||
/// </summary>
|
||||
/// <param name="url">请求URL</param>
|
||||
/// <param name="jobj">请求的JSON对象</param>
|
||||
/// <returns>处理结果</returns>
|
||||
public static string WEB_Request(string url, [FromBody] JObject jobj)
|
||||
{
|
||||
var result = new MsgResHeader<string>();
|
||||
result.code = 200;
|
||||
result.message = "";
|
||||
|
||||
if (jobj == null)
|
||||
{
|
||||
result.code = 500;
|
||||
result.message = "参数格式不正确!";
|
||||
string retString1 = JsonConvert.SerializeObject(result);
|
||||
SaveMesLog("WEB进入请求", "参数格式不正确!", Helper.MesLogType.ERROR);
|
||||
MyLog4Net.MyLogHelper.Info("WEB请求进入接口res:", retString1);
|
||||
return retString1;
|
||||
}
|
||||
|
||||
string str = jobj.ToString();
|
||||
//存储请求日志
|
||||
SaveLog_Interface_Request(url, 2, str, out int AID);
|
||||
|
||||
try
|
||||
{
|
||||
// 解析WEB请求内容
|
||||
WEB_Request webRequest = JsonConvert.DeserializeObject<WEB_Request>(str);
|
||||
|
||||
// 必填字段校验
|
||||
if (string.IsNullOrWhiteSpace(webRequest.type))
|
||||
{
|
||||
throw new Exception("请求类型(type)不能为空");
|
||||
}
|
||||
switch (webRequest.type)
|
||||
{
|
||||
case "OperAtion_JobStart":
|
||||
// 手动重新开始工作
|
||||
// 使用JObject的索引器或Value<T>方法来获取值
|
||||
string workStation1 = webRequest.paramObj?["工位号"]?.ToString() ?? "";
|
||||
string orderNo1 = webRequest.paramObj?["订单号"]?.ToString() ?? "";
|
||||
string workpieceNo1 = webRequest.paramObj?["工件编号"]?.ToString() ?? "";
|
||||
|
||||
// 验证必要参数
|
||||
if (string.IsNullOrWhiteSpace(workStation1) ||
|
||||
string.IsNullOrWhiteSpace(orderNo1) ||
|
||||
string.IsNullOrWhiteSpace(workpieceNo1))
|
||||
{
|
||||
throw new Exception("OperAtion_JobStart 缺少必要参数:工位号、订单号或工件编号");
|
||||
}
|
||||
|
||||
CALL_Inerface_DataHandle.CALL_Inerface_JobStart(workStation1, orderNo1, workpieceNo1);
|
||||
break;
|
||||
|
||||
case "OperAtion_JobFinished":
|
||||
// 手动完成工作
|
||||
// 使用JObject的索引器或Value<T>方法来获取值
|
||||
string workStation2 = webRequest.paramObj?["工位号"]?.ToString() ?? "";
|
||||
string orderNo2 = webRequest.paramObj?["订单号"]?.ToString() ?? "";
|
||||
string workpieceNo2 = webRequest.paramObj?["工件编号"]?.ToString() ?? "";
|
||||
|
||||
// 验证必要参数
|
||||
if (string.IsNullOrWhiteSpace(workStation2) ||
|
||||
string.IsNullOrWhiteSpace(orderNo2) ||
|
||||
string.IsNullOrWhiteSpace(workpieceNo2))
|
||||
{
|
||||
throw new Exception("OperAtion_JobFinished 缺少必要参数:工位号、订单号或工件编号");
|
||||
}
|
||||
|
||||
CALL_Inerface_DataHandle.CALL_Inerface_JobFinished(workStation2, orderNo2, workpieceNo2);
|
||||
break;
|
||||
|
||||
default:
|
||||
result.code = 500;
|
||||
result.message = "无此类型~";
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
// 记录错误日志
|
||||
SaveMesLog("WEB端调用接口", err.Message, Helper.MesLogType.ERROR);
|
||||
|
||||
result.code = 500;
|
||||
result.message = err.Message;
|
||||
}
|
||||
|
||||
string retString = JsonConvert.SerializeObject(result);
|
||||
// 存储响应日志
|
||||
SaveLog_Interface_Response(retString, AID);
|
||||
return retString;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 批量读取PLC点位值
|
||||
/// </summary>
|
||||
/// <param name="url">请求URL</param>
|
||||
/// <param name="jobj">请求的JSON对象,包含OpName和TagTypeCodeIDs数组</param>
|
||||
/// <returns>处理结果</returns>
|
||||
public static string WEB_ReadPLCValues(string url, [FromBody] JObject jobj)
|
||||
{
|
||||
var result = new MsgResHeader<List<PLCTagValueResult>>
|
||||
{
|
||||
code = 200,
|
||||
message = "",
|
||||
Data = new List<PLCTagValueResult>()
|
||||
};
|
||||
|
||||
if (jobj == null)
|
||||
{
|
||||
result.code = 500;
|
||||
result.message = "参数格式不正确!";
|
||||
string retString1 = JsonConvert.SerializeObject(result);
|
||||
SaveMesLog("WEB批量读取PLC点位值", "参数格式不正确!", Helper.MesLogType.ERROR);
|
||||
MyLog4Net.MyLogHelper.Info("WEB_ReadPLCValues res:", retString1);
|
||||
return retString1;
|
||||
}
|
||||
|
||||
string str = jobj.ToString();
|
||||
// 存储请求日志
|
||||
SaveLog_Interface_Request(url, 2, str, out int AID);
|
||||
|
||||
try
|
||||
{
|
||||
string opName = jobj["OpName"]?.ToString() ?? "";
|
||||
JArray tagTypeCodeIDsArray = jobj["TagTypeCodeIDs"] as JArray;
|
||||
|
||||
// 参数校验
|
||||
if (string.IsNullOrEmpty(opName))
|
||||
{
|
||||
throw new Exception("工位号(OpName)不能为空");
|
||||
}
|
||||
|
||||
if (tagTypeCodeIDsArray == null || tagTypeCodeIDsArray.Count == 0)
|
||||
{
|
||||
throw new Exception("TagTypeCodeID数组不能为空");
|
||||
}
|
||||
|
||||
int[] tagTypeCodeIDs = tagTypeCodeIDsArray.Select(x => (int)x).ToArray();
|
||||
|
||||
// 读取工位全部数据
|
||||
var rtList = MIS_BASE.ReadPLC_OpName(opName);
|
||||
if (rtList == null)
|
||||
{
|
||||
throw new Exception($"读取工位[{opName}]数据失败");
|
||||
}
|
||||
|
||||
var pp = JsonConvert.SerializeObject(rtList);
|
||||
// 使用 dynamic 类型避免程序集引用问题
|
||||
var tagValues = JsonConvert.DeserializeObject<System.Collections.Concurrent.ConcurrentDictionary<string, dynamic>>(pp);
|
||||
|
||||
// 根据传入的TagTypeCodeID数组过滤并返回对应的值
|
||||
foreach (var tagTypeCodeID in tagTypeCodeIDs)
|
||||
{
|
||||
var tagResult = new PLCTagValueResult
|
||||
{
|
||||
TagTypeCodeID = tagTypeCodeID,
|
||||
Success = false,
|
||||
TagValue = null,
|
||||
Message = ""
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
var matchedTag = tagValues.Where(x => (int)x.Value.TagTypeCodeID == tagTypeCodeID).FirstOrDefault();
|
||||
if (matchedTag.Value != null)
|
||||
{
|
||||
tagResult.Success = true;
|
||||
tagResult.TagValue = (int)matchedTag.Value.TagValue;
|
||||
tagResult.TagName = (string)matchedTag.Value.TagName;
|
||||
tagResult.OpName = (string)matchedTag.Value.OpName;
|
||||
tagResult.TimeStamp = (string)matchedTag.Value.TimeStamp;
|
||||
}
|
||||
else
|
||||
{
|
||||
tagResult.Message = $"未找到TagTypeCodeID={tagTypeCodeID}的点位";
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
tagResult.Message = $"读取TagTypeCodeID={tagTypeCodeID}失败: {ex.Message}";
|
||||
}
|
||||
|
||||
result.Data.Add(tagResult);
|
||||
}
|
||||
|
||||
result.message = "读取成功";
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
// 记录错误日志
|
||||
SaveMesLog("WEB批量读取PLC点位值", err.Message, Helper.MesLogType.ERROR);
|
||||
|
||||
result.code = 500;
|
||||
result.message = err.Message;
|
||||
result.Data = null;
|
||||
}
|
||||
|
||||
string retString = JsonConvert.SerializeObject(result);
|
||||
// 存储响应日志
|
||||
SaveLog_Interface_Response(retString, AID);
|
||||
return retString;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入PLC点位值
|
||||
/// </summary>
|
||||
/// <param name="url">请求URL</param>
|
||||
/// <param name="jobj">请求的JSON对象,包含TagTypeCodeID、OpName和TagValue</param>
|
||||
/// <returns>处理结果</returns>
|
||||
public static string WEB_WritePLC(string url, [FromBody] JObject jobj)
|
||||
{
|
||||
var result = new MsgResHeader<object>
|
||||
{
|
||||
code = 200,
|
||||
message = "",
|
||||
Data = null
|
||||
};
|
||||
|
||||
if (jobj == null)
|
||||
{
|
||||
result.code = 500;
|
||||
result.message = "参数格式不正确!";
|
||||
string retString1 = JsonConvert.SerializeObject(result);
|
||||
SaveMesLog("WEB写入PLC", "参数格式不正确!", Helper.MesLogType.ERROR);
|
||||
MyLog4Net.MyLogHelper.Info("WEB_WritePLC res:", retString1);
|
||||
return retString1;
|
||||
}
|
||||
|
||||
string str = jobj.ToString();
|
||||
// 存储请求日志
|
||||
SaveLog_Interface_Request(url, 2, str, out int AID);
|
||||
|
||||
try
|
||||
{
|
||||
int tagTypeCodeID = jobj["TagTypeCodeID"]?.Value<int>() ?? 0;
|
||||
string opName = jobj["OpName"]?.ToString() ?? "";
|
||||
object tagValue = jobj["TagValue"]?.ToObject<object>();
|
||||
|
||||
// 参数校验
|
||||
if (string.IsNullOrEmpty(opName))
|
||||
{
|
||||
throw new Exception("工位号(OpName)不能为空");
|
||||
}
|
||||
|
||||
if (tagTypeCodeID == 0)
|
||||
{
|
||||
throw new Exception("TagTypeCodeID不能为0");
|
||||
}
|
||||
|
||||
// 调用MIS_BASE.WritePLC方法写入PLC
|
||||
bool writeResult = MIS_BASE.WritePLC(tagTypeCodeID, opName, tagValue);
|
||||
|
||||
if (writeResult)
|
||||
{
|
||||
result.code = 200;
|
||||
result.message = "写入成功";
|
||||
result.Data = new { Success = true };
|
||||
}
|
||||
else
|
||||
{
|
||||
result.code = 500;
|
||||
result.message = "写入失败";
|
||||
result.Data = new { Success = false };
|
||||
}
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
// 记录错误日志
|
||||
SaveMesLog("WEB写入PLC", err.Message, Helper.MesLogType.ERROR);
|
||||
|
||||
result.code = 500;
|
||||
result.message = err.Message;
|
||||
result.Data = new { Success = false };
|
||||
}
|
||||
|
||||
string retString = JsonConvert.SerializeObject(result);
|
||||
// 存储响应日志
|
||||
SaveLog_Interface_Response(retString, AID);
|
||||
return retString;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 磨合转序
|
||||
/// 调用AGV转序接口,成功后执行转序存储过程
|
||||
/// </summary>
|
||||
/// <param name="url">请求URL</param>
|
||||
/// <param name="jobj">请求的JSON对象,包含转序相关参数</param>
|
||||
/// <returns>处理结果</returns>
|
||||
public static string WEB_RunningInTransfer(string url, [FromBody] JObject jobj)
|
||||
{
|
||||
var result = new MsgResHeader<object>
|
||||
{
|
||||
code = 200,
|
||||
message = "",
|
||||
Data = null
|
||||
};
|
||||
|
||||
if (jobj == null)
|
||||
{
|
||||
result.code = 500;
|
||||
result.message = "参数格式不正确!";
|
||||
string retString1 = JsonConvert.SerializeObject(result);
|
||||
SaveMesLog("WEB磨合转序", "参数格式不正确!", Helper.MesLogType.ERROR);
|
||||
MyLog4Net.MyLogHelper.Info("WEB_RunningInTransfer res:", retString1);
|
||||
return retString1;
|
||||
}
|
||||
|
||||
string str = jobj.ToString();
|
||||
// 存储请求日志
|
||||
SaveLog_Interface_Request(url, 2, str, out int AID);
|
||||
|
||||
try
|
||||
{
|
||||
// 获取参数
|
||||
string startPositionCode = jobj["startPositionCode"]?.ToString() ?? "";
|
||||
string endPositionCode = jobj["endPositionCode"]?.ToString() ?? "";
|
||||
string productCode = jobj["productCode"]?.ToString() ?? "";
|
||||
string productModel = jobj["productModel"]?.ToString() ?? "";
|
||||
string targetProcess = jobj["targetProcess"]?.ToString() ?? "";
|
||||
string targetProcessNo = jobj["targetProcessNo"]?.ToString() ?? "";
|
||||
|
||||
// 参数校验
|
||||
if (string.IsNullOrEmpty(startPositionCode) || string.IsNullOrEmpty(endPositionCode))
|
||||
{
|
||||
throw new Exception("起始库位号和目标库位号不能为空");
|
||||
}
|
||||
|
||||
// 1. 调用AGV转序接口
|
||||
var agvResult = CALL_Inerface_DataHandle.CALL_Inerface_MaterialTransfer(startPositionCode, endPositionCode);
|
||||
int agvCode = 500;
|
||||
int.TryParse(agvResult["code"]?.ToString() ?? "500", out agvCode);
|
||||
|
||||
if (agvCode != 200)
|
||||
{
|
||||
result.code = agvCode;
|
||||
result.message = $"AGV调度失败:{agvResult["message"]?.ToString() ?? "未知错误"}";
|
||||
}
|
||||
else
|
||||
{
|
||||
// 2. AGV调度成功,执行转序存储过程
|
||||
var param = new SqlParameter[] {
|
||||
new SqlParameter("@库位号", startPositionCode),
|
||||
new SqlParameter("@产品编号", productCode),
|
||||
new SqlParameter("@产品型号", productModel),
|
||||
new SqlParameter("@目标库位号", endPositionCode),
|
||||
new SqlParameter("@目标工序", targetProcess),
|
||||
new SqlParameter("@目标工序号", targetProcessNo)
|
||||
};
|
||||
|
||||
DataLinkMesWork2.DataAccess2.ExecuteStoredProcedure("XD_磨合_开始下一序", ref param, out string errMessage);
|
||||
|
||||
if (!string.IsNullOrEmpty(errMessage))
|
||||
{
|
||||
result.code = 500;
|
||||
result.message = $"AGV调度成功,但存储过程执行失败:{errMessage}";
|
||||
}
|
||||
else
|
||||
{
|
||||
result.code = 200;
|
||||
result.message = "转序操作成功";
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
// 记录错误日志
|
||||
SaveMesLog("WEB磨合转序", err.Message, Helper.MesLogType.ERROR);
|
||||
|
||||
result.code = 500;
|
||||
result.message = err.Message;
|
||||
}
|
||||
|
||||
string retString = JsonConvert.SerializeObject(result);
|
||||
// 存储响应日志
|
||||
SaveLog_Interface_Response(retString, AID);
|
||||
return retString;
|
||||
}
|
||||
}
|
||||
}
|
||||
67
Interface_WebAPI/SlMesDbIterface/WebAPI/WEB/WEB_Models.cs
Normal file
67
Interface_WebAPI/SlMesDbIterface/WebAPI/WEB/WEB_Models.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace MisDataSaveDate
|
||||
{
|
||||
/// <summary>
|
||||
/// WEB请求类型
|
||||
/// </summary>
|
||||
public class WEB_Request
|
||||
{
|
||||
/// <summary>
|
||||
/// Type 操作类型 用来区分Web的各操作
|
||||
/// </summary>
|
||||
public string type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 参数对象 根据Type 会传递不同的参数
|
||||
/// 使用JObject可以接收任意JSON结构的数据,无需定义实体类
|
||||
/// </summary>
|
||||
public JObject paramObj { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// PLC点位值返回结果
|
||||
/// </summary>
|
||||
public class PLCTagValueResult
|
||||
{
|
||||
/// <summary>
|
||||
/// TagTypeCodeID
|
||||
/// </summary>
|
||||
public int TagTypeCodeID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否读取成功
|
||||
/// </summary>
|
||||
public bool Success { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 点位值
|
||||
/// </summary>
|
||||
public object TagValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 点位名称
|
||||
/// </summary>
|
||||
public string TagName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 工位号
|
||||
/// </summary>
|
||||
public string OpName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 时间戳
|
||||
/// </summary>
|
||||
public string TimeStamp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 消息(错误时返回错误信息)
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user