1048 lines
35 KiB
ObjectPascal
1048 lines
35 KiB
ObjectPascal
unit json_webservice;
|
||
|
||
interface
|
||
|
||
uses REST.Client, REST.Types, System.JSON, Winapi.ActiveX, FMX.Forms
|
||
,system.NetEncoding, system.SysUtils, System.Classes, uKsoap
|
||
, uSafeLog;
|
||
|
||
const
|
||
ACCESS_KEY = '58297a8c75e21d218b1da2c610b6f62c';
|
||
baseUrl= 'http://192.168.5.9'; //'http://iot.mrpiot.com:8924';
|
||
|
||
type
|
||
TDevRecord=record //单表内容
|
||
///mirror-plate/put/product/
|
||
P_ORG_CODE:string;
|
||
P_LOT:string;
|
||
P_BC:string;
|
||
P_PC:string;
|
||
P_LINE:string;
|
||
P_LINE_NUM:string;
|
||
P_LOT_TYPE:string;
|
||
P_TROLLEY_NUM:string;
|
||
P_COPPER_MODEL:string;
|
||
P_BUFFER_TYPE:string;
|
||
P_ID:string;
|
||
P_CREATION_DATE:string;
|
||
vParentId:Integer;
|
||
vId:Integer;
|
||
end;
|
||
|
||
TPro_feedback = record
|
||
// id: Integer; // [必填]记录ID
|
||
workstationId: Integer; // [必填]工作站ID
|
||
workstationCode: string; // 工作站编号
|
||
workstationName: string; // 工作站名称
|
||
workorderId: Integer; // [必填]生产工单ID
|
||
workorderCode: string; // 生产工单编号
|
||
workorderName: string; // 生产工单名称
|
||
taskId: Integer; // 生产任务ID
|
||
taskCode: string; // 生产任务编号
|
||
itemId: Integer; // [必填]产品物料ID
|
||
itemCode: string; // [必填]产品物料编码(默认值:'0.00')
|
||
itemName: string; // [必填]产品物料名称
|
||
unitOfMeasure: string; // 计量单位
|
||
quantity: Double; // 报工数量(默认值:0.00)
|
||
assignUsername: string; // 分配用户名
|
||
userName: string; // 报工用户名
|
||
feedbackTime: string; // 开工时间(日期)
|
||
status: string; // 状态(默认值:'PREPARE')
|
||
creator: string; // 创建者(默认值:'')
|
||
createTime: string; // 创建时间(日期)(默认值:当前时间)
|
||
updater: string; // 更新者(默认值:'')
|
||
updateTime: string; // 更新时间(日期)(默认值:当前时间)
|
||
processId: Integer; // [必填]工序ID
|
||
processCode: string; // 工序编码
|
||
processName: string; // 工序名称
|
||
equipmentCode: string; // 设备编号
|
||
finishedTime: string; // 完工时间(日期)
|
||
pauseTime: string; // 暂停时间
|
||
pauseReason: string; // 暂停原因
|
||
orderQuantity: Double; // 排产数量(默认值:1.00)
|
||
workOrderQuentity: Double; // 订单数量(默认值:1.00)
|
||
reportingProgress: Double; // 报工进度(默认值:0.00)
|
||
deleted: Boolean; // [必填]是否删除(默认值:False)
|
||
qc_process: string; // 是否合格
|
||
ordTemp9: Double; // 参数8
|
||
ordTemp8: Double; // 参数8
|
||
ordTemp7: Double; // 参数7
|
||
ordTemp6: Double; // 参数6
|
||
ordTemp5: Double; // 参数5
|
||
ordTemp4: Double; // 参数4
|
||
ordTemp3: Double; // 参数3
|
||
ordTemp2: Double; // 参数2
|
||
ordTemp1: Double; // 参数1
|
||
tenantId: Integer; // [必填]租户编号(默认值:1)
|
||
end;
|
||
|
||
TKJSon = class
|
||
private
|
||
FP_ORG_CODE:string; //厂区
|
||
FP_WORK_NUM:string; //工号
|
||
FP_PC:string; //工艺
|
||
FP_LINE:string; //线别
|
||
FP_LINE_NUM:string; //线别编号
|
||
FP_Lot:string; //单号
|
||
FP_Goods_Num:string; //二维码
|
||
FP_Lot_Num:Integer; //单号数量
|
||
FP_Traceability_ID:double; //主表ID
|
||
FThreadId:Integer;
|
||
FFixture_Code:string;
|
||
FP_Token:string;
|
||
FOnLine:boolean;
|
||
|
||
public
|
||
FList_pro_process, List_system_users, List_pro_workorder, List_Code_workorder: TStrings;
|
||
list_md_workstation, list_pro_task: TStrings; // 工作站,生产任务表
|
||
function REST_Value(Value: String; sKey: String): String;
|
||
function REST_pro_List(const Value: String; const iValue: Integer; var sError:string):String;
|
||
function REST_pro_Value(const Value: String; var sError:string):String;
|
||
function Query_String(ListUrl:String):String;
|
||
function Query_String_list(ListUrl: String; Params: TStringList = nil): String;
|
||
function query_user_profile(ListUrl:String; const iValue: Integer; var sError:string):String;
|
||
function PostJSONWithREST_Login(const username,password:string; var sError:string):String;
|
||
function Thread_xxcc_work_num_f(vP_ORG_CODE,vP_WORK_NUM,vP_PC,vP_LINE:string;var sError:string):boolean;
|
||
function xxcc_work_num_f(vP_ORG_CODE,vP_WORK_NUM,vP_PC,vP_LINE:string;var sError:string):boolean;
|
||
function Insert_CM_WIP_PROCESS_LINE_HISTORY_NEW(vLotNoRecord:TLotNoRecord;var sError:string):boolean;
|
||
function Thread_Insert_CM_WIP_PROCESS_LINE_HISTORY_NEW(vLotNoRecord:TLotNoRecord;var sError:string):boolean;
|
||
procedure ClearData(); //清除 廠區 工號 製程 線別 信息
|
||
constructor Create; virtual;
|
||
destructor Destroy; override;
|
||
end;
|
||
|
||
function KJSon():TKJSon;
|
||
|
||
var
|
||
FKJSon:TKJSon;
|
||
sbaseUrl:String;
|
||
fPro_feedback: TPro_feedback;
|
||
|
||
implementation
|
||
|
||
function TKJSon. PostJSONWithREST_Login(const username,password:string; var sError:string):String;
|
||
var
|
||
RESTClient: TRESTClient;
|
||
RESTRequest: TRESTRequest;
|
||
RESTResponse: TRESTResponse;
|
||
|
||
JsonString, JsonString1: string;
|
||
JsonObject, JsonObject1: TJsonObject;
|
||
begin
|
||
///production/workOrder/list //查询工单列表
|
||
/// api/login
|
||
RESTClient := TRESTClient.Create(sbaseUrl+'/admin-api/system/auth/login');
|
||
// RESTClient := TRESTClient.Create('http://192.168.5.9:8080/login');
|
||
RESTRequest := TRESTRequest.Create(nil);
|
||
RESTResponse := TRESTResponse.Create(nil);
|
||
try
|
||
sError:= '1';
|
||
RESTRequest.Client := RESTClient;
|
||
RESTRequest.Response := RESTResponse;
|
||
RESTRequest.Method := rmPOST;
|
||
// RESTRequest.Method := rmGET;
|
||
// RESTRequest.AddBody('{"key":"value"}', ctAPPLICATION_JSON);
|
||
// 修正Content-Type设置方式(移除URL编码)
|
||
RESTRequest.AddParameter('Content-Type', 'application/json',
|
||
TRESTRequestParameterKind.pkHTTPHEADER, [poDoNotEncode]);
|
||
RESTRequest.AddParameter('charset', 'UTF-8',
|
||
TRESTRequestParameterKind.pkHTTPHEADER, [poDoNotEncode]);
|
||
RESTRequest.AddParameter('access-control-allow-credentials', 'true',
|
||
TRESTRequestParameterKind.pkHTTPHEADER, [poDoNotEncode]);
|
||
//租户编号
|
||
RESTRequest.AddParameter('tenant-id', '1',
|
||
TRESTRequestParameterKind.pkHTTPHEADER, [poDoNotEncode]);
|
||
// 统一设置请求头
|
||
|
||
RESTRequest.AddBody(Format('{'
|
||
+'"tenantName": "春景智能MES",'
|
||
+'"username": "%s",'
|
||
+'"password": "%s", '
|
||
+'"captchaVerification": "NozBNT2MSDdP2gD1/Eme3saOUQp5e1FPNwbw/Qf9YNjgsGyH+/qwuUng1LC88F4NLX3u8Xw0vN/ttuc+2XtFwg==",'
|
||
+'"rememberMe": true '
|
||
+'}', [username, password]), ctAPPLICATION_JSON);
|
||
// RESTRequest.AddBody('{"password":"123456"}', ctAPPLICATION_JSON);
|
||
RESTRequest.Execute;
|
||
|
||
JsonString:= RESTResponse.Content;
|
||
|
||
// 输出完整响应信息
|
||
WorkLog.MessageInfo('状态码: %d, 响应: %s', [RESTResponse.StatusCode, JsonString]);
|
||
|
||
// 将字符串解析为 TJsonObject
|
||
JsonObject := TJsonObject.ParseJSONValue(JsonString) as TJsonObject;
|
||
if (JsonObject <> nil) then
|
||
begin
|
||
if JsonObject.Values['data']<>nil then
|
||
begin
|
||
JsonString1:= JsonObject.Values['data'].ToString;
|
||
WorkLog.MessageInfo('数据: %s', [JsonString1]);
|
||
|
||
JsonObject1 := TJsonObject.ParseJSONValue(JsonString1) as TJsonObject;
|
||
|
||
if JsonObject1.Values['accessToken']<>nil then
|
||
begin
|
||
FP_Token:= JsonObject1.Values['accessToken'].Value;
|
||
Result:= FP_Token;
|
||
// 访问 JSON 对象中的数据
|
||
WorkLog.MessageInfo('token: ' + Result);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
finally
|
||
RESTResponse.Free;
|
||
RESTRequest.Free;
|
||
RESTClient.Free;
|
||
end;
|
||
end;
|
||
|
||
function TKJSon. REST_pro_Value(const Value: String; var sError:string):String;
|
||
begin
|
||
Result:= Query_String(Format('/admin-api/system/user/page?username=%s&pageSize=10&pageNo=1',[Value]));
|
||
end;
|
||
|
||
function TKJSon. REST_pro_List(const Value: String; const iValue: Integer; var sError:string):String;
|
||
begin
|
||
case iValue of
|
||
0: query_user_profile('/admin-api/mes/md/panhao/list?number=&pageNo=1&pageSize=10', iValue, sError);
|
||
1: begin
|
||
//查工序
|
||
FList_pro_process.Clear;
|
||
query_user_profile('/admin-api/mes/pro/process/list?processCode=&processName=&enableFlag=&pageNo=1&pageSize=10', iValue, sError);
|
||
end;
|
||
2: begin
|
||
//查用户
|
||
List_system_users.Clear;
|
||
query_user_profile(Format('/admin-api/system/user/page?username=%s&pageSize=10&pageNo=1', [Value]), iValue, sError);
|
||
end;
|
||
3: begin
|
||
//要工单
|
||
List_pro_workorder.Clear;
|
||
query_user_profile(Format('/admin-api/mes/pro/workorder/list?pageNo=1&pageSize=10&workorderCode=%s', [Value]), iValue, sError);
|
||
end;
|
||
5: begin
|
||
//查二维码
|
||
list_md_workstation.Clear;
|
||
query_user_profile(Format('/admin-api/mes/md/workstation/list?pageNo=1&pageSize=10%s', [Value]), iValue, sError);
|
||
end;
|
||
6: begin
|
||
|
||
list_pro_task.Clear; //findTaskByOrderCode
|
||
query_user_profile(Format('/admin-api/mes/pro/task/list?%s', [Value]), iValue, sError);
|
||
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function TKJSon. query_user_profile(ListUrl:String; const iValue: Integer; var sError:string):String;
|
||
var
|
||
sTome:string;
|
||
|
||
function GetListValue(sValue: string; Var ListValue:TStrings): Boolean;
|
||
var
|
||
I: Integer;
|
||
sTest: string;
|
||
JsonObject: TJsonObject;
|
||
begin
|
||
JsonObject := TJsonObject.ParseJSONValue(sValue) as TJsonObject;
|
||
if (JsonObject = nil) then Exit;
|
||
try
|
||
// if (JsonObject <> nil) and (JsonObject.Values['data']<>nil) then
|
||
// begin
|
||
// if (JsonObject.Values['data'].FindValue('total')<>nil) then
|
||
// begin
|
||
// WorkLog.MessageInfo('total: ' + JsonObject.Values['data'].FindValue('total').ToString);
|
||
// for I := 0 to StrToInt(JsonObject.Values['data'].FindValue('total').ToString) - 1 do
|
||
// begin
|
||
// sTest:= JsonObject.Values['data'].FindValue('list').A[I].ToString;
|
||
// ListValue.Add(sTest);
|
||
// WorkLog.MessageInfo('list'+IntToStr(I)+': ' + sTest);
|
||
// end;
|
||
// end;
|
||
// end;
|
||
WorkLog.MessageInfo('TKJSon%d_sValue: %s', [iValue, sValue ]);
|
||
if JsonObject.Values['taskPage']<>nil then
|
||
JsonObject:= TJsonObject.ParseJSONValue(JsonObject.Values['taskPage'].ToString) as TJsonObject;
|
||
|
||
|
||
if (JsonObject <> nil) and (JsonObject.Values['total']<>nil) then
|
||
begin
|
||
WorkLog.MessageInfo('total: ' + JsonObject.Values['total'].ToString);
|
||
|
||
for I := 0 to StrToInt(JsonObject.Values['total'].ToString) - 1 do
|
||
begin
|
||
sTest:= JsonObject.Values['list'].A[I].ToString;
|
||
ListValue.Add(sTest);
|
||
WorkLog.MessageInfo('list'+IntToStr(I)+': ' + sTest);
|
||
end;
|
||
|
||
end;
|
||
finally
|
||
JsonObject.Free;
|
||
end;
|
||
end;
|
||
begin
|
||
sTome:= query_String(ListUrl);
|
||
|
||
case iValue of
|
||
0: begin
|
||
|
||
end;
|
||
1: begin
|
||
GetListValue(sTome, FList_pro_process);
|
||
end;
|
||
2: begin
|
||
GetListValue(sTome, List_system_users);
|
||
end;
|
||
3: begin
|
||
GetListValue(sTome, List_pro_workorder);
|
||
end;
|
||
4: begin
|
||
GetListValue(sTome, List_Code_workorder);
|
||
end;
|
||
5: begin
|
||
GetListValue(sTome, List_md_workstation);
|
||
end;
|
||
6: begin
|
||
GetListValue(sTome, list_pro_task);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function TKJSon. Query_String(ListUrl:String):String;
|
||
var
|
||
RESTClient: TRESTClient;
|
||
RESTRequest: TRESTRequest;
|
||
RESTResponse: TRESTResponse;
|
||
|
||
JsonString: string;
|
||
JsonObject: TJsonObject;
|
||
|
||
begin
|
||
if FP_Token='' then
|
||
begin
|
||
Result:='';
|
||
exit;
|
||
end;
|
||
|
||
///production/workOrder/list //查询工单列表
|
||
/// api/login
|
||
/// system/user/profile
|
||
RESTClient := TRESTClient.Create(sbaseUrl + ListUrl);
|
||
RESTRequest := TRESTRequest.Create(nil);
|
||
RESTResponse := TRESTResponse.Create(nil);
|
||
try
|
||
RESTRequest.Client := RESTClient;
|
||
RESTRequest.Response := RESTResponse;
|
||
// RESTRequest.Method := rmPOST;
|
||
RESTRequest.Method := rmGET;
|
||
// RESTRequest.AddBody('{"key":"value"}', ctAPPLICATION_JSON);
|
||
// 修正Content-Type设置方式(移除URL编码)
|
||
RESTRequest.AddParameter('Content-Type', 'application/json',
|
||
TRESTRequestParameterKind.pkHTTPHEADER, [poDoNotEncode]);
|
||
RESTRequest.AddParameter('charset', 'UTF-8',
|
||
TRESTRequestParameterKind.pkHTTPHEADER, [poDoNotEncode]);
|
||
RESTRequest.AddParameter('access-control-allow-credentials', 'true',
|
||
TRESTRequestParameterKind.pkHTTPHEADER, [poDoNotEncode]);
|
||
RESTRequest.AddParameter('access-control-allow-origin', '192.168.5.9',
|
||
TRESTRequestParameterKind.pkHTTPHEADER, [poDoNotEncode]);
|
||
// 统一设置请求头
|
||
RESTRequest.AddParameter('Authorization','Bearer ' + FP_Token,
|
||
TRESTRequestParameterKind.pkHTTPHEADER, [poDoNotEncode]);
|
||
|
||
//access-control-allow-credentials: true
|
||
//access-control-allow-origin: http://120.229.200.252
|
||
//content-type: application/json;charset=UTF-8
|
||
|
||
// RESTRequest.AddAuthParameter('Authorization', 'Basic ' +
|
||
// TNetEncoding.Base64.Encode('dyp:123456'), TRESTRequestParameterKind.pkHTTPHEADER);
|
||
// RESTRequest.AddBody('{"username":"dyp","password":"123456"}', ctAPPLICATION_JSON);
|
||
// RESTRequest.AddBody('{"password":"123456"}', ctAPPLICATION_JSON);
|
||
RESTRequest.Execute;
|
||
|
||
JsonString:= RESTResponse.Content;
|
||
|
||
if RESTResponse.StatusCode = 500 then
|
||
begin
|
||
PostJSONWithREST_Login(fDevRecord.FP_User,fDevRecord.FP_Pass,JsonString);
|
||
Exit;
|
||
end;
|
||
|
||
// 输出完整响应信息
|
||
WorkLog.MessageInfo('状态码: %d, 提交:%s, 响应: %s',
|
||
[RESTResponse.StatusCode, ListUrl, JsonString]);
|
||
|
||
// 将字符串解析为 TJsonObject
|
||
JsonObject := TJsonObject.ParseJSONValue(JsonString) as TJsonObject;
|
||
if (JsonObject <> nil) and (JsonObject.Values['data']<>nil) then
|
||
begin
|
||
// FP_Token:= JsonObject.Values['token'].Value;
|
||
// 访问 JSON 对象中的数据
|
||
|
||
Result:=JsonObject.Values['data'].ToString;
|
||
WorkLog.MessageInfo('data: ' + Result);
|
||
end;
|
||
|
||
// except
|
||
// on E:Exception do
|
||
// WorkLog.MessageError('API调用异常: ' + E.Message);
|
||
// ShowMessage(RESTResponse.Content);
|
||
finally
|
||
RESTResponse.Free;
|
||
RESTRequest.Free;
|
||
RESTClient.Free;
|
||
end;
|
||
end;
|
||
|
||
function TKJSon.Query_String_list(ListUrl: String; Params: TStringList = nil): String;
|
||
var
|
||
RESTClient: TRESTClient;
|
||
RESTRequest: TRESTRequest;
|
||
RESTResponse: TRESTResponse;
|
||
JsonValue: TJSONValue;
|
||
sParams, Param, sEress: string;
|
||
RetryCount: Integer;
|
||
|
||
JsonBody: TJSONObject; // 新增JSON对象
|
||
const
|
||
MAX_RETRY = 1; // 最大重试次数
|
||
begin
|
||
Result := '';
|
||
if FP_Token = '' then Exit;
|
||
|
||
RetryCount := 0;
|
||
|
||
// 记录请求日志
|
||
WorkLog.MessageInfo('请求: %s', [ListUrl]);
|
||
|
||
while RetryCount <= MAX_RETRY do
|
||
try
|
||
RESTClient := TRESTClient.Create(sbaseUrl + ListUrl);
|
||
try
|
||
RESTRequest := TRESTRequest.Create(nil);
|
||
RESTResponse := TRESTResponse.Create(nil);
|
||
try
|
||
RESTRequest.Client := RESTClient;
|
||
RESTRequest.Response := RESTResponse;
|
||
RESTRequest.Method := rmPOST;
|
||
|
||
// 添加头部参数
|
||
RESTRequest.AddParameter('Authorization', 'Bearer ' + FP_Token,
|
||
TRESTRequestParameterKind.pkHTTPHEADER, [poDoNotEncode]);
|
||
RESTRequest.AddParameter('Content-Type', 'application/json',
|
||
TRESTRequestParameterKind.pkHTTPHEADER, [poDoNotEncode]);
|
||
RESTRequest.AddParameter('charset', 'UTF-8',
|
||
TRESTRequestParameterKind.pkHTTPHEADER, [poDoNotEncode]);
|
||
|
||
// 构建JSON请求体
|
||
JsonBody := TJSONObject.Create;
|
||
try
|
||
if Assigned(Params) then
|
||
begin
|
||
for var I := 0 to Params.Count - 1 do
|
||
begin
|
||
|
||
// 处理 equipmentCode - 解析字符串为 JSON 数组
|
||
// if Params.Names[I] = 'equipmentCode' then
|
||
// begin
|
||
// try
|
||
// JsonValue := TJSONObject.ParseJSONValue(Params.ValueFromIndex[I]);
|
||
// if (JsonValue <> nil) and (JsonValue is TJSONArray) then
|
||
// JsonBody.AddPair('equipmentCode', JsonValue as TJSONArray);
|
||
// except
|
||
// end;
|
||
// end
|
||
// else
|
||
// 添加键值对到JSON对象
|
||
JsonBody.AddPair(
|
||
Params.Names[I], // 参数名 (如 "page")
|
||
TJSONString.Create(Params.ValueFromIndex[I]) // 参数值 (如 "1")
|
||
);
|
||
|
||
end;
|
||
end;
|
||
|
||
// 设置JSON请求体
|
||
RESTRequest.AddBody(JsonBody.ToString, ContentTypeFromString('application/json'));
|
||
finally
|
||
JsonBody.Free; // 释放JSON对象
|
||
end;
|
||
|
||
sParams := '';
|
||
for var i := 0 to RESTRequest.Params.Count - 1 do
|
||
sParams := sParams + Format('%s=%s; ', [
|
||
RESTRequest.Params[i].Name,
|
||
RESTRequest.Params[i].Value
|
||
]);
|
||
|
||
WorkLog.MessageInfo('提交Request: %s', [sParams]);
|
||
RESTRequest.Execute;
|
||
|
||
// 记录请求日志
|
||
WorkLog.MessageInfo('请求: %s, 状态码: %d, 响应: %s',
|
||
[ListUrl, RESTResponse.StatusCode, RESTResponse.Content]);
|
||
|
||
// 处理特殊状态码
|
||
case RESTResponse.StatusCode of
|
||
401: // 未授权
|
||
begin
|
||
if RetryCount < MAX_RETRY then
|
||
begin
|
||
// 尝试重新登录获取新token
|
||
if PostJSONWithREST_Login(fDevRecord.FP_User, fDevRecord.FP_Pass, sEress)<>'' then
|
||
begin
|
||
Inc(RetryCount);
|
||
Continue; // 重试请求
|
||
end;
|
||
end;
|
||
WorkLog.MessageInfo('授权失败: %s', [RESTResponse.Content]);
|
||
Exit;
|
||
end;
|
||
|
||
500: // 服务器错误
|
||
begin
|
||
WorkLog.MessageInfo('服务器错误: %s', [RESTResponse.Content]);
|
||
Exit;
|
||
end;
|
||
end;
|
||
|
||
// 解析JSON响应
|
||
JsonValue := TJSONObject.ParseJSONValue(RESTResponse.Content);
|
||
try
|
||
if not Assigned(JsonValue) then
|
||
begin
|
||
WorkLog.MessageInfo('无效的JSON响应: %s', [RESTResponse.Content]);
|
||
Exit;
|
||
end;
|
||
|
||
// 提取data字段
|
||
if (JsonValue is TJSONObject) and
|
||
(TJSONObject(JsonValue).GetValue('data') <> nil) then
|
||
begin
|
||
Result := TJSONObject(JsonValue).GetValue('data').ToJSON;
|
||
WorkLog.MessageInfo('提取的data字段: %s', [Result]);
|
||
end
|
||
else
|
||
begin
|
||
WorkLog.MessageInfo('响应中缺少data字段: %s', [RESTResponse.Content]);
|
||
end;
|
||
finally
|
||
JsonValue.Free;
|
||
end;
|
||
|
||
Break; // 成功处理,退出循环
|
||
finally
|
||
FreeAndNil(RESTResponse);
|
||
FreeAndNil(RESTRequest);
|
||
end;
|
||
except
|
||
on E: Exception do
|
||
begin
|
||
WorkLog.MessageInfo('请求执行异常: %s', [E.Message]);
|
||
Break;
|
||
end;
|
||
end;
|
||
finally
|
||
FreeAndNil(RESTClient);
|
||
end;
|
||
end;
|
||
|
||
function TKJSon. REST_Value(Value: String; sKey: String): String;
|
||
var
|
||
// JsonString: string; //processName
|
||
JsonObject: TJsonObject;
|
||
begin
|
||
Result := '';
|
||
JsonObject := TJsonObject.ParseJSONValue(Value) as TJsonObject;
|
||
if (JsonObject <> nil) and (JsonObject.Values[sKey]<>nil) then
|
||
begin
|
||
Result := StringReplace(JsonObject.Values[sKey].ToString, '"', '', [rfReplaceAll]);
|
||
end;
|
||
end;
|
||
|
||
//http://iot.mrpiot.com:8924
|
||
|
||
function KJSon():TKJSon;
|
||
begin
|
||
if FKJSon = nil then
|
||
FKJSon := TKJSon.Create;
|
||
Result := FKJSon;
|
||
end;
|
||
|
||
constructor TKJSon. Create;
|
||
begin
|
||
inherited;
|
||
ClearData();
|
||
end;
|
||
|
||
destructor TKJSon. Destroy;
|
||
begin
|
||
FList_pro_process.Free;
|
||
List_system_users.Free;
|
||
List_pro_workorder.Free;
|
||
List_Code_workorder.Free;
|
||
list_md_workstation.Free;
|
||
list_pro_task.Free;
|
||
|
||
inherited Destroy;
|
||
end;
|
||
|
||
procedure TKJSon. ClearData(); //清除 廠區 工號 製程 線別 信息
|
||
begin
|
||
FList_pro_process:= TStringList.Create;
|
||
List_system_users:= TStringList.Create;
|
||
List_pro_workorder:= TStringList.Create;
|
||
List_Code_workorder:= TStringList.Create;
|
||
list_md_workstation:= TStringList.Create;
|
||
list_pro_task:= TStringList.Create;
|
||
|
||
// P_ORG_CODE:='';
|
||
// P_WORK_NUM:='';
|
||
// P_PC:='';
|
||
// P_LINE:='';
|
||
// FP_LINE_NUM:='';
|
||
end;
|
||
|
||
function TKJSon. xxcc_work_num_f(vP_ORG_CODE,vP_WORK_NUM,vP_PC,vP_LINE:string;var sError:string):boolean;
|
||
//var
|
||
// a:compeq_webservice.xxcc_work_num_f;
|
||
// Response:xxcc_work_num_fResponse;
|
||
begin
|
||
if not FOnLine then begin Result:=true;Exit; end;
|
||
|
||
sError:= Format('%s,%s,%s,%s',[vP_ORG_CODE,vP_WORK_NUM,vP_PC,vP_LINE]);
|
||
WorkLog.MessageInfo('提交数据:' + sError);
|
||
|
||
Result:=false;
|
||
// a:=compeq_webservice.xxcc_work_num_f.create;
|
||
try
|
||
// a.P_ORG_CODE:=vP_ORG_CODE;
|
||
// a.P_WORK_NUM:=vP_WORK_NUM;
|
||
// a.P_PC:=vP_PC;
|
||
// a.P_LINE:=vP_LINE;
|
||
// DbApiLog.MessageInfo('xxcc_work_num_f 请求:P_ORG_CODE=%s,P_WORK_NUM=%s,P_PC=%s,P_LINE=%s',[vP_ORG_CODE,vP_WORK_NUM,vP_PC,vP_LINE]);
|
||
// try
|
||
// Response:=compeq_webservice.GetServiceSoap().xxcc_work_num_f(a); //System.False,'',FRIO
|
||
// Result:=Response.xxcc_work_num_fResult.ToUpper='OK';
|
||
// DbApiLog.MessageInfo('xxcc_work_num_f 返回:%s',[Response.xxcc_work_num_fResult]);
|
||
// if Result then
|
||
// begin
|
||
// FP_ORG_CODE:=vP_ORG_CODE;
|
||
// FP_WORK_NUM:=vP_WORK_NUM;
|
||
// FP_PC:=vP_PC;
|
||
// FP_LINE:=vP_LINE;
|
||
// end
|
||
// else //返回出错信息
|
||
// begin
|
||
// sError:= Response.xxcc_work_num_fResult;
|
||
// end;
|
||
// except
|
||
// on e:Exception do
|
||
// begin
|
||
// Result:=false;
|
||
// DbApiLog.Error('xxcc_work_num_f 错误:%s',[ChangeErrorInfo(E.Message)]);
|
||
// sError:=ChangeErrorInfo(E.Message);
|
||
// end;
|
||
// end;
|
||
finally
|
||
// a.Free;
|
||
end;
|
||
end;
|
||
|
||
function TKJSon. Thread_xxcc_work_num_f(vP_ORG_CODE,vP_WORK_NUM,vP_PC,vP_LINE:string;var sError:string):boolean;
|
||
var
|
||
ssError:string;
|
||
bThreadResult:boolean;
|
||
begin
|
||
Result:=false;
|
||
bThreadResult:=false;
|
||
FThreadId:=0;
|
||
TThread.CreateAnonymousThread(
|
||
procedure
|
||
var
|
||
bResult:boolean;
|
||
begin
|
||
CoInitialize(nil);
|
||
try
|
||
bResult:=xxcc_work_num_f(vP_ORG_CODE,vP_WORK_NUM,vP_PC,vP_LINE,ssError);
|
||
TThread.Synchronize(nil,
|
||
procedure
|
||
begin
|
||
bThreadResult:=bResult;
|
||
FThreadId:=1;
|
||
end);
|
||
finally
|
||
CoUninitialize;
|
||
end;
|
||
end).Start;
|
||
while FThreadId=0 do Application.ProcessMessages;
|
||
Result:=bThreadResult;
|
||
sError:=ssError;
|
||
end;
|
||
|
||
procedure InitializeProFeedback(var feedback: TPro_feedback);
|
||
begin
|
||
with feedback do
|
||
begin
|
||
// id := 0;
|
||
workstationId := 0;
|
||
workstationCode := '';
|
||
workstationName := '';
|
||
workorderId := 0;
|
||
workorderCode := '';
|
||
workorderName := '';
|
||
taskId := 0;
|
||
taskCode := '';
|
||
itemId := 0;
|
||
itemCode := '0.00';
|
||
itemName := '';
|
||
unitOfMeasure := '';
|
||
quantity := 0.00;
|
||
assignUsername := '';
|
||
userName := '';
|
||
feedbackTime := '';
|
||
status := 'PREPARE';
|
||
creator := '';
|
||
createTime := DateTimeToStr(Now);
|
||
updater := '';
|
||
updateTime := DateTimeToStr(Now);
|
||
processId := 0;
|
||
processCode := '';
|
||
processName := '';
|
||
equipmentCode := '';
|
||
finishedTime := '';
|
||
pauseTime := '';
|
||
pauseReason := '';
|
||
orderQuantity := 1.00;
|
||
workOrderQuentity := 1.00;
|
||
reportingProgress := 0.00;
|
||
deleted := False;
|
||
ordTemp8 := 0;
|
||
ordTemp7 := 0;
|
||
ordTemp6 := 0;
|
||
ordTemp5 := 0;
|
||
ordTemp4 := 0;
|
||
ordTemp3 := 0;
|
||
ordTemp2 := 0;
|
||
ordTemp1 := 0;
|
||
tenantId := 1;
|
||
end;
|
||
end;
|
||
|
||
|
||
function LocateJSONRow(List: TStrings; Conditions: TJSONObject): Integer;
|
||
var
|
||
I: Integer;
|
||
JSONRow, Value: TJSONValue;
|
||
DataObj: TJSONObject;
|
||
ConditionPair: TJSONPair;
|
||
Key, DataStr, ConditionStr: string;
|
||
IsMatch: Boolean;
|
||
begin
|
||
Result := -1; // 默认未找到
|
||
|
||
// 添加调试日志
|
||
WorkLog.MessageInfo('开始定位,条件数量: %d', [Conditions.Count]);
|
||
|
||
for I := 0 to List.Count - 1 do
|
||
begin
|
||
try
|
||
// 解析 JSON
|
||
JSONRow := TJSONObject.ParseJSONValue(List[I]);
|
||
if not Assigned(JSONRow) then
|
||
begin
|
||
WorkLog.MessageInfo('行 %d: JSON 解析失败', [I]);
|
||
Continue;
|
||
end;
|
||
|
||
// 检查是否为对象
|
||
if not (JSONRow is TJSONObject) then
|
||
begin
|
||
WorkLog.MessageInfo('行 %d: 不是 JSON 对象', [I]);
|
||
JSONRow.Free;
|
||
Continue;
|
||
end;
|
||
|
||
DataObj := TJSONObject(JSONRow);
|
||
IsMatch := True;
|
||
|
||
// 调试:输出当前行关键信息
|
||
if DataObj.TryGetValue('workorderCode', Value) then
|
||
WorkLog.MessageInfo('检查行 %d: workorderCode=%s', [I, Value.Value])
|
||
else
|
||
WorkLog.MessageInfo('检查行 %d: workorderCode 不存在', [I]);
|
||
|
||
// 检查所有条件
|
||
for ConditionPair in Conditions do
|
||
begin
|
||
Key := ConditionPair.JsonString.Value;
|
||
|
||
// 调试日志
|
||
WorkLog.MessageInfo('-- 检查条件: %s=%s', [Key, ConditionPair.JsonValue.Value]);
|
||
|
||
// 获取数据值
|
||
if not DataObj.TryGetValue(Key, Value) then
|
||
begin
|
||
WorkLog.MessageInfo('-- 行 %d: 缺少键 %s', [I, Key]);
|
||
IsMatch := False;
|
||
Break;
|
||
end;
|
||
|
||
// 处理 null 值
|
||
if (Value is TJSONNull) then
|
||
begin
|
||
if not (ConditionPair.JsonValue is TJSONNull) then
|
||
begin
|
||
WorkLog.MessageInfo('-- 行 %d: %s 为 null', [I, Key]);
|
||
IsMatch := False;
|
||
Break;
|
||
end;
|
||
Continue;
|
||
end;
|
||
|
||
// 转换为字符串并修剪空格
|
||
DataStr := Trim(Value.Value);
|
||
ConditionStr := Trim(ConditionPair.JsonValue.Value);
|
||
|
||
// 比较值(不区分大小写)
|
||
if not SameText(DataStr, ConditionStr) then
|
||
begin
|
||
WorkLog.MessageInfo('-- 行 %d: %s 不匹配 (%s ≠ %s)',
|
||
[I, Key, DataStr, ConditionStr]);
|
||
IsMatch := False;
|
||
Break;
|
||
end;
|
||
end;
|
||
|
||
// 找到匹配行
|
||
if IsMatch then
|
||
begin
|
||
Result := I;
|
||
WorkLog.MessageInfo('找到匹配行: %d', [I]);
|
||
// JSONRow.Free;
|
||
Exit;
|
||
end;
|
||
finally
|
||
if Assigned(JSONRow) then
|
||
JSONRow.Free;
|
||
end;
|
||
end;
|
||
|
||
WorkLog.MessageInfo('未找到匹配行');
|
||
end;
|
||
|
||
function TKJSon. Insert_CM_WIP_PROCESS_LINE_HISTORY_NEW(vLotNoRecord:TLotNoRecord;var sError:string):boolean;
|
||
var
|
||
Params: TStringList;
|
||
sTemp: String;
|
||
Conditions: TJSONObject;
|
||
RowIndex: Integer;
|
||
|
||
begin
|
||
Result:=false;
|
||
|
||
// if list_md_workstation.Count=0 then
|
||
// begin
|
||
// REST_pro_List('', 5, sError);
|
||
// end;
|
||
|
||
if list_pro_task.Count=0 then
|
||
begin
|
||
// REST_pro_List('&processCode='+fDevRecord.P_LINE, 6, sError);
|
||
REST_pro_List('workOrderCode='+fDevRecord.P_LOT, 6, sError);
|
||
end;
|
||
|
||
WorkLog.MessageInfo('提交数据12:' + sError);
|
||
// if list_md_workstation.Count=0 then exit;
|
||
if list_pro_task.Count=0 then exit;
|
||
|
||
// sTemp:= list_md_workstation.Strings[0];
|
||
|
||
InitializeProFeedback(fPro_feedback);
|
||
WorkLog.MessageInfo('提交数据12:%s,%s',['workOrderCode!' + fDevRecord.P_LOT,'processCode!' + fDevRecord.P_LINE]);
|
||
|
||
// 创建查询条件
|
||
Conditions := TJSONObject.Create;
|
||
try
|
||
Conditions.AddPair('workorderCode', fDevRecord.P_LOT);
|
||
Conditions.AddPair('processCode', fDevRecord.P_LINE);
|
||
// Conditions.AddPair('status', TJSONNumber.Create(0));
|
||
|
||
// 执行查询
|
||
RowIndex := LocateJSONRow(list_pro_task, Conditions);
|
||
WorkLog.MessageInfo('提交数据13:%d',[RowIndex]);
|
||
|
||
finally
|
||
Conditions.Free;
|
||
end;
|
||
|
||
if (RowIndex<0) or (RowIndex>list_pro_task.Count-1) then exit;
|
||
|
||
|
||
sTemp:= list_pro_task.Strings[RowIndex];
|
||
fPro_feedback.workstationId:= StrToInt(REST_Value(sTemp,'workstationId')); //
|
||
fPro_feedback.workstationcode:= REST_Value(sTemp,'workstationCode');
|
||
fPro_feedback.workstationname:= REST_Value(sTemp,'workstationName');
|
||
|
||
fPro_feedback.workorderId:= StrToInt(REST_Value(sTemp,'id'));
|
||
fPro_feedback.workorderCode:= REST_Value(sTemp,'workorderCode');
|
||
fPro_feedback.workorderName:= REST_Value(sTemp,'workorderName');
|
||
|
||
fPro_feedback.taskId:= StrToInt(REST_Value(sTemp,'id'));
|
||
fPro_feedback.taskCode:= REST_Value(sTemp,'taskCode');
|
||
|
||
fPro_feedback.itemId:= StrToInt(REST_Value(sTemp,'itemId')); // 物料ID(整数)
|
||
fPro_feedback.itemCode:= (REST_Value(sTemp,'itemCode')); // 物料编码(字符串)
|
||
fPro_feedback.itemName:= (REST_Value(sTemp,'itemName')); // 物料名称(字符串)
|
||
fPro_feedback.unitOfMeasure:= (REST_Value(sTemp,'unitOfMeasure')); // 计量单位(字符串)
|
||
|
||
WorkLog.MessageInfo('提交数据2:' + sTemp);
|
||
|
||
// 人员信息参数
|
||
fPro_feedback.assignUsername:= fDevRecord.P_BC; // 分配人账号(字符串)
|
||
fPro_feedback.userName:= fDevRecord.P_BC; // 操作人姓名(字符串)
|
||
fPro_feedback.creator:= fDevRecord.P_BC; // 创建人(字符串)
|
||
fPro_feedback.updater:= fDevRecord.P_BC; // 更新人(字符串)
|
||
|
||
// 时间戳参数
|
||
fPro_feedback.feedbackTime:= FormatDateTime('yyyy-mm-dd hh:nn:ss', Now()); // fPro_feedback.feedbackTime反馈时间(日期时间字符串)
|
||
fPro_feedback.createTime:= FormatDateTime('yyyy-mm-dd hh:nn:ss', Now()); // 创建时间(日期时间字符串)
|
||
fPro_feedback.updateTime:= FormatDateTime('yyyy-mm-dd hh:nn:ss', Now()); // 更新时间(日期时间字符串)
|
||
fPro_feedback.finishedTime:= FormatDateTime('yyyy-mm-dd hh:nn:ss', Now()); // 完成时间(日期时间字符串)
|
||
|
||
fPro_feedback.quantity:= 1; // 实际完成数量(浮点数)
|
||
fPro_feedback.orderQuantity:= 1; // 订单需求数量(浮点数)
|
||
fPro_feedback.workOrderQuentity:= StrToFloat(REST_Value(sTemp,'quantity')); // 工单计划数量(浮点数)
|
||
fPro_feedback.reportingProgress:= (fPro_feedback.quantity/fPro_feedback.orderQuantity) * 100; // 进度百分比(浮点数)
|
||
|
||
fPro_feedback.qc_process:= vLotNoRecord.P_DIE_NAME; //是否合格
|
||
fPro_feedback.ordTemp1:= vLotNoRecord.P_DIE_USE_NUM; //温度
|
||
fPro_feedback.ordTemp2:= vLotNoRecord.P_LINE_SPEED; //距离
|
||
fPro_feedback.ordTemp3:= vLotNoRecord.P_ELE_CUR_DENSITY; //回波时间
|
||
fPro_feedback.ordTemp4:= vLotNoRecord.P_ELE_AREA1; //幅值
|
||
fPro_feedback.ordTemp5:= vLotNoRecord.P_PRODUCT_PRESSURE; //入水盲区
|
||
fPro_feedback.ordTemp6:= vLotNoRecord.P_COM_TEMPERATURE; //底噪
|
||
if vLotNoRecord.P_SIDE<>'' then fPro_feedback.ordTemp7:= StrToFloat(vLotNoRecord.P_SIDE); //出水盲区
|
||
if vLotNoRecord.P_SHORT_CIRCUIT<>'' then fPro_feedback.ordTemp8:= StrToFloat(vLotNoRecord.P_SHORT_CIRCUIT); //盲区差值
|
||
|
||
|
||
//fPro_feedback.equipmentCode:= '[{"code": "M0401"}]';
|
||
fPro_feedback.equipmentCode:= 'M0401';
|
||
|
||
WorkLog.MessageInfo('提交数据21:' + fPro_feedback.workstationname);
|
||
|
||
Params := TStringList.Create;
|
||
try
|
||
// Params.Add('id=' + IntToStr(fPro_feedback.id));
|
||
|
||
// 工作站相关参数
|
||
Params.Add('workstationId=' + IntToStr(fPro_feedback.workstationId)); // 工作站唯一标识符(整数)
|
||
Params.Add('workstationCode=' + fPro_feedback.workstationCode); // 工作站编码(字符串)
|
||
Params.Add('workstationName=' + fPro_feedback.workstationName); // 工作站名称(字符串)
|
||
|
||
// 工单相关参数
|
||
Params.Add('workorderId=' + IntToStr(fPro_feedback.workorderId)); // 工单ID(整数)
|
||
Params.Add('workorderCode=' + fPro_feedback.workorderCode); // 工单编号(字符串)
|
||
Params.Add('workorderName=' + fPro_feedback.workorderName); // 工单名称(字符串)
|
||
|
||
// 任务相关参数
|
||
Params.Add('taskId=' + IntToStr(fPro_feedback.taskId)); // 任务ID(整数)
|
||
Params.Add('taskCode=' + fPro_feedback.taskCode); // 任务编码(字符串)
|
||
|
||
// 物料相关参数
|
||
Params.Add('itemId=' + IntToStr(fPro_feedback.itemId)); // 物料ID(整数)
|
||
Params.Add('itemCode=' + fPro_feedback.itemCode); // 物料编码(字符串)
|
||
Params.Add('itemName=' + fPro_feedback.itemName); // 物料名称(字符串)
|
||
Params.Add('unitOfMeasure=' + fPro_feedback.unitOfMeasure); // 计量单位(字符串)
|
||
Params.Add('quantity=' + FloatToStr(fPro_feedback.quantity)); // 实际完成数量(浮点数)
|
||
Params.Add('orderQuantity=' + FloatToStr(fPro_feedback.orderQuantity));// 订单需求数量(浮点数)
|
||
Params.Add('workOrderQuentity=' + FloatToStr(fPro_feedback.workOrderQuentity)); // 工单计划数量(浮点数)
|
||
|
||
// 人员信息参数
|
||
Params.Add('assignUsername=' + fPro_feedback.assignUsername); // 分配人账号(字符串)
|
||
Params.Add('userName=' + fPro_feedback.userName); // 操作人姓名(字符串)
|
||
Params.Add('creator=' + fPro_feedback.creator); // 创建人(字符串)
|
||
Params.Add('updater=' + fPro_feedback.updater); // 更新人(字符串)
|
||
|
||
// 时间戳参数
|
||
Params.Add('feedbackTime=' + fPro_feedback.feedbackTime); // fPro_feedback.feedbackTime反馈时间(日期时间字符串)
|
||
Params.Add('createTime=' + fPro_feedback.createTime); // 创建时间(日期时间字符串)
|
||
Params.Add('updateTime=' + fPro_feedback.updateTime); // 更新时间(日期时间字符串)
|
||
Params.Add('finishedTime=' + fPro_feedback.finishedTime); // 完成时间(日期时间字符串)
|
||
Params.Add('pauseTime=' + fPro_feedback.pauseTime); // 暂停时间(日期时间字符串)
|
||
|
||
// 状态参数
|
||
Params.Add('status=' + fPro_feedback.status); // 任务状态(字符串)
|
||
Params.Add('deleted=' + BoolToStr(fPro_feedback.deleted)); // 删除标记(布尔值)
|
||
Params.Add('pauseReason=' + fPro_feedback.pauseReason); // 暂停原因(字符串)
|
||
|
||
// 进度参数
|
||
Params.Add('reportingProgress=' + FloatToStr(fPro_feedback.reportingProgress)); // 进度百分比(浮点数)
|
||
|
||
// 工艺参数
|
||
Params.Add('processId=' + IntToStr(fPro_feedback.processId)); // 工艺ID(整数)
|
||
Params.Add('processCode=' + fPro_feedback.processCode); // 工艺编码(字符串)
|
||
Params.Add('processName=' + fPro_feedback.processName); // 工艺名称(字符串)
|
||
|
||
// 设备参数
|
||
Params.Add('equipmentCode=' + fPro_feedback.equipmentCode); // 设备编码(字符串)
|
||
|
||
// 租户参数
|
||
Params.Add('tenantId=' + IntToStr(fPro_feedback.tenantId)); // 租户ID(整数)
|
||
|
||
Params.Add('fPro_feedback.qc_process=' + fPro_feedback.qc_process); // 是否合格
|
||
|
||
|
||
// 预留字段(临时变量)
|
||
Params.Add('ordTemp8=' + FloatToStr(fPro_feedback.ordTemp8)); // 预留字段8(浮点数)
|
||
Params.Add('ordTemp7=' + FloatToStr(fPro_feedback.ordTemp7)); // 预留字段7(浮点数)
|
||
Params.Add('ordTemp6=' + FloatToStr(fPro_feedback.ordTemp6)); // 预留字段6(浮点数)
|
||
Params.Add('ordTemp5=' + FloatToStr(fPro_feedback.ordTemp5)); // 预留字段5(浮点数)
|
||
Params.Add('ordTemp4=' + FloatToStr(fPro_feedback.ordTemp4)); // 预留字段4(浮点数)
|
||
Params.Add('ordTemp3=' + FloatToStr(fPro_feedback.ordTemp3)); // 预留字段3(浮点数)
|
||
Params.Add('ordTemp2=' + FloatToStr(fPro_feedback.ordTemp2)); // 预留字段2(浮点数)
|
||
Params.Add('ordTemp1=' + FloatToStr(fPro_feedback.ordTemp1)); // 预留字段1(浮点数)
|
||
|
||
Result := Query_String_list('/admin-api/mes/pro/feedback/save', Params)=''; //insert
|
||
finally
|
||
Params.Free;
|
||
end;
|
||
|
||
Result:=true;
|
||
end;
|
||
|
||
function TKJSon. Thread_Insert_CM_WIP_PROCESS_LINE_HISTORY_NEW(vLotNoRecord:TLotNoRecord;var sError:string):boolean;
|
||
var
|
||
ssError:string;
|
||
bThreadResult:boolean;
|
||
begin
|
||
Result:=false;
|
||
bThreadResult:=false;
|
||
FThreadId:=0;
|
||
TThread.CreateAnonymousThread(
|
||
procedure
|
||
var
|
||
bResult:boolean;
|
||
begin
|
||
CoInitialize(nil);
|
||
try
|
||
bResult:=Insert_CM_WIP_PROCESS_LINE_HISTORY_NEW(vLotNoRecord,ssError);
|
||
TThread.Synchronize(nil,
|
||
procedure
|
||
begin
|
||
bThreadResult:=bResult;
|
||
FThreadId:=1;
|
||
end);
|
||
finally
|
||
CoUninitialize;
|
||
end;
|
||
end).Start;
|
||
while FThreadId=0 do Application.ProcessMessages;
|
||
Result:=bThreadResult;
|
||
sError:=ssError;
|
||
|
||
end;
|
||
|
||
end.
|