ProjectManagerFme.pas 57 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888
  1. unit ProjectManagerFme;
  2. interface
  3. uses
  4. ProjectManagerDm, ZhAPI,
  5. NewProjectFrm,
  6. Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  7. Dialogs, ZjGridDBA, ZJGrid, ComCtrls, ToolWin, ActnList,
  8. dxBar, sdGridDBA, sdGridTreeDBA, sdIDTree, CslJson, ExtCtrls,
  9. StdCtrls, sdDB, CslButton, OrderCheckerFme, Contnrs;
  10. type
  11. TStrArr = array of string;
  12. TProjectManagerFrame = class(TFrame)
  13. ToolBar: TToolBar;
  14. tobtnOpen: TToolButton;
  15. zgProjects: TZJGrid;
  16. tobtnDelete: TToolButton;
  17. ActionList1: TActionList;
  18. actnOpen: TAction;
  19. actnDelete: TAction;
  20. dxpmProjectManager: TdxBarPopupMenu;
  21. actnReceiveProject: TAction;
  22. stdProjects: TsdGridTreeDBA;
  23. actnNewProject: TAction;
  24. actnNewSubProject: TAction;
  25. actnNewTender: TAction;
  26. pnlTenderProperty: TPanel;
  27. sdTenderProperty: TsdGridDBA;
  28. sprProperty: TSplitter;
  29. tobtnRenane: TToolButton;
  30. actnRename: TAction;
  31. tobtnImport: TToolButton;
  32. tobtnExport: TToolButton;
  33. actnImport: TAction;
  34. actnExport: TAction;
  35. tobtn1: TToolButton;
  36. pnlWeb: TPanel;
  37. pnlProject: TPanel;
  38. shp2: TShape;
  39. shp1: TShape;
  40. shp3: TShape;
  41. shp4: TShape;
  42. pnlTenderTitle: TPanel;
  43. lblBidName: TLabel;
  44. pnlShadow: TPanel;
  45. pnlProgress: TPanel;
  46. lblPeriodTotal: TLabel;
  47. lblPeriodState: TLabel;
  48. lblProgress: TLabel;
  49. lblPeriod: TLabel;
  50. pnlBelongProject: TPanel;
  51. lblBelongProject: TLabel;
  52. lblProjName: TLabel;
  53. lblLeftHalfBracket: TLabel;
  54. lblOnwerCompany: TLabel;
  55. lblOnwerName: TLabel;
  56. pnlProjectType: TPanel;
  57. lblProjectType: TLabel;
  58. lblWebProjCtgyName: TLabel;
  59. zgTenderProperty: TZJGrid;
  60. actnOpenBackupFolder: TAction;
  61. sbChecker: TScrollBox;
  62. procedure actnOpenExecute(Sender: TObject);
  63. procedure actnDeleteExecute(Sender: TObject);
  64. procedure zgProjectsMouseDown(Sender: TObject; Button: TMouseButton;
  65. Shift: TShiftState; X, Y: Integer);
  66. procedure actnReceiveProjectExecute(Sender: TObject);
  67. procedure actnNewProjectExecute(Sender: TObject);
  68. procedure actnNewSubProjectExecute(Sender: TObject);
  69. procedure actnNewTenderExecute(Sender: TObject);
  70. procedure zgProjectsDrawCellText(ACanvas: TCanvas; const ARect: TRect;
  71. const ACoord: TPoint; AGrid: TZJGrid; const Text: String;
  72. var ADefaultDraw: Boolean);
  73. procedure actnNewSubProjectUpdate(Sender: TObject);
  74. procedure actnNewTenderUpdate(Sender: TObject);
  75. procedure zgProjectsCurrentChanged(Sender: TObject; Col, Row: Integer);
  76. procedure actnSubmitProjectUpdate(Sender: TObject);
  77. procedure actnReplyProjectUpdate(Sender: TObject);
  78. procedure actnRenameExecute(Sender: TObject);
  79. procedure actnOpenUpdate(Sender: TObject);
  80. procedure actnImportExecute(Sender: TObject);
  81. procedure actnExportExecute(Sender: TObject);
  82. procedure actnDeleteUpdate(Sender: TObject);
  83. procedure actnOpenBackupFolderExecute(Sender: TObject);
  84. procedure actnRenameUpdate(Sender: TObject);
  85. procedure zgProjectsShowHint(var HintStr: String; var CanShow: Boolean;
  86. var HintInfo: THintInfo; const ACoord: TPoint);
  87. procedure actnExportUpdate(Sender: TObject);
  88. procedure actnOpenBackupFolderUpdate(Sender: TObject);
  89. private
  90. FProjectManagerData: TProjectManagerData;
  91. // Chenshilong,2016.03.24
  92. // 这部分线上和本地一致,无需区分
  93. FID: Integer; // 本地标段文件ID
  94. FWebID: Integer; // 关联服务器用的ID(服务器有自己的ID体系)
  95. FWebAuthorID: Integer; // 编制人
  96. FWebOwnerID: Integer; // 业主
  97. // 本地存储值、线上存储值。线上修改后,需要同步到本地
  98. FWebMD5_Local: string; // 本地存储的MD5
  99. FWebMD5_OnLine: string; // 线上存储的最新的MD5(下同)
  100. FWebBidName_Local: string; // 标段名 (当无法同线上取得联系时,本地需要用到该名称来提示)
  101. FWebBidName_OnLine: string;
  102. FWebFolder_OnLine: string; // 这个命名不妥,但很直观。线上的项目名称、项目类型概念跟本地颠倒,很混乱。
  103. FWebSubFolder_OnLine: string;
  104. FWebOwnerCompany: string;
  105. FWebOwnerRole: string;
  106. FWebOwnerName: string;
  107. FWebCheckStatusMy: TCheckStatus; // 登陆用户在当前项目中的工作状态。
  108. FWebCheckStatusProject: TCheckStatus; // 项目的审核状态。
  109. FOnLineCheckerBegin: Integer; // 线上审批的起始人。 010110111 起7止9。 0101101110 起0止0。
  110. FOnLineCheckerEnd: Integer; // 线上审批的截止人。
  111. FPhaseTotal: Integer;
  112. FPhaseNo: Integer;
  113. FCurPos: Integer; // 用来控制审核人的添加位置
  114. FCheckerList: TObjectList;
  115. function ReceiveFile(const AFileName: string; AIsReback: Boolean = False): Boolean;
  116. function ImportFile(const AFileName: string; AFileMD5: string = ''): Boolean;
  117. procedure ConnectButtonWithAction;
  118. function GetImportProjectName(const AFileName: string; AParent: TsdIDTreeNode): string;
  119. function IsProject(ANode: TsdIDTreeNode): Boolean;
  120. function IsLeafProject(ANode: TsdIDTreeNode): Boolean;
  121. function IsUnEmptyLeafProject(ANode: TsdIDTreeNode): Boolean;
  122. function CheckOpened(ANode: TsdIDTreeNode): Boolean;
  123. procedure SetPropertyVisible(AVisible: Boolean);
  124. procedure ShowProjectInfoTopAndCheckers;
  125. // 网络上的目录结构,本地有则定位,没有则创建。
  126. procedure CheckWebFolders(AFolderID, ASubFolderID: Integer;
  127. AFolderName, ASubFolderName: string);
  128. // ANewBidName: 项目的最新标段名(取自服务器,有人改名了,本地的就变成旧的)
  129. procedure CheckBidName(AID: Integer; ANewBidName: string); overload;
  130. procedure CheckBidName(AUserID, AWebID: Integer; ANewBidName: string); overload;
  131. procedure ClearLocalValues;
  132. procedure GetLocalValues(ARec: TsdDataRecord); overload;
  133. // 用户ID、网络标段ID、Type=1可以定位一个标段。
  134. procedure GetLocalValues(AUserID, AWebID: Integer); overload;
  135. // 1 等待我审核的标段文件; 2 我参与的全部标段文件
  136. procedure DoBatchReceiveOnline(ARequestType: Integer);
  137. function LocalMD5(AUserID, AWebID: Integer): string;
  138. procedure BubbleSortProjects;
  139. // AReceiveKind: 1 接收; 2 导入
  140. function FileDownAndReceive(ADownURL: string; AReceiveKind: Integer): Boolean;
  141. // 线上审批的起止人
  142. procedure OnLineChecker(AAr: TOVArr; var ABegin, AEnd: Integer);
  143. public
  144. constructor Create(AOwner: TComponent); override;
  145. destructor Destroy; override;
  146. procedure DoBatchReceiveAllOnline;
  147. // AType: -2 繁忙; -1 正常读取; 0 第0期; 1 第1期。
  148. procedure ShowProjectInfoTop(AType: Integer = -1);
  149. function Rec(AProjectID: Integer): TsdDataRecord;
  150. function CurRec: TsdDataRecord;
  151. function CurRecAttachmentPath: string;
  152. function AttachmentFileCountsWithoutManageFile(ANode: TsdIDTreeNode): Integer;
  153. property ProjectCheckStatus: TCheckStatus read FWebCheckStatusProject;
  154. end;
  155. implementation
  156. uses
  157. MainFrm, UtilMethods, ProjectCommands, Globals, ConfigDoc, ConstUnit,
  158. <<<<<<< HEAD
  159. WebNewTenderFrm, PHPWebDm, Math, mProgressFrm, ProgressHintFrm,
  160. ShellAPI;
  161. =======
  162. WebNewTenderFrm, PHPWebDm, Math, CslJson, mProgressFrm, ProgressHintFrm,
  163. ShellAPI, ProjectFme;
  164. >>>>>>> 3.1.5
  165. {$R *.dfm}
  166. procedure TProjectManagerFrame.ConnectButtonWithAction;
  167. begin
  168. SetDxBtnAction(actnNewProject, MainForm.dxbtnNewProject);
  169. SetDxBtnAction(actnNewSubProject, MainForm.dxbtnNewSubProject);
  170. SetDxBtnAction(actnNewTender, MainForm.dxbtnNewTender);
  171. SetDxBtnAction(actnOpen, MainForm.dxbtnOpenProject);
  172. SetDxBtnAction(actnDelete, MainForm.dxbtnDeleteProject);
  173. SetDxBtnAction(actnReceiveProject, MainForm.dxbtnReceiveProject);
  174. SetDxBtnAction(actnOpenBackupFolder, MainForm.dxbtnOpenBackupFolder);
  175. SetDxBtnAction(actnRename, MainForm.dxbtnRename);
  176. end;
  177. constructor TProjectManagerFrame.Create(AOwner: TComponent);
  178. begin
  179. inherited;
  180. FCheckerList := TObjectList.Create;
  181. FProjectManagerData := ProjectManager;
  182. FProjectManagerData.Open;
  183. stdProjects.IDTree := FProjectManagerData.ProjectsTree;
  184. sdTenderProperty.DataView := FProjectManagerData.sdvTenderProperty;
  185. ConnectButtonWithAction;
  186. SetPropertyVisible(False);
  187. sbChecker.Height := 0;
  188. if G_IsCloud then
  189. begin
  190. Application.HintPause := 200;
  191. Application.HintHidePause := 60000;
  192. tobtnImport.Visible := False;
  193. stdProjects.TreeOptions := stdProjects.TreeOptions - [aoAllowUpLevel, aoAllowDownLevel];
  194. stdProjects.Options := stdProjects.Options - [aoAllowUpMove, aoAllowDownMove];
  195. CreateProgress('正在从云端下载新项目');
  196. try
  197. actnReceiveProject.Execute;
  198. finally
  199. CloseProgress;
  200. end;
  201. end;
  202. end;
  203. function SearchFileOnline(AURL: string; var ADownURL, AFolder, ASubFolder, ABidName, AMD5Web, AError: string;
  204. var AFolderID, ASubFolderID: Integer): Integer;
  205. var vArr: TOVArr;
  206. begin
  207. Result := PHPWeb.Search(AURL, [''], [''], vArr);
  208. AError := '';
  209. if Result = 1 then
  210. begin
  211. if High(vArr) >= 0 then
  212. begin
  213. ADownURL := vArr[0, 0];
  214. AFolder := vArr[0, 2];
  215. ASubFolder := vArr[0, 3];
  216. AMD5Web := vArr[0, 1];
  217. AFolderID := StrToInt(vArr[0, 4]);
  218. ASubFolderID := StrToInt(vArr[0, 5]);
  219. ABidName := vArr[0, 6];
  220. end
  221. else
  222. Result := 10; // 返回10,表示无记录。用这个数字代表是否觉得怪异?没办法,0被占用了。
  223. end
  224. else if Result = 0 then
  225. AError := PHPWeb.PageError('标段更新数据失败')
  226. else if Result = -1 then
  227. AError := PHPWeb.NetError('标段更新数据失败');
  228. end;
  229. // 双击打开项目 TagB
  230. procedure TProjectManagerFrame.actnOpenExecute(Sender: TObject);
  231. var
  232. vSel: TsdIDTreeNode;
  233. vRec: TsdDataRecord;
  234. sHint: string;
  235. function CanOpen: Boolean;
  236. var
  237. sSearchURL, sDownURL,
  238. sMD5_UnLock, sError, sLocalFile: string;
  239. iSearch, iFolderID, iSubFolderID: Integer;
  240. <<<<<<< HEAD
  241. function HasWebBidInfo(AWebID: Integer): Boolean;
  242. var vArr: array of string;
  243. iResult: Integer;
  244. begin
  245. sSearchURL := Format('%stender/get/%d/exist', [PHPWeb.MeasureURL, AWebID]);
  246. vArr := VarArrayOf(['id', 'name']);
  247. iResult := PHPWeb.Search(sSearchURL, [''], [''], vArr);
  248. if (iResult = 1) and (High(vArr) >= 0) then
  249. Result := True
  250. else
  251. Result := False;
  252. end;
  253. =======
  254. bLock, bCanImp: Boolean;
  255. vFileCheck: TTenderFileChecker;
  256. >>>>>>> 3.1.5
  257. begin
  258. Result := False;
  259. // 先按正常接口找到最新的MD5码看是否需要更新
  260. sSearchURL := Format('%stender/get/%d/update', [PHPWeb.MeasureURL, FWebID]);
  261. iSearch := SearchFileOnline(sSearchURL, sDownURL, FWebFolder_OnLine, FWebSubFolder_OnLine, FWebBidName_OnLine, FWebMD5_OnLine, sError, iFolderID, iSubFolderID);
  262. if iSearch = 1 then
  263. begin
  264. try
  265. CheckWebFolders(iFolderID, iSubFolderID, FWebFolder_OnLine, FWebSubFolder_OnLine);
  266. CheckBidName(FID, FWebBidName_OnLine);
  267. finally
  268. if vSel <> nil then
  269. vSel.LocateInControl;
  270. end;
  271. // 打开前一定要先下载最新的标段文件(无论审核有没有通过)
  272. if FWebMD5_OnLine <> FWebMD5_Local then
  273. if not FileDownAndReceive(sDownURL, 1) then Exit;
  274. // 编制人且项目末通过
  275. if (FWebAuthorID = PHPWeb.UserID) and (FWebCheckStatusProject = csNotPass) then
  276. begin
  277. sHint := '本期计量审批不通过,你现在可以:' + #10#13 + '点击【是(Y)】重新开始本期计量,软件将打开本期上报时的数据,开始重新计量;' +
  278. #10#13 +'点击【否(N)】查看不通过计量,软件将打开本期最后审批的数据,重新打开标段' + '可再次打开本确认窗口。';
  279. if Application.MessageBox(PChar(sHint), '询问', MB_YESNO + MB_ICONQUESTION) = ID_Yes then
  280. begin
  281. sSearchURL := Format('%suser/create/%d/%d/new/audit', [PHPWeb.MeasureURL, FWebID, FPhaseNo]);
  282. case SearchFileOnline(sSearchURL, sDownURL, FWebFolder_OnLine, FWebSubFolder_OnLine, FWebBidName_OnLine, sMD5_UnLock, sError, iFolderID, iSubFolderID) of
  283. 1:
  284. begin
  285. <<<<<<< HEAD
  286. if not FileDownAndReceive(sDownURL, 2) then Exit;
  287. =======
  288. // 下载
  289. sLocalFile := PHPWeb.UserPath + ExtractFileName(sDownURL);
  290. if not PHPWeb.DownFile(sDownURL, sLocalFile) then
  291. begin
  292. sHint := '云端已找到原报上传的无锁文件,但因网络出错无法下载,本次操作已取消。请重试!';
  293. Application.MessageBox(PChar(sHint), '警告', MB_OK + MB_ICONWARNING);
  294. Exit;
  295. end;
  296. // 导入更新-------------------------------------------------------
  297. // 导入前须检测无锁文件中仅含有原报数据
  298. vFileCheck := TTenderFileChecker.Create;
  299. try
  300. // 有一期以上数据,且最新期数据审核状态为原报
  301. bCanImp := vFileCheck.CheckFileValid(sLocalFile)
  302. and (vFileCheck.PhaseCount > 0) and (vFileCheck.AuditStatus = 0);
  303. if not bCanImp then
  304. begin
  305. Application.MessageBox(PChar('已从云端下载原报上传的无锁文件到本地,但文件有错误,禁止导入!请致电纵横服务人员以获取帮助。'), '警告', MB_OK + MB_ICONWARNING);
  306. Exit;
  307. end;
  308. finally
  309. vFileCheck.Free;
  310. end;
  311. if not ImportFile(sLocalFile, sMD5) then
  312. begin
  313. Application.MessageBox(PChar('已从云端下载原报上传的无锁文件到本地,但导入失败!请重试。'), '警告', MB_OK + MB_ICONWARNING);
  314. Exit;
  315. end;
  316. sHint := '【重要提示】:本期计量已重新开始,在本次上报完成前,请勿删除该标段或更换电脑。';
  317. Application.MessageBox(PChar(sHint), '提示', MB_OK + MB_ICONINFORMATION);
  318. // 导入更新---------------------------------↑↑↑↑↑↑↑↑↑↑↑
  319. >>>>>>> 3.1.5
  320. end;
  321. 0, -1:
  322. begin
  323. sHint := sError + '(因网络出错,无法连接到云端以获取本期原报上传的无锁文件,无法重新开始本期,本次操作已取消。请重试。';
  324. Application.MessageBox(PChar(sHint), '警告', MB_OK + MB_ICONWARNING);
  325. Exit;
  326. end;
  327. end;
  328. end;
  329. end;
  330. end
  331. else if (iSearch = 10) then
  332. begin
  333. if not PHPWeb.ExistInServer(FWebID) then
  334. begin
  335. sHint :='该项目[' + FWebBidName_Local + ']在云端已被删除,点击"确定"后,可手动删除该项目。';
  336. Application.MessageBox(PChar(sHint), '提示', MB_OK + MB_ICONINFORMATION);
  337. Exit;
  338. end;
  339. end
  340. else if (iSearch = 0) or (iSearch = -1) then
  341. begin
  342. sHint := sError + '(因网络出错,无法检测[' + FWebBidName_Local + ']在云端是否有更新,本次操作已取消,请重试)。';
  343. Application.MessageBox(PChar(sHint), '警告', MB_OK + MB_ICONWARNING);
  344. Exit;
  345. end;
  346. Result := True;
  347. end;
  348. var
  349. CurProjectFme: TProjectFrame;
  350. begin
  351. // 打开前先下载更新
  352. Screen.Cursor := crHourGlass;
  353. try
  354. vSel := stdProjects.IDTree.Selected;
  355. vRec := vSel.Rec;
  356. if G_IsCloud then
  357. begin
  358. GetLocalValues(CurRec);
  359. // 以下这段已经包含在MainForm.OpenProject(vRec)中了,但在调用这句之前,网络版要提前用一下。
  360. if MainForm.HasOpened(FID) then
  361. begin
  362. MainForm.LocateProject(FID);
  363. Exit;
  364. end;
  365. if not CanOpen then
  366. Exit;
  367. end;
  368. CurProjectFme := MainForm.OpenProject(vRec);
  369. if G_IsCloud then
  370. begin
  371. // 云版,如果用户在打开项目的过程中,切换界面回项目管理,MainFrom.CurProjectFrame值为nil,后面的调用,包括MainForm.actnCloseProject.Execute都会出错
  372. // 其中由于前面调用的MainForm.LocateProject触发的一系列事件中,调用到了SetPropertyVisible,其中执行了Screen.Cursor := crDefault
  373. // 导致鼠标状态还原,用户可以点击,单机版下测试,属性状态为crHourGlass时,亦可以切换会项目管理
  374. // 按逻辑,CheckFileAndCloudCheckerList这种方法不应在界面,应在控制器,亦不可直接调用MainForm.actnCloseProject.Execute
  375. // 怕按逻辑改动引起更多Bug,故继续错下去,检查MainForm.CurProjectFrame是否正确,并再次禁用鼠标
  376. if CurProjectFme <> MainForm.CurProjectFrame then
  377. begin
  378. Screen.Cursor := crHourGlass;
  379. MainForm.LocateProject(CurProjectFme.ProjectData.ProjectID);
  380. end;
  381. if not MainForm.CurProjectFrame.CheckFileAndCloudChekerList then
  382. begin
  383. sHint := '项目校验:“' + FWebBidName_OnLine + '”文件中的审核人和云端的审核人不一致,' +
  384. '禁止继续操作,项目即将关闭!请删除本地项目重新从云端获取,' +
  385. '重新获取后如果仍然存在同样的问题,请联系纵横服务人员以寻求帮助。';
  386. Application.MessageBox(PChar(sHint), '文件错误', MB_OK +MB_ICONWARNING);
  387. MainForm.actnCloseProject.Execute;
  388. Exit;
  389. end;
  390. end;
  391. finally
  392. Screen.Cursor := crDefault;
  393. end;
  394. end;
  395. procedure TProjectManagerFrame.actnDeleteExecute(Sender: TObject);
  396. begin
  397. if stdProjects.IDTree.Count = 0 then Exit;
  398. with stdProjects.IDTree.Selected.Rec do
  399. if QuestMessage(Format('确定要删除[%s]吗?', [ValueByName('Name').AsString])) then
  400. begin
  401. Screen.Cursor := crHourGlass;
  402. try
  403. FProjectManagerData.Delete;
  404. finally
  405. Screen.Cursor := crDefault;
  406. end;
  407. end;
  408. end;
  409. procedure TProjectManagerFrame.zgProjectsMouseDown(Sender: TObject;
  410. Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  411. begin
  412. if Button = mbRight then
  413. dxpmProjectManager.PopupFromCursorPos
  414. else if (zgProjects.CurCol = 1) and (Button = mbLeft) and (ssDouble in Shift)
  415. and Assigned(stdProjects.IDTree.Selected) then
  416. begin
  417. if IsProject(stdProjects.IDTree.Selected) then
  418. stdProjects.IDTree.Selected.Expand
  419. else
  420. actnOpen.Execute;
  421. end;
  422. end;
  423. function TProjectManagerFrame.ReceiveFile(const AFileName: string; AIsReback: Boolean): Boolean;
  424. var
  425. vRP: TReceiveProject;
  426. vNode: TsdIDTreeNode;
  427. bLock, bIsOwner: Boolean;
  428. begin
  429. Result := False;
  430. vRP := TReceiveProject.Create(stdProjects.IDTree.Selected);
  431. try
  432. ProjectManager.RefreshSeedID;
  433. if G_IsCloud then
  434. begin
  435. vRP.IsReback := AIsReback;
  436. bLock := (FWebAuthorID = PHPWeb.UserID) or
  437. ((FWebAuthorID <> PHPWeb.UserID) and (FWebCheckStatusMy <> csChecking));
  438. vRP.Lock := bLock;
  439. bIsOwner := FWebOwnerID = PHPWeb.UserID;
  440. vNode := vRP.ReceiveForLost(AFileName, FOnLineCheckerBegin, FOnLineCheckerEnd, bIsOwner);
  441. if vNode <> nil then
  442. begin
  443. vNode.Rec.BeginUpdate;
  444. vNode.Rec.ValueByName('WebMD5').AsString := FWebMD5_OnLine;
  445. vNode.Rec.ValueByName('WebUserID').AsInteger := PHPWeb.UserID;
  446. vNode.Rec.EndUpdate;
  447. end;
  448. end
  449. else
  450. vNode := vRP.Receive(AFileName);
  451. finally
  452. case vRP.MessageID of
  453. 0: begin
  454. Result := True;
  455. vNode.LocateInControl;
  456. end;
  457. 1: ErrorMessage('当前标段处于打开状态,未能成功接收,请先关闭标段再次接收。');
  458. 2: ErrorMessage('下载数据与审核状态不一致,未能成功接收,请再次接收。');
  459. 3: ErrorMessage('升级数据失败,未能成功接收,请再次接收。');
  460. end;
  461. vRP.Free;
  462. FProjectManagerData.Save;
  463. end;
  464. end;
  465. // 登录后自动扫描等待我审核的项目 TagC
  466. procedure TProjectManagerFrame.actnReceiveProjectExecute(Sender: TObject);
  467. procedure DoReceiveLocal;
  468. var
  469. sFileName: string;
  470. begin
  471. if SelectFile(sFileName, '.rmf;*.arf') then
  472. begin
  473. ShowProgressHint('正在接收项目并升级数据');
  474. try
  475. ReceiveFile(sFileName);
  476. finally
  477. CloseProgressHint;
  478. end;
  479. end;
  480. end;
  481. var OnCC: TZjCellNotifyEvent;
  482. begin
  483. Screen.Cursor := crHourGlass;
  484. try
  485. if G_IsCloud then
  486. begin
  487. OnCC := zgProjects.OnCurrentChanged;
  488. try
  489. zgProjects.OnCurrentChanged := nil;
  490. DoBatchReceiveOnline(1);
  491. if stdProjects.IDTree.FirstNode <> nil then
  492. stdProjects.IDTree.FirstNode.LocateInControl;
  493. finally
  494. zgProjects.OnCurrentChanged := OnCC;
  495. end;
  496. end
  497. else
  498. DoReceiveLocal;
  499. finally
  500. Screen.Cursor := crDefault;
  501. end;
  502. end;
  503. function TProjectManagerFrame.GetImportProjectName(
  504. const AFileName: string; AParent: TsdIDTreeNode): string;
  505. begin
  506. Result := ExtractSimpleFileName(AFileName);
  507. while FProjectManagerData.ExistProject(Result, AParent) do
  508. if not InputNewProjectName(Result, '导入', AParent) then Abort;
  509. end;
  510. procedure TProjectManagerFrame.actnNewProjectExecute(Sender: TObject);
  511. var
  512. sName: string;
  513. begin
  514. if G_IsCloud then Exit; // 云版线上与本地要保持同步,不允许本地新建
  515. if InputNewProjectName(sName, '新建', stdProjects.IDTree.Selected) then
  516. FProjectManagerData.InsertProject(sName, stdProjects.IDTree.Selected);
  517. end;
  518. procedure TProjectManagerFrame.actnNewSubProjectExecute(Sender: TObject);
  519. var
  520. sName: string;
  521. begin
  522. if G_IsCloud then Exit;
  523. if InputNewProjectName(sName, '新建', stdProjects.IDTree.Selected) then
  524. FProjectManagerData.InsertSubProject(sName, stdProjects.IDTree.Selected);
  525. end;
  526. procedure TProjectManagerFrame.actnNewTenderExecute(Sender: TObject);
  527. function AddAndOpenTender(const ATenderName: string): TsdIDTreeNode;
  528. begin
  529. Result := FProjectManagerData.InsertTender(ATenderName, stdProjects.IDTree.Selected);
  530. MainForm.OpenProject(Result.Rec);
  531. end;
  532. // 网络版新建标段 TagD
  533. procedure NewProjectWithOnline;
  534. var
  535. WebNewTenderForm: TWebNewTenderForm;
  536. sName, sKey, sURL: string;
  537. stnNew: TsdIDTreeNode;
  538. iID, iFolderID, iSubFolderID: Integer;
  539. vRec: TsdDataRecord;
  540. vArr: array of string;
  541. begin
  542. WebNewTenderForm := TWebNewTenderForm.Create(nil);
  543. try
  544. WebNewTenderForm.ShowModal;
  545. if WebNewTenderForm.ModalResult = mrOK then
  546. begin
  547. sKey := WebNewTenderForm.edtKey.Text;
  548. sName := WebNewTenderForm.edtTenderName.Text;
  549. // 同服务器取得联系
  550. iID := -1;
  551. vArr := VarArrayOf(['catid', 'name', 'company', 'phone', 'mobile', 'qq',
  552. 'pname', 'ptype', 'jobs', 'avatar', 'ownuid', 'pnameid', 'ptypeid']);
  553. sURL := Format('%s%d/%s/%s/creatmeasure', [PHPWeb.MeasureURL, PHPWeb.UserID, sName, sKey]); // AnsiToUtf8(sName)
  554. case PHPWeb.Search(sURL, [], [], vArr) of
  555. 1:
  556. begin
  557. iID := StrToInt(vArr[0]);
  558. iFolderID := StrToInt(vArr[11]);
  559. iSubFolderID := StrToInt(vArr[12]);
  560. CheckWebFolders(iFolderID, iSubFolderID, vArr[6], vArr[7]);
  561. end;
  562. 0:
  563. begin
  564. Application.MessageBox(PChar(PHPWeb.PageError('创建标段失败' + '[' + vArr[0] + ']')),
  565. '警告', MB_OK + MB_ICONWARNING);
  566. Exit;
  567. end;
  568. -1:
  569. begin
  570. Application.MessageBox(PChar(PHPWeb.NetError('创建标段失败')),
  571. '警告', MB_OK + MB_ICONWARNING);
  572. Exit;
  573. end;
  574. end;
  575. // 本地创建
  576. stnNew := FProjectManagerData.InsertTender(sName, stdProjects.IDTree.Selected);
  577. // 这里把Web获取的信息存储到项目管理里面。
  578. vRec := stnNew.Rec;
  579. vRec.BeginUpdate;
  580. vRec.ValueByName('WebID').AsInteger := iID;
  581. vRec.ValueByName('WebOwnerID').AsInteger := StrToInt(vArr[10]); // 业主
  582. vRec.ValueByName('WebAuthorID').AsInteger := PHPWeb.UserID; // 编制人
  583. vRec.ValueByName('WebUserID').AsInteger := PHPWeb.UserID; // 当前用户,用于只显示自己的项目
  584. vRec.ValueByName('WebKey').AsString := sKey;
  585. vRec.EndUpdate;
  586. GetLocalValues(vRec);
  587. FWebOwnerName := vArr[1];
  588. FWebOwnerCompany := vArr[2];
  589. FWebOwnerRole := vArr[8];
  590. FWebFolder_OnLine := vArr[6];
  591. FWebSubFolder_OnLine := vArr[7];
  592. // WebOwnerImage := vArr[9];
  593. // WebOwnerPhone := vArr[3];
  594. // WebOwnerMobile := vArr[4];
  595. // WebOwnerQQ := vArr[5];
  596. ShowProjectInfoTop(0);
  597. FProjectManagerData.Save;
  598. MainForm.OpenProject(vRec);
  599. end;
  600. finally
  601. WebNewTenderForm.Free;
  602. end;
  603. end;
  604. procedure NewProject;
  605. var
  606. sName: string;
  607. begin
  608. if InputNewProjectName(sName, '新建', stdProjects.IDTree.Selected) then
  609. AddAndOpenTender(sName);
  610. end;
  611. begin
  612. if G_IsCloud then
  613. NewProjectWithOnline
  614. else
  615. NewProject;
  616. end;
  617. procedure TProjectManagerFrame.zgProjectsDrawCellText(ACanvas: TCanvas;
  618. const ARect: TRect; const ACoord: TPoint; AGrid: TZJGrid;
  619. const Text: String; var ADefaultDraw: Boolean);
  620. procedure GetBitmap(AImage: TBitmap; ANode: TsdIDTreeNode);
  621. begin
  622. if Assigned(ANode) and Assigned(ANode.Rec) then
  623. begin
  624. if ANode.Rec.ValueByName('Type').AsInteger = 0 then
  625. if ANode.Expanded and ANode.HasChildren then
  626. MainForm.Images.GetBitmap(34, AImage)
  627. else
  628. MainForm.Images.GetBitmap(34, AImage)
  629. else
  630. MainForm.Images.GetBitmap(11, AImage);
  631. end
  632. else
  633. AImage := nil;
  634. end;
  635. const
  636. rIconWidth = 16;
  637. rIconHeight = 16;
  638. var
  639. Img: TBitmap;
  640. Cell: TZjCell;
  641. rImg: TRect;
  642. vNode: TsdIDTreeNode;
  643. begin
  644. if (ACoord.X = 1) and (ACoord.Y > zgProjects.FixedRowCount - 1) then
  645. begin
  646. Cell := zgProjects.Cells[ACoord.X, ACoord.Y];
  647. Img := TBitmap.Create;
  648. try
  649. vNode := stdProjects.IDTree.Items[ACoord.Y-zgProjects.FixedRowCount];
  650. GetBitmap(Img, vNode);
  651. case Cell.Align of
  652. gaTopLeft, gaTopCenter, gaTopRight:
  653. rImg := Rect(ARect.Left + 2, ARect.Top, ARect.Left + rIconWidth, ARect.Top + rIconHeight);
  654. gaCenterLeft, gaCenterCenter, gaCenterRight:
  655. rImg := Rect(ARect.Left + 2, ARect.Top + (ARect.Bottom - ARect.Top - rIconHeight) div 2, ARect.Left + rIconWidth, ARect.Bottom - (ARect.Bottom - ARect.Top - rIconHeight) div 2);
  656. gaBottomLeft, gaBottomCenter, gaBottomRight:
  657. rImg := Rect(ARect.Left + 2, ARect.Bottom - rIconHeight, ARect.Left + rIconWidth, ARect.Bottom);
  658. end;
  659. ACanvas.StretchDraw(rImg, Img);
  660. WriteText(ACanvas, Rect(ARect.Left + rIconWidth, ARect.Top, ARect.Right, ARect.Bottom)
  661. , 2, 2, Text, Cell.Align, False);
  662. ADefaultDraw := False;
  663. finally
  664. Img.Free;
  665. end;
  666. end;
  667. end;
  668. procedure TProjectManagerFrame.actnNewSubProjectUpdate(Sender: TObject);
  669. begin
  670. TAction(Sender).Enabled := Assigned(stdProjects.IDTree.Selected)
  671. and IsProject(stdProjects.IDTree.Selected)
  672. and (not IsUnEmptyLeafProject(stdProjects.IDTree.Selected));
  673. end;
  674. procedure TProjectManagerFrame.actnNewTenderUpdate(Sender: TObject);
  675. var bCloud: Boolean;
  676. vNode: TsdIDTreeNode;
  677. begin
  678. bCloud := G_IsCloud;
  679. // 只有编制人才能创建新标段?逻辑先后有问题:编制人是在创建标段之后产生的。
  680. // 创建前,当前用户只是一个帐户,它是不是编制人末知,因为它还可以是其它角色。
  681. // 同一帐户在不同的标段可以作为不同的角色。
  682. if bCloud then
  683. begin
  684. TAction(Sender).Enabled := True;
  685. end
  686. else
  687. begin
  688. vNode := stdProjects.IDTree.Selected;
  689. TAction(Sender).Enabled := Assigned(vNode) and IsProject(vNode) and IsLeafProject(vNode);
  690. end;
  691. end;
  692. function TProjectManagerFrame.IsLeafProject(ANode: TsdIDTreeNode): Boolean;
  693. begin
  694. if ANode.HasChildren then
  695. Result := ANode.FirstChild.Rec.ValueByName('Type').AsInteger = 1
  696. else
  697. Result := ANode.Rec.ValueByName('Type').AsInteger = 0;
  698. end;
  699. function TProjectManagerFrame.IsProject(ANode: TsdIDTreeNode): Boolean;
  700. begin
  701. Result := ANode.Rec.ValueByName('Type').AsInteger = 0;
  702. end;
  703. function TProjectManagerFrame.IsUnEmptyLeafProject(
  704. ANode: TsdIDTreeNode): Boolean;
  705. begin
  706. Result := ANode.HasChildren and (ANode.Rec.ValueByName('Type').AsInteger = 1);
  707. end;
  708. procedure TProjectManagerFrame.SetPropertyVisible(AVisible: Boolean);
  709. begin
  710. // 单击刷新项目信息 TagA
  711. if G_IsCloud then
  712. begin
  713. if CurRec = nil then Exit;
  714. pnlTenderProperty.Visible := False;
  715. pnlWeb.Visible := AVisible;
  716. if AVisible then
  717. begin
  718. CreateProgress('云端读取项目信息');
  719. try
  720. ShowProjectInfoTopAndCheckers;
  721. finally
  722. CloseProgress;
  723. end;
  724. end;
  725. end
  726. else
  727. begin
  728. pnlWeb.Visible := False;
  729. pnlTenderProperty.Visible := AVisible;
  730. sprProperty.Visible := AVisible;
  731. end;
  732. end;
  733. procedure TProjectManagerFrame.zgProjectsCurrentChanged(Sender: TObject;
  734. Col, Row: Integer);
  735. begin
  736. if G_IsCloud then
  737. begin
  738. if CurRec <> nil then
  739. begin
  740. // 加这句后产生Bug:上报项目后,记录不曾移动,FID不变,不会刷新
  741. // if FID <> CurRec.ValueByName('ID').AsInteger then
  742. SetPropertyVisible(CurRec.ValueByName('Type').AsInteger = 1);
  743. // OnCurrentChanged取得的 CurRec.ValueByName() 值并不总是可靠,这里加保险。
  744. // 如调用locateInControl后,执行到这里取得的CurRec.ValueByName('ID')值还是上一条的。
  745. if (CurRec.ValueByName('Type').AsInteger = 1) and (not pnlWeb.Visible) then
  746. pnlWeb.Visible := True;
  747. end;
  748. end;
  749. end;
  750. procedure TProjectManagerFrame.actnSubmitProjectUpdate(Sender: TObject);
  751. begin
  752. TAction(Sender).Enabled := Assigned(stdProjects.IDTree.Selected)
  753. and (stdProjects.IDTree.Selected.Rec.ValueByName('Type').AsInteger = 1)
  754. and (stdProjects.IDTree.Selected.Rec.ValueByName('AuditStatus').AsInteger < iMaxStageCount-1);
  755. end;
  756. procedure TProjectManagerFrame.actnReplyProjectUpdate(Sender: TObject);
  757. begin
  758. TAction(Sender).Enabled := Assigned(stdProjects.IDTree.Selected)
  759. and (stdProjects.IDTree.Selected.Rec.ValueByName('Type').AsInteger = 1);
  760. end;
  761. procedure TProjectManagerFrame.actnRenameExecute(Sender: TObject);
  762. function CanRename(ARec: TsdDataRecord; const ANewName: string): Boolean;
  763. var
  764. sURL: string;
  765. iRename: Integer;
  766. vArr: array [0..0] of string;
  767. begin
  768. Result := True;
  769. if not G_IsCloud then Exit;
  770. // 云版 重命名须确保同步服务器
  771. sURL := Format('%stender/%d/%s/update', [PHPWeb.MeasureURL, ARec.ValueByName('WebID').AsInteger, ANewName]);
  772. iRename := PHPWeb.Search(sURL, [], [], vArr);
  773. Result := iRename = 1;
  774. case iRename of
  775. 1: ShowMessage('新的标段名称已同步到服务器!');
  776. 0: Application.MessageBox(PChar(PHPWeb.PageError('重命名同步到云端失败' + '[' + vArr[0] + ']')),
  777. '警告', MB_OK + MB_ICONWARNING);
  778. -1: Application.MessageBox(PChar(PHPWeb.NetError('重命名同步到云端失败')),
  779. '警告', MB_OK + MB_ICONWARNING);
  780. end;
  781. end;
  782. var
  783. stnNode: TsdIDTreeNode;
  784. sName: string;
  785. begin
  786. stnNode := stdProjects.IDTree.Selected;
  787. sName := stnNode.Rec.ValueByName('Name').AsString;
  788. if not Assigned(OpenProjectManager.FindProjectData(stnNode.ID)) then
  789. begin
  790. if InputNewProjectName(sName, '重命名', stnNode.Parent, stnNode.ID) then
  791. begin
  792. if (sName <> stnNode.Rec.ValueByName('Name').AsString) and CanRename(stnNode.Rec, sName) then
  793. begin
  794. stnNode.Rec.ValueByName('Name').AsString := sName;
  795. ProjectManager.Save;
  796. end;
  797. end;
  798. end
  799. else
  800. ErrorMessage(Format('项目[%s]已经打开,无法重命名!', [sName]));
  801. end;
  802. procedure TProjectManagerFrame.actnOpenUpdate(Sender: TObject);
  803. begin
  804. TAction(Sender).Enabled := Assigned(stdProjects.IDTree.Selected)
  805. and (stdProjects.IDTree.Selected.Rec.ValueByName('Type').AsInteger = 1);
  806. end;
  807. procedure TProjectManagerFrame.actnImportExecute(Sender: TObject);
  808. procedure ImportTender(const AFileName, AProjectName: string);
  809. var
  810. Importor: TTenderImport;
  811. begin
  812. Importor := TTenderImport.Create(stdProjects.IDTree.Selected,
  813. AProjectName, AFileName);
  814. try
  815. Importor.Execute;
  816. finally
  817. Importor.Free;
  818. end;
  819. end;
  820. procedure ImportProject(const AFileName, AProjectName: string);
  821. var
  822. Importor: TProjectImport;
  823. begin
  824. Importor := TProjectImport.Create(stdProjects.IDTree.Selected,
  825. AProjectName, AFileName);
  826. try
  827. Importor.Execute;
  828. finally
  829. Importor.Free;
  830. end;
  831. end;
  832. var
  833. sFileName, sProjectName: string;
  834. vCur: TsdIDTreeNode;
  835. begin
  836. if SelectFile(sFileName, '.mtf;*.mpf') then
  837. begin
  838. vCur := stdProjects.IDTree.Selected;
  839. if Assigned(vCur) then
  840. begin
  841. if SameText(ExtractFileExt(sFileName), '.mtf')
  842. and (vCur.Rec.ValueByName('Type').AsInteger = 0) then
  843. sProjectName := GetImportProjectName(sFileName, stdProjects.IDTree.Selected)
  844. else
  845. sProjectName := GetImportProjectName(sFileName, stdProjects.IDTree.Selected.Parent);
  846. end
  847. else
  848. sProjectName := GetImportProjectName(sFileName, vCur);
  849. Screen.Cursor := crHourGlass;
  850. try
  851. if SameText(ExtractFileExt(sFileName), '.mtf') then
  852. ImportTender(sFileName, sProjectName)
  853. else
  854. ImportProject(sFileName, sProjectName);
  855. finally
  856. Screen.Cursor := crDefault;
  857. end;
  858. end;
  859. FProjectManagerData.Save;
  860. end;
  861. procedure TProjectManagerFrame.actnExportExecute(Sender: TObject);
  862. procedure ExportTender(ANode: TsdIDTreeNode);
  863. var
  864. Exportor: TTenderExport;
  865. sFileName, sHint: string;
  866. bExpAtch: Boolean;
  867. iCount: Integer;
  868. begin
  869. bExpAtch := False;
  870. sFileName := SupportManager.ConfigInfo.OutputPath + ANode.Rec.ValueByName('Name').AsString + '.mtf';
  871. if SaveFile(sFileName, '.mtf') then
  872. begin
  873. if FileExists(sFileName) and not QuestMessage(Format('存在同名文件“%s”,是否替换?', [ExtractFileName(sFileName)])) then
  874. Exit;
  875. Screen.Cursor := crHourGlass;
  876. try
  877. Exportor := TTenderExport.Create(ANode.Rec, sFileName);
  878. try
  879. { if not G_IsCloud then
  880. begin
  881. iCount := FileCount(CurRecAttachmentPath);
  882. if iCount > 1 then // 排除管理文件库
  883. begin
  884. sHint := Format('本标段包含 %d 个附件,是否将附件一起导出?', [iCount - 1]);
  885. bExpAtch := Application.MessageBox(PChar(sHint), '询问', MB_YESNO + MB_ICONQUESTION + MB_DEFBUTTON2) = ID_Yes;
  886. end;
  887. end; } // FFFFF
  888. Exportor.Execute(bExpAtch);
  889. finally
  890. Exportor.Free;
  891. end;
  892. finally
  893. Screen.Cursor := crDefault;
  894. end;
  895. end;
  896. end;
  897. procedure ExportProject(ANode: TsdIDTreeNode);
  898. var
  899. Exportor: TProjectExport;
  900. sFileName, sHint: string;
  901. bExpAtch: Boolean;
  902. iCount: Integer;
  903. begin
  904. sFileName := SupportManager.ConfigInfo.OutputPath + ANode.Rec.ValueByName('Name').AsString + '.mpf';
  905. if SaveFile(sFileName, '.mpf') then
  906. begin
  907. if FileExists(sFileName) and not QuestMessage(Format('存在同名文件“%s”,是否替换?', [ExtractFileName(sFileName)])) then
  908. Exit;
  909. Screen.Cursor := crHourGlass;
  910. try
  911. bExpAtch := False;
  912. { if not G_IsCloud then
  913. begin
  914. iCount := AttachmentFileCountsWithoutManageFile(ANode);
  915. if iCount > 0 then
  916. begin
  917. sHint := Format('本建设项目共包含 %d 个附件,是否将附件一起导出?', [iCount]);
  918. bExpAtch := Application.MessageBox(PChar(sHint), '询问', MB_YESNO + MB_ICONQUESTION + MB_DEFBUTTON2) = ID_Yes;
  919. end;
  920. end; } // FFFFF
  921. Exportor := TProjectExport.Create(ANode, sFileName, bExpAtch);
  922. try
  923. Exportor.Execute;
  924. finally
  925. Exportor.Free;
  926. end;
  927. finally
  928. Screen.Cursor := crDefault;
  929. end;
  930. end;
  931. end;
  932. var
  933. stnNode: TsdIDTreeNode;
  934. begin
  935. stnNode := stdProjects.IDTree.Selected;
  936. if stnNode.Rec.ValueByName('Type').AsInteger = 1 then
  937. begin
  938. ExportTender(stnNode);
  939. end
  940. else
  941. ExportProject(stnNode);
  942. end;
  943. procedure TProjectManagerFrame.actnDeleteUpdate(Sender: TObject);
  944. begin
  945. if Assigned(stdProjects.IDTree.Selected) then
  946. TAction(Sender).Enabled := not CheckOpened(stdProjects.IDTree.Selected)
  947. else
  948. TAction(Sender).Enabled := False;
  949. end;
  950. function TProjectManagerFrame.CheckOpened(ANode: TsdIDTreeNode): Boolean;
  951. var
  952. iChild: Integer;
  953. begin
  954. Result := False;
  955. if ANode.Rec.ValueByName('Type').AsInteger = 1 then
  956. Result := OpenProjectManager.ProjectIndex(ANode.ID) > -1
  957. else
  958. begin
  959. if not ANode.HasChildren then
  960. Result := False
  961. else
  962. begin
  963. for iChild := 0 to ANode.ChildCount - 1 do
  964. Result := Result or CheckOpened(ANode.ChildNodes[iChild]);
  965. end
  966. end;
  967. end;
  968. procedure TProjectManagerFrame.ShowProjectInfoTopAndCheckers;
  969. var
  970. vPSArr: TStrArr;
  971. vCArr: TOVArr; // Checkers
  972. vChecker: TOrderCheckerFrame;
  973. sPicPath, sURL: string;
  974. procedure AddChecker(AType: TCheckerFrameType; AArr: array of string);
  975. begin
  976. vChecker := TOrderCheckerFrame.Create(self);
  977. FCheckerList.Add(vChecker);
  978. vChecker.Owner := Self;
  979. sbChecker.VertScrollBar.Range := sbChecker.VertScrollBar.Range + vChecker.Height;
  980. sbChecker.Height := Min(sbChecker.Height + vChecker.Height, pnlWeb.Height - pnlProject.Height);
  981. vChecker.Parent := sbChecker;
  982. vChecker.Top := FCurPos;
  983. FCurPos := FCurPos + vChecker.Height;
  984. vChecker.Align := alTop;
  985. sPicPath := PHPWeb.UserPath + '1_' + AArr[0] + '.jpg';
  986. PHPWeb.DownFile(AArr[4], sPicPath);
  987. vChecker.Init(AType, StrToInt(AArr[0]), AArr[1], AArr[3],
  988. AArr[2], sPicPath, AArr[6], TCheckStatus(StrToInt(AArr[5])-1));
  989. vChecker.Name := 'ProjectOrderFrame' + AArr[0];
  990. end;
  991. procedure RepairOrder;
  992. var k: Integer;
  993. begin
  994. for k := 0 to sbChecker.ControlCount - 1 do
  995. TOrderCheckerFrame(sbChecker.Controls[k]).Order := k + 1;
  996. end;
  997. <<<<<<< HEAD
  998. procedure ShowProjectCheckers;
  999. var i, j, n: Integer;
  1000. vOwner: array of string; // 业主信息
  1001. =======
  1002. procedure RefreshProjectCheckers;
  1003. var i, j: Integer;
  1004. vOwner: array[0..6] of string; // 业主信息
  1005. >>>>>>> 3.1.5
  1006. begin
  1007. FCheckerList.Clear;
  1008. sbChecker.Height := 0;
  1009. FCurPos := 0;
  1010. sbChecker.VertScrollBar.Range := 0;
  1011. for i := Low(vCArr) to High(vCArr) do
  1012. begin
  1013. if StrToInt(vCArr[i, 0]) = PHPWeb.UserID then
  1014. FWebCheckStatusMy := TCheckStatus(StrToInt(vCArr[i, 5])-1);
  1015. if StrToInt(vCArr[i, 0]) = FWebOwnerID then
  1016. begin
  1017. for j := 0 to 6 do
  1018. vOwner[j] := vCArr[i, j];
  1019. Continue;
  1020. end;
  1021. AddChecker(cftChecker, vCArr[i]);
  1022. end;
  1023. if vOwner[0] <> '' then
  1024. AddChecker(cftOwner, vOwner);
  1025. RepairOrder;
  1026. OnLineChecker(vCArr, FOnLineCheckerBegin, FOnLineCheckerEnd);
  1027. end;
  1028. begin
  1029. GetLocalValues(CurRec);
  1030. if FWebID = 0 then Exit;
  1031. SetLength(vPSArr, 8);
  1032. sURL := Format('%smeasure/status/%d/get', [PHPWeb.MeasureURL, FWebID]);
  1033. if PHPWeb.Search(sURL, [''], [''], 3, vPSArr, vCArr) = 1 then
  1034. begin
  1035. LockWindowUpdate(pnlWeb.Handle);
  1036. try
  1037. FPhaseNo := StrToInt(vPSArr[0]);
  1038. FWebCheckStatusProject := TCheckStatus(StrToInt(vPSArr[1])-1);
  1039. FPhaseTotal := StrToInt(vPSArr[2]);
  1040. FWebFolder_OnLine := vPSArr[3];
  1041. FWebSubFolder_OnLine := vPSArr[4];
  1042. FWebOwnerName := vPSArr[5];
  1043. FWebOwnerCompany := vPSArr[6];
  1044. FWebOwnerRole := vPSArr[7];
  1045. ShowProjectInfoTop;
  1046. ShowProjectCheckers;
  1047. finally
  1048. LockWindowUpdate(0);
  1049. end;
  1050. end
  1051. else
  1052. begin
  1053. FPhaseNo := 0;
  1054. FWebCheckStatusProject := csNotBegin;
  1055. FPhaseTotal := 0;
  1056. FWebFolder_OnLine := '';
  1057. FWebSubFolder_OnLine := '';
  1058. FWebOwnerName := '';
  1059. FWebOwnerCompany := '';
  1060. FWebOwnerRole := '';
  1061. ShowProjectInfoTop;
  1062. sbChecker.Height := 0;
  1063. end;
  1064. end;
  1065. procedure TProjectManagerFrame.ShowProjectInfoTop(AType: Integer);
  1066. procedure ShowOwner;
  1067. begin
  1068. lblBidName.Caption := FWebBidName_Local;
  1069. lblBidName.Update;
  1070. lblProjName.Caption := FWebFolder_OnLine;
  1071. lblProjName.Update;
  1072. lblWebProjCtgyName.Caption := FWebSubFolder_OnLine;
  1073. lblWebProjCtgyName.Update;
  1074. lblOnwerName.Caption := FWebOwnerName;
  1075. lblOnwerName.Update;
  1076. lblOnwerCompany.Caption := Format('-%s)', [FWebOwnerCompany]);
  1077. lblOnwerCompany.Update;
  1078. lblOnwerCompany.Left := lblOnwerName.Left + lblOnwerName.Width;
  1079. end;
  1080. procedure ShowStatus(ANo: Integer; AState: TCheckStatus);
  1081. begin
  1082. lblPeriod.Caption := Format('第%d期', [ANo]);
  1083. lblPeriod.Update;
  1084. lblPeriodState.Caption := CheckStatusNames[AState];
  1085. lblPeriodState.Font.Color := CheckStatusColors[AState];
  1086. lblPeriodState.Update;
  1087. lblPeriodState.Left := lblPeriod.Left + lblPeriod.Width + 5;
  1088. lblPeriodTotal.Caption := Format('(共%d期)', [ANo]);
  1089. lblPeriodTotal.Update;
  1090. lblPeriodTotal.Left := lblPeriodState.Left + lblPeriodState.Width + 3;
  1091. end;
  1092. begin
  1093. GetLocalValues(CurRec);
  1094. case AType of
  1095. -2:
  1096. begin
  1097. lblPeriod.Caption := '正在从云端读取状态信息...';
  1098. lblPeriod.Update;
  1099. end;
  1100. -1:
  1101. begin
  1102. ShowOwner;
  1103. ShowStatus(FPhaseNo, FWebCheckStatusProject);
  1104. end;
  1105. 0:
  1106. begin
  1107. ShowOwner;
  1108. ShowStatus(0, csNotBegin);
  1109. end;
  1110. end;
  1111. end;
  1112. // 检查后,应该定位到最后一层目录,不应该回到原先的选择节点。否则从网络拉下来的项目无法组织正确的树结构。
  1113. procedure TProjectManagerFrame.CheckWebFolders(AFolderID, ASubFolderID: Integer;
  1114. AFolderName, ASubFolderName: string);
  1115. var
  1116. vTree: TsdIDTree;
  1117. vNode, vSubNode: TsdIDTreeNode;
  1118. i: Integer;
  1119. sName: string;
  1120. iUserID, iWebID, iWebFolderLevel: Integer;
  1121. bExist, bSubExist, bModified: Boolean;
  1122. begin
  1123. bExist := False;
  1124. bSubExist := False;
  1125. bModified := False;
  1126. vTree := stdProjects.IDTree;
  1127. for i := 0 to vTree.Count - 1 do
  1128. begin
  1129. vNode := vTree.Items[i];
  1130. sName := vNode.Rec.ValueByName('Name').AsString;
  1131. iUserID := vNode.Rec.ValueByName('WebUserID').AsInteger;
  1132. iWebID := vNode.Rec.ValueByName('WebID').AsInteger;
  1133. iWebFolderLevel := vNode.Rec.ValueByName('WebFolderLevel').AsInteger;
  1134. if (iWebID = AFolderID) and (iWebFolderLevel = G_WFL_ProjName) and (iUserID = PHPWeb.UserID) then
  1135. begin
  1136. bExist := True;
  1137. vNode.LocateInControl;
  1138. if not SameText(sName, AFolderName) then
  1139. begin
  1140. vNode.Rec.ValueByName('Name').AsString := AFolderName;
  1141. bModified := True;
  1142. end;
  1143. Break;
  1144. end;
  1145. end;
  1146. if not bExist then
  1147. begin
  1148. vNode := vTree.Items[0];
  1149. if Assigned(vNode) then
  1150. vNode.LocateInControl;
  1151. vNode := FProjectManagerData.InsertProject(AFolderName, stdProjects.IDTree.Selected, AFolderID, G_WFL_ProjName);
  1152. vNode.LocateInControl;
  1153. end;
  1154. for i := 0 to vNode.ChildCount - 1 do
  1155. begin
  1156. vSubNode := vNode.ChildNodes[i];
  1157. sName := vSubNode.Rec.ValueByName('Name').AsString;
  1158. iUserID := vSubNode.Rec.ValueByName('WebUserID').AsInteger;
  1159. iWebID := vSubNode.Rec.ValueByName('WebID').AsInteger;
  1160. iWebFolderLevel := vSubNode.Rec.ValueByName('WebFolderLevel').AsInteger;
  1161. if (iWebID = ASubFolderID) and (iWebFolderLevel = G_WFL_BidType) and (iUserID = PHPWeb.UserID) then
  1162. begin
  1163. bSubExist := True;
  1164. vSubNode.LocateInControl;
  1165. if not SameText(sName, ASubFolderName) then
  1166. begin
  1167. vSubNode.Rec.ValueByName('Name').AsString := ASubFolderName;
  1168. bModified := True;
  1169. end;
  1170. Break;
  1171. end;
  1172. end;
  1173. if not bSubExist then
  1174. begin
  1175. vNode.LocateInControl;
  1176. vNode := FProjectManagerData.InsertSubProject(ASubFolderName, stdProjects.IDTree.Selected, ASubFolderID, G_WFL_BidType);
  1177. vNode.LocateInControl;
  1178. end;
  1179. if bModified then
  1180. ProjectManager.Save;
  1181. end;
  1182. function TProjectManagerFrame.Rec(AProjectID: Integer): TsdDataRecord;
  1183. var i: Integer;
  1184. vTree: TsdIDTree;
  1185. begin
  1186. vTree := stdProjects.IDTree;
  1187. if vTree.Selected.Rec.ValueByName('ID').AsInteger = AProjectID then
  1188. begin
  1189. Result := stdProjects.IDTree.Selected.Rec;
  1190. Exit;
  1191. end;
  1192. for i := 0 to vTree.Count - 1 do
  1193. begin
  1194. if vTree.Items[i].Rec.ValueByName('ID').AsInteger = AProjectID then
  1195. begin
  1196. Result := vTree.Items[i].Rec;
  1197. vTree.Items[i].LocateInControl;
  1198. Break;
  1199. end;
  1200. end;
  1201. end;
  1202. destructor TProjectManagerFrame.Destroy;
  1203. begin
  1204. FCheckerList.Free;
  1205. inherited;
  1206. end;
  1207. procedure TProjectManagerFrame.DoBatchReceiveOnline(ARequestType: Integer);
  1208. var
  1209. sURL, sCheckersURL, sHint: string;
  1210. vArr: TOVArr;
  1211. i, iFolderID, iSubFolderID: Integer;
  1212. vPSArr: TStrArr;
  1213. vCArr: TOVArr; // Checkers
  1214. begin
  1215. // 查询等待我审核的标段文件,杰哥说分三种:①业主未审核 ②业主审核中 ③审核人审核中 (为什么加①?问杰哥)
  1216. case PHPWeb.Search(PHPWeb.MeasureURL + 'user/get/audit/project', ['audituid', 'RequestType'],
  1217. [IntToStr(PHPWeb.UserID), IntToStr(ARequestType)], vArr) of
  1218. 1:
  1219. begin
  1220. CreateProgress('正在从云端下载新项目');
  1221. try
  1222. for i := Low(vArr) to High(vArr) do
  1223. begin
  1224. sURL := vArr[i, 0];
  1225. FWebFolder_OnLine := vArr[i, 1];
  1226. FWebSubFolder_OnLine := vArr[i, 2];
  1227. FWebMD5_OnLine := vArr[i, 3];
  1228. FWebID := StrToInt(vArr[i, 5]);
  1229. iFolderID := StrToInt(vArr[i, 6]);
  1230. iSubFolderID := StrToInt(vArr[i, 7]);
  1231. FWebCheckStatusMy := TCheckStatus(StrToInt(vArr[i, 8])-1); // vArr[i, 4]项目审核状态;vArr[i, 8]当前登陆用户的审核状态
  1232. FWebAuthorID := StrToInt(vArr[i, 9]);
  1233. FWebBidName_OnLine := vArr[i, 10];
  1234. FWebMD5_Local := LocalMD5(PHPWeb.UserID, FWebID);
  1235. CheckWebFolders(iFolderID, iSubFolderID, FWebFolder_OnLine, FWebSubFolder_OnLine);
  1236. CheckBidName(PHPWeb.UserID, FWebID, FWebBidName_OnLine);
  1237. if FWebMD5_OnLine <> FWebMD5_Local then
  1238. begin
  1239. sCheckersURL := Format('%smeasure/status/%d/get', [PHPWeb.MeasureURL, FWebID]);
  1240. if PHPWeb.Search(sCheckersURL, [''], [''], 3, vPSArr, vCArr) = 1 then
  1241. OnLineChecker(vCArr, FOnLineCheckerBegin, FOnLineCheckerEnd)
  1242. else
  1243. begin
  1244. FOnLineCheckerBegin := 0;
  1245. FOnLineCheckerEnd := 0;
  1246. end;
  1247. if not FileDownAndReceive(sURL, 1) then Exit;
  1248. end;
  1249. end;
  1250. BubbleSortProjects;
  1251. finally
  1252. CloseProgress;
  1253. end;
  1254. end;
  1255. 0, -1:
  1256. begin
  1257. sHint := '网络出错,无法查询云端项目的更新情况,请重试!';
  1258. Application.MessageBox(PChar(sHint), '警告', MB_OK + MB_ICONWARNING);
  1259. Exit;
  1260. end;
  1261. end;
  1262. end;
  1263. function TProjectManagerFrame.ImportFile(const AFileName: string; AFileMD5: string): Boolean;
  1264. var
  1265. vImport: TTenderImport;
  1266. vNode: TsdIDTreeNode;
  1267. begin
  1268. Result := False;
  1269. vNode := stdProjects.IDTree.Selected;
  1270. vImport := TTenderImport.Create(vNode, '', AFileName);
  1271. try
  1272. try
  1273. vImport.ImportToSelect;
  1274. vNode.LocateInControl;
  1275. Result := True;
  1276. except
  1277. Result := False;
  1278. end;
  1279. finally
  1280. vImport.Free;
  1281. vNode.Rec.BeginUpdate;
  1282. vNode.Rec.ValueByName('WebMD5').AsString := AFileMD5;
  1283. vNode.Rec.ValueByName('WebUserID').AsInteger := PHPWeb.UserID;
  1284. vNode.Rec.EndUpdate;
  1285. FProjectManagerData.Save;
  1286. end;
  1287. end;
  1288. procedure TProjectManagerFrame.actnOpenBackupFolderExecute(
  1289. Sender: TObject);
  1290. var
  1291. stnNode: TsdIDTreeNode;
  1292. begin
  1293. stnNode := stdProjects.IDTree.Selected;
  1294. if stnNode.Rec.ValueByName('BackupFolder').AsString = '' then
  1295. TipMessage('该项目暂无备份数据!')
  1296. else
  1297. ShellExecute(Handle, 'open', 'Explorer.exe',
  1298. PChar(FProjectManagerData.BackupPath(stnNode.ID)), nil, 1);
  1299. end;
  1300. procedure TProjectManagerFrame.actnRenameUpdate(Sender: TObject);
  1301. var
  1302. Rec: TsdDataRecord;
  1303. bNet, bEnabled: Boolean;
  1304. begin
  1305. if Assigned(stdProjects.IDTree.Selected) and Assigned(stdProjects.IDTree.Selected.Rec) then
  1306. begin
  1307. bEnabled := True;
  1308. Rec := stdProjects.IDTree.Selected.Rec;
  1309. bNet := G_IsCloud;
  1310. if bNet then
  1311. begin
  1312. bEnabled := (Rec.ValueByName('Type').AsInteger = 1) and
  1313. (Rec.ValueByName('WebAuthorID').AsInteger = PHPWeb.UserID);
  1314. end;
  1315. end
  1316. else
  1317. bEnabled := False;
  1318. if bEnabled <> TAction(Sender).Enabled then
  1319. TAction(Sender).Enabled := bEnabled;
  1320. end;
  1321. procedure TProjectManagerFrame.CheckBidName(AID: Integer; ANewBidName: string);
  1322. var vNode: TsdIDTreeNode;
  1323. begin
  1324. vNode := stdProjects.IDTree.FindNode(AID);
  1325. if vNode = nil then Exit;
  1326. if vNode.Rec.ValueByName('Name').AsString <> ANewBidName then
  1327. begin
  1328. vNode.Rec.ValueByName('Name').AsString := ANewBidName;
  1329. ProjectManager.Save;
  1330. end;
  1331. end;
  1332. procedure TProjectManagerFrame.DoBatchReceiveAllOnline;
  1333. var
  1334. OnCC: TZjCellNotifyEvent;
  1335. begin
  1336. OnCC := zgProjects.OnCurrentChanged;
  1337. try
  1338. zgProjects.OnCurrentChanged := nil;
  1339. DoBatchReceiveOnline(2);
  1340. if stdProjects.IDTree.FirstNode <> nil then
  1341. stdProjects.IDTree.FirstNode.LocateInControl;
  1342. finally
  1343. zgProjects.OnCurrentChanged := OnCC;
  1344. end;
  1345. end;
  1346. procedure TProjectManagerFrame.GetLocalValues(ARec: TsdDataRecord);
  1347. begin
  1348. if not Assigned(ARec) then
  1349. begin
  1350. ClearLocalValues;
  1351. Exit;
  1352. end;
  1353. // 加这句后产生Bug:上报项目后,记录不曾移动,FID不变,不会刷新
  1354. // if ARec.ValueByName('ID').AsInteger <> FID then
  1355. begin
  1356. FID := ARec.ValueByName('ID').AsInteger;
  1357. FWebID := ARec.ValueByName('WebID').AsInteger;
  1358. FWebAuthorID := ARec.ValueByName('WebAuthorID').AsInteger;
  1359. FWebOwnerID := ARec.ValueByName('WebOwnerID').AsInteger;
  1360. FWebMD5_Local := ARec.ValueByName('WebMD5').AsString;
  1361. FWebBidName_Local := ARec.ValueByName('Name').AsString;
  1362. end;
  1363. end;
  1364. procedure TProjectManagerFrame.GetLocalValues(AUserID, AWebID: Integer);
  1365. var i: Integer;
  1366. vTree: TsdIDTree;
  1367. vRec: TsdDataRecord;
  1368. begin
  1369. ClearLocalValues; // 先清空,以防没找到。
  1370. if (CurRec <> nil) and
  1371. (CurRec.ValueByName('WebUserID').AsInteger = AUserID) and
  1372. (CurRec.ValueByName('WebID').AsInteger = AWebID) and
  1373. (CurRec.ValueByName('Type').AsInteger = 1) then
  1374. begin
  1375. GetLocalValues(vRec);
  1376. Exit;
  1377. end;
  1378. vTree := stdProjects.IDTree;
  1379. for i := 0 to vTree.Count - 1 do
  1380. begin
  1381. vRec := vTree.Items[i].Rec;
  1382. if (vRec.ValueByName('WebUserID').AsInteger = AUserID) and
  1383. (vRec.ValueByName('WebID').AsInteger = AWebID) and
  1384. (vRec.ValueByName('Type').AsInteger = 1) then
  1385. begin
  1386. GetLocalValues(vRec);
  1387. Break;
  1388. end;
  1389. end;
  1390. end;
  1391. procedure TProjectManagerFrame.ClearLocalValues;
  1392. begin
  1393. FID := -1;
  1394. FWebID := -1;
  1395. FWebAuthorID := -1;
  1396. FWebOwnerID := -1;
  1397. FWebMD5_Local := '';
  1398. FWebBidName_Local := '';
  1399. end;
  1400. function TProjectManagerFrame.LocalMD5(AUserID, AWebID: Integer): string;
  1401. var i: Integer;
  1402. vTree: TsdIDTree;
  1403. vRec: TsdDataRecord;
  1404. begin
  1405. Result := '本地无MD5码';
  1406. if (CurRec <> nil) and
  1407. (CurRec.ValueByName('WebUserID').AsInteger = AUserID) and
  1408. (CurRec.ValueByName('WebID').AsInteger = AWebID) and
  1409. (CurRec.ValueByName('Type').AsInteger = 1) then
  1410. begin
  1411. Result := vRec.ValueByName('WebMD5').AsString;
  1412. Exit;
  1413. end;
  1414. vTree := stdProjects.IDTree;
  1415. for i := 0 to vTree.Count - 1 do
  1416. begin
  1417. vRec := vTree.Items[i].Rec;
  1418. if (vRec.ValueByName('WebUserID').AsInteger = AUserID) and
  1419. (vRec.ValueByName('WebID').AsInteger = AWebID) and
  1420. (vRec.ValueByName('Type').AsInteger = 1) then
  1421. begin
  1422. Result := vRec.ValueByName('WebMD5').AsString;
  1423. Break;
  1424. end;
  1425. end;
  1426. end;
  1427. function TProjectManagerFrame.CurRec: TsdDataRecord;
  1428. begin
  1429. if stdProjects.IDTree.Selected = nil then
  1430. Result := nil
  1431. else
  1432. Result := stdProjects.IDTree.Selected.Rec;
  1433. end;
  1434. procedure TProjectManagerFrame.CheckBidName(AUserID, AWebID: Integer;
  1435. ANewBidName: string);
  1436. var i: Integer;
  1437. vTree: TsdIDTree;
  1438. vRec: TsdDataRecord;
  1439. begin
  1440. if (CurRec <> nil) and
  1441. (CurRec.ValueByName('WebUserID').AsInteger = AUserID) and
  1442. (CurRec.ValueByName('WebID').AsInteger = AWebID) and
  1443. (CurRec.ValueByName('Type').AsInteger = 1) then
  1444. begin
  1445. if (CurRec.ValueByName('Name').AsString <> ANewBidName) then
  1446. begin
  1447. CurRec.ValueByName('Name').AsString := ANewBidName;
  1448. ProjectManager.Save;
  1449. end;
  1450. Exit;
  1451. end;
  1452. vTree := stdProjects.IDTree;
  1453. for i := 0 to vTree.Count - 1 do
  1454. begin
  1455. vRec := vTree.Items[i].Rec;
  1456. if (vRec.ValueByName('WebUserID').AsInteger = AUserID) and
  1457. (vRec.ValueByName('WebID').AsInteger = AWebID) and
  1458. (vRec.ValueByName('Type').AsInteger = 1) then
  1459. begin
  1460. if vRec.ValueByName('Name').AsString <> ANewBidName then
  1461. begin
  1462. vRec.ValueByName('Name').AsString := ANewBidName;
  1463. ProjectManager.Save;
  1464. end;
  1465. Break;
  1466. end;
  1467. end;
  1468. end;
  1469. function TProjectManagerFrame.CurRecAttachmentPath: string;
  1470. begin
  1471. if G_IsCloud then
  1472. Result := PHPWeb.WebPath + 'Projects\' + CurRec.ValueByName('WebID').AsString + '\Attachment\'
  1473. else
  1474. Result := GetMyProjectsFilePath + 'Attachment\' + CurRec.ValueByName('FileName').AsString + '\';
  1475. end;
  1476. function TProjectManagerFrame.AttachmentFileCountsWithoutManageFile(ANode: TsdIDTreeNode): Integer;
  1477. function GetCount(ANode: TsdIDTreeNode): Integer;
  1478. var sPath: string;
  1479. begin
  1480. if not Assigned(ANode) then Exit;
  1481. Result := 0;
  1482. if ANode.Rec.ValueByName('Type').AsInteger = 0 then
  1483. Result := Result + 0
  1484. else
  1485. begin
  1486. sPath := GetMyProjectsFilePath + 'Attachment\' + ANode.Rec.ValueByName('FileName').AsString + '\';
  1487. Result := Result + FileCount(sPath) - 1;
  1488. end;
  1489. if Assigned(ANode.FirstChild) then
  1490. Result := Result + GetCount(ANode.FirstChild);
  1491. if Assigned(ANode.NextSibling) then
  1492. Result := Result + GetCount(ANode.NextSibling);
  1493. end;
  1494. begin
  1495. if not Assigned(ANode) then Exit;
  1496. if Assigned(ANode.FirstChild) then
  1497. Result := GetCount(ANode.FirstChild)
  1498. else
  1499. Result := 0;
  1500. end;
  1501. procedure TProjectManagerFrame.BubbleSortProjects;
  1502. // 不能排最顶层
  1503. procedure BubbleSort(ANode: TsdIDTreeNode);
  1504. var n, t, c, temp: Integer;
  1505. bSwap: Boolean;
  1506. vNode1, vNode2, vTempNode: TsdIDTreeNode;
  1507. begin
  1508. if ANode = nil then Exit;
  1509. // if ANode.Rec.ValueByName('WebFolderLevel').AsInteger = G_WFL_ProjName then Exit;
  1510. n := ANode.ChildCount;
  1511. for t := 1 to n - 1 do
  1512. begin
  1513. bSwap := False;
  1514. for c := 1 to (n - t) do
  1515. begin
  1516. vNode1 := ANode.ChildNodes[c - 1];
  1517. vNode2 := ANode.ChildNodes[c];
  1518. if AnsiCompareStr(vNode1.Rec.ValueByName('Name').AsString,
  1519. vNode2.Rec.ValueByName('Name').AsString) = 1 then
  1520. begin
  1521. vNode1.DownMove;
  1522. bSwap := True;
  1523. end;
  1524. end;
  1525. if bSwap = False then Break;
  1526. end;
  1527. if Assigned(ANode.FirstChild) then
  1528. BubbleSort(ANode.FirstChild);
  1529. if Assigned(ANode.NextSibling) then
  1530. BubbleSort(ANode.NextSibling);
  1531. end;
  1532. begin
  1533. BubbleSort(stdProjects.IDTree.FirstNode);
  1534. end;
  1535. procedure TProjectManagerFrame.zgProjectsShowHint(var HintStr: String;
  1536. var CanShow: Boolean; var HintInfo: THintInfo; const ACoord: TPoint);
  1537. var
  1538. vCell: TZjCell;
  1539. vNode: TsdIDTreeNode;
  1540. iLevelWidth: Integer;
  1541. rText: TRect;
  1542. procedure CalcTextRect(var R: TRect);
  1543. var
  1544. DC: HDC;
  1545. iTextHeight: Integer;
  1546. begin
  1547. DC := CreateCompatibleDC(0);
  1548. try
  1549. SelectObject(DC, vCell.Font.Handle);
  1550. iTextHeight := DrawText(DC, PChar(vCell.Text), Length(vCell.Text), R, DT_SINGLELINE or DT_VCenter
  1551. or DT_NOCLIP or DT_CALCRECT);
  1552. finally
  1553. DeleteDC(DC);
  1554. end;
  1555. end;
  1556. begin
  1557. if (ACoord.Y < 1) and (ACoord.X <> 1) then Exit;
  1558. vCell := zgProjects.Cells[ACoord.X, ACoord.Y];
  1559. with HintInfo do
  1560. begin
  1561. vNode := stdProjects.IDTree.Items[ACoord.Y - 1];
  1562. if not Assigned(vNode) then Exit;
  1563. iLevelWidth := (vNode.Level + 1) * 20 + 16;
  1564. rText := CursorRect;
  1565. CalcTextRect(rText);
  1566. if (rText.Right - rText.Left + iLevelWidth > CursorRect.Right - CursorRect.Left) or
  1567. (rText.Right > ClientWidth) then
  1568. begin
  1569. CanShow := True;
  1570. HintStr := vCell.Text;
  1571. GetCursorPos(HintPos);
  1572. end;
  1573. end;
  1574. end;
  1575. <<<<<<< HEAD
  1576. function TProjectManagerFrame.FileDownAndReceive(ADownURL: string; AReceiveKind: Integer): Boolean;
  1577. var sLocalFile, sHint: string;
  1578. bCanImp: Boolean;
  1579. vFileCheck: TTenderFileChecker;
  1580. begin
  1581. Result := False;
  1582. // 下载
  1583. sLocalFile := PHPWeb.UserPath + ExtractFileName(ADownURL);
  1584. if not PHPWeb.DownFile(ADownURL, sLocalFile) then
  1585. begin
  1586. sHint := Format('云端已找到[%s]的新文件,但由于网络原因下载失败!请重试!', [FWebBidName_Local]);
  1587. Application.MessageBox(PChar(sHint), '系统提醒', MB_OK + MB_ICONWARNING);
  1588. Exit;
  1589. end;
  1590. // 接收前先检验原报文件是否正确(审核不通过打回)
  1591. if AReceiveKind = 2 then
  1592. begin
  1593. // 有时原报文件出错:包含了1审2审的数据。
  1594. vFileCheck := TTenderFileChecker.Create;
  1595. try
  1596. // 有一期以上数据,且最新期数据审核状态为原报
  1597. bCanImp := vFileCheck.CheckFileValid(sLocalFile) and (vFileCheck.PhaseCount > 0) and (vFileCheck.AuditStatus = 0);
  1598. if not bCanImp then
  1599. begin
  1600. Application.MessageBox(PChar('已从云端下载原报文件到本地,但文件有错误(包含1审数据)禁止接收!请致电纵横服务人员以获取帮助。'),
  1601. '警告', MB_OK + MB_ICONWARNING);
  1602. Exit;
  1603. end;
  1604. finally
  1605. vFileCheck.Free;
  1606. end;
  1607. {注意: 审核末通过的导入更新,这里的MD5码应取最终审核不通过项目的,否则会带来下载循环问题。
  1608. 问题描述:
  1609. ①编制人运行软件,双击项目,发现审核不通过,自动下载无锁文件,开始新一期,保存关闭。
  1610. ②编制人再次运行软件,双击项目,MD5码不同,自动下载旧的审核不通过文件,覆盖本地。
  1611. ③编制人再次运行软件,双击项目,发现审核不通过,重复①,循环....
  1612. 问:①那里下载无锁文件后不能改成新的MD5码吗?
  1613. 答:不能,因为审核人的项目会变成无锁文件,看不到不通过项目。MD5码只能在上传后更新。
  1614. 且编制人有个交互界面2种选择:a.下载更新不通过项目查看;b.下载更新无锁文件开始新一期。}
  1615. end;
  1616. // 接收更新
  1617. if not ReceiveFile(sLocalFile, (AReceiveKind = 2)) then
  1618. begin
  1619. sHint := Format('已从云端下载新的[%s]到本地[%s],但接收失败,请删除该项目然后重新从云端获取!', [FWebBidName_Local, sLocalFile]);
  1620. Application.MessageBox(PChar(sHint), '系统提醒', MB_OK + MB_ICONWARNING);
  1621. Exit;
  1622. end;
  1623. if FileExists(sLocalFile) then
  1624. DeleteFile(sLocalFile);
  1625. Result := True;
  1626. end;
  1627. // 为了跟PHP的数组兼容,这里限制数组的第一个元素是A[0](不能是A[1])
  1628. procedure TProjectManagerFrame.OnLineChecker(AAr: TOVArr; var ABegin,
  1629. AEnd: Integer);
  1630. var i, j, n: Integer;
  1631. vCS: TCheckStatus;
  1632. begin
  1633. ABegin := 0;
  1634. AEnd := 0;
  1635. n := -1;
  1636. for i := 0 to High(AAr) do
  1637. begin
  1638. vCS := TCheckStatus(StrToInt(AAr[i, 5])-1);
  1639. if vCS = csChecking then
  1640. begin
  1641. n := i - 1; // 非常重要:传入的数组必须从第一个审核人到轮到工作中的那个人的前一个人
  1642. Break;
  1643. end;
  1644. end;
  1645. for i := n downto 0 do
  1646. begin
  1647. if AAr[i, 7] = '1' then // 接口返回的第7列是线上审批标记
  1648. begin
  1649. AEnd := i + 1;
  1650. Break;
  1651. end
  1652. else
  1653. Break;
  1654. end;
  1655. if AEnd = 0 then Exit;
  1656. i := i - 1;
  1657. if i < 0 then
  1658. begin
  1659. ABegin := 1;
  1660. Exit;
  1661. end;
  1662. for j := i downto 0 do
  1663. begin
  1664. if AAr[j, 7] = '0' then
  1665. begin
  1666. ABegin := j + 2;
  1667. Break;
  1668. end
  1669. else
  1670. begin
  1671. if j = 0 then
  1672. ABegin := 1;
  1673. end;
  1674. end;
  1675. =======
  1676. procedure TProjectManagerFrame.actnExportUpdate(Sender: TObject);
  1677. begin
  1678. TAction(Sender).Enabled := Assigned(stdProjects.IDTree.Selected);
  1679. end;
  1680. procedure TProjectManagerFrame.actnOpenBackupFolderUpdate(Sender: TObject);
  1681. begin
  1682. TAction(Sender).Enabled := Assigned(stdProjects.IDTree.Selected) and
  1683. (stdProjects.IDTree.Selected.Rec.ValueByName('Type').AsInteger = 1);
  1684. >>>>>>> 3.1.5
  1685. end;
  1686. end.