ProjectManagerDm.pas 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658
  1. unit ProjectManagerDm;
  2. interface
  3. uses
  4. TenderBackupManager,
  5. SysUtils, Classes, DB, DBClient, Provider, ADODB, Connections, ZhAPI,
  6. sdDB, sdProvider, sdIDTree;
  7. type
  8. TProjectManagerData = class(TDataModule)
  9. sdpProjectsInfo: TsdADOProvider;
  10. sddProjectsInfo: TsdDataSet;
  11. sdvProjectsInfo: TsdDataView;
  12. sdpTenderProperty: TsdADOProvider;
  13. sddTenderProperty: TsdDataSet;
  14. sdvTenderProperty: TsdDataView;
  15. sdvProjectsSpare: TsdDataView;
  16. procedure sdvProjectsInfoGetText(var Text: String;
  17. ARecord: TsdDataRecord; AValue: TsdValue; AColumn: TsdViewColumn;
  18. DisplayText: Boolean);
  19. procedure sdvProjectsInfoFilterRecord(ARecord: TsdDataRecord;
  20. var Allow: Boolean);
  21. procedure DataModuleCreate(Sender: TObject);
  22. procedure sdvProjectsInfoBeforeDeleteRecord(ARecord: TsdDataRecord;
  23. var Allow: Boolean);
  24. private
  25. FConnection: TCommonConnection;
  26. FProjectsTree: TsdIDTree;
  27. procedure UpdateManagerDataBase;
  28. //procedure ReNameCurrentProject(const AName: string);
  29. procedure CreateNewProjectFile(const AName: string);
  30. procedure DeleteAllTenderFiles(ANode: TsdIDTreeNode);
  31. procedure DeleteAttachmentFiles(ANode: TsdIDTreeNode);
  32. function CreateBackupFolder(AProjectID: Integer): string;
  33. procedure ExportTender(ARec: TsdDataRecord; AFileName: string);
  34. function NewID: Integer;
  35. public
  36. constructor Create;
  37. destructor Destroy; override;
  38. procedure Open;
  39. procedure Save;
  40. function HasProject: Boolean;
  41. function ExistProject(const AName: string; ANode: TsdIDTreeNode): Boolean;
  42. function ProjectID(const AName: string; ANode: TsdIDTreeNode): Integer;
  43. // 云版要记下网络文件夹的ID和层次。
  44. function InsertProject(const AName: string; APreNode: TsdIDTreeNode; AFolderID: Integer = -1; AFolderLevel: Integer = -1): TsdIDTreeNode;
  45. function InsertSubProject(const AName: string; AParent: TsdIDTreeNode; AFolderID: Integer = -1; AFolderLevel: Integer = -1): TsdIDTreeNode;
  46. function InsertTender(const AName: string; AParent: TsdIDTreeNode): TsdIDTreeNode;
  47. procedure Delete;
  48. procedure ReName(const AName: string; ANode: TsdIDTreeNode);
  49. procedure RestoreTender(AID: Integer);
  50. procedure RefreshSeedID;
  51. function BackupPath(AProjectID: Integer): String;
  52. procedure AddOpenTenderBackup(AProjectID: Integer);
  53. procedure AddSaveTenderBackup(AProjectID: Integer);
  54. property ProjectsTree: TsdIDTree read FProjectsTree;
  55. end;
  56. implementation
  57. uses
  58. UtilMethods, UpdateDataBase, ProjectCommands, PHPWebDm, ConstUnit;
  59. {$R *.dfm}
  60. { TProjectManagerData }
  61. constructor TProjectManagerData.Create;
  62. begin
  63. inherited Create(nil);
  64. FConnection := TCommonConnection.Create;
  65. FProjectsTree := TsdIDTree.Create;
  66. FProjectsTree.KeyFieldName := 'ID';
  67. FProjectsTree.ParentFieldName := 'ParentID';
  68. FProjectsTree.NextSiblingFieldName := 'NextSiblingID';
  69. FProjectsTree.AutoCreateKeyID := True;
  70. FProjectsTree.AutoExpand := True;
  71. FProjectsTree.SeedID := 1;
  72. FProjectsTree.DataView := sdvProjectsInfo;
  73. end;
  74. procedure TProjectManagerData.CreateNewProjectFile(const AName: string);
  75. var
  76. TempFolder: string;
  77. begin
  78. try
  79. TempFolder := GenerateTempFolder(GetTempFilePath);
  80. CopyFileOrFolder(GetEmptyDataBaseFileName, TempFolder + '\Main.dat');
  81. ZipFolder(TempFolder, GetMyProjectsFilePath + AName);
  82. finally
  83. DeleteFileOrFolder(TempFolder);
  84. end;
  85. end;
  86. procedure TProjectManagerData.Delete;
  87. begin
  88. if HasProject then
  89. begin
  90. DeleteAttachmentFiles(FProjectsTree.Selected);
  91. DeleteAllTenderFiles(FProjectsTree.Selected);
  92. FProjectsTree.DeleteNode(FProjectsTree.Selected);
  93. Save;
  94. end;
  95. end;
  96. destructor TProjectManagerData.Destroy;
  97. begin
  98. FProjectsTree.Free;
  99. FConnection.Free;
  100. inherited;
  101. end;
  102. function TProjectManagerData.ExistProject(const AName: string;
  103. ANode: TsdIDTreeNode): Boolean;
  104. var
  105. vCur: TsdIDTreeNode;
  106. begin
  107. Result := False;
  108. if not Assigned(ANode) then Exit;
  109. vCur := ANode.FirstChild;
  110. while not Result and Assigned(vCur) do
  111. begin
  112. Result := vCur.Rec.ValueByName('Name').AsString = AName;
  113. vCur := vCur.NextSibling;
  114. end;
  115. end;
  116. function TProjectManagerData.HasProject: Boolean;
  117. begin
  118. Result := sddProjectsInfo.RecordCount > 0;
  119. end;
  120. function TProjectManagerData.InsertProject(const AName: string;
  121. APreNode: TsdIDTreeNode; AFolderID: Integer; AFolderLevel: Integer): TsdIDTreeNode;
  122. var
  123. vNew: TsdIDTreeNode;
  124. bOnLine, bCanCreate: Boolean;
  125. begin
  126. // 云版判断是否已存在的标准是服务端传来的ID,不是单机版所使用的名称。
  127. // 判断条件写在这里面不合适,因为云版调用不正确,应该写到方法外面。
  128. // 现在已经这样了,改起来麻烦,先补丁的方式用着。
  129. if G_IsCloud then
  130. bCanCreate := True
  131. else if (not G_IsCloud) and (not Assigned(APreNode)
  132. or not ExistProject(AName, APreNode.Parent)) then
  133. bCanCreate := True
  134. else
  135. bCanCreate := False;
  136. if bCanCreate then
  137. begin
  138. RefreshSeedID;
  139. if Assigned(APreNode) then
  140. vNew := FProjectsTree.Add(APreNode.ParentID, APreNode.NextSiblingID)
  141. else
  142. vNew := FProjectsTree.Add(-1, -1);
  143. vNew.Rec.BeginUpdate;
  144. vNew.Rec.ValueByName('Type').AsInteger := 0;
  145. vNew.Rec.ValueByName('Name').AsString := AName;
  146. {---------------------------------------------------------------------------
  147. 恼火的问题:直接写成下面这样,则第二句编译不进:
  148. if G_IsOnLine then
  149. vNew.Rec.ValueByName('WebUserID').AsInteger := PHPWeb.UserID;
  150. 这里用局部变量bOnLine转接一下,能解决问题。
  151. ---------------------------------------------------------------------------}
  152. bOnLine := G_IsCloud;
  153. if bOnLine then
  154. begin
  155. vNew.Rec.ValueByName('WebID').AsInteger := AFolderID;
  156. vNew.Rec.ValueByName('WebUserID').AsInteger := PHPWeb.UserID;
  157. vNew.Rec.ValueByName('WebFolderLevel').AsInteger := AFolderLevel;
  158. end;
  159. vNew.Rec.EndUpdate;
  160. Result := vNew;
  161. Save;
  162. end
  163. else
  164. raise Exception.Create('存在同名类别!');
  165. end;
  166. function TProjectManagerData.InsertSubProject(const AName: string;
  167. AParent: TsdIDTreeNode; AFolderID: Integer; AFolderLevel: Integer): TsdIDTreeNode;
  168. var
  169. vNew: TsdIDTreeNode;
  170. bOnLine, bCanCreate: Boolean;
  171. begin
  172. if G_IsCloud then
  173. bCanCreate := True
  174. else if (not G_IsCloud) and (not ExistProject(AName, AParent)) then
  175. bCanCreate := True
  176. else
  177. bCanCreate := False;
  178. if bCanCreate then
  179. begin
  180. RefreshSeedID;
  181. vNew := FProjectsTree.Add(AParent.ID, -1);
  182. vNew.Rec.ValueByName('Type').AsInteger := 0;
  183. vNew.Rec.ValueByName('Name').AsString := AName;
  184. {---------------------------------------------------------------------------
  185. 恼火的问题:直接写成下面这样,则第二句编译不进:
  186. if G_IsOnLine then
  187. vNew.Rec.ValueByName('WebUserID').AsInteger := PHPWeb.UserID;
  188. 这里用局部变量bOnLine转接一下,能解决问题。
  189. ---------------------------------------------------------------------------}
  190. bOnLine := G_IsCloud;
  191. if bOnLine then
  192. begin
  193. vNew.Rec.ValueByName('WebID').AsInteger := AFolderID;
  194. vNew.Rec.ValueByName('WebUserID').AsInteger := PHPWeb.UserID;
  195. vNew.Rec.ValueByName('WebFolderLevel').AsInteger := AFolderLevel;
  196. end;
  197. Result := vNew;
  198. Save;
  199. end
  200. else
  201. raise Exception.Create('存在同名类别!');
  202. end;
  203. function TProjectManagerData.InsertTender(const AName: string;
  204. AParent: TsdIDTreeNode): TsdIDTreeNode;
  205. var bOnLine: Boolean;
  206. begin
  207. if not ExistProject(AName, AParent) then
  208. begin
  209. RefreshSeedID;
  210. Result := FProjectsTree.Add(AParent.ID, -1);
  211. {---------------------------------------------------------------------------
  212. 恼火的问题:直接写成下面这样,则第二句编译不进:
  213. if G_IsOnLine then
  214. Result.Rec.ValueByName('WebUserID').AsInteger := PHPWeb.UserID;
  215. 这里用局部变量bOnLine转接一下,能解决问题。
  216. ---------------------------------------------------------------------------}
  217. // if G_IsOnLine then
  218. // Result.Rec.ValueByName('WebUserID').AsInteger := PHPWeb.UserID; // 编译不进
  219. bOnLine := G_IsCloud;
  220. if bOnLine then
  221. Result.Rec.ValueByName('WebUserID').AsInteger := PHPWeb.UserID;
  222. Result.Rec.ValueByName('Type').AsInteger := 1;
  223. Result.Rec.ValueByName('Name').AsString := AName;
  224. Result.Rec.ValueByName('PhaseCount').AsInteger := 0;
  225. Result.Rec.ValueByName('AuditStatus').AsInteger := 0;
  226. Result.Rec.ValueByName('FileName').AsString :=
  227. ExtractSimpleFileName(GetNewGUIDFileName(GetMyProjectsFilePath));
  228. Result.Rec.ValueByName('CreateDate').AsString := FormatDateTime('yyyy-mm-dd', Date);
  229. CreateNewProjectFile(Result.Rec.ValueByName('FileName').AsString);
  230. Save;
  231. end
  232. else
  233. raise Exception.Create('存在同名标段!');
  234. end;
  235. procedure TProjectManagerData.Open;
  236. var
  237. sFileName: string;
  238. FQuery: TADOQuery;
  239. begin
  240. sFileName := GetAppFilePath + 'Data\ProjectManager.dat';
  241. if FileEncrypted(sFileName) then
  242. SimpleDecrypt(sFileName, sFileName);
  243. FConnection.Open(sFileName);
  244. UpdateManagerDataBase;
  245. sdpProjectsInfo.Connection := FConnection.Connection;
  246. sddProjectsInfo.Open;
  247. sdvProjectsInfo.Open;
  248. sdvProjectsSpare.Open;
  249. sddProjectsInfo.AddIndex('idxID', 'ID');
  250. sdvProjectsInfo.IndexName := 'idxID';
  251. sdpTenderProperty.Connection := FConnection.Connection;
  252. sddTenderProperty.Open;
  253. sdvTenderProperty.Open;
  254. end;
  255. procedure TProjectManagerData.Save;
  256. begin
  257. sddTenderProperty.Save;
  258. sddProjectsInfo.Save;
  259. FConnection.Save;
  260. end;
  261. procedure TProjectManagerData.UpdateManagerDataBase;
  262. var
  263. vUpdator: TUpdateManagerDB;
  264. begin
  265. vUpdator := TUpdateManagerDB.Create;
  266. try
  267. vUpdator.Update(FConnection);
  268. finally
  269. vUpdator.Free;
  270. end;
  271. end;
  272. procedure TProjectManagerData.sdvProjectsInfoGetText(var Text: String;
  273. ARecord: TsdDataRecord; AValue: TsdValue; AColumn: TsdViewColumn;
  274. DisplayText: Boolean);
  275. function NumToAuditStatus(AValue: Integer): string;
  276. begin
  277. case AValue of
  278. -1:
  279. if ARecord.ValueByName('PhaseCount').AsInteger = 0 then
  280. Result := '原报'
  281. else
  282. Result := '批复';
  283. 0:
  284. Result := '原报';
  285. else
  286. Result := Format('%d 审', [AValue]);
  287. end;
  288. end;
  289. function GetFormatString(ADigitValue: TsdValue): string;
  290. begin
  291. if not ADigitValue.IsNull then
  292. begin
  293. case ADigitValue.AsInteger of
  294. 0: Result := '0';
  295. 1: Result := '0.#';
  296. 2: Result := '0.##';
  297. 3: Result := '0.###';
  298. 4: Result := '0.####';
  299. 5: Result := '0.#####';
  300. 6: Result := '0.######';
  301. 7: Result := '0.#######';
  302. 8: Result := '0.########';
  303. 9: Result := '0.#########';
  304. else
  305. Result := '0.##########';
  306. end;
  307. end
  308. else
  309. Result := '';
  310. end;
  311. function FormatCommonTotalPrice(ATotalPrice: Double): string;
  312. var
  313. sFormat: string;
  314. begin
  315. Result := Text;
  316. sFormat := GetFormatString(ARecord.ValueByName('CommonDigit'));
  317. if sFormat <> '' then
  318. Result := FormatFloat(sFormat, ATotalPrice);
  319. end;
  320. function FormatDealPayTotalPrice(ATotalPrice: Double): string;
  321. var
  322. sFormat: string;
  323. begin
  324. Result := Text;
  325. sFormat := GetFormatString(ARecord.ValueByName('DealPayDigit'));
  326. if sFormat <> '' then
  327. Result := FormatFloat(sFormat, ATotalPrice);
  328. end;
  329. begin
  330. if not Assigned(ARecord) then Exit;
  331. if SameText(AColumn.FieldName, 'AuditStatus') then
  332. if ARecord.ValueByName('Type').AsInteger = 1 then
  333. Text := NumToAuditStatus(AValue.AsInteger)
  334. else
  335. Text := ''
  336. else if DisplayText then
  337. begin
  338. if Pos('TotalPrice', AColumn.FieldName) > 0 then
  339. Text := FormatCommonTotalPrice(AValue.AsFloat)
  340. else if SameText('PhasePay', AColumn.FieldName) then
  341. Text := FormatDealPayTotalPrice(AValue.AsFloat);
  342. end;
  343. end;
  344. procedure TProjectManagerData.DeleteAllTenderFiles(ANode: TsdIDTreeNode);
  345. var
  346. iChild: Integer;
  347. begin
  348. if ANode.HasChildren then
  349. for iChild := 0 to ANode.ChildCount - 1 do
  350. DeleteAllTenderFiles(ANode.ChildNodes[iChild])
  351. else if ANode.Rec.ValueByName('Type').AsInteger = 1 then
  352. DeleteFile(GetMyProjectsFilePath + ANode.Rec.ValueByName('FileName').AsString);
  353. end;
  354. procedure TProjectManagerData.ReName(const AName: string;
  355. ANode: TsdIDTreeNode);
  356. begin
  357. ANode.Rec.ValueByName('Name').AsString := AName;
  358. Save;
  359. end;
  360. procedure TProjectManagerData.RestoreTender(AID: Integer);
  361. var
  362. vNode: TsdIDTreeNode;
  363. sRestoreFile: string;
  364. Exportor: TTenderExport;
  365. begin
  366. vNode := FProjectsTree.FindNode(AID);
  367. if not FileExists(GetMyProjectsFilePath + vNode.Rec.ValueByName('FileName').AsString) then Exit;
  368. sRestoreFile := GetBackUpFilePath + vNode.Rec.ValueByName('Name').AsString
  369. + '[' + FormatDateTime('yyyy-mm-dd hh,nn,ss', Now) + '].mtf';
  370. Exportor := TTenderExport.Create(vNode.Rec, sRestoreFile);
  371. try
  372. Exportor.Execute;
  373. finally
  374. Exportor.Free;
  375. end;
  376. end;
  377. procedure TProjectManagerData.sdvProjectsInfoFilterRecord(
  378. ARecord: TsdDataRecord; var Allow: Boolean);
  379. begin
  380. if G_IsCloud then
  381. begin
  382. if ARecord.ValueByName('WebUserID').AsInteger = PHPWeb.UserID then
  383. Allow := True
  384. else
  385. Allow := False;
  386. end
  387. else
  388. begin
  389. if ARecord.ValueByName('WebUserID').AsInteger = 0 then
  390. Allow := True
  391. else
  392. Allow := False;
  393. end;
  394. end;
  395. procedure TProjectManagerData.DataModuleCreate(Sender: TObject);
  396. begin
  397. // 单机版也要过滤:防止单机版程序能显示所有用户的项目。
  398. // if G_IsOnLine then
  399. sdvProjectsInfo.Filtered := True;
  400. sdvProjectsSpare.Filtered := True;
  401. end;
  402. function TProjectManagerData.NewID: Integer;
  403. var
  404. idxID: TsdIndex;
  405. begin
  406. if sddProjectsInfo.RecordCount > 0 then
  407. begin
  408. idxID := sddProjectsInfo.FindIndex('idxID');
  409. Result := idxID.Records[idxID.RecordCount - 1].ValueByName('ID').AsInteger + 1;
  410. end
  411. else
  412. Result := 1;
  413. end;
  414. procedure TProjectManagerData.RefreshSeedID;
  415. begin
  416. FProjectsTree.SeedID := NewID;
  417. end;
  418. function TProjectManagerData.BackupPath(AProjectID: Integer): String;
  419. var
  420. Rec: TsdDataRecord;
  421. begin
  422. Result := GetAppFilePath + 'FileBackup\TenderBackup';
  423. Rec := ProjectsTree.FindNode(AProjectID).Rec;
  424. if Rec.ValueByName('BackupFolder').AsString = '' then
  425. Rec.ValueByName('BackupFolder').AsString := CreateBackupFolder(AProjectID);
  426. Result := Result + '\' + Rec.ValueByName('BackupFolder').AsString + '\';
  427. end;
  428. function TProjectManagerData.CreateBackupFolder(
  429. AProjectID: Integer): string;
  430. function GetParentNames(ANode: TsdIDTreeNode): string;
  431. var
  432. stnParent: TsdIDTreeNode;
  433. begin
  434. Result := '';
  435. stnParent := ANode.Parent;
  436. while Assigned(stnParent) do
  437. begin
  438. if Result <> '' then
  439. Result := stnParent.Rec.ValueByName('Name').AsString + '--' + Result
  440. else
  441. Result := stnParent.Rec.ValueByName('Name').AsString;
  442. stnParent := stnParent.Parent;
  443. end;
  444. end;
  445. var
  446. stnNode: TsdIDTreeNode;
  447. sGUID, sPath: string;
  448. sgs: TStringList;
  449. begin
  450. stnNode := ProjectsTree.FindNode(AProjectID);
  451. Result := stnNode.Rec.ValueByName('BackupFolder').AsString;
  452. if Result <> '' then Exit;
  453. sPath := GetAppFilePath + 'FileBackup\TenderBackup\';
  454. sGUID := GetNewGUIDFileName(sPath);
  455. if FileExists(sGUID) then DeleteFile(sGUID);
  456. CreateDirectoryInDeep(sGUID);
  457. sgs := TStringList.Create;
  458. try
  459. sgs.Add('项目备份文件夹');
  460. sgs.Add(Format('项目名称:%s', [stnNode.Rec.ValueByName('Name').AsString]));
  461. sgs.Add(Format('所属项目:%s', [GetParentNames(stnNode)]));
  462. sgs.Add(Format('创建时间:%s', [DateTimeToStr(Now)]));
  463. finally
  464. sgs.SaveToFile(sGUID + '\说明.txt');
  465. sgs.Free;
  466. end;
  467. Result := ExtractSimpleFileName(sGUID)
  468. end;
  469. procedure TProjectManagerData.sdvProjectsInfoBeforeDeleteRecord(
  470. ARecord: TsdDataRecord; var Allow: Boolean);
  471. var
  472. sOrgFolder, sNewFolder: string;
  473. begin
  474. if ARecord.ValueByName('BackupFolder').AsString <> '' then
  475. begin
  476. sOrgFolder := GetAppFilePath + 'FileBackup\TenderBackup\'
  477. + ARecord.ValueByName('BackupFolder').AsString;
  478. sNewFolder := GetAppFilePath + 'FileBackup\RecycleBackup\'
  479. + ARecord.ValueByName('BackupFolder').AsString;
  480. CopyFileOrFolder(sOrgFolder, sNewFolder);
  481. DeleteFileOrFolder(sOrgFolder);
  482. end;
  483. end;
  484. procedure TProjectManagerData.AddOpenTenderBackup(AProjectID: Integer);
  485. var
  486. vBackupManager: TBackupManager;
  487. BackupRec, Rec: TsdDataRecord;
  488. sBackupFile: string;
  489. begin
  490. Rec := sddProjectsInfo.FindKey('idxID', AProjectID);
  491. if not Assigned(Rec) then Exit;
  492. vBackupManager := TBackupManager.Create;
  493. try
  494. vBackupManager.LoadBackupFile(BackupPath(AProjectID));
  495. if vBackupManager.LastestOpenBackupIsToday then Exit;
  496. sBackupFile := vBackupManager.OpenBackupFile;
  497. if FileExists(sBackupFile) then DeleteFile(sBackupFile);
  498. ExportTender(Rec, sBackupFile);
  499. finally
  500. vBackupManager.Free;
  501. end;
  502. end;
  503. procedure TProjectManagerData.AddSaveTenderBackup(AProjectID: Integer);
  504. var
  505. vBackupManager: TBackupManager;
  506. BackupRec, Rec: TsdDataRecord;
  507. sBackupFile: string;
  508. begin
  509. Rec := sddProjectsInfo.FindKey('idxID', AProjectID);
  510. if not Assigned(Rec) then Exit;
  511. vBackupManager := TBackupManager.Create;
  512. try
  513. vBackupManager.LoadBackupFile(BackupPath(AProjectID));
  514. sBackupFile := vBackupManager.SaveBackupFile;
  515. if FileExists(sBackupFile) then DeleteFile(sBackupFile);
  516. ExportTender(Rec, sBackupFile);
  517. finally
  518. vBackupManager.Free;
  519. end;
  520. end;
  521. procedure TProjectManagerData.ExportTender(ARec: TsdDataRecord;
  522. AFileName: string);
  523. var
  524. Exportor : TTenderExport;
  525. begin
  526. Exportor := TTenderExport.Create(ARec, AFileName);
  527. try
  528. Exportor.Execute;
  529. finally
  530. Exportor.Free;
  531. end;
  532. end;
  533. function TProjectManagerData.ProjectID(const AName: string;
  534. ANode: TsdIDTreeNode): Integer;
  535. var
  536. vCur: TsdIDTreeNode;
  537. begin
  538. Result := -1;
  539. if not Assigned(ANode) then Exit;
  540. vCur := ANode.FirstChild;
  541. while (Result = -1) and Assigned(vCur) do
  542. begin
  543. if vCur.Rec.ValueByName('Name').AsString = AName then
  544. Result := vCur.ID;
  545. vCur := vCur.NextSibling;
  546. end;
  547. end;
  548. procedure TProjectManagerData.DeleteAttachmentFiles(ANode: TsdIDTreeNode);
  549. var sDir: string;
  550. procedure DeleteAtch(ANode: TsdIDTreeNode);
  551. begin
  552. // 如果文件名为空,删除时会删除整个附件文件夹,危险!
  553. if ANode.Rec.ValueByName('FileName').AsString = '' then Exit;
  554. sDir := GetMyProjectsFilePath + 'Attachment\' + ANode.Rec.ValueByName('FileName').AsString;
  555. DeleteFolder(sDir);
  556. end;
  557. procedure DeleteNodes(ANode: TsdIDTreeNode);
  558. begin
  559. if ANode = nil then Exit;
  560. if ANode.FirstChild <> nil then
  561. DeleteNodes(ANode.FirstChild);
  562. if ANode.Rec.ValueByName('Type').AsInteger = 1 then
  563. DeleteAtch(ANode);
  564. if ANode.NextSibling <> nil then
  565. DeleteNodes(ANode.NextSibling);
  566. end;
  567. begin
  568. if not G_IsCloud then
  569. begin
  570. if not Assigned(ANode) then Exit;
  571. if ANode.Rec.ValueByName('Type').AsInteger = 0 then
  572. begin
  573. if Assigned(ANode.FirstChild) then
  574. DeleteNodes(ANode.FirstChild);
  575. end
  576. else
  577. DeleteAtch(ANode);
  578. end;
  579. end;
  580. end.