ProjectCommands.pas 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252
  1. unit ProjectCommands;
  2. interface
  3. uses
  4. ProjectData, XMLDoc, XMLIntf, ProjectManagerDm, sdIDTree, sdDB,
  5. Connections;
  6. type
  7. {1. 生成临时文件夹
  8. 2. 打开项目
  9. 3. 修改项目(上报、批复相应修改)
  10. 4. 保存修改后项目的属性至xml文件
  11. 5. 保存项目至临时文件夹中
  12. 6. 压缩临时文件夹,得到上报、批复文件
  13. 7. 复制粘贴结果文件得用户选择
  14. 8. 删除临时文件夹}
  15. TReportBase = class
  16. private
  17. // 临时文件夹(生成的项目文件、xml属性文件)
  18. FTempFolder: string;
  19. FProjectName: string;
  20. FFileName: string;
  21. FProjectID: Integer;
  22. FProjectData: TProjectData;
  23. FFileType: string;
  24. // xml项目信息文件
  25. FXmlInfoFile: string;
  26. // 结果文件
  27. FResultFile: string;
  28. // 接收文件时是否需要升级文件
  29. FNeedUpdate: Boolean;
  30. procedure SaveProjectInfo(AXmlNode: IXMLNode);
  31. procedure SaveTenderProperty(AXmlNode: IXMLNode);
  32. procedure SaveInfoToXmlDocument(AXmlNode: IXMLNode);
  33. procedure ExportXmlInfo;
  34. function GetNewOutputFileName: string;
  35. function CheckFile(const AFileName: string): Boolean;
  36. protected
  37. procedure OpenProject; virtual;
  38. procedure SaveProject; virtual;
  39. public
  40. constructor Create(const AProjectName, AFileName: string; AProjectID: Integer);
  41. destructor Destroy; override;
  42. function Execute: Boolean; virtual;
  43. function ExportTo(AFileName: string): Boolean; virtual;
  44. end;
  45. TSubmitProject = class(TReportBase)
  46. protected
  47. procedure OpenProject; override;
  48. procedure SaveProject; override;
  49. public
  50. function Execute: Boolean; override;
  51. function ExportTo(AFileName: string): Boolean; override;
  52. end;
  53. TReplyProject = class(TReportBase)
  54. protected
  55. procedure OpenProject; override;
  56. procedure SaveProject; override;
  57. public
  58. function Execute: Boolean; override;
  59. function ExportTo(AFileName: string): Boolean; override;
  60. end;
  61. {1. 生成临时文件夹
  62. 2. 解压选中文件至临时文件夹
  63. 3. 读取xml信息文件中的数据
  64. 4. 检查同名项目,存在则备份原项目,不存在则创建新节点
  65. 5. 根据xml文件更新数据项目信息,标段属性
  66. 6. 从临时文件夹中复制粘贴项目文件至新节点的数据文件
  67. 7. 打开该数据文件,根据情况修改
  68. 8. 保存该数据文件
  69. 9. 删除临时文件夹}
  70. TReceiveProject = class
  71. private
  72. FTempFolder: string;
  73. FFileType: string;
  74. FXmlDocument: IXMLDocument;
  75. // 导入后的节点
  76. FCurNode: TsdIDTreeNode;
  77. FProjectName: string;
  78. FFileName: string;
  79. FSelect: TsdIDTreeNode;
  80. FProjectData: TProjectData;
  81. // 初次在线审批人,自上次Exe上报/审批
  82. FStartAudit: Integer;
  83. // 末次在线审批人,自上次Exe上报/审批
  84. FEndAudit: Integer;
  85. // 文件中的审核状态
  86. FOrgAuditStatus: Integer;
  87. // 应升级至的审核状态
  88. FNewAuditStatus: Integer;
  89. FStageCount: Integer;
  90. FReply: Boolean;
  91. FLostStageCount: Integer;
  92. // 控制是否需要升级更新文件
  93. FNeedUpdate: Boolean;
  94. FLock: Boolean;
  95. FMessageID: Integer;
  96. FIsReback: Boolean;
  97. function CheckOpen: Boolean;
  98. function GetNewTender: TsdIDTreeNode;
  99. procedure GetCurNode;
  100. procedure LoadProjectInfo(AXmlNode: IXMLNode);
  101. procedure LoadTenderProperty(AXmlNode: IXMLNode);
  102. procedure LoadInfoFromXmlDocument;
  103. function CheckUpdateStatusValid: Boolean;
  104. procedure ReadXmlInfo;
  105. function UpdateData(const AFileName: string): Boolean;
  106. public
  107. constructor Create(ASelect: TsdIDTreeNode);
  108. destructor Destroy; override;
  109. function Receive(const AFileName: string): TsdIDTreeNode;
  110. // 在线审批使用
  111. // 原报、1审(Online)、2审(Online)、3审(Online)、4审、5审(Online)、6审、7审
  112. // 则4审在Exe端打开项目时,AStartAudit=1,AEndAudit=3
  113. // 6审在Exe端打开项目时,AStartAudit=AEndAudit=5
  114. // 7审在Exe端打开项目时,AStartAudit=AEndAudit=0
  115. function ReceiveForLost(const AFileName: string; AStartAudit, AEndAudit: Integer; AReply: Boolean = False): TsdIDTreeNode;
  116. // 供网络版使用
  117. // 原报已提交,1审已审核并提交后,此时除了2审人以外的参与人接收数据时不可生成二审数据
  118. property Lock: Boolean read FLock write FLock;
  119. // 被打回的数据
  120. property IsReback: Boolean read FIsReback write FIsReback;
  121. // 信息: 0[接收成功]
  122. // 1[接收失败,应接收节点打开状态]
  123. // 2[接收失败,下载文件跟网页状态不一致]
  124. // 3[接收失败,升级文件失败]
  125. property MessageID: Integer read FMessageID;
  126. end;
  127. {1. 生成临时文件夹
  128. 2. 保存标段的属性至xml文件
  129. 3. 复制粘贴标段文件至临时文件夹
  130. 4. 压缩临时文件夹,得到导出的标段文件(结果文件)
  131. 5. 复制粘贴结果文件得用户选择
  132. 6. 删除临时文件夹}
  133. TTenderExport = class
  134. private
  135. // 临时文件夹(生成的项目文件、xml属性文件)
  136. FTempFolder: string;
  137. FProjectName: string;
  138. FFileName: string;
  139. FProjectID: Integer;
  140. FFileType: string;
  141. // xml项目信息文件
  142. FXmlInfoFile: string;
  143. // 结果文件
  144. FResultFile: string;
  145. FAttachmentPath: string;
  146. procedure SaveProjectInfo(AXmlNode: IXMLNode);
  147. procedure SaveTenderProperty(AXmlNode: IXMLNode);
  148. procedure SaveInfoToXmlDocument(AXmlNode: IXMLNode);
  149. procedure ExportXmlInfo;
  150. public
  151. constructor Create(ARec: TsdDataRecord; const AFileName: string);
  152. destructor Destroy; override;
  153. // 参数AExportAttachment:是否导出附件
  154. procedure Execute(AExportAttachment: Boolean = False);
  155. end;
  156. TTenderImport = class
  157. private
  158. FTempFolder: string;
  159. FSelect: TsdIDTreeNode;
  160. FNewNode: TsdIDTreeNode;
  161. FProjectName: string;
  162. FFileName: string;
  163. FTenderFileName: string;
  164. procedure GetNewNode;
  165. procedure LoadProjectInfo(AXmlNode: IXMLNode);
  166. procedure LoadTenderProperty(AXmlNode: IXMLNode);
  167. procedure LoadInfoFromXmlDocument(AXmlNode: IXMLNode);
  168. procedure LoadXmlInfo;
  169. public
  170. constructor Create(ASelect: TsdIDTreeNode; const AProjectName, AFileName: string);
  171. destructor Destroy; override;
  172. procedure Execute;
  173. procedure ImportToSelect;
  174. end;
  175. {1. 生成临时文件夹
  176. 2. 导出选中节点及其所有子节点信息
  177. 3. 递归所有子节点,分类(Type = 0)则新建同名文件夹,标段(Type = 1)则导出该标段
  178. 4. 压缩临时文件夹,得到导出的分类文件(结果文件)
  179. 5. 复制粘贴结果文件得用户选择
  180. 6. 删除临时文件夹}
  181. TProjectExport = class
  182. private
  183. // 临时文件夹(按层次结构生成所有项目文件)
  184. FTempFolder: string;
  185. // xml树结构文件
  186. FXmlInfoFile: string;
  187. // 结果文件
  188. FResultFile: string;
  189. FExportNode: TsdIDTreeNode;
  190. FTenderExportor: TTenderExport;
  191. FExportAttachment: Boolean;
  192. procedure SaveTreeNodeInfo(AXmlNode: IXMLNode; ANode: TsdIDTreeNode);
  193. procedure ExportXmlInfo;
  194. procedure ExportTender(ANode: TsdIDTreeNode; const AExportPath: string);
  195. procedure ExportNode(ANode: TsdIDTreeNode; const AExportPath: string);
  196. public
  197. constructor Create(ANode: TsdIDTreeNode; const AFileName: string; AExportAttachment: Boolean = False);
  198. destructor Destroy; override;
  199. procedure Execute;
  200. end;
  201. {1. 生成临时文件夹
  202. 2. 解压选中文件至临时文件夹
  203. 3. 根据用户选择新建子分类FNew
  204. 3. 打开Xml树结构信息文件
  205. 4. 根据Xml文件中结构,依次建立分类或导入标段文件
  206. 5. 删除临时文件夹}
  207. TProjectImport = class
  208. private
  209. FTempFolder: string;
  210. FProjectName: string;
  211. FFileName: string;
  212. FSelect: TsdIDTreeNode;
  213. FNew: TsdIDTreeNode;
  214. function AddNewNode(AParentID, ANextID: Integer; const ANodeName: string): TsdIDTreeNode;
  215. procedure LoadTender(AXmlNode: IXMLNode;
  216. AParent: TsdIDTreeNode; const APath: string);
  217. procedure LoadChild(AXmlNode: IXMLNode;
  218. AParent: TsdIDTreeNode; const APath: string);
  219. procedure LoadChildrenFormXml;
  220. public
  221. constructor Create(ASelect: TsdIDTreeNode; const AProjectName, AFileName: string);
  222. destructor Destroy; override;
  223. procedure Execute;
  224. end;
  225. // 文件检验
  226. {
  227. 检验分为两部分:
  228. 1. 一致性检验:检验文件中的xml记录数据,与数据库中数据是否一致,以检验文件是否可用
  229. 2. 主动检验: 提供xml记录的部分数据,用户主动检验是否为所需文件
  230. 流程:
  231. 1. 解压文件,得到xml文件,项目文件
  232. 2. 读取xml文件,得到主要数据,与项目文件名
  233. 3. 读取项目文件,并检验基本数据是否与xml文件中描述一致
  234. PS:用于主动检验的数据,在第2步中同步进行。要求,如果进行主动检验,必须先通过一致性检验。
  235. }
  236. TTenderFileChecker = class
  237. private
  238. FFileName: string;
  239. FTempFolder: string;
  240. FTenderFileName: string;
  241. FTenderTempFolder: string;
  242. FValid: Boolean;
  243. FPhaseCount: Integer;
  244. FAuditStatus: Integer;
  245. FProjectName: string;
  246. procedure LoadProjectInfo(AXmlNode: IXMLNode);
  247. procedure LoadInfoFromXmlDocument(AXmlNode: IXMLNode);
  248. procedure LoadInfoFromXml;
  249. procedure LoadInfo;
  250. function DecryptFile(const AFileName: string): Boolean;
  251. function CheckFileMatchXml: Boolean;
  252. public
  253. // 检验项目数据库数据与xml文件中主要数据是否吻合
  254. function CheckFileValid(const AFileName: string): Boolean;
  255. // xml文件中记录的信息,用于主动检验
  256. property PhaseCount: Integer read FPhaseCount;
  257. property AuditStatus: Integer read FAuditStatus;
  258. end;
  259. TTenderZipCheckType = (zctAllPhase, zctLastPhase);
  260. // 文件检验
  261. TTenderZipCompleteChecker = class
  262. private
  263. FFileName: string;
  264. FTempFolder: string;
  265. FProjectData: TProjectData;
  266. FCheckType: TTenderZipCheckType;
  267. function CheckMain: Boolean;
  268. function CheckAllPhase: Boolean;
  269. function CheckLastPhase: Boolean;
  270. public
  271. constructor Create;
  272. destructor Destroy; override;
  273. function CheckFileValid(const AFileName: string): Boolean;
  274. property CheckType: TTenderZipCheckType read FCheckType write FCheckType;
  275. end;
  276. implementation
  277. uses
  278. UtilMethods, ZhAPI, Globals, SysUtils, SupportUnit, NewProjectFrm,
  279. PhaseData, ConfigDoc, ConstUnit, PHPWebDm;
  280. { TSubmitProject }
  281. function TSubmitProject.Execute: Boolean;
  282. begin
  283. FFileType := '.rmf';
  284. FNeedUpdate := True;
  285. //FProjectData.LockedDataForSubmit;
  286. Result := inherited Execute;
  287. end;
  288. function TSubmitProject.ExportTo(AFileName: string): Boolean;
  289. begin
  290. FNeedUpdate := True;
  291. //FProjectData.LockedDataForSubmit;
  292. Result := inherited ExportTo(AFileName);
  293. end;
  294. procedure TSubmitProject.OpenProject;
  295. begin
  296. FProjectData.OpenForSubmit(FFileName);
  297. end;
  298. procedure TSubmitProject.SaveProject;
  299. begin
  300. FProjectData.SaveAsForSubmit(FTempFolder + '\' + ExtractSimpleFileName(FFileName));
  301. end;
  302. { TReportBase }
  303. constructor TReportBase.Create(const AProjectName, AFileName: string;
  304. AProjectID: Integer);
  305. begin
  306. FProjectName := AProjectName;
  307. FFileName := AFileName;
  308. FProjectID := AProjectID;
  309. FProjectData := TProjectData.Create;
  310. FFileType := '.dat';
  311. FTempFolder := GenerateTempFolder(GetTempFilePath);
  312. FXmlInfoFile := FTempFolder + '\Info.xml';
  313. FResultFile := GetTempFileName;
  314. FNeedUpdate := False;
  315. OpenProject;
  316. end;
  317. destructor TReportBase.Destroy;
  318. begin
  319. DeleteFileOrFolder(FTempFolder);
  320. DeleteFileOrFolder(FResultFile);
  321. FProjectData.Free;
  322. inherited;
  323. end;
  324. function TReportBase.Execute: Boolean;
  325. var
  326. sFileName: string;
  327. begin
  328. Result := False;
  329. ExportXmlInfo;
  330. SaveProject;
  331. ZipFolder(FTempFolder, FResultFile);
  332. // 检验导出文件
  333. if CheckFile(FResultFile) then
  334. begin
  335. Result := True;
  336. sFileName := GetNewOutputFileName;
  337. if SaveFile(sFileName, FFileType) then
  338. CopyFileOrFolder(FResultFile, sFileName);
  339. end;
  340. end;
  341. function TReportBase.ExportTo(AFileName: string): Boolean;
  342. begin
  343. Result := False;
  344. ExportXmlInfo;
  345. FProjectData.SimpleSaveAs(FTempFolder + '\' + ExtractSimpleFileName(FFileName));
  346. ZipFolder(FTempFolder, FResultFile);
  347. if CheckFile(FResultFile) then
  348. begin
  349. Result := True;
  350. CopyFileOrFolder(FResultFile, AFileName);
  351. end;
  352. end;
  353. procedure TReportBase.ExportXmlInfo;
  354. var
  355. FXmlDocument: IXMLDocument;
  356. begin
  357. FXmlDocument := TXMLDocument.Create(nil) as IXMLDocument;
  358. try
  359. FXmlDocument.Options := [doNodeAutoCreate,doNodeAutoIndent,doAttrNull,doAutoPrefix,doNamespaceDecl];
  360. FXmlDocument.Active := True;
  361. FXmlDocument.Encoding := 'GB2312';
  362. FXmlDocument.AddChild('ProjectMangerInfo');
  363. SaveInfoToXmlDocument(FXmlDocument.DocumentElement);
  364. FXmlDocument.SaveToFile(FXmlInfoFile);
  365. finally
  366. FXmlDocument := nil;
  367. end;
  368. end;
  369. function TReportBase.GetNewOutputFileName: string;
  370. begin
  371. Result := SupportManager.ConfigInfo.AuditPath + FProjectName
  372. + Format('-第%d期', [FProjectData.ProjProperties.PhaseCount]);
  373. if FProjectData.ProjProperties.AuditCompany <> '' then
  374. Result := Result + '-' + FProjectData.ProjProperties.AuditCompany;
  375. Result := Result + Format('-%s-', [FProjectData.ProjProperties.AuditStatusStr])
  376. + FormatDateTime('yyyy-mm-dd', Date) + FFileType;
  377. end;
  378. procedure TReportBase.OpenProject;
  379. begin
  380. FProjectData.SimpleOpen(FFileName);
  381. end;
  382. procedure TReportBase.SaveProject;
  383. begin
  384. FProjectData.SimpleSaveAs(FTempFolder + '\' + ExtractSimpleFileName(FFileName));
  385. end;
  386. procedure TReportBase.SaveInfoToXmlDocument(AXmlNode: IXMLNode);
  387. begin
  388. SaveProjectInfo(AXmlNode);
  389. SaveTenderProperty(AXmlNode);
  390. end;
  391. procedure TReportBase.SaveProjectInfo(AXmlNode: IXMLNode);
  392. var
  393. vInfo: IXMLNode;
  394. InfoRec: TsdDataRecord;
  395. begin
  396. vInfo := AXmlNode.AddChild('ProjectInfo');
  397. InfoRec := ProjectManager.sddProjectsInfo.FindKey('idxID', FProjectID);
  398. vInfo.Attributes['ProjectName'] := FProjectName;
  399. vInfo.Attributes['NeedUpdate'] := FNeedUpdate;
  400. vInfo.Attributes['DealTotalPrice'] := InfoRec.ValueByName('DealTotalPrice').AsFloat;
  401. vInfo.Attributes['PhaseTotalPrice'] := InfoRec.ValueByName('PhaseTotalPrice').AsFloat;
  402. vInfo.Attributes['EndDealTotalPrice'] := InfoRec.ValueByName('EndDealTotalPrice').AsFloat;
  403. vInfo.Attributes['EndChangeTotalPrice'] := InfoRec.ValueByName('EndChangeTotalPrice').AsFloat;
  404. vInfo.Attributes['EndTotalPrice'] := InfoRec.ValueByName('EndTotalPrice').AsFloat;
  405. vInfo.Attributes['PreTotalPrice'] := InfoRec.ValueByName('PreTotalPrice').AsFloat;
  406. vInfo.Attributes['PhasePay'] := InfoRec.ValueByName('PhasePay').AsFloat;
  407. vInfo.Attributes['Deal_BGLTotalPrice'] := InfoRec.ValueByName('Deal_BGLTotalPrice').AsFloat;
  408. vInfo.Attributes['PhaseCount'] := FProjectData.ProjProperties.PhaseCount;
  409. vInfo.Attributes['AuditStatus'] := FProjectData.ProjProperties.AuditStatus;
  410. vInfo.Attributes['FileName'] := ExtractSimpleFileName(FFileName);
  411. if G_IsCloud then
  412. begin
  413. vInfo.Attributes['WebID'] := InfoRec.ValueByName('WebID').AsInteger;
  414. vInfo.Attributes['WebOwnerID'] := InfoRec.ValueByName('WebOwnerID').AsInteger;
  415. vInfo.Attributes['WebAuthorID'] := InfoRec.ValueByName('WebAuthorID').AsInteger;
  416. end;
  417. end;
  418. procedure TReportBase.SaveTenderProperty(AXmlNode: IXMLNode);
  419. var
  420. vProp: IXMLNode;
  421. begin
  422. vProp := AXmlNode.AddChild('TenderProperty');
  423. end;
  424. function TReportBase.CheckFile(const AFileName: string): Boolean;
  425. var
  426. vChecker: TTenderFileChecker;
  427. begin
  428. Result := False;
  429. vChecker := TTenderFileChecker.Create;
  430. try
  431. Result := vChecker.CheckFileValid(AFileName);
  432. finally
  433. vChecker.Free;
  434. end;
  435. end;
  436. { TReplyProject }
  437. function TReplyProject.Execute: Boolean;
  438. begin
  439. FFileType := '.arf';
  440. FProjectData.LockedDataForReply;
  441. Result := inherited Execute;
  442. end;
  443. function TReplyProject.ExportTo(AFileName: string): Boolean;
  444. begin
  445. FProjectData.LockedDataForReply;
  446. Result := inherited ExportTo(AFileName);
  447. end;
  448. procedure TReplyProject.OpenProject;
  449. begin
  450. FProjectData.OpenForReply(FFileName);
  451. end;
  452. procedure TReplyProject.SaveProject;
  453. begin
  454. FProjectData.SaveForReply(FTempFolder + '\' + ExtractSimpleFileName(FFileName));
  455. end;
  456. { TReceiveProject }
  457. function TReceiveProject.CheckUpdateStatusValid: Boolean;
  458. procedure GetCurAuditStatus;
  459. begin
  460. {if FStageCount > 0 then
  461. FLostStageCount := FStageCount - (AXmlNode.Attributes['AuditStatus'] + 1) - 1;
  462. if FNeedUpdate then
  463. begin
  464. if FReply then
  465. Result := -1
  466. else if FStageCount > 0 then
  467. Result := FStageCount - 1
  468. else
  469. Result := AXmlNode.Attributes['AuditStatus'] + 1
  470. end
  471. else
  472. Result := AXmlNode.Attributes['AuditStatus'];}
  473. end;
  474. var
  475. ChildNodes: IXMLNodeList;
  476. vProjInfo, vXmlElement: IXMLNode;
  477. begin
  478. Result := True;
  479. vXmlElement := FXmlDocument.DocumentElement;
  480. ChildNodes := vXmlElement.ChildNodes;
  481. vProjInfo := ChildNodes.FindNode('ProjectInfo');
  482. FFileName := vProjInfo.Attributes['FileName'];
  483. FNeedUpdate := vProjInfo.Attributes['NeedUpdate'];
  484. FOrgAuditStatus := vProjInfo.Attributes['AuditStatus'];
  485. if not FIsReback and FNeedUpdate then
  486. begin
  487. if FStartAudit <> 0 then
  488. begin
  489. if (FStartAudit <> FOrgAuditStatus + 1) or (FEndAudit < FStartAudit) then
  490. Result := False
  491. else
  492. FLostStageCount := FEndAudit - FStartAudit + 1 + 1;
  493. end
  494. else
  495. FLostStageCount := 1;
  496. // 锁定的情况下
  497. if FLock then
  498. FLostStageCount := FLostStageCount - 1;
  499. if FReply then
  500. FNewAuditStatus := -1
  501. else
  502. FNewAuditStatus := FOrgAuditStatus + FLostStageCount;
  503. end
  504. else
  505. FNewAuditStatus := FOrgAuditStatus;
  506. end;
  507. function TReceiveProject.CheckOpen: Boolean;
  508. begin
  509. Result := OpenProjectManager.ProjectIndex(FCurNode.ID) <> -1;
  510. if Result then
  511. FMessageID := 1;
  512. end;
  513. constructor TReceiveProject.Create(ASelect: TsdIDTreeNode);
  514. begin
  515. FSelect := ASelect;
  516. FTempFolder := GenerateTempFolder(GetTempFilePath);
  517. FReply := False;
  518. FLock := False;
  519. FMessageID := 0;
  520. FIsReback := False;
  521. FXmlDocument := TXMLDocument.Create(nil) as IXMLDocument;
  522. end;
  523. destructor TReceiveProject.Destroy;
  524. begin
  525. FXmlDocument := nil;
  526. DeleteFileOrFolder(FTempFolder);
  527. inherited;
  528. end;
  529. procedure TReceiveProject.GetCurNode;
  530. var
  531. I: Integer;
  532. begin
  533. if FSelect.Rec.ValueByName('Type').AsInteger = 0 then
  534. FCurNode := FSelect.FirstChild
  535. else
  536. FCurNode := FSelect.Parent.FirstChild;
  537. while Assigned(FCurNode) and (FCurNode.Rec.ValueByName('Name').AsString <> FProjectName) do
  538. FCurNode := FCurNode.NextSibling;
  539. if not Assigned(FCurNode) then
  540. FCurNode := GetNewTender
  541. else if CheckOpen then Abort;
  542. end;
  543. function TReceiveProject.GetNewTender: TsdIDTreeNode;
  544. begin
  545. if FSelect.Rec.ValueByName('Type').AsInteger = 0 then
  546. Result := ProjectManager.ProjectsTree.Add(FSelect.ID, -1)
  547. else
  548. Result := ProjectManager.ProjectsTree.Add(FSelect.ParentID, FSelect.NextSiblingID);
  549. Result.Rec.ValueByName('Name').AsString := FProjectName;
  550. Result.Rec.ValueByName('Type').AsInteger := 1;
  551. Result.Rec.ValueByName('FileName').AsString := ExtractSimpleFileName(GetNewGUIDFileName(GetMyProjectsFilePath));
  552. end;
  553. procedure TReceiveProject.LoadInfoFromXmlDocument;
  554. var
  555. ChildNodes: IXMLNodeList;
  556. vProjInfo, vXmlElement: IXMLNode;
  557. begin
  558. vXmlElement := FXmlDocument.DocumentElement;
  559. ChildNodes := vXmlElement.ChildNodes;
  560. vProjInfo := ChildNodes.FindNode('ProjectInfo');
  561. FProjectName := vProjInfo.Attributes['ProjectName'];
  562. GetCurNode;
  563. // 备份旧文件
  564. // 备份须放在这里的原因是,需要打开xml文件后,才能确认是否要备份文件以及应备份哪个文件
  565. // 但是又不能再导入xml数据以后,导入xml数据后,项目的属性会变掉
  566. ProjectManager.RestoreTender(FCurNode.ID);
  567. LoadProjectInfo(ChildNodes.FindNode('ProjectInfo'));
  568. LoadTenderProperty(ChildNodes.FindNode('TenderProperty'));
  569. end;
  570. procedure TReceiveProject.LoadProjectInfo(AXmlNode: IXMLNode);
  571. begin
  572. FCurNode.Rec.ValueByName('DealTotalPrice').AsFloat := AXmlNode.Attributes['DealTotalPrice'];
  573. FCurNode.Rec.ValueByName('PhaseTotalPrice').AsFloat := AXmlNode.Attributes['PhaseTotalPrice'];
  574. FCurNode.Rec.ValueByName('EndDealTotalPrice').AsFloat := AXmlNode.Attributes['EndDealTotalPrice'];
  575. FCurNode.Rec.ValueByName('EndChangeTotalPrice').AsFloat := AXmlNode.Attributes['EndChangeTotalPrice'];
  576. FCurNode.Rec.ValueByName('EndTotalPrice').AsFloat := AXmlNode.Attributes['EndTotalPrice'];
  577. FCurNode.Rec.ValueByName('PreTotalPrice').AsFloat := AXmlNode.Attributes['PreTotalPrice'];
  578. FCurNode.Rec.ValueByName('PhasePay').AsFloat := AXmlNode.Attributes['PhasePay'];
  579. if AXmlNode.HasAttribute('Deal_BGLTotalPrice') then
  580. FCurNode.Rec.ValueByName('Deal_BGLTotalPrice').AsFloat := AXmlNode.Attributes['Deal_BGLTotalPrice'];
  581. FCurNode.Rec.ValueByName('PhaseCount').AsInteger := AXmlNode.Attributes['PhaseCount'];
  582. FCurNode.Rec.ValueByName('AuditStatus').AsInteger := FNewAuditStatus;
  583. FCurNode.Rec.ValueByName('CreateDate').AsString := FormatDateTime('yyyy-mm-dd', Date);
  584. if G_IsCloud then
  585. begin
  586. FCurNode.Rec.ValueByName('WebID').AsInteger := AXmlNode.Attributes['WebID'];
  587. FCurNode.Rec.ValueByName('WebOwnerID').AsInteger := AXmlNode.Attributes['WebOwnerID'];
  588. FCurNode.Rec.ValueByName('WebAuthorID').AsInteger := AXmlNode.Attributes['WebAuthorID'];
  589. end;
  590. end;
  591. procedure TReceiveProject.LoadTenderProperty(AXmlNode: IXMLNode);
  592. begin
  593. // ToDo
  594. end;
  595. procedure TReceiveProject.ReadXmlInfo;
  596. begin
  597. FXmlDocument.LoadFromFile(FTempFolder + '\Info.xml');
  598. FXmlDocument.Options := [doNodeAutoCreate,doNodeAutoIndent,doAutoPrefix,doNamespaceDecl];
  599. end;
  600. function TReceiveProject.Receive(const AFileName: string): TsdIDTreeNode;
  601. begin
  602. Result := nil;
  603. FFileType := ExtractFileExt(AFileName);
  604. UnZipFile(AFileName, FTempFolder);
  605. ReadXmlInfo;
  606. if CheckUpdateStatusValid then
  607. begin
  608. if UpdateData(FTempFolder + '\' + FFileName) then
  609. begin
  610. LoadInfoFromXmlDocument;
  611. CopyFileOrFolder(FTempFolder + '\' + FFileName,
  612. GetMyProjectsFilePath + FCurNode.Rec.ValueByName('FileName').AsString);
  613. Result := FCurNode;
  614. end
  615. else
  616. FMessageID := 3;
  617. end
  618. else
  619. FMessageID := 2;
  620. end;
  621. function TReceiveProject.ReceiveForLost(const AFileName: string;
  622. AStartAudit, AEndAudit: Integer; AReply: Boolean = False): TsdIDTreeNode;
  623. begin
  624. FStartAudit := AStartAudit;
  625. FEndAudit := AEndAudit;
  626. FReply := AReply;
  627. Result := Receive(AFileName);
  628. end;
  629. function TReceiveProject.UpdateData(const AFileName: string): Boolean;
  630. var
  631. I: Integer;
  632. begin
  633. if not IsReback and FNeedUpdate then
  634. begin
  635. Result := False;
  636. FProjectData := TProjectData.Create;
  637. try
  638. FProjectData.OpenForReceive(AFileName);
  639. FProjectData.LockedDataForSubmit;
  640. for I := 0 to FLostStageCount - 1 do
  641. FProjectData.UpdateDataForReceive;
  642. if FReply then
  643. FProjectData.LockedDataForReply;
  644. FProjectData.SaveForReceive(AFileName);
  645. Result := True;
  646. finally
  647. FProjectData.Free;
  648. end;
  649. end
  650. else
  651. Result := True;
  652. end;
  653. { TTenderExport }
  654. constructor TTenderExport.Create(ARec: TsdDataRecord;
  655. const AFileName: string);
  656. begin
  657. FProjectName := ARec.ValueByName('Name').AsString;
  658. FFileName := GetMyProjectsFilePath + ARec.ValueByName('FileName').AsString;
  659. if not G_IsCloud then
  660. FAttachmentPath := GetMyProjectsFilePath + 'Attachment\' + ARec.ValueByName('FileName').AsString + '\';
  661. FProjectID := ARec.ValueByName('ID').AsInteger;
  662. FTempFolder := GenerateTempFolder(GetTempFilePath);
  663. FXmlInfoFile := FTempFolder + '\Info.xml';
  664. FResultFile := AFileName;
  665. end;
  666. destructor TTenderExport.Destroy;
  667. begin
  668. DeleteFileOrFolder(FTempFolder);
  669. inherited;
  670. end;
  671. procedure TTenderExport.Execute(AExportAttachment: Boolean);
  672. var
  673. sFileName: string;
  674. begin
  675. ExportXmlInfo;
  676. sFileName := ExtractSimpleFileName(FResultFile);
  677. CopyFileOrFolder(FFileName, FTempFolder + '\' + sFileName);
  678. // if not G_IsCloud then // 云版不导出附件,云版的运作机制是从网上下载
  679. // if AExportAttachment then
  680. // CopyFolder(FAttachmentPath, FTempFolder + '\' + sFileName + '[附件包]');
  681. ZipFolder(FTempFolder, FResultFile);
  682. end;
  683. procedure TTenderExport.ExportXmlInfo;
  684. var
  685. FXmlDocument: IXMLDocument;
  686. begin
  687. FXmlDocument := TXMLDocument.Create(nil) as IXMLDocument;
  688. try
  689. FXmlDocument.Options := [doNodeAutoCreate,doNodeAutoIndent,doAttrNull,doAutoPrefix,doNamespaceDecl];
  690. FXmlDocument.Active := True;
  691. FXmlDocument.Encoding := 'GB2312';
  692. FXmlDocument.AddChild('ProjectMangerInfo');
  693. SaveInfoToXmlDocument(FXmlDocument.DocumentElement);
  694. FXmlDocument.SaveToFile(FXmlInfoFile);
  695. finally
  696. FXmlDocument := nil;
  697. end;
  698. end;
  699. procedure TTenderExport.SaveInfoToXmlDocument(AXmlNode: IXMLNode);
  700. begin
  701. SaveProjectInfo(AXmlNode);
  702. SaveTenderProperty(AXmlNode);
  703. end;
  704. procedure TTenderExport.SaveProjectInfo(AXmlNode: IXMLNode);
  705. var
  706. vInfo: IXMLNode;
  707. InfoRec: TsdDataRecord;
  708. begin
  709. vInfo := AXmlNode.AddChild('ProjectInfo');
  710. InfoRec := ProjectManager.sddProjectsInfo.FindKey('idxID', FProjectID);
  711. vInfo.Attributes['ProjectName'] := FProjectName;
  712. vInfo.Attributes['DealTotalPrice'] := InfoRec.ValueByName('DealTotalPrice').AsFloat;
  713. vInfo.Attributes['PhaseTotalPrice'] := InfoRec.ValueByName('PhaseTotalPrice').AsFloat;
  714. vInfo.Attributes['EndDealTotalPrice'] := InfoRec.ValueByName('EndDealTotalPrice').AsFloat;
  715. vInfo.Attributes['EndChangeTotalPrice'] := InfoRec.ValueByName('EndChangeTotalPrice').AsFloat;
  716. vInfo.Attributes['EndTotalPrice'] := InfoRec.ValueByName('EndTotalPrice').AsFloat;
  717. vInfo.Attributes['PreTotalPrice'] := InfoRec.ValueByName('PreTotalPrice').AsFloat;
  718. vInfo.Attributes['PhasePay'] := InfoRec.ValueByName('PhasePay').AsFloat;
  719. vInfo.Attributes['Deal_BGLTotalPrice'] := InfoRec.ValueByName('Deal_BGLTotalPrice').AsFloat;
  720. vInfo.Attributes['PhaseCount'] := InfoRec.ValueByName('PhaseCount').AsInteger;
  721. vInfo.Attributes['AuditStatus'] := InfoRec.ValueByName('AuditStatus').AsInteger;
  722. vInfo.Attributes['FileName'] := ExtractSimpleFileName(FResultFile);
  723. if G_IsCloud then
  724. begin
  725. vInfo.Attributes['WebID'] := InfoRec.ValueByName('WebID').AsInteger;
  726. vInfo.Attributes['WebOwnerID'] := InfoRec.ValueByName('WebOwnerID').AsInteger;
  727. vInfo.Attributes['WebAuthorID'] := InfoRec.ValueByName('WebAuthorID').AsInteger;
  728. end;
  729. end;
  730. procedure TTenderExport.SaveTenderProperty(AXmlNode: IXMLNode);
  731. var
  732. vProp: IXMLNode;
  733. begin
  734. vProp := AXmlNode.AddChild('TenderProperty');
  735. end;
  736. { TProjectExport }
  737. constructor TProjectExport.Create(ANode: TsdIDTreeNode; const AFileName: string; AExportAttachment: Boolean);
  738. begin
  739. FTempFolder := GenerateTempFolder(GetTempFilePath);
  740. FExportNode := ANode;
  741. FResultFile := AFileName;
  742. FExportAttachment := AExportAttachment;
  743. FXmlInfoFile := FTempFolder + '\TreeInfo.xml';
  744. end;
  745. destructor TProjectExport.Destroy;
  746. begin
  747. DeleteFileOrFolder(FTempFolder);
  748. inherited;
  749. end;
  750. procedure TProjectExport.Execute;
  751. begin
  752. ExportXmlInfo;
  753. ExportNode(FExportNode.FirstChild, FTempFolder + '\');
  754. ZipFolder(FTempFolder, FResultFile);
  755. end;
  756. procedure TProjectExport.ExportNode(ANode: TsdIDTreeNode;
  757. const AExportPath: string);
  758. var
  759. ACurPath: string;
  760. begin
  761. if not Assigned(ANode) then Exit;
  762. if ANode.HasChildren or (ANode.Rec.ValueByName('Type').AsInteger = 0) then
  763. begin
  764. ACurPath := AExportPath + ANode.Rec.ValueByName('Name').AsString + '\';
  765. CreateDirectoryInDeep(ACurPath);
  766. ExportNode(ANode.FirstChild, ACurPath);
  767. end
  768. else
  769. ExportTender(ANode, AExportPath);
  770. ExportNode(ANode.NextSibling, AExportPath);
  771. end;
  772. procedure TProjectExport.ExportTender(ANode: TsdIDTreeNode;
  773. const AExportPath: string);
  774. begin
  775. FTenderExportor := TTenderExport.Create(ANode.Rec,
  776. AExportPath + ANode.Rec.ValueByName('Name').AsString);
  777. try
  778. FTenderExportor.Execute(FExportAttachment);
  779. finally
  780. FTenderExportor.Free;
  781. end;
  782. end;
  783. procedure TProjectExport.ExportXmlInfo;
  784. var
  785. FXmlDocument: IXMLDocument;
  786. begin
  787. FXmlDocument := TXMLDocument.Create(nil) as IXMLDocument;
  788. try
  789. FXmlDocument.Options := [doNodeAutoCreate,doNodeAutoIndent,doAttrNull,doAutoPrefix,doNamespaceDecl];
  790. FXmlDocument.Active := True;
  791. FXmlDocument.Encoding := 'GB2312';
  792. FXmlDocument.AddChild('ProjectTreeInfo');
  793. SaveTreeNodeInfo(FXmlDocument.DocumentElement, FExportNode.FirstChild);
  794. FXmlDocument.SaveToFile(FXmlInfoFile);
  795. finally
  796. FXmlDocument := nil;
  797. end;
  798. end;
  799. procedure TProjectExport.SaveTreeNodeInfo(AXmlNode: IXMLNode;
  800. ANode: TsdIDTreeNode);
  801. var
  802. CurNode: IXMLNode;
  803. begin
  804. if not Assigned(ANode) then Exit;
  805. CurNode := AXmlNode.AddChild('TreeNode');
  806. CurNode.Attributes['Name'] := ANode.Rec.ValueByName('Name').AsString;
  807. CurNode.Attributes['Type'] := ANode.Rec.ValueByName('Type').AsInteger;
  808. if ANode.HasChildren then
  809. SaveTreeNodeInfo(CurNode, ANode.FirstChild);
  810. SaveTreeNodeInfo(AXmlNode, ANode.NextSibling);
  811. end;
  812. { TProjectImport }
  813. function TProjectImport.AddNewNode(AParentID, ANextID: Integer;
  814. const ANodeName: string): TsdIDTreeNode;
  815. begin
  816. with ProjectManager.ProjectsTree do
  817. Result := Add(AParentID, ANextID);
  818. Result.Rec.ValueByName('Name').AsString := ANodeName;
  819. Result.Rec.ValueByName('Type').AsInteger := 0;
  820. end;
  821. constructor TProjectImport.Create(ASelect: TsdIDTreeNode;
  822. const AProjectName, AFileName: string);
  823. begin
  824. FSelect := ASelect;
  825. FProjectName := AProjectName;
  826. FFileName := AFileName;
  827. FTempFolder := GenerateTempFolder(GetTempFilePath);
  828. end;
  829. destructor TProjectImport.Destroy;
  830. begin
  831. DeleteFileOrFolder(FTempFolder);
  832. inherited;
  833. end;
  834. procedure TProjectImport.Execute;
  835. begin
  836. UnZipFile(FFileName, FTempFolder);
  837. // ID 188 需求变更,一直作为后兄弟节点导入
  838. {if FSelect.Rec.ValueByName('Type').AsInteger = 1 then
  839. FNew := AddNewNode(FSelect.ParentID, FSelect.NextSiblingID, FProjectName)
  840. else
  841. FNew := AddNewNode(FSelect.ID, -1, FProjectName);}
  842. if Assigned(FSelect) then
  843. FNew := AddNewNode(FSelect.ParentID, FSelect.NextSiblingID, FProjectName)
  844. else
  845. FNew := AddNewNode(-1, -1, FProjectName);
  846. LoadChildrenFormXml;
  847. end;
  848. procedure TProjectImport.LoadChild(AXmlNode: IXMLNode;
  849. AParent: TsdIDTreeNode; const APath: string);
  850. var
  851. I, iType: Integer;
  852. XmlNode: IXMLNode;
  853. stnNewNode: TsdIDTreeNode;
  854. begin
  855. for I := 0 to AXmlNode.ChildNodes.Count - 1 do
  856. begin
  857. XmlNode := AXmlNode.ChildNodes.Get(I);
  858. iType := XmlNode.Attributes['Type'];
  859. if iType = 0 then
  860. begin
  861. stnNewNode := AddNewNode(AParent.ID, -1, XmlNode.Attributes['Name']);
  862. if XmlNode.HasChildNodes then
  863. LoadChild(XmlNode, stnNewNode, APath + XmlNode.Attributes['Name'] + '\');
  864. end
  865. else
  866. LoadTender(XmlNode, AParent, APath);
  867. end;
  868. end;
  869. procedure TProjectImport.LoadChildrenFormXml;
  870. var
  871. FXmlDocument: IXMLDocument;
  872. XmlNode: IXMLNode;
  873. FRootList: IXMLNodeList;
  874. begin
  875. FXmlDocument := TXMLDocument.Create(nil) as IXMLDocument;
  876. try
  877. FXmlDocument.LoadFromFile(FTempFolder + '\TreeInfo.xml');
  878. FXmlDocument.Options := [doNodeAutoCreate,doNodeAutoIndent,doAutoPrefix,doNamespaceDecl];
  879. XmlNode := FXmlDocument.DocumentElement;
  880. LoadChild(XmlNode, FNew, FTempFolder + '\');
  881. finally
  882. FRootList := nil;
  883. FXmlDocument := nil;
  884. end;
  885. end;
  886. procedure TProjectImport.LoadTender(AXmlNode: IXMLNode;
  887. AParent: TsdIDTreeNode; const APath: string);
  888. var
  889. TenderImportor: TTenderImport;
  890. begin
  891. TenderImportor := TTenderImport.Create(AParent,
  892. AXmlNode.Attributes['Name'], APath + AXmlNode.Attributes['Name']);
  893. try
  894. TenderImportor.Execute;
  895. finally
  896. TenderImportor.Free;
  897. end;
  898. end;
  899. { TTenderImport }
  900. constructor TTenderImport.Create(ASelect: TsdIDTreeNode;
  901. const AProjectName, AFileName: string);
  902. begin
  903. FSelect := ASelect;
  904. FProjectName := AProjectName;
  905. FFileName := AFileName;
  906. FTempFolder := GenerateTempFolder(GetTempFilePath);
  907. end;
  908. destructor TTenderImport.Destroy;
  909. begin
  910. DeleteFileOrFolder(FTempFolder);
  911. inherited;
  912. end;
  913. procedure TTenderImport.Execute;
  914. var
  915. sFile, sFJ: string;
  916. begin
  917. UnZipFile(FFileName, FTempFolder);
  918. GetNewNode;
  919. LoadXmlInfo;
  920. sFile := FTempFolder + '\' + FTenderFileName;
  921. // sFJ := sFile + '[附件包]';
  922. CopyFileOrFolder(sFile, GetMyProjectsFilePath + FNewNode.Rec.ValueByName('FileName').AsString);
  923. // if not G_IsCloud then // 云版附件从服务器获取,不导入。
  924. // if DirectoryExists(sFJ) then
  925. // CopyFolder(sFJ, GetMyProjectsFilePath + 'Attachment\' + FNewNode.Rec.ValueByName('FileName').AsString);
  926. end;
  927. procedure TTenderImport.GetNewNode;
  928. begin
  929. if FSelect.Rec.ValueByName('Type').AsInteger = 1 then
  930. FNewNode := ProjectManager.ProjectsTree.Add(FSelect.ParentID, FSelect.NextSiblingID)
  931. else
  932. FNewNode := ProjectManager.ProjectsTree.Add(FSelect.ID, -1);
  933. FNewNode.Rec.ValueByName('Name').AsString := FProjectName;
  934. FNewNode.Rec.ValueByName('Type').AsInteger := 1;
  935. FNewNode.Rec.ValueByName('FileName').AsString := ExtractSimpleFileName(GetNewGUIDFileName(GetMyProjectsFilePath));
  936. end;
  937. procedure TTenderImport.ImportToSelect;
  938. begin
  939. UnZipFile(FFileName, FTempFolder);
  940. FNewNode := FSelect;
  941. LoadXmlInfo;
  942. CopyFileOrFolder(FTempFolder + '\' + FTenderFileName,
  943. GetMyProjectsFilePath + FNewNode.Rec.ValueByName('FileName').AsString);
  944. end;
  945. procedure TTenderImport.LoadInfoFromXmlDocument(AXmlNode: IXMLNode);
  946. var
  947. ChildNodes: IXMLNodeList;
  948. begin
  949. ChildNodes := AXmlNode.ChildNodes;
  950. LoadProjectInfo(ChildNodes.FindNode('ProjectInfo'));
  951. LoadTenderProperty(ChildNodes.FindNode('TenderProperty'));
  952. end;
  953. procedure TTenderImport.LoadProjectInfo(AXmlNode: IXMLNode);
  954. begin
  955. FTenderFileName := AXmlNode.Attributes['FileName'];
  956. FNewNode.Rec.ValueByName('DealTotalPrice').AsFloat := AXmlNode.Attributes['DealTotalPrice'];
  957. FNewNode.Rec.ValueByName('PhaseTotalPrice').AsFloat := AXmlNode.Attributes['PhaseTotalPrice'];
  958. FNewNode.Rec.ValueByName('EndDealTotalPrice').AsFloat := AXmlNode.Attributes['EndDealTotalPrice'];
  959. FNewNode.Rec.ValueByName('EndChangeTotalPrice').AsFloat := AXmlNode.Attributes['EndChangeTotalPrice'];
  960. FNewNode.Rec.ValueByName('EndTotalPrice').AsFloat := AXmlNode.Attributes['EndTotalPrice'];
  961. FNewNode.Rec.ValueByName('PreTotalPrice').AsFloat := AXmlNode.Attributes['PreTotalPrice'];
  962. FNewNode.Rec.ValueByName('PhasePay').AsFloat := AXmlNode.Attributes['PhasePay'];
  963. if AXmlNode.HasAttribute('Deal_BGLTotalPrice') then
  964. FNewNode.Rec.ValueByName('Deal_BGLTotalPrice').AsFloat := AXmlNode.Attributes['Deal_BGLTotalPrice'];
  965. FNewNode.Rec.ValueByName('PhaseCount').AsInteger := AXmlNode.Attributes['PhaseCount'];
  966. FNewNode.Rec.ValueByName('AuditStatus').AsInteger := AXmlNode.Attributes['AuditStatus'];
  967. FNewNode.Rec.ValueByName('CreateDate').AsString := FormatDateTime('yyyy-mm-dd', Date);
  968. if G_IsCloud then
  969. begin
  970. FNewNode.Rec.ValueByName('WebID').AsInteger := AXmlNode.Attributes['WebID'];
  971. FNewNode.Rec.ValueByName('WebOwnerID').AsInteger := AXmlNode.Attributes['WebOwnerID'];
  972. FNewNode.Rec.ValueByName('WebAuthorID').AsInteger := AXmlNode.Attributes['WebAuthorID'];
  973. end;
  974. end;
  975. procedure TTenderImport.LoadTenderProperty(AXmlNode: IXMLNode);
  976. begin
  977. // TODO
  978. end;
  979. procedure TTenderImport.LoadXmlInfo;
  980. var
  981. FXmlDocument: IXMLDocument;
  982. XmlNode: IXMLNode;
  983. FRootList: IXMLNodeList;
  984. begin
  985. FXmlDocument := TXMLDocument.Create(nil) as IXMLDocument;
  986. try
  987. FXmlDocument.LoadFromFile(FTempFolder + '\Info.xml');
  988. FXmlDocument.Options := [doNodeAutoCreate,doNodeAutoIndent,doAutoPrefix,doNamespaceDecl];
  989. XmlNode := FXmlDocument.DocumentElement;
  990. LoadInfoFromXmlDocument(XmlNode);
  991. finally
  992. FRootList := nil;
  993. FXmlDocument := nil;
  994. end;
  995. end;
  996. { TTenderFileChecker }
  997. function TTenderFileChecker.CheckFileMatchXml: Boolean;
  998. var
  999. FProjectData: TProjectData;
  1000. begin
  1001. FProjectData := TProjectData.Create;
  1002. try
  1003. try
  1004. FProjectData.SimpleOpen(FTenderFileName);
  1005. Result := FProjectData.CheckDataBaseInfo(FPhaseCount, FAuditStatus);
  1006. except
  1007. Result := False;
  1008. end;
  1009. finally
  1010. FProjectData.Free;
  1011. end;
  1012. end;
  1013. function TTenderFileChecker.CheckFileValid(const AFileName: string): Boolean;
  1014. begin
  1015. FTempFolder := GenerateTempFolder(GetTempFilePath);
  1016. FTenderTempFolder := FTempFolder + '\Tender';
  1017. CreateDirectoryInDeep(FTenderTempFolder);
  1018. try
  1019. Result := DecryptFile(AFileName) and CheckFileMatchXml;
  1020. finally
  1021. DeleteFileOrFolder(FTempFolder);
  1022. end;
  1023. end;
  1024. function TTenderFileChecker.DecryptFile(const AFileName: string): Boolean;
  1025. begin
  1026. Result := UnZipFile(AFileName, FTempFolder);
  1027. if not Result then Exit;
  1028. LoadInfo;
  1029. Result := UnZipFile(FTenderFileName, FTenderTempFolder);
  1030. end;
  1031. procedure TTenderFileChecker.LoadInfo;
  1032. begin
  1033. LoadInfoFromXml;
  1034. end;
  1035. procedure TTenderFileChecker.LoadInfoFromXml;
  1036. var
  1037. FXmlDocument: IXMLDocument;
  1038. XmlNode: IXMLNode;
  1039. FRootList: IXMLNodeList;
  1040. begin
  1041. FXmlDocument := TXMLDocument.Create(nil) as IXMLDocument;
  1042. try
  1043. FXmlDocument.LoadFromFile(FTempFolder + '\Info.xml');
  1044. FXmlDocument.Options := [doNodeAutoCreate,doNodeAutoIndent,doAutoPrefix,doNamespaceDecl];
  1045. XmlNode := FXmlDocument.DocumentElement;
  1046. LoadInfoFromXmlDocument(XmlNode);
  1047. finally
  1048. FRootList := nil;
  1049. FXmlDocument := nil;
  1050. end;
  1051. end;
  1052. procedure TTenderFileChecker.LoadInfoFromXmlDocument(AXmlNode: IXMLNode);
  1053. var
  1054. ChildNodes: IXMLNodeList;
  1055. begin
  1056. ChildNodes := AXmlNode.ChildNodes;
  1057. LoadProjectInfo(ChildNodes.FindNode('ProjectInfo'));
  1058. end;
  1059. procedure TTenderFileChecker.LoadProjectInfo(AXmlNode: IXMLNode);
  1060. begin
  1061. FProjectName := AXmlNode.Attributes['ProjectName'];
  1062. FPhaseCount := AXmlNode.Attributes['PhaseCount'];
  1063. FAuditStatus := AXmlNode.Attributes['AuditStatus'];
  1064. FTenderFileName := FTempFolder + '\' + AXmlNode.Attributes['FileName'];
  1065. end;
  1066. { TTenderZipCompleteChecker }
  1067. function TTenderZipCompleteChecker.CheckAllPhase: Boolean;
  1068. begin
  1069. Result := Assigned(FProjectData) and FProjectData.CheckPhaseFileComplete;
  1070. end;
  1071. function TTenderZipCompleteChecker.CheckFileValid(
  1072. const AFileName: string): Boolean;
  1073. begin
  1074. FFileName := AFileName;
  1075. FTempFolder := GenerateTempFolder(GetTempFilePath);
  1076. try
  1077. case CheckType of
  1078. zctAllPhase: Result := UnZipFile(AFileName, FTempFolder) and CheckMain and CheckAllPhase;
  1079. zctLastPhase: Result := UnZipFile(AFileName, FTempFolder) and CheckMain and CheckLastPhase;
  1080. end;
  1081. finally
  1082. if Assigned(FProjectData) then
  1083. FProjectData.Free;
  1084. DeleteFileOrFolder(FTempFolder);
  1085. end;
  1086. end;
  1087. function TTenderZipCompleteChecker.CheckLastPhase: Boolean;
  1088. begin
  1089. Result := Assigned(FProjectData) and FProjectData.CheckLastPhaseFileExist;
  1090. end;
  1091. function TTenderZipCompleteChecker.CheckMain: Boolean;
  1092. begin
  1093. Result := False;
  1094. if FileExists(FTempFolder + '\main.dat') then
  1095. begin
  1096. try
  1097. FProjectData := TProjectData.Create;
  1098. FProjectData.OpenForSubmit(FFileName);
  1099. Result := True;
  1100. except
  1101. Result := False;
  1102. end;
  1103. end;
  1104. end;
  1105. constructor TTenderZipCompleteChecker.Create;
  1106. begin
  1107. FCheckType := zctAllPhase;
  1108. end;
  1109. destructor TTenderZipCompleteChecker.Destroy;
  1110. begin
  1111. inherited;
  1112. end;
  1113. end.