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

441 lines
15 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 uFrame_Dyp003;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Graphics, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.StdCtrls,
System.ImageList, FMX.ImgList, FMX.Controls.Presentation, FMX.Edit,
FMX.Objects,uFrameBase,uShowInfo,uKsoap,uPucFun, FMX.Memo.Types,
FMX.ScrollBox, FMX.Memo, DateUtils, StrUtils, System.JSON, System.RegularExpressions, uExceptionHandler;
type
TFrame_Dyp003 = class(TFrameBase)
Rectangle88: TRectangle;
Option1: TRectangle;
Glyph9: TGlyph;
OptionLabel1: TText;
Text19: TText;
Edit_CaiZhi: TEdit;
Option2: TRectangle;
Glyph2: TGlyph;
OptionLabel3: TText;
Text6: TText;
Edit_banhou: TEdit;
Option3: TRectangle;
Glyph3: TGlyph;
OptionLabel5: TText;
Text23: TText;
Edit_jiexi: TEdit;
Option4: TRectangle;
Glyph12: TGlyph;
OptionLabel7: TText;
Text28: TText;
Edit_xiankuang: TEdit;
Option7: TRectangle;
Glyph13: TGlyph;
OptionLabel9: TText;
Text30: TText;
Edit_rongchadada: TEdit;
ImageList1: TImageList;
Option6: TRectangle;
Glyph1: TGlyph;
Text1: TText;
Text2: TText;
Edit_rongchaxiao: TEdit;
Option5: TRectangle;
Glyph4: TGlyph;
Text3: TText;
Text4: TText;
Edit_jianju: TEdit;
TxtError: TText;
Timer1: TTimer;
OpenDialog1: TOpenDialog;
Memo1: TMemo;
procedure Edit_CaiZhiClick(Sender: TObject);
procedure FrameDblClick(Sender: TObject);
// procedure Timer1Timer(Sender: TObject);
private
iLine: integer;
{ Private declarations }
public
procedure FillDefaultValue(sPartnumValue,sDefaultTxt:string);override; //填写默认值
function DoExec():boolean;override; //判断输入是否有效,执行插入主表,或打开窗体
function CheckValid(var sTxt:string):boolean;override;
end;
implementation
{$R *.fmx}
uses uDM, json_dypSave, uSafeLog, uFile3Json;
function TFrame_Dyp003.CheckValid(var sTxt:string):boolean; //返回面次数据
var
aa:Extended;
begin
Result:=false;
if Trim(Edit_CaiZhi.Text)='' then begin Error(Edit_CaiZhi,TxtError,'水距离值不能为空');Exit;end;
// if Trim(Edit_banhou.Text)='' then begin Error(Edit_banhou,TxtError,'板厚輸入不能為空');Exit;end;
// if Trim(Edit_jiexi.Text)='' then begin Error(Edit_jiexi,TxtError,'是否合格不能为空');Exit;end;
// if Trim(Edit_xiankuang.Text)='' then begin Error(Edit_xiankuang,TxtError,'最小线宽輸入不能為空');Exit;end;
if (self.Tag=2) and (Trim(Edit_jianju.Text)='') then begin Error(Edit_jianju,TxtError,'水距离值');Exit;end;
// if Trim(Edit_rongchaxiao.Text)='' then begin Error(Edit_rongchaxiao,TxtError,'线宽容差最小值輸入不能為空');Exit;end;
// if Trim(Edit_rongchadada.Text)='' then begin Error(Edit_rongchadada,TxtError,'线宽容差最大值輸入不能為空');Exit;end;
// if not TryStrToFloat(Edit_banhou.Text,aa) then begin Error(Edit_banhou,TxtError,'板厚輸入類型錯誤,請重新輸入。');Exit;end;
// if not TryStrToFloat(Edit_jiexi.Text,aa) then begin Error(Edit_jiexi,TxtError,'解析度輸入類型錯誤,請重新輸入。');Exit;end;
// if not TryStrToFloat(Edit_xiankuang.Text,aa) then begin Error(Edit_xiankuang,TxtError,'最小线宽輸入類型錯誤,請重新輸入。');Exit;end;
// if not TryStrToFloat(Edit_jianju.Text,aa) then begin Error(Edit_jianju,TxtError,'最小间距輸入類型錯誤,請重新輸入。');Exit;end;
// if not TryStrToFloat(Edit_rongchaxiao.Text,aa) then begin Error(Edit_rongchaxiao,TxtError,'线宽容差最小值輸入類型錯誤,請重新輸入。');Exit;end;
// if not TryStrToFloat(Edit_rongchadada.Text,aa) then begin Error(Edit_rongchadada,TxtError,'线宽容差最大值輸入類型錯誤,請重新輸入。');Exit;end;
Result:=true;
if Result then Error(Edit_CaiZhi,TxtError,'');
end;
procedure TFrame_Dyp003.FillDefaultValue(sPartnumValue,sDefaultTxt:string);
var
tmpList:TStrings;
sError:string;
function ExtractValue(const InputString: string): string;
var
ColonPos: Integer;
begin
ColonPos := Pos(':', InputString);
if ColonPos > 0 then
Result := Copy(InputString, ColonPos + 1, Length(InputString) - ColonPos)
else
Result := InputString; // 如果没有冒号,返回原字符串
end;
begin
option3.Visible:= self.Tag=2;
if sDefaultTxt='' then Exit;
WorkLog.MessageInfo('FillDefaultValue%s,%s ' , [sPartnumValue, sDefaultTxt]);
// tmpList:=TStringList.Create;
try
// tmpList.DelimitedText:= ReplaceStrWork(sDefaultTxt);
// if tmpList.Count>4 then
begin
//{"ID":"ffff0032ffff0022ffffff16031cd895","入水距离":150,"入水卡关状态":"不合格,","出水距离":65533,"出水卡关状态":"合格,"}
Edit_CaiZhi.Text:= ReplaceStrWork(GetJSONValue(sDefaultTxt, '距离'));//ExtractValue(ReplaceStrWork(tmpList.Strings[tmpList.Count-3]));
// Edit_banhou.Text:=tmpList.Strings[0];
if self.Tag=2 then
Edit_jiexi.Text:= ReplaceStrWork(GetJSONValue(sDefaultTxt, '出水距离'));//ExtractValue(ReplaceStrWork(tmpList.Strings[tmpList.Count-3]));
// Edit_xiankuang.Text:=tmpList.Strings[4];
Edit_jianju.Text:= (GetJSONValue(sDefaultTxt, '卡关')).Replace(',','');//ExtractValue(tmpList.Strings[tmpList.Count-2]);
// Edit_rongchaxiao.Text:=tmpList.Strings[20];
// Edit_rongchadada.Text:=tmpList.Strings[21];
end;
{tmpList.DelimitedText:=sPartnumValue;
if tmpList.Count>5 then //这里根据料号返回信息填写缺省值
Edit_banhou.Text:=tmpList.Strings[5];}
// 从第24个字符开始提取32个字符作为ID
// if tmpList.Count>2 then // 确保字符串足够长 (24+32)
begin
fDevRecord.P_ORG_CODE_id := (GetJSONValue(sDefaultTxt, 'ID')).Replace(',','');
fDevRecord.P_ORG_CODE := (GetJSONValue(sDefaultTxt, 'SN码')).Replace(',','').Replace(';','');
// if (fDevRecord.P_ORG_CODE_id<>'') or (fDevRecord.P_ORG_CODE='') then
// KJSon.REST_pro_List('pageNum=1&pageSize=30&materialNo='+fDevRecord.P_ORG_CODE_id, 7, sError); //ID查二维码
// // 处理提取的ID
// // fDevRecord.P_ORG_CODE_id := FormatDataToJSON(sID);
//
// if KJSon.list_pro_temp.Count>0 then
// begin
// fDevRecord.P_ORG_CODE:= GetJSONValue(KJSon.list_pro_Temp.Strings[KJSon.list_pro_temp.Count - 1], 'snArray');
//
// fDevRecord.P_DIE_NAME:= Edit_jianju.Text; //是否合格
//
// // ShowInfoOK('fDevRecord.P_ORG_CODE_id:'+fDevRecord.P_ORG_CODE_id);
//
// end;
if Assigned(self.OnPanelButClick) then
self.OnPanelButClick(Self, 0); // 将Frame自身作为Sender传递
end
finally
// tmpList.Free;
end;
end;
function GetLatestFileInDir(const DirPath: string): string;
var
SearchRec: TSearchRec;
LatestTime: TDateTime;
CurrentTime: TDateTime;
begin
Result := '';
LatestTime := MinDateTime; // 初始化为最小日期
if FindFirst(IncludeTrailingPathDelimiter(DirPath) + 'cl-*.txt', faAnyFile, SearchRec) = 0 then
begin
repeat
if (SearchRec.Name <> '.') and (SearchRec.Name <> '..') then
begin
CurrentTime := FileDateToDateTime(SearchRec.Time);
if CompareDateTime(CurrentTime, LatestTime) > 0 then
begin
LatestTime := CurrentTime;
Result := IncludeTrailingPathDelimiter(DirPath) + SearchRec.Name;
end;
end;
until FindNext(SearchRec) <> 0;
FindClose(SearchRec);
end;
end;
function ExtractDataToJson(const inputStr: string): string;
var
match: TMatch;
procedureStr, snStr, idStr, distanceStr, resultStr: string;
jsonObj: TJSONObject;
distanceList: TArray<string>;
begin
try
// 使用正则表达式匹配关键字段,增加SN码匹配
match := TRegEx.Match(inputStr,
'当前工序:(\d+).*?SN码:([^;,]+).*?ID([^,]+).*?距离值:\[(.*?)\].*?卡关:([^,]+)');
if not match.Success then
RaiseValidationException('InputString', InputStr, '输入字符串格式不符,无法提取数据');
procedureStr := match.Groups[1].Value;
snStr := match.Groups[2].Value;
idStr := match.Groups[3].Value;
distanceStr := match.Groups[4].Value;
resultStr := match.Groups[5].Value;
// 提取距离值的最后一个元素
distanceList := distanceStr.Split([',', ' '], TStringSplitOptions.ExcludeEmpty);
if Length(distanceList) = 0 then
RaiseValidationException('DistanceList', distanceStr, '距离值列表为空');
// 创建JSON对象
jsonObj := TJSONObject.Create;
try
jsonObj.AddPair('工序', procedureStr);
jsonObj.AddPair('SN码', snStr); // 新增SN码字段
jsonObj.AddPair('ID', idStr);
jsonObj.AddPair('距离', distanceList[High(distanceList)]);
jsonObj.AddPair('卡关', resultStr);
// 使用 ToString 而不是 ToJSON 来避免 Unicode 转义
Result := jsonObj.ToString;
finally
jsonObj.Free;
end;
except
on E: Exception do
begin
Result := Format('{"错误": "%s", "原始数据": "%s"}', [E.Message, inputStr]);
end;
end;
end;
procedure TFrame_Dyp003.FrameDblClick(Sender: TObject);
var
sFPhat: String;
tmpList: TStringList;
FileMonitor: TFileMonitor;
ResultJSON: string;
i:integer;
begin
inherited;
sFPhat := GetLatestFileInDir(dm.MemTableReadKeyValue('tv_DirData', 'locad_dir')); // 本地文件目录
if FileExists(sFPhat) then
begin
tmpList := TStringList.Create;
FileMonitor := TFileMonitor.Create;
try
// 读取文件内容
tmpList.LoadFromFile(sFPhat);
if (tmpList.Count>0) then
begin
if self.Tag=2 then
begin
// 处理文件内容并获取结果
ResultJSON := FileMonitor.ProcessFileContent(tmpList);
end
else
begin
for I := tmpList.Count-1 downto 0 do
begin
if Trim(tmpList.Strings[i]) <> '' then
ResultJSON:= tmpList.Strings[i];
break;
end;
// 检查是否包含距离值信息
if Pos(',距离值:', ResultJSON) > 0 then
begin
ResultJSON := ExtractDataToJson(ResultJSON);
end;
end;
// 使用处理结果
// ShowMessage(ResultJSON);
// 输出调试信息
// if FileMonitor.DebugInfo.Count>0 then
// for I := 0 to FileMonitor.DebugInfo.Count - 1 do
// begin
// Writeln(FileMonitor.DebugInfo[I]);
// WorkLog.MessageInfo('ResultJSON1-%d:%s ' , [i, FileMonitor.DebugInfo[I]]);
// end;
WorkLog.MessageInfo('ResultJSON3-%d:%s ' , [self.Tag, ResultJSON]);
JSonProcessSensorData:= ResultJSON;
end;
FillDefaultValue('', JSonProcessSensorData);
finally
FileMonitor.Free;
tmpList.Free;
end;
end;
if JSonProcessSensorData<>'' then
begin
self.OnPanelButClick(self, 8);
end;
end;
//procedure TFrame_Dyp003.Timer1Timer(Sender: TObject);
//var
// sFPhat: String;
// y, iLen: Integer;
// tmpList:TStrings;
// fileStream: TFileStream; // 用于以只读方式打开文件
//
// procedure ListfillValue(sDefaultTxt:string);
// var
// tmpList:TStrings;
// ii: Integer;
// begin
// if sDefaultTxt='' then Exit;
// tmpList:=TStringList.Create;
// try
// tmpList.Delimiter:= ',';
// tmpList.DelimitedText:= ReplaceStrWork(sDefaultTxt);
// Memo1.Lines.Clear;
// for ii := 0 to tmpList.Count-1 do
// Memo1.Lines.Add(tmpList.Strings[ii]);
//
// finally
// tmpList.Free;
// end;
// end;
//begin
// inherited;
// sFPhat:= GetLatestFileInDir(dm.MemTableReadKeyValue('tv_DirData','locad_dir')); //本地文件目录
// if FileExists(sFPhat) then
// begin
// tmpList:= TStringList.Create;
// fileStream := TFileStream.Create(sFPhat, fmOpenRead or fmShareDenyWrite); // 只读且禁止写入
// with tmpList do
// try
// tmpList.LoadFromStream(fileStream); // 从流加载内容
// iLen := Count;
// if iLen>iLine then
// begin
// // if OpenDialog1.Execute then
// Memo1.BeginUpdate;
// try
// if tmpList.Count>0 then
// for y := tmpList.Count downto 1 do
// if (tmpList.Strings[y-1]<>'') then
// begin
// JSonProcessSensorData:= FormatDataToJSON(tmpList.Strings[y-1]);
// FillDefaultValue('', JSonProcessSensorData);
// break;
// end;
// // Memo1.Lines.Assign(tmpList); // 关键修改:将当前TStringList内容复制到Memo
// finally
// Memo1.EndUpdate;
// end;
// iLine := tmpList.Count;
//
//
// end;
// finally
// fileStream.Free; // 释放文件流
// Free;
// end;
// end;
//end;
function TFrame_Dyp003.DoExec():boolean;
var
LotNoRecord:TLotNoRecord;
vId:Integer;
sTxt:string;
sError:string;
vP_ID:Double;
begin
Result:=false;
// WorkLog.MessageInfo('Dyp003.DoExec:1');
if CheckValid(sTxt) then //上传数据
begin
// WorkLog.MessageInfo('Dyp003.DoExec:2');
LotNoRecord:=TLotNoRecord.Create('-1'); //初始化记录
LotNoRecord.P_LOT:=ksoap.P_Lot;
LotNoRecord.P_LOT_TYPE:='正常板';
LotNoRecord.P_Enable:='Y';
LotNoRecord.P_ID:=0;
LotNoRecord.P_ORG_CODE:=ksoap.P_ORG_CODE; //廠區
LotNoRecord.P_NUM:=ksoap.P_WORK_NUM; //工號
LotNoRecord.P_PC:=ksoap.P_PC; //製程
LotNoRecord.P_LINE:=ksoap.P_LINE; //線別
LotNoRecord.P_LINE_NUM:=ksoap.P_LINE_NUM; //線別編號
LotNoRecord.P_LINE_SPEED:=StrToFloat(Edit_CaiZhi.Text); //回波距离
if Edit_jiexi.Text.Length>0 then LotNoRecord.P_SLICKER_PRESSURE:= StrToFloat(Edit_jiexi.Text); //出水距离
LotNoRecord.P_DIE_NAME:=(Edit_jianju.Text); //是否合格
LotNoRecord.P_CREATION_DATE:=FormatDateTime('yyyymmdd hh:mm:ss',Now);
// WorkLog.MessageInfo('Dyp003.DoExec:3');
sError:='';
// vP_ID:=KJSon.Thread_cf_traceability_seq_f(ksoap.P_ORG_CODE,sError);
// LotNoRecord.P_ID:=vP_ID;
//直接调用API,出错再保存本地
if not KJSon.Thread_Insert_CM_WIP_PROCESS_LINE_HISTORY_NEW(LotNoRecord,sError) then //提交主表不成功
begin
if sError='連接數據庫服務器失败' then
begin
dm.InsertMain(vId,LotNoRecord,true);
ShowInfoOK('数据库连接失败,已暂存本地,可以继生产', False);
Result:=true;
end
else
ShowError(sError);
end
else
begin
ShowInfoOK('数据上传成功, 可以继生产', True);
Result:=true;
end;
end;
end;
procedure TFrame_Dyp003.Edit_CaiZhiClick(Sender: TObject);
begin
inherited;
ShowTouchKeyBoard();
end;
end.