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

1048 lines
35 KiB
ObjectPascal
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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.