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

628 lines
21 KiB
ObjectPascal
Raw Permalink 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_dypSave;
interface
uses REST.Client, REST.Types, System.JSON, Winapi.ActiveX, FMX.Forms
,system.NetEncoding, system.SysUtils, System.Classes, uKsoap
, uSafeLog, uWorkOrderRecordUnit;
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;
TKJSonSave = 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 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():TKJSonSave;
var
FKJSon:TKJSonSave;
// sbaseUrl:String;
implementation
uses uProReportUnit, json_webservice;
//http://iot.mrpiot.com:8924
function KJSon():TKJSonSave;
begin
if FKJSon = nil then
FKJSon := TKJSonSave.Create;
Result := FKJSon;
end;
constructor TKJSonSave. Create;
begin
inherited;
ClearData();
end;
destructor TKJSonSave. 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;
// FKJSon.Destroy;
inherited Destroy;
end;
procedure TKJSonSave. 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 TKJSonSave. 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;
function TKJSonSave. REST_pro_List(const Value: String; const iValue: Integer; var sError:string):String;
begin
case iValue of
0: WebJSon.query_user_profile('/prod-api/mes/md/panhao/list?number=&pageNum=1&pageSize=30', iValue, nil, sError);
1: begin
//通过工单查工序
// FList_pro_process.Clear;
// list_pro_Temp.Clear;
if List_pro_workorder.Count=0 then exit;
WebJSon.query_user_profile('/prod-api/masterdata/material/'+ REST_Value(List_pro_workorder.Strings[0],'materialId'), iValue, list_pro_Temp, sError);
if list_pro_Temp.Count=0 then exit;
WebJSon.query_user_profile('/prod-api/production/route/'+ REST_Value(list_pro_Temp.Strings[0],'routeId'), iValue, FList_pro_process, sError);
// http://192.168.5.9/prod-api/production/route/11
end;
2: begin
//查用户
WebJSon.query_user_profile(Format('/prod-api/system/user/list?userName=%s&pageSize=30&pageNum=1', [Value]), iValue, List_system_users, sError);
end;
3: begin
//查工单
WebJSon.query_user_profile(Format('/prod-api/production/workOrder/list?pageNum=1&pageSize=30&proStatus=B&number=%s', [Value]), iValue, List_pro_workorder, sError);
end;
4: begin
//查二维码
WebJSon.query_user_profile(Format('/prod-api/production/report/list?pageNum=1&pageSize=30%s', [Value]), iValue, List_Code_workorder, sError);
end;
5: begin
//查二维码
WebJSon.query_user_profile(Format('/prod-api/production/workOrder/list?pageNum=1&pageSize=30&proStatus=B%s', [Value]), iValue, list_md_workstation, sError);
end;
6: begin
//查报工单
//findTaskByOrderCode
WebJSon.query_user_profile(Format('/prod-api/production/report/list?%s', [Value]), iValue, list_pro_task, sError);
end;
7: begin
//ID查二维码
//findTaskByOrderCode
WebJSon.query_user_profile(Format('/prod-api/production/report/list?%s', [Value]), iValue, list_pro_Temp, sError);
end;
8: begin
//查子工单
WebJSon.query_user_profile(Format('/prod-api/production/workOrder/getInfoByEntryId/%s', [Value]), iValue, List_pro_workorderEntry, sError);
end;
9: begin //查所有工序
WebJSon.query_user_profile('/prod-api/production/process/list?processCode=&processName=&enableFlag=&pageNum=1&pageSize=100', iValue,FList_pro_process, sError);
end;
end;
end;
function TKJSonSave. 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 TKJSonSave. 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 TKJSonSave. Insert_CM_WIP_PROCESS_LINE_HISTORY_NEW(vLotNoRecord:TLotNoRecord;var sError:string):boolean;
var
Params: TStringList;
sProWork, sProWorkEntry: String; //
sTemp: 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 + '&snCode=' + fDevRecord.P_ORG_CODE, 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:' + IntToStr(fDevRecord.P_LINE_id)]);
if (list_pro_task.Count>0) then
begin
RowIndex:= -1;
// 创建查询条件
Conditions := TJSONObject.Create;
try
// Conditions.AddPair('number', fDevRecord.P_LOT);
if fDevRecord.P_LINE_index-1>-1 then
begin
sTemp:= REST_Value(KJson.FList_pro_process.Strings[fDevRecord.P_LINE_index-1],'id');
Conditions.AddPair('stationId', sTemp);
// Conditions.AddPair('status', TJSONNumber.Create(0));
// 执行查询
// RowIndex := LocateJSONRow(list_pro_task, Conditions);
RowIndex:= list_pro_task[0].IndexOf('"stationId":' + sTemp); //从最上面的数据取工号卡关
WorkLog.MessageInfo('提交数据13: %d, %s, %s',[RowIndex, sTemp, list_pro_task[0]]);
end;
finally
Conditions.Free;
end;
if (RowIndex<0) and (fDevRecord.P_LINE_index=0) and (vLotNoRecord.P_OFF_NET=-1) then //判断是不是第一个工序,去掉维修的
begin
sTemp:= REST_Value(KJson.FList_pro_process.Strings[0],'id'); //工序列表
RowIndex:= list_pro_task[0].IndexOf('"stationId":' + sTemp);
WorkLog.MessageInfo('提交数据14: %d, %s, %s',[RowIndex, sTemp, list_pro_task[0]]);
sError:= '没有报工数据';
end;
if (RowIndex<0) and (vLotNoRecord.P_OFF_NET=-1) then
begin
if list_pro_task.Count>0 then
begin
WorkLog.MessageInfo('数据列表14:%S',[list_pro_task.Text]);
sError:= Format('产品当前刚过站:%s',[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
WorkLog.MessageInfo('工单数据:%d',[List_pro_workorder.Count]);
sError:= '没有工单数据';
Exit;
end;
sProWork:= List_pro_workorder.Strings[0]; //取工单数据
WorkLog.MessageInfo('提交数据15: %d,RowIndex%d',[List_pro_workorderEntry.Count,RowIndex]);
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.quality_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
WorkLog.MessageInfo('提交数据16: %d',[List_system_users.Count]);
// 人员信息参数
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; // 进度百分比(浮点数)
if vLotNoRecord.P_DIE_NAME='-1' then vLotNoRecord.P_DIE_NAME:= '合格';
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); //盲区差值
fPro_feedback.ord_Temp9:= vLotNoRecord.P_SLICKER_PRESSURE; //出水距离
fPro_feedback.status:= '正常';
if vLotNoRecord.P_OFF_NET=1 then
begin
WorkLog.MessageInfo('返修数据01');
fPro_feedback.status:= '返修';
fPro_feedback.remark:= vLotNoRecord.P_MESH; //维修备注
// fPro_feedback.station_name:= '维修部';
// fPro_feedback.station_id:= StrToInt(fDevRecord.P_LINE_Num);
// fPro_feedback.station_name:= fDevRecord.P_LINE;
fPro_feedback.workshop_name:= '维修部';
WorkLog.MessageInfo('提交返修数据02:' + fPro_feedback.remark);
end;
// 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, WebJSon.FP_Token);
if (FList_pro_process.Count>0)
and (REST_Value(FList_pro_process[fDevRecord.P_LINE_index],'processId')=REST_Value(FList_pro_process[FList_pro_process.Count-1],'processId'))
and (List_pro_workorder.Count>0) then //判断是不是最后一个工序
begin
RowIndex:= -1;
try
RowIndex:= StrToInt(REST_Value(List_pro_workorder[0],'id'));
WorkLog.MessageInfo('提交数据22:%d',[RowIndex]);
if RowIndex>-1 then
SendWordOrderRequest(RowIndex,sbaseUrl, WebJSon.FP_Token);
except
WorkLog.MessageInfo('提交数据23:' + '');
end;
end;
finally
free;
end;
finally
Params.Free;
prm.Free;
end;
Result:=true;
end;
function TKJSonSave. 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.