ProjectCommands.pas 32 KB

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