Files
dyp/backup_ansi/json_webservice.pas
2026-05-07 20:25:34 +08:00

1106 lines
36 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, uWorkOrderRecordUnit;
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;
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, list_pro_Temp, List_pro_workorderEntry: 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_List_xc(const Value: String; const iValue: Integer; var sError:string):String;
function REST_pro_Value(const Value: String; var sError:string):String;
function REST_pro_Value_xc(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 PostJSONWithREST_Login_xingcheng(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;
implementation
uses uProReportUnit;
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'); //xingcheng
RESTClient := TRESTClient.Create(sbaseUrl + '/prod-api/login'); //yjh
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;
if RESTResponse.StatusCode=200 then
WorkLog.MessageInfo('url:%s,状态码: %d', [RESTClient.BaseURL, RESTResponse.StatusCode])
else
// 输出完整响应信息
WorkLog.MessageInfo('url:%s,状态码: %d, 响应: %s', [RESTClient.BaseURL, RESTResponse.StatusCode, JsonString]);
// 将字符串解析为 TJsonObject
JsonObject := TJsonObject.ParseJSONValue(JsonString) as TJsonObject;
if (JsonObject <> nil) then
begin
if JsonObject.Values['token']<>nil then
begin
JsonString1:= JsonObject.Values['token'].ToString;
FP_Token:= JsonString1.Replace('"','');//JsonObject1.Values['token'].Value;
Result:= FP_Token;
WorkLog.MessageInfo('token: ' + Result);
end;
end;
finally
RESTResponse.Free;
RESTRequest.Free;
RESTClient.Free;
end;
end;
function TKJSon. PostJSONWithREST_Login_xingcheng(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'); //xingcheng
// RESTClient := TRESTClient.Create('http://192.168.5.9:8080/login'); //yjh
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('url:%s,状态码: %d, 响应: %s', [RESTClient.BaseURL, 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=30&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('/prod-api/mes/md/panhao/list?number=&pageNum=1&pageSize=30', iValue, sError);
1: begin
//查工序
FList_pro_process.Clear;
query_user_profile('/prod-api/production/process/list?processCode=&processName=&enableFlag=&pageNum=1&pageSize=100', iValue, sError);
end;
2: begin
//查用户
List_system_users.Clear;
query_user_profile(Format('/prod-api/system/user/list?userName=%s&pageSize=30&pageNum=1', [Value]), iValue, sError);
end;
3: begin
//查工单
List_pro_workorder.Clear;
query_user_profile(Format('/prod-api/production/workOrder/list?pageNum=1&pageSize=30&number=%s', [Value]), iValue, sError);
end;
4: begin
//查二维码
List_Code_workorder.Clear;
query_user_profile(Format('/prod-api/production/report/list?pageNum=1&pageSize=30%s', [Value]), iValue, sError);
end;
5: begin
//查二维码
list_md_workstation.Clear;
query_user_profile(Format('/prod-api/production/workOrder/list?pageNum=1&pageSize=30%s', [Value]), iValue, sError);
end;
6: begin
//查报工单
list_pro_task.Clear; //findTaskByOrderCode
query_user_profile(Format('/prod-api/production/report/list?%s', [Value]), iValue, sError);
end;
7: begin
//ID查二维码
list_pro_Temp.Clear; //findTaskByOrderCode
query_user_profile(Format('/prod-api/production/report/list?%s', [Value]), iValue, sError);
end;
8: begin
//查子工单
List_pro_workorderEntry.Clear;
query_user_profile(Format('/prod-api/production/workOrder/getInfoByEntryId/%s', [Value]), iValue, sError);
end;
end;
end;
function TKJSon. REST_pro_Value_xc(const Value: String; var sError:string):String;
begin
Result:= Query_String(Format('/admin-api/system/user/page?username=%s&pageSize=30&pageNo=1',[Value]));
end;
function TKJSon. REST_pro_List_xc(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=&pageNum=1&pageSize=30', iValue, sError);
1: begin
//查工序
FList_pro_process.Clear;
query_user_profile('/admin-api/mes/pro/process/list?processCode=&processName=&enableFlag=&pageNum=1&pageSize=30', iValue, sError);
end;
2: begin
//查用户
List_system_users.Clear;
query_user_profile(Format('/admin-api/system/user/page?username=%s&pageNum=1&pageSize=30&pageNo=1', [Value]), iValue, sError);
end;
3: begin
//要工单
List_pro_workorder.Clear;
query_user_profile(Format('/admin-api/mes/pro/workorder/list?pageNum=1&pageSize=30&workorderCode=%s', [Value]), iValue, sError);
end;
5: begin
//查二维码
list_md_workstation.Clear;
query_user_profile(Format('/admin-api/mes/md/workstation/list?pageNum=1&pageSize=30%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;
7: begin
list_pro_temp.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.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);
// WorkLog.MessageInfo('total: ' + sValue);
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;
if i<1 then
WorkLog.MessageInfo('TKJSon%d_sValue: %s', [iValue, sValue ]);
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;
7: begin
GetListValue(sTome, list_pro_temp);
end;
8: begin
GetListValue(sTome, List_pro_workorderEntry);
end;
end;
end;
function TKJSon. Query_String(ListUrl:String):String;
var
RESTClient: TRESTClient;
RESTRequest: TRESTRequest;
RESTResponse: TRESTResponse;
JsonString: string;
JsonObject: TJsonObject;
i: integer;
Param: TRESTRequestParameter;
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.0.150',
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;
for i := 0 to RESTRequest.Params.Count - 1 do
begin
Param := RESTRequest.Params[i];
WorkLog.MessageInfo(Format('[i码:%d] %s: %s', [i, Param.Name, Param.Value]));
end;
if RESTResponse.StatusCode=200 then
WorkLog.MessageInfo('url:%s,状态码: %d', [RESTClient.BaseURL, RESTResponse.StatusCode])
else
// 输出完整响应信息
WorkLog.MessageInfo('状态码: %d, 提交:%s, 响应: %s',
[RESTResponse.StatusCode, ListUrl, JsonString]);
// 将字符串解析为 TJsonObject
JsonObject := TJsonObject.ParseJSONValue(JsonString) as TJsonObject;
if (JsonObject <> nil) then
begin
WorkLog.MessageInfo('data:%s ',[JsonObject.ToString]);
end;
if (JsonObject <> nil) and (JsonObject.Values['rows']<>nil) then
begin
// FP_Token:= JsonObject.Values['token'].Value;
// 访问 JSON 对象中的数据
Result:=JsonObject.Values['rows'].ToString;
if Result.IndexOf('"list"')<0 then
Result:='{"list":'+Result+',"total":'+JsonObject.Values['total'].ToString+'}';
WorkLog.MessageInfo('data:ok ');
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_workorderEntry.Free;
list_pro_task.Free;
list_pro_temp.Free;
inherited Destroy;
end;
procedure TKJSon. ClearData(); //清除 廠區 工號 製程 線別 信息
begin
FList_pro_process:= TStringList.Create;
List_system_users:= TStringList.Create;
List_pro_workorder:= TStringList.Create;
List_pro_workorderEntry:= TStringList.Create;
List_Code_workorder:= TStringList.Create;
list_md_workstation:= TStringList.Create;
list_pro_task:= TStringList.Create;
list_pro_temp:= 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
WorkLog.MessageInfo('提交数据main:' + sError);
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;
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, sProWork, sProWorkEntry: String;
Conditions: TJSONObject;
RowIndex: Integer;
prm: TProReportMapper;
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('pageNum=1&pageSize=30&workOrderNumber='+fDevRecord.P_LOT, 6, sError);
end;
WorkLog.MessageInfo('提交数据12:%s,%d,%d', [sError, FList_pro_process.Count,fDevRecord.P_LINE_index]);// FList_pro_process.IndexOf(fDevRecord.P_LINE)]);
// if list_md_workstation.Count=0 then exit;
if (list_pro_task.Count=0) and (fDevRecord.P_LINE_index>0) then
begin
sError:= Format('产品还没有在第一站生产%s',['']);
exit; // and (fDevRecord.P_LINE<>'PROCESS557')
end;
WorkLog.MessageInfo('提交数据12-1:%s,%s',['number!' + fDevRecord.P_LOT,'processCode!' + fDevRecord.P_LINE]);
if (list_pro_task.Count>0) then
begin
// 创建查询条件
Conditions := TJSONObject.Create;
try
// Conditions.AddPair('number', fDevRecord.P_LOT);
if fDevRecord.P_LINE_index-1>-1 then
Conditions.AddPair('stationId', KJson.REST_Value(KJson.FList_pro_process.Strings[fDevRecord.P_LINE_index-1],'id'));
// 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) then
begin
if list_pro_task.Count>0 then
begin
WorkLog.MessageInfo('数据列表:%S',[list_pro_task.Text]);
sError:= Format('产品当前刚过站:%s',[KJson.REST_Value(list_pro_task.Strings[0], 'stationName')]);
end;
exit;
end;
if RowIndex>-1 then
begin
sTemp:= list_pro_task.Strings[RowIndex];
end
else
begin
end;
end;
//检查工单有没有数据
if (List_pro_workorder.Count=0) then
begin
Exit;
end;
sProWork:= List_pro_workorder.Strings[0]; //取工单数据
REST_pro_List(''+REST_Value(sProWork,'id'), 8, sError);
if List_pro_workorderEntry.Count>0 then
begin
sProWorkEntry:= List_pro_workorderEntry.Strings[0]; //取子工单数据
fPro_feedback.work_order_entry_id:= StrToInt(REST_Value(sProWorkEntry,'id'));
end;
prm:= TProReportMapper.Create;
Params:= TStringList.Create;
try
fPro_feedback.material_number:= REST_Value(sProWork,'materialNumber'); //
fPro_feedback.status:= vLotNoRecord.P_DIE_NAME;
// 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.station_id:= fDevRecord.P_Line_id;
fPro_feedback.station_name:= fDevRecord.P_Line_name;
fPro_feedback.work_order_number:= fDevRecord.P_LOT; //工单号
fPro_feedback.sn_array:= fDevRecord.P_ORG_CODE; //产品二维码
if fDevRecord.P_ORG_CODE_id<>'' then
fPro_feedback.material_no:= fDevRecord.P_ORG_CODE_id; //产品二维码id
// fPro_feedback.material_no:= fDevRecord.P_LOT; //dyp产品ID
// 人员信息参数
if KJSon.List_system_users.Count>0 then
fPro_feedback.report_user_id:= StrToInt(REST_Value(KJSon.List_system_users[0],'userId')); // 报工人ID - 必须字段
fPro_feedback.report_user_name:= fDevRecord.P_BC; // 操作人姓名(字符串)
fPro_feedback.create_by:= fDevRecord.P_BC; // 创建人(字符串)
fPro_feedback.update_by:= fDevRecord.P_BC; // 更新人(字符串)
//
// // 时间戳参数
fPro_feedback.create_time:= Now(); // 创建时间(日期时间字符串)
fPro_feedback.report_time:= Now(); // 报工时间(日期时间字符串)
fPro_feedback.update_time:= Now(); // 更新时间(日期时间字符串)
// fPro_feedback.finishedTime:= FormatDateTime('yyyy-mm-dd hh:nn:ss', Now()); // 完成时间(日期时间字符串)
fPro_feedback.report_quantity:= 1; // 实际完成数量(浮点数)
fPro_feedback.qualified_quantity:= 1; // 订单需求数量(浮点数)
// fPro_feedback.workOrderQuentity:= StrToFloat(REST_Value(sTemp,'quantity')); // 工单计划数量(浮点数)
// fPro_feedback.reportingProgress:= (fPro_feedback.quantity/fPro_feedback.orderQuantity) * 100; // 进度百分比(浮点数)
fPro_feedback.quality_status:= vLotNoRecord.P_DIE_NAME; //是否合格
fPro_feedback.ord_Temp1:= vLotNoRecord.P_DIE_USE_NUM; //温度
fPro_feedback.ord_Temp2:= vLotNoRecord.P_LINE_SPEED; //距离
fPro_feedback.ord_Temp3:= vLotNoRecord.P_ELE_CUR_DENSITY; //回波时间
fPro_feedback.ord_Temp4:= vLotNoRecord.P_ELE_AREA1; //幅值
fPro_feedback.ord_Temp5:= vLotNoRecord.P_PRODUCT_PRESSURE; //入水盲区
fPro_feedback.ord_Temp6:= vLotNoRecord.P_COM_TEMPERATURE; //底噪
if vLotNoRecord.P_SIDE<>'' then fPro_feedback.ord_Temp7:= StrToFloat(vLotNoRecord.P_SIDE); //出水盲区
if vLotNoRecord.P_SHORT_CIRCUIT<>'' then fPro_feedback.ord_Temp8:= StrToFloat(vLotNoRecord.P_SHORT_CIRCUIT); //盲区差值
if vLotNoRecord.P_SHORT_CIRCUIT<>'' then fPro_feedback.ord_Temp8:= StrToFloat(vLotNoRecord.P_SHORT_CIRCUIT); //盲区差值
// Conditions.AddPair('number', fDevRecord.P_LOT);
//
// //fPro_feedback.equipmentCode:= '[{"code": "M0401"}]';
// fPro_feedback.equipmentCode:= 'M0401';
WorkLog.MessageInfo('提交数据21:' + '');
// prm.RecordToParams(fpro_feedback,Params);
// Result := Query_String_list('/prod-api/production/report/add', Params)=''; //insert
with TReportHTTPClient.Create do
try
SendReportRequest(fpro_feedback,sbaseUrl,FP_Token);
finally
free;
end;
finally
Params.Free;
prm.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.