442 lines
11 KiB
Plaintext
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.
|