BSOne.SFC/eCrmHE/EXE_eCrmHomeEdition/Manager/ManagerPrint.pas

442 lines
11 KiB
Plaintext

{*******************************************************}
{ }
{ ManagerPrint }
{ }
{ Copyright (C) 2024 kku }
{ }
{*******************************************************}
unit ManagerPrint;
interface
uses
Tocsg.Obj, System.SysUtils, System.Generics.Collections, Tocsg.Printer,
Winapi.Windows, CttSchDefine, System.SyncObjs, System.Classes;
const
DAT_PRINTINFO = 'pinfo.dat';
PASS_PRINTINFO = '2S=Z0WM\B<5h_X*F';
// PASS_EMFZIP = '251014ToCSG-bs1';
type
PPrtEnt = ^TPrtEnt;
TPrtEnt = record
dtReg,
dtAprv: TDateTime;
sId,
sText,
sOcrText,
sVioText,
sThumbIds,
sPName,
sFPath: String;
WInfo: TPrtWaterEnt;
bPostApv: Boolean;
end;
TPrtEntList = TList<PPrtEnt>;
TManagerPrint = class(TTgObject)
private
CS_: TCriticalSection;
sDataDir_: String;
EntList_: TPrtEntList;
dwChkTick_: DWORD;
procedure Lock;
procedure Unlock;
procedure OnEntNotify(Sender: TObject; const Item: PPrtEnt; Action: TCollectionNotification);
public
Constructor Create;
Destructor Destroy; override;
function AddPrintInfo(PrtInfo: TPrtJobDevInfo; sPName, sFPath, sSpoolPath,
sEmfDir, sPortInfo, sText, sOcrText, sVioText, sThumbIds: String;
bPostApv: Boolean): PPrtEnt;
function GetPrintInfo(sId: String): PPrtEnt;
function DelPrintInfo(sId: String; bSave: Boolean = false): PPrtEnt;
function GetEnts: TEnumerator<PPrtEnt>;
procedure Save(bLock: Boolean = true);
procedure Load;
procedure ProcessExpired;
property DataDir: String read sDataDir_;
end;
implementation
uses
Tocsg.Exception, Tocsg.Strings, ManagerService, Tocsg.Path, Tocsg.Files,
superobject, Tocsg.Json, Tocsg.Convert, Tocsg.DRM.Encrypt, GlobalDefine,
Condition, ManagerModel, Tocsg.Safe, System.DateUtils, System.Zip;
{ TManagerPrint }
Constructor TManagerPrint.Create;
begin
Inherited Create;
dwChkTick_ := 0;
CS_ := TCriticalSection.Create;
sDataDir_ := GetRunExePathDir + 'Data\Print\';
EntList_ := TPrtEntList.Create;
EntList_.OnNotify := OnEntNotify;
Load;
end;
Destructor TManagerPrint.Destroy;
begin
FreeAndNil(EntList_);
Inherited;
FreeAndNil(CS_);
end;
procedure TManagerPrint.Lock;
begin
CS_.Acquire;
end;
procedure TManagerPrint.Unlock;
begin
CS_.Release;
end;
procedure TManagerPrint.OnEntNotify(Sender: TObject; const Item: PPrtEnt; Action: TCollectionNotification);
begin
if Action = cnRemoved then
Dispose(Item);
end;
function TManagerPrint.AddPrintInfo(PrtInfo: TPrtJobDevInfo; sPName, sFPath, sSpoolPath,
sEmfDir, sPortInfo, sText, sOcrText, sVioText, sThumbIds: String; bPostApv: Boolean): PPrtEnt;
var
sId, sPath, sDept: String;
pEnt: PPrtEnt;
enc: TTgDrmEnc;
PO: TPrefModel;
bResult: Boolean;
begin
Result := nil;
try
sId := GetGUID;
{$IFDEF DEUBG}
ASSERT(sId <> '');
sId := UpperCase(sId);
{$ELSE}
if sId = '' then
sId := FormatDateTime('yyyymmddhhnnss+', Now) + gMgSvc.EmpNo
else
sId := UpperCase(sId);
{$ENDIF}
bResult := false;
// sPath := sDataDir_ + sId + '.pdh';
// if ForceDirectories(sDataDir_) then
// begin
// // 스풀파일 암호화 후 저장 24_0924 14:54:14 kku
// enc := TTgDrmEnc.Create(sPath);
// try
// PO := gMgSvc.PrefModel;
// sDept := gMgSvc.DeptName;
// if sDept = '' then
// sDept := PO.DeptName;
//
// enc.SetHaed(PASS_DRM_HEAD, SIG_DRM, gMgSvc.EmpNo, gMgSvc.UserName,
// sDept, PO.PolicyName, CUSTOMER_TYPE);
// bResult := enc.EncryptFromFile(GetMK + '&PtRh', CutFileExt(sSpoolPath) + '.shd');
// finally
// FreeAndNil(enc);
// end;
// end;
sPath := sDataDir_ + sId + '.pdt';
if ForceDirectories(sDataDir_) then
begin
// 스풀파일 암호화 후 저장 24_0924 14:54:14 kku
enc := TTgDrmEnc.Create(sPath);
try
PO := gMgSvc.PrefModel;
sDept := gMgSvc.DeptName;
if sDept = '' then
sDept := PO.DeptName;
enc.SetHaed(PASS_DRM_HEAD, SIG_DRM, gMgSvc.EmpNo, gMgSvc.UserName,
sDept, PO.PolicyName, CUSTOMER_TYPE);
bResult := enc.EncryptFromFile(GetMK + '&PtR', sSpoolPath);
finally
FreeAndNil(enc);
end;
if DirectoryExists(sEmfDir) then
begin
var EmfList: TStringList;
Guard(EmfList, TStringList.Create);
ExtrFilesFromDir(sEmfDir, EmfList, false, 'em1');
if EmfList.Count > 0 then
begin
sPath := sDataDir_ + sId + '.dat';
var zip: TZipFile;
Guard(zip, TZipFile.Create);
zip.Open(sPath, zmWrite);
zip.UTF8Support := true;
var i: Integer;
for i := 0 to EmfList.Count - 1 do
zip.Add(sEmfDir + EmfList[i]);
end;
end;
end;
if bResult then
begin
New(pEnt);
ZeroMemory(pEnt, SizeOf(TPrtEnt));
pEnt.dtReg := Now;
pEnt.sId := sId;
pEnt.sText := sText;
pEnt.sOcrText := sOcrText;
pEnt.sVioText := sVioText;
pEnt.sThumbIds := sThumbIds;
pEnt.sPName := sPName;
pEnt.sFPath := sFPath;
pEnt.bPostApv := bPostApv;
pEnt.WInfo.sPtrName := PrtInfo.sPtrName;
pEnt.WInfo.sDocName := PrtInfo.sDocName;
pEnt.WInfo.DevMode := TTgRtti.SetTypeToStr<TDeviceMode>(PrtInfo.DevMode);
pEnt.WInfo.dwCopy := PrtInfo.dwCopyCount;
pEnt.WInfo.dwTotalPage := PrtInfo.dwTotalPage;
pEnt.WInfo.bPaperV := PrtInfo.bPaperV;
pEnt.WInfo.bColor := PrtInfo.bColor;
pEnt.WInfo.sPaperInfo := PrtInfo.sPaperInfo;
pEnt.WInfo.sPrtIp := PrinterDriverToIP(PrtInfo.sDrvName);
pEnt.WInfo.sPdfPath := sPortInfo;
pEnt.WInfo.bUseWM := true;
Lock;
try
EntList_.Add(pEnt);
finally
Unlock;
end;
Result := pEnt;
Save;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. AddPrintInfo()');
end;
end;
function TManagerPrint.GetPrintInfo(sId: String): PPrtEnt;
var
i: Integer;
begin
Result := nil;
try
Lock;
try
for i := 0 to EntList_.Count - 1 do
begin
if EntList_[i].sId = sId then
begin
Result := EntList_[i];
exit;
end;
end;
finally
Unlock;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. GetPrintInfo()');
end;
end;
function TManagerPrint.DelPrintInfo(sId: String; bSave: Boolean = false): PPrtEnt;
var
i: Integer;
begin
Result := nil;
try
Lock;
try
for i := 0 to EntList_.Count - 1 do
begin
if EntList_[i].sId = sId then
begin
DeleteFile_wait(sDataDir_ + sId + '.pdt');
DeleteFile_wait(sDataDir_ + sId + '.dat');
DeleteDir(sDataDir_ + sId);
// DeleteFile_wait(sDataDir_ + sId + '.pdh');
EntList_.Delete(i);
if bSave then Save(false);
exit;
end;
end;
finally
Unlock;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. DelPrintInfo()');
end;
end;
function TManagerPrint.GetEnts: TEnumerator<PPrtEnt>;
begin
Lock;
try
Result := EntList_.GetEnumerator;
finally
Unlock;
end;
end;
procedure TManagerPrint.Save(bLock: Boolean = true);
var
O, OA: ISuperObject;
i: Integer;
begin
try
OA := TSuperObject.Create(stArray);
if bLock then Lock;
try
for i := 0 to EntList_.Count - 1 do
OA.AsArray.Add(TTgJson.ValueToJsonObject<TPrtEnt>(EntList_[i]^));
finally
if bLock then Unlock;
end;
O := SO;
O.O['List'] := OA;
SaveJsonObjToEncFile(O, sDataDir_ + DAT_PRINTINFO, PASS_PRINTINFO);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. Save()');
end;
end;
procedure TManagerPrint.Load;
var
O: ISuperObject;
i: Integer;
Ent: TPrtEnt;
pEnt: PPrtEnt;
begin
try
EntList_.Clear;
if LoadJsonObjFromEncFile(O, sDataDir_ + DAT_PRINTINFO, PASS_PRINTINFO) then
begin
if O.O['List'] = nil then
exit;
if O.O['List'].DataType <> stArray then
exit;
if O.A['List'].Length > 0 then
begin
for i := 0 to O.A['List'].Length - 1 do
begin
// Ent := TTgJSon.GetDataAsType<TPrtEnt>(O.A['List'][i]);
Ent.dtReg := JavaToDelphiDateTime(O.A['List'][i].I['dtReg']);
Ent.dtAprv := JavaToDelphiDateTime(O.A['List'][i].I['dtAprv']);
Ent.sId := O.A['List'][i].S['sId'];
Ent.sText := O.A['List'][i].S['sText'];
Ent.sOcrText := O.A['List'][i].S['sOcrText'];
Ent.sVioText := O.A['List'][i].S['sVioText'];
Ent.sThumbIds := O.A['List'][i].S['sThumbIds'];
Ent.sPName := O.A['List'][i].S['sPName'];
Ent.sFPath := O.A['List'][i].S['sFPath'];
if O.A['List'][i].O['WInfo'] <> nil then
Ent.WInfo := TTgJSon.GetDataAsType<TPrtWaterEnt>(O.A['List'][i].O['WInfo']);
Ent.bPostApv := O.A['List'][i].B['bPostApv'];
if FileExists(sDataDir_ + Ent.sId + '.pdt') then
begin
New(pEnt);
pEnt^ := Ent;
EntList_.Add(pEnt);
end;
end;
end else begin
DeleteDirSub(sDataDir_);
end;
Save;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. Load()');
end;
end;
procedure TManagerPrint.ProcessExpired;
var
enum: TEnumerator<PPrtEnt>;
dtNow: TDateTime;
pEnt: PPrtEnt;
bMoveNext, bUpdate: Boolean;
i: Integer;
begin
try
// 1시간에 한번만 처리
if (dwChkTick_ <> 0) and
( (GetTickCount - dwChkTick_) < 600000 ) then exit;
dwChkTick_ := GetTickCount;
bUpdate := false;
dtNow := Now;
Guard(enum, GetEnts);
bMoveNext := enum.MoveNext;
Lock;
try
while bMoveNext do
begin
pEnt := enum.Current;
if pEnt = nil then
break;
bMoveNext := enum.MoveNext;
// 승인 후 24시간 이후면 제거
if (pEnt.dtAprv <> 0) and (HoursBetween(pEnt.dtAprv, dtNow) >= 24) then
begin
i := EntList_.IndexOf(pEnt);
if i <> -1 then
begin
EntList_.Delete(i);
bUpdate := true;
end;
continue;
end;
// 요청 후 30시간 이후면 제거
if HoursBetween(pEnt.dtReg, dtNow) >= 30 then
begin
i := EntList_.IndexOf(pEnt);
if i <> -1 then
begin
EntList_.Delete(i);
bUpdate := true;
end;
end;
end;
if bUpdate then
Save(false);
finally
Unlock;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. ProcessExpired()');
end;
end;
end.