unit uProReportUnit; interface uses System.SysUtils, System.Classes, Data.DB, System.DateUtils, System.JSON, System.JSON.Types, System.JSON.Readers, System.JSON.Writers, REST.Client, REST.Types, REST.Response.Adapter, TypInfo; // 添加 Indy 相关单元 type { 必须字段验证异常 } ERequiredFieldException = class(Exception); { JSON转换异常 } EJSONConversionException = class(Exception); { 报工单记录结构 - 对应数据库报工单表 } TProReportRecord = record id: Int64; // id - 主键 number: string; // 编号 work_order_number: string; // 工单表编号 - 必须字段 work_order_entry_id: Int64; // 工单子表ID - 必须字段 report_user_id: Int64; // 报工人ID - 必须字段 report_user_name: string; // 报工人名称 - 必须字段 report_channel: string; // 报工途径,默认'PC' status: string; // 状态,默认'A' remark: string; // 备注 create_by: string; // 创建人 - 必须字段 create_time: TDateTime; // 创建时间 - 必须字段 update_by: string; // 更新人 update_time: TDateTime; // 更新时间 report_time: TDateTime; // 报工时间 - 必须字段 report_quantity: Double; // 报工数量 - 必须字段 qualified_quantity: Double; // 合格数量 unqualified_quantity: Double; // 不合格数量 workshop_id: Int64; // 车间ID workshop_name: string; // 车间名称 station_id: Int64; // 工位ID station_name: string; // 工位名称 is_settle: string; // 是否结算工资,默认'N' wages: Double; // 结算工资,默认0.000 quality_status: string; // 质检状态 sn_array: string; // SN码数组 material_number: string; //产品编号 material_no: string; //'dyp_no一个临时的编号' ord_temp12: Double; // 参数12 ord_temp11: Double; // 参数11 ord_temp10: Double; // 参数10 ord_temp9: Double; // 参数9 ord_temp8: Double; // 参数8 ord_temp7: Double; // 参数7 ord_temp6: Double; // 参数6 ord_temp5: Double; // 参数5 ord_temp4: Double; // 参数4 ord_temp3: Double; // 参数3 ord_temp2: Double; // 参数2 ord_temp1: Double; // 参数1 // 扩展字段 extend_field: string; // 扩展字段 { 初始化记录为默认值 } procedure Initialize; { 检查记录是否为空(新记录) } function IsEmpty: Boolean; { 将记录转换为JSON对象 } function ToJSONObject: TJSONObject; { 将记录转换为JSON字符串 } function ToJSONString: string; end; { 报工单映射器类 - 负责数据转换和验证 } TProReportMapper = class public { 创建并返回一个具有默认值的新记录 } class function CreateDefaultRecord: TProReportRecord; { 从数据集转换为记录 } class function DataSetToRecord(DataSet: TDataSet): TProReportRecord; { 从JSON对象转换为记录 } class function JSONToRecord(JSON: TJSONObject): TProReportRecord; overload; { 从JSON字符串转换为记录 } class function JSONToRecord(const JSONString: string): TProReportRecord; overload; { 将记录转换为参数,用于数据库操作 } class procedure RecordToParams(const ARecord: TProReportRecord; Params: TParams); overload; class procedure RecordToParams(const ARecord: TProReportRecord; Params: TStrings); overload; { 验证记录必须字段 } class function ValidateRequiredFields(const ARecord: TProReportRecord): Boolean; { 获取验证错误信息 } class function GetValidationErrors(const ARecord: TProReportRecord): string; end; { HTTP 请求工具类 } TReportHTTPClient = class public { 发送报工请求 } class procedure SendReportRequest1(const ARecord: TProReportRecord; const BaseURL: string; const AuthToken: string); class procedure SendReportRequest(const ARecord: TProReportRecord; const BaseURL: string; const AuthToken: string); end; var fPro_feedback: TProReportRecord; implementation { TProReportRecord } uses uSafeLog; procedure TProReportRecord.Initialize; begin id := 0; number := ''; work_order_number := ''; work_order_entry_id := 0; report_user_id := 0; report_user_name := ''; report_channel := 'PC'; status := 'A'; remark := ''; create_by := ''; create_time := 0; update_by := ''; update_time := 0; report_time := 0; report_quantity := 0; qualified_quantity := 0; unqualified_quantity := 0; workshop_id := 0; workshop_name := ''; station_id := 0; station_name := ''; is_settle := 'N'; wages := 0.000; quality_status := ''; sn_array := ''; material_number:=''; material_no:=''; ord_temp12 := 0; ord_temp11 := 0; ord_temp10 := 0; ord_temp9 := 0; ord_temp8 := 0; ord_temp7 := 0; ord_temp6 := 0; ord_temp5 := 0; ord_temp4 := 0; ord_temp3 := 0; ord_temp2 := 0; ord_temp1 := 0; // 扩展字段 extend_field:= ''; // 扩展字段 end; function TProReportRecord.IsEmpty: Boolean; begin Result := id = 0; end; function TProReportRecord.ToJSONObject: TJSONObject; begin Result := TJSONObject.Create; try Result.AddPair('id', TJSONNumber.Create(id)); Result.AddPair('number', number); Result.AddPair('workOrderNumber', work_order_number); Result.AddPair('workOrderEntryId', TJSONNumber.Create(work_order_entry_id)); Result.AddPair('reportUserId', TJSONNumber.Create(report_user_id)); Result.AddPair('reportUserName', report_user_name); Result.AddPair('reportChannel', report_channel); Result.AddPair('status', status); Result.AddPair('remark', remark); Result.AddPair('createBy', create_by); Result.AddPair('createTime', FormatDateTime('yyyy-mm-dd hh:nn:ss', create_time)); Result.AddPair('updateBy', update_by); if update_time > 0 then Result.AddPair('updateTime', FormatDateTime('yyyy-mm-dd hh:nn:ss', update_time)) else Result.AddPair('updateTime', TJSONNull.Create); Result.AddPair('reportTime', FormatDateTime('yyyy-mm-dd hh:nn:ss', report_time)); Result.AddPair('reportQuantity', TJSONNumber.Create(report_quantity)); Result.AddPair('qualifiedQuantity', TJSONNumber.Create(qualified_quantity)); Result.AddPair('unqualifiedQuantity', TJSONNumber.Create(unqualified_quantity)); Result.AddPair('workshopId', TJSONNumber.Create(workshop_id)); Result.AddPair('workshopName', workshop_name); Result.AddPair('stationId', TJSONNumber.Create(station_id)); Result.AddPair('stationName', station_name); Result.AddPair('isSettle', is_settle); Result.AddPair('wages', TJSONNumber.Create(wages)); Result.AddPair('qualityStatus', quality_status); Result.AddPair('snArray', sn_array); Result.AddPair('materialNumber', material_number); // 修正了字段名拼写 Result.AddPair('materialNo', material_no); Result.AddPair('ordTemp12', TJSONNumber.Create(ord_temp12)); Result.AddPair('ordTemp11', TJSONNumber.Create(ord_temp11)); Result.AddPair('ordTemp10', TJSONNumber.Create(ord_temp10)); Result.AddPair('ordTemp9', TJSONNumber.Create(ord_temp9)); Result.AddPair('ordTemp8', TJSONNumber.Create(ord_temp8)); Result.AddPair('ordTemp7', TJSONNumber.Create(ord_temp7)); Result.AddPair('ordTemp6', TJSONNumber.Create(ord_temp6)); Result.AddPair('ordTemp5', TJSONNumber.Create(ord_temp5)); Result.AddPair('ordTemp4', TJSONNumber.Create(ord_temp4)); Result.AddPair('ordTemp3', TJSONNumber.Create(ord_temp3)); Result.AddPair('ordTemp2', TJSONNumber.Create(ord_temp2)); Result.AddPair('ordTemp1', TJSONNumber.Create(ord_temp1)); except on E: Exception do begin Result.Free; raise EJSONConversionException.Create('Error converting record to JSON: ' + E.Message); end; end; end; function TProReportRecord.ToJSONString: string; var JSONObject: TJSONObject; begin JSONObject := ToJSONObject; try Result := JSONObject.ToString; finally JSONObject.Free; end; end; { TProReportMapper } class function TProReportMapper.CreateDefaultRecord: TProReportRecord; begin Result.Initialize; end; class function TProReportMapper.DataSetToRecord(DataSet: TDataSet): TProReportRecord; begin Result.Initialize; if not DataSet.IsEmpty then begin Result.id := DataSet.FieldByName('id').AsLargeInt; Result.number := DataSet.FieldByName('number').AsString; Result.work_order_number := DataSet.FieldByName('work_order_number').AsString; Result.work_order_entry_id := DataSet.FieldByName('work_order_entry_id').AsLargeInt; Result.report_user_id := DataSet.FieldByName('report_user_id').AsLargeInt; Result.report_user_name := DataSet.FieldByName('report_user_name').AsString; Result.report_channel := DataSet.FieldByName('report_channel').AsString; Result.status := DataSet.FieldByName('status').AsString; Result.remark := DataSet.FieldByName('remark').AsString; Result.create_by := DataSet.FieldByName('create_by').AsString; Result.create_time := DataSet.FieldByName('create_time').AsDateTime; Result.update_by := DataSet.FieldByName('update_by').AsString; Result.update_time := DataSet.FieldByName('update_time').AsDateTime; Result.report_time := DataSet.FieldByName('report_time').AsDateTime; Result.report_quantity := DataSet.FieldByName('report_quantity').AsFloat; Result.qualified_quantity := DataSet.FieldByName('qualified_quantity').AsFloat; Result.unqualified_quantity := DataSet.FieldByName('unqualified_quantity').AsFloat; Result.workshop_id := DataSet.FieldByName('workshop_id').AsLargeInt; Result.workshop_name := DataSet.FieldByName('workshop_name').AsString; Result.station_id := DataSet.FieldByName('station_id').AsLargeInt; Result.station_name := DataSet.FieldByName('station_name').AsString; Result.is_settle := DataSet.FieldByName('is_settle').AsString; Result.wages := DataSet.FieldByName('wages').AsFloat; Result.quality_status := DataSet.FieldByName('quality_status').AsString; Result.sn_array := DataSet.FieldByName('sn_array').AsString; Result.material_number := DataSet.FieldByName('material_number').AsString; Result.material_no := DataSet.FieldByName('material_no').AsString; Result.ord_temp12 := DataSet.FieldByName('ord_temp12').AsFloat; Result.ord_temp11 := DataSet.FieldByName('ord_temp11').AsFloat; Result.ord_temp10 := DataSet.FieldByName('ord_temp10').AsFloat; Result.ord_temp9 := DataSet.FieldByName('ord_temp9').AsFloat; Result.ord_temp8 := DataSet.FieldByName('ord_temp8').AsFloat; Result.ord_temp7 := DataSet.FieldByName('ord_temp7').AsFloat; Result.ord_temp6 := DataSet.FieldByName('ord_temp6').AsFloat; Result.ord_temp5 := DataSet.FieldByName('ord_temp5').AsFloat; Result.ord_temp4 := DataSet.FieldByName('ord_temp4').AsFloat; Result.ord_temp3 := DataSet.FieldByName('ord_temp3').AsFloat; Result.ord_temp2 := DataSet.FieldByName('ord_temp2').AsFloat; Result.ord_temp1 := DataSet.FieldByName('ord_temp1').AsFloat; end; end; class function TProReportMapper.JSONToRecord(JSON: TJSONObject): TProReportRecord; begin Result.Initialize; try if JSON.GetValue('id') <> nil then Result.id := (JSON.GetValue('id') as TJSONNumber).AsInt64; if JSON.GetValue('number') <> nil then Result.number := JSON.GetValue('number').Value; if JSON.GetValue('work_order_number') <> nil then Result.number := JSON.GetValue('work_order_number').Value; if JSON.GetValue('work_order_entry_id') <> nil then Result.work_order_entry_id := (JSON.GetValue('work_order_entry_id') as TJSONNumber).AsInt64; if JSON.GetValue('report_user_id') <> nil then Result.report_user_id := (JSON.GetValue('report_user_id') as TJSONNumber).AsInt64; if JSON.GetValue('report_user_name') <> nil then Result.report_user_name := JSON.GetValue('report_user_name').Value; if JSON.GetValue('report_channel') <> nil then Result.report_channel := JSON.GetValue('report_channel').Value; if JSON.GetValue('status') <> nil then Result.status := JSON.GetValue('status').Value; if JSON.GetValue('remark') <> nil then Result.remark := JSON.GetValue('remark').Value; if JSON.GetValue('create_by') <> nil then Result.create_by := JSON.GetValue('create_by').Value; if JSON.GetValue('create_time') <> nil then Result.create_time := ISO8601ToDate(JSON.GetValue('create_time').Value); if JSON.GetValue('update_by') <> nil then Result.update_by := JSON.GetValue('update_by').Value; if JSON.GetValue('update_time') <> nil then Result.update_time := ISO8601ToDate(JSON.GetValue('update_time').Value); if JSON.GetValue('report_time') <> nil then Result.report_time := ISO8601ToDate(JSON.GetValue('report_time').Value); if JSON.GetValue('report_quantity') <> nil then Result.report_quantity := (JSON.GetValue('report_quantity') as TJSONNumber).AsDouble; if JSON.GetValue('qualified_quantity') <> nil then Result.qualified_quantity := (JSON.GetValue('qualified_quantity') as TJSONNumber).AsDouble; if JSON.GetValue('unqualified_quantity') <> nil then Result.unqualified_quantity := (JSON.GetValue('unqualified_quantity') as TJSONNumber).AsDouble; if JSON.GetValue('workshop_id') <> nil then Result.workshop_id := (JSON.GetValue('workshop_id') as TJSONNumber).AsInt64; if JSON.GetValue('workshop_name') <> nil then Result.workshop_name := JSON.GetValue('workshop_name').Value; if JSON.GetValue('station_id') <> nil then Result.station_id := (JSON.GetValue('station_id') as TJSONNumber).AsInt64; if JSON.GetValue('station_name') <> nil then Result.station_name := JSON.GetValue('station_name').Value; if JSON.GetValue('is_settle') <> nil then Result.is_settle := JSON.GetValue('is_settle').Value; if JSON.GetValue('wages') <> nil then Result.wages := (JSON.GetValue('wages') as TJSONNumber).AsDouble; if JSON.GetValue('quality_status') <> nil then Result.quality_status := JSON.GetValue('quality_status').Value; if JSON.GetValue('sn_array') <> nil then Result.sn_array := JSON.GetValue('sn_array').Value; if JSON.GetValue('material_number') <> nil then Result.material_number := JSON.GetValue('material_number').Value; if JSON.GetValue('material_no') <> nil then Result.material_no := JSON.GetValue('material_no').Value; if JSON.GetValue('ord_temp12') <> nil then Result.ord_temp12 := (JSON.GetValue('ord_temp12') as TJSONNumber).AsDouble; if JSON.GetValue('ord_temp11') <> nil then Result.ord_temp11 := (JSON.GetValue('ord_temp11') as TJSONNumber).AsDouble; if JSON.GetValue('ord_temp10') <> nil then Result.ord_temp10 := (JSON.GetValue('ord_temp10') as TJSONNumber).AsDouble; if JSON.GetValue('ord_temp9') <> nil then Result.ord_temp9 := (JSON.GetValue('ord_temp9') as TJSONNumber).AsDouble; if JSON.GetValue('ord_temp8') <> nil then Result.ord_temp8 := (JSON.GetValue('ord_temp8') as TJSONNumber).AsDouble; if JSON.GetValue('ord_temp7') <> nil then Result.ord_temp7 := (JSON.GetValue('ord_temp7') as TJSONNumber).AsDouble; if JSON.GetValue('ord_temp6') <> nil then Result.ord_temp6 := (JSON.GetValue('ord_temp6') as TJSONNumber).AsDouble; if JSON.GetValue('ord_temp5') <> nil then Result.ord_temp5 := (JSON.GetValue('ord_temp5') as TJSONNumber).AsDouble; if JSON.GetValue('ord_temp4') <> nil then Result.ord_temp4 := (JSON.GetValue('ord_temp4') as TJSONNumber).AsDouble; if JSON.GetValue('ord_temp3') <> nil then Result.ord_temp3 := (JSON.GetValue('ord_temp3') as TJSONNumber).AsDouble; if JSON.GetValue('ord_temp2') <> nil then Result.ord_temp2 := (JSON.GetValue('ord_temp2') as TJSONNumber).AsDouble; if JSON.GetValue('ord_temp1') <> nil then Result.ord_temp1 := (JSON.GetValue('ord_temp1') as TJSONNumber).AsDouble; except on E: Exception do raise EJSONConversionException.Create('Error converting JSON to record: ' + E.Message); end; end; class function TProReportMapper.JSONToRecord(const JSONString: string): TProReportRecord; var JSONObject: TJSONObject; begin JSONObject := TJSONObject.ParseJSONValue(JSONString) as TJSONObject; try Result := JSONToRecord(JSONObject); finally JSONObject.Free; end; end; class procedure TProReportMapper.RecordToParams(const ARecord: TProReportRecord; Params: TStrings); begin Params.Values['id'] := IntToStr(ARecord.id); Params.Values['number'] := ARecord.number; Params.Values['work_order_number'] := ARecord.work_order_number; Params.Values['work_order_entry_id'] := IntToStr(ARecord.work_order_entry_id); Params.Values['report_user_id'] := IntToStr(ARecord.report_user_id); Params.Values['report_user_name'] := ARecord.report_user_name; Params.Values['report_channel'] := ARecord.report_channel; Params.Values['status'] := ARecord.status; Params.Values['remark'] := ARecord.remark; Params.Values['create_by'] := ARecord.create_by; Params.Values['create_time'] := FormatDateTime('yyyy-mm-dd hh:nn:ss', ARecord.create_time); Params.Values['update_by'] := ARecord.update_by; if ARecord.update_time > 0 then Params.Values['update_time'] := FormatDateTime('yyyy-mm-dd hh:nn:ss', ARecord.update_time) else Params.Values['update_time'] := ''; Params.Values['report_time'] := FormatDateTime('yyyy-mm-dd hh:nn:ss', ARecord.report_time); Params.Values['report_quantity'] := FloatToStr(ARecord.report_quantity); Params.Values['qualified_quantity'] := FloatToStr(ARecord.qualified_quantity); Params.Values['unqualified_quantity'] := FloatToStr(ARecord.unqualified_quantity); Params.Values['workshop_id'] := IntToStr(ARecord.workshop_id); Params.Values['workshop_name'] := ARecord.workshop_name; Params.Values['station_id'] := IntToStr(ARecord.station_id); Params.Values['station_name'] := ARecord.station_name; Params.Values['is_settle'] := ARecord.is_settle; Params.Values['wages'] := FloatToStr(ARecord.wages); Params.Values['quality_status'] := ARecord.quality_status; Params.Values['sn_array'] := ARecord.sn_array; Params.Values['material_number'] := ARecord.material_number; Params.Values['material_no'] := ARecord.material_no; Params.Values['ord_temp12'] := FloatToStr(ARecord.ord_temp12); Params.Values['ord_temp11'] := FloatToStr(ARecord.ord_temp11); Params.Values['ord_temp10'] := FloatToStr(ARecord.ord_temp10); Params.Values['ord_temp9'] := FloatToStr(ARecord.ord_temp9); Params.Values['ord_temp8'] := FloatToStr(ARecord.ord_temp8); Params.Values['ord_temp7'] := FloatToStr(ARecord.ord_temp7); Params.Values['ord_temp6'] := FloatToStr(ARecord.ord_temp6); Params.Values['ord_temp5'] := FloatToStr(ARecord.ord_temp5); Params.Values['ord_temp4'] := FloatToStr(ARecord.ord_temp4); Params.Values['ord_temp3'] := FloatToStr(ARecord.ord_temp3); Params.Values['ord_temp2'] := FloatToStr(ARecord.ord_temp2); Params.Values['ord_temp1'] := FloatToStr(ARecord.ord_temp1); end; class procedure TProReportMapper.RecordToParams(const ARecord: TProReportRecord; Params: TParams); begin Params.ParamByName('id').AsLargeInt := ARecord.id; Params.ParamByName('number').AsString := ARecord.number; Params.ParamByName('work_order_number').AsString := ARecord.work_order_number; Params.ParamByName('work_order_entry_id').AsLargeInt := ARecord.work_order_entry_id; Params.ParamByName('report_user_id').AsLargeInt := ARecord.report_user_id; Params.ParamByName('report_user_name').AsString := ARecord.report_user_name; Params.ParamByName('report_channel').AsString := ARecord.report_channel; Params.ParamByName('status').AsString := ARecord.status; Params.ParamByName('remark').AsString := ARecord.remark; Params.ParamByName('create_by').AsString := ARecord.create_by; Params.ParamByName('create_time').AsDateTime := ARecord.create_time; Params.ParamByName('update_by').AsString := ARecord.update_by; Params.ParamByName('update_time').AsDateTime := ARecord.update_time; Params.ParamByName('report_time').AsDateTime := ARecord.report_time; Params.ParamByName('report_quantity').AsFloat := ARecord.report_quantity; Params.ParamByName('qualified_quantity').AsFloat := ARecord.qualified_quantity; Params.ParamByName('unqualified_quantity').AsFloat := ARecord.unqualified_quantity; Params.ParamByName('workshop_id').AsLargeInt := ARecord.workshop_id; Params.ParamByName('workshop_name').AsString := ARecord.workshop_name; Params.ParamByName('station_id').AsLargeInt := ARecord.station_id; Params.ParamByName('station_name').AsString := ARecord.station_name; Params.ParamByName('is_settle').AsString := ARecord.is_settle; Params.ParamByName('wages').AsFloat := ARecord.wages; Params.ParamByName('quality_status').AsString := ARecord.quality_status; Params.ParamByName('sn_array').AsString := ARecord.sn_array; Params.ParamByName('material_number').AsString := ARecord.material_number; Params.ParamByName('material_no').AsString := ARecord.material_no; Params.ParamByName('ord_temp12').AsFloat := ARecord.ord_temp12; Params.ParamByName('ord_temp11').AsFloat := ARecord.ord_temp11; Params.ParamByName('ord_temp10').AsFloat := ARecord.ord_temp10; Params.ParamByName('ord_temp9').AsFloat := ARecord.ord_temp9; Params.ParamByName('ord_temp8').AsFloat := ARecord.ord_temp8; Params.ParamByName('ord_temp7').AsFloat := ARecord.ord_temp7; Params.ParamByName('ord_temp6').AsFloat := ARecord.ord_temp6; Params.ParamByName('ord_temp5').AsFloat := ARecord.ord_temp5; Params.ParamByName('ord_temp4').AsFloat := ARecord.ord_temp4; Params.ParamByName('ord_temp3').AsFloat := ARecord.ord_temp3; Params.ParamByName('ord_temp2').AsFloat := ARecord.ord_temp2; Params.ParamByName('ord_temp1').AsFloat := ARecord.ord_temp1; end; class function TProReportMapper.ValidateRequiredFields(const ARecord: TProReportRecord): Boolean; begin Result := False; if ARecord.work_order_entry_id = 0 then Exit; if ARecord.report_user_id = 0 then Exit; if ARecord.report_user_name.IsEmpty then Exit; if ARecord.create_by.IsEmpty then Exit; if ARecord.create_time = 0 then Exit; if ARecord.report_time = 0 then Exit; if ARecord.report_quantity = 0 then Exit; Result := True; end; class function TProReportMapper.GetValidationErrors(const ARecord: TProReportRecord): string; begin Result := ''; if ARecord.work_order_number = '' then Result := Result + '工单表编号不能为空; '; if ARecord.material_number = '' then Result := Result + '产品二维码不能为空; '; if ARecord.report_user_id = 0 then Result := Result + '报工人ID不能为空; '; if ARecord.report_user_name.IsEmpty then Result := Result + '报工人名称不能为空; '; if ARecord.create_by.IsEmpty then Result := Result + '创建人不能为空; '; if ARecord.create_time = 0 then Result := Result + '创建时间不能为空; '; if ARecord.report_time = 0 then Result := Result + '报工时间不能为空; '; if ARecord.report_quantity = 0 then Result := Result + '报工数量不能为空; '; end; { TReportHTTPClient } class procedure TReportHTTPClient.SendReportRequest1(const ARecord: TProReportRecord; const BaseURL: string; const AuthToken: string); var RESTClient: TRESTClient; RESTRequest: TRESTRequest; RESTResponse: TRESTResponse; JSONArray: TJSONArray; JSONObject: TJSONObject; URL: string; begin RESTClient := TRESTClient.Create(nil); RESTRequest := TRESTRequest.Create(nil); RESTResponse := TRESTResponse.Create(nil); try // 关联组件 RESTRequest.Client := RESTClient; RESTRequest.Response := RESTResponse; // 构建完整 URL URL := BaseURL + '/prod-api/production/report'; RESTClient.BaseURL := URL; // 设置请求方法为 POST RESTRequest.Method := rmPOST; // 设置请求头 RESTRequest.AddParameter('Authorization', 'Bearer ' + AuthToken, pkHTTPHEADER, [poDoNotEncode]); RESTRequest.AddParameter('Content-Type', 'application/json', pkHTTPHEADER, [poDoNotEncode]); // 构建 JSON 请求体 JSONArray := TJSONArray.Create; try JSONObject := ARecord.ToJSONObject; JSONArray.AddElement(JSONObject); // 设置请求体 RESTRequest.AddBody(JSONArray.ToString, ctAPPLICATION_JSON); try // 发送请求 RESTRequest.Execute; // 记录请求和响应信息 WorkLog.MessageInfo('url:%s,状态码: %d, 响应: %s', [URL, RESTResponse.StatusCode, RESTResponse.Content]); // 处理响应 if RESTResponse.StatusCode = 200 then begin // 解析响应 // ProcessResponse(RESTResponse.Content); end else begin // 处理错误 WorkLog.MessageError('HTTP错误: %d - %s', [RESTResponse.StatusCode, RESTResponse.Content]); end; except on E: Exception do begin // 处理异常 WorkLog.MessageError('异常: %s', [E.Message]); end; end; finally JSONArray.Free; end; finally RESTClient.Free; RESTRequest.Free; RESTResponse.Free; end; end; class procedure TReportHTTPClient.SendReportRequest(const ARecord: TProReportRecord; const BaseURL: string; const AuthToken: string); var RESTClient: TRESTClient; RESTRequest: TRESTRequest; RESTResponse: TRESTResponse; JSONArray: TJSONArray; JSONObject: TJSONObject; URL: string; begin RESTClient := TRESTClient.Create(nil); RESTRequest := TRESTRequest.Create(nil); RESTResponse := TRESTResponse.Create(nil); try RESTRequest.Client := RESTClient; RESTRequest.Response := RESTResponse; // 构建完整 URL - 注意去掉了 "/add",因为 @PostMapping 映射到根路径 URL := BaseURL + '/prod-api/production/report'; RESTClient.BaseURL := URL; // 设置请求方法为 POST RESTRequest.Method := rmPOST; // 设置请求头 RESTRequest.AddParameter('Authorization', 'Bearer ' + AuthToken, pkHTTPHEADER, [poDoNotEncode]); RESTRequest.AddParameter('Content-Type', 'application/json', pkHTTPHEADER, [poDoNotEncode]); // 构建 JSON 请求体 - 创建一个包含单个对象的数组 JSONArray := TJSONArray.Create; try // 创建 Report 对象 JSONObject := TJSONObject.Create; // 根据后端 Report 类的字段名添加属性 // 注意:这些字段名必须与后端 Report 类的属性名完全匹配 JSONObject.AddPair('stationId', TJSONNumber.Create(ARecord.station_id)); JSONObject.AddPair('workOrderEntryId', TJSONNumber.Create(1));//ARecord.work_order_entry_id JSONObject.AddPair('stationName', ARecord.station_name); JSONObject.AddPair('reportUserId', TJSONNumber.Create(ARecord.report_user_id)); JSONObject.AddPair('reportUserName', ARecord.report_user_name); JSONObject.AddPair('createBy', ARecord.create_by); JSONObject.AddPair('updateBy', ARecord.update_by); // 格式化时间为字符串(根据后端期望的格式) JSONObject.AddPair('createTime', FormatDateTime('yyyy-mm-dd hh:nn:ss', ARecord.create_time)); JSONObject.AddPair('reportTime', FormatDateTime('yyyy-mm-dd hh:nn:ss', ARecord.report_time)); JSONObject.AddPair('updateTime', FormatDateTime('yyyy-mm-dd hh:nn:ss', ARecord.update_time)); JSONObject.AddPair('reportQuantity', TJSONNumber.Create(ARecord.report_quantity)); JSONObject.AddPair('qualifiedQuantity', TJSONNumber.Create(ARecord.qualified_quantity)); JSONObject.AddPair('qualityStatus', ARecord.quality_status); // 添加自定义字段(根据后端 Report 类的实际字段名) JSONObject.AddPair('ordTemp1', ARecord.ord_Temp1); JSONObject.AddPair('ordTemp2', ARecord.ord_Temp2); JSONObject.AddPair('ordTemp3', ARecord.ord_Temp3); JSONObject.AddPair('ordTemp4', ARecord.ord_Temp4); JSONObject.AddPair('ordTemp5', ARecord.ord_Temp5); JSONObject.AddPair('ordTemp6', ARecord.ord_Temp6); JSONObject.AddPair('ordTemp7', TJSONNumber.Create(ARecord.ord_Temp7)); JSONObject.AddPair('ordTemp8', TJSONNumber.Create(ARecord.ord_Temp8)); // 将对象添加到数组中 JSONArray.AddElement(ARecord.ToJSONObject); //ToJSONObject JSONObject // 记录发送的 JSON 内容 WorkLog.MessageInfo('发送的 JSON: %s', [ARecord.ToJSONObject.ToString]); // 设置请求体 RESTRequest.AddBody(JSONArray.ToString, ctAPPLICATION_JSON); try // 发送请求 RESTRequest.Execute; // 记录完整的请求和响应信息 WorkLog.MessageInfo('请求 URL: %s', [URL]); WorkLog.MessageInfo('请求方法: %s', [GetEnumName(TypeInfo(TRESTRequestMethod), Ord(RESTRequest.Method))]); WorkLog.MessageInfo('状态码: %d', [RESTResponse.StatusCode]); WorkLog.MessageInfo('响应: %s', [RESTResponse.Content]); // 处理响应 if RESTResponse.StatusCode = 200 then begin // 检查响应内容 if Pos('"code":200', RESTResponse.Content) > 0 then begin WorkLog.MessageInfo('请求成功: %s', [RESTResponse.Content]); end else if Pos('"code":500', RESTResponse.Content) > 0 then begin // 处理服务器返回的业务错误 if Pos('请检查是否领料', RESTResponse.Content) > 0 then WorkLog.MessageError('服务器错误: 请检查是否领料%s', [RESTResponse.Content]) else if Pos('该工位未绑定报工仓库', RESTResponse.Content) > 0 then WorkLog.MessageError('服务器错误: 该工位未绑定报工仓库%s', [RESTResponse.Content]) else WorkLog.MessageError('服务器返回错误: %s', [RESTResponse.Content]); end else begin WorkLog.MessageError('未知响应格式: %s', [RESTResponse.Content]); end; end else begin // 处理 HTTP 错误 WorkLog.MessageError('HTTP错误: %d - %s', [RESTResponse.StatusCode, RESTResponse.Content]); end; except on E: Exception do begin // 处理异常 WorkLog.MessageError('请求异常: %s', [E.Message]); end; end; finally JSONArray.Free; end; finally RESTClient.Free; RESTRequest.Free; RESTResponse.Free; end; end; end.