| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373 | {*******************************************************************************  单元名称:  CheckerFme.pas  单元说明:  审核人窗口。  作者时间:  Chenshilong, 2014-07-11*******************************************************************************}unit CheckerFme;interfaceuses  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  Dialogs, ExtCtrls, StdCtrls, OrderCheckerFme, JimLabels, Contnrs, Checker;type  TCheckerFrame = class(TFrame)    pnlProject: TPanel;    sbChecker: TScrollBox;    pnlTitle: TPanel;    labTitle: TJimGradLabel;    tRefreshCheckers: TTimer;    procedure tRefreshCheckersTimer(Sender: TObject);  private    FProjectData: TObject;    FCount: Integer;    FOwner: TObject;    FOwnerFrame: TOrderCheckerFrame;    FAddFrame: TOrderCheckerFrame;    FList: TObjectList;          // Add窗也进FList    FCurPos: Integer;    procedure SetProjectData(const Value: TObject);    procedure SetOwner(const Value: TObject);    { Private declarations }  public    { Public declarations }    property ProjectData: TObject read FProjectData write SetProjectData;    property Owner: TObject read FOwner write SetOwner;    property OwnerFrame: TOrderCheckerFrame read FOwnerFrame write FOwnerFrame;  // 这个特指终审人的Frame    property AddFrame: TOrderCheckerFrame read FAddFrame write FAddFrame;        // 这个特指新增人的Frame    property List: TObjectList read FList;    property CurPos: Integer read FCurPos write FCurPos;    constructor Create(AOwner: TComponent); override;    destructor Destroy; override;    procedure Init;    // 审核人的名字、职位、公司、图像    procedure AddNewChecker(AType: TCheckerFrameType; AID: Integer; AName,      ARole, ACompany, AImagePath, ACheckerMemo: string; ACheckStatus: TCheckStatus;      ACheckeTime: string; ACheckeOnLine: Integer);    function InCheckerList(ACheckerID: Integer): Boolean;    function HasNormalChecker: Boolean;        // 有普通审核人就返回True(光有业主不算)    function HasChecker: Boolean;              // 列表不为空即返回True(光Add也算)    procedure CheckerNameList(var ASL: TStringList);    procedure RepairOrder;    procedure RepairDelete(ACanDelete: Boolean);    function FirstChecker: TOrderCheckerFrame;    function NextChecker: TOrderCheckerFrame;    function LastChecker: TOrderCheckerFrame;    function Me: TOrderCheckerFrame;    function CheckNo(ACheckStatus: TCheckStatus): Integer;                // 返回指定的审核状态是列表中的第几个人  end;implementationuses FindUserFrm, PHPWebDm, ProjectData, CslJson, ConstUnit, ProjectFme;{$R *.dfm}procedure TCheckerFrame.AddNewChecker(AType: TCheckerFrameType; AID: Integer;  AName, ARole, ACompany, AImagePath, ACheckerMemo: string; ACheckStatus: TCheckStatus;  ACheckeTime: string; ACheckeOnLine: Integer);var vChecker: TOrderCheckerFrame;begin  vChecker := TOrderCheckerFrame.Create(Self);  vChecker.Owner := Self;  vChecker.Init(AType, AID, AName, ARole, ACompany, AImagePath, ACheckerMemo, ACheckStatus, ACheckeTime, ACheckeOnLine);  sbChecker.Height := sbChecker.Height + vChecker.Height;  vChecker.Parent := sbChecker;  vChecker.Top := FCurPos;  FCurPos := FCurPos + vChecker.Height;  vChecker.Align := alTop;  // 调整位置  case AType of    cftChecker:    begin      vChecker.Name := 'OrderFrame' + IntToStr(AID);      if Assigned(AddFrame) then       // 适用于查找审核人添加数据库后,插入Add窗之前      begin        vChecker.Top := AddFrame.Top;        AddFrame.Top := vChecker.Top + vChecker.Height;        OwnerFrame.Top := AddFrame.Top + AddFrame.Height;        FList.Insert(FList.Indexof(AddFrame), vChecker);      end      else        FList.Add(vChecker);    end;    cftOwner:      // 保险,保证终审窗一定在Add窗之后    begin      OwnerFrame := vChecker;      vChecker.Name := 'OwnerFrame';      if Assigned(AddFrame) then        OwnerFrame.Top := AddFrame.Top + AddFrame.Height;      FList.Add(vChecker);    end;    cftAdd:        // Add窗插入到终审窗之前    begin      AddFrame := vChecker;      vChecker.Name := 'AddFrame';      if Assigned(OwnerFrame) then      begin        AddFrame.Top := OwnerFrame.Top;        OwnerFrame.Top := AddFrame.Top + AddFrame.Height;        FList.Insert(FList.Indexof(OwnerFrame), vChecker);      end      else        FList.Add(vChecker);    end;  end;end;procedure TCheckerFrame.Init;var  i, iIndex: Integer;  vA: TOVArr;  sURL, sPicPath, sID, sErrors: string;  vProj: TProjectData;  bOwner, bOwnerFinish: Boolean;  vStatus: TCheckStatus;  vCM: TChecker;begin  FList.Clear;  OwnerFrame := nil;  AddFrame := nil;  sbChecker.Height := 0;  FCurPos := 0;  vProj := TProjectData(FProjectData);  vProj.Checkers.Clear;    // 这里,这里搞死爹...编制人第一期上报后,关掉项目,重新打开这个项目,第一次,  // 我说的是第一次——一定读取不了审核人列表,但第二次、以后每次都正常。你知道  // 读取不了这个列表的后果有多严重吗?网络版的每个角落都依赖于审核人的角色,所  // 以后果就是直接崩溃,无法使用。查明原因:服务器那头的PHP第一次接收不了传上  // 去的数据,日志显示读取到的数组为空。  // 所以这里把参数移到URL中,通过URL的方式传递,避开用数组传递,问题解决。  // 很明显,这种方式的局限性很大,只适合参数较少的情况。该问题已被珠海纵横公司  // 计量支付网络版研发团队定性为PHP业界的灵异事件。如果哪天你用科学解释了它,请  // 一定要告诉我个中缘由。chenshilong, 2014-07-21  sURL := Format('%suser/get/all/%d/%d/measure', [PHPWeb.MeasureURL, vProj.WebID, vProj.PhaseIndex]);  if PHPWeb.Search(sURL, [''], [''], vA) = 1 then  begin    for i := Low(vA) to High(vA) do    begin      sID := vA[i, 4];      sPicPath := PHPWeb.UserPath + '1_' + sID + '.jpg';      PHPWeb.DownFile(vA[i, 5], sPicPath);      vStatus :=  TCheckStatus(StrToInt(vA[i, 3])-1);  // Json返回1、2、3、4      bOwner := StrToInt(sID) = TProjectData(ProjectData).WebOwnerID;      if bOwner then   // 添加业主      begin        if TProjectData(ProjectData).CurUserIsAuthor then        begin         {如果是编制人,添加业主前先添加Add框。         数据库中,编制人没有审核人这样的状态。只有跟随标段的两种状态:         ①有标段(顺便记录了编制人,标段是编制人创建的) ②没有标段。         为什么不通过是否有标段来判断当前是否显示“添加新的审核人”呢?         因为无法得知当前项目是数据库中已存在的最新一期还是仅存于本地尚末入库         的最新一期。改由添加的位置给出提示}         if (TProjectData(ProjectData).PhaseIndex > 0) and (not TProjectFrame(Owner).IsUped) then           AddNewChecker(cftAdd, -1, '', '', '', '', '', csNotBegin, '', -1);        end;        AddNewChecker(cftOwner, StrToInt(sID),          vA[i, 0], vA[i, 2], vA[i, 1], sPicPath, vA[i, 6], vStatus, vA[i, 8], StrToInt(vA[i, 7]));      end      else        AddNewChecker(cftChecker, StrToInt(vA[i, 4]),          vA[i, 0], vA[i, 2], vA[i, 1], sPicPath, vA[i, 6], vStatus, vA[i, 8], StrToInt(vA[i, 7]));      vCM := TChecker.Create;      iIndex := vProj.Checkers.Add(StrToInt(vA[i, 4]), vA[i, 0], vA[i, 2], vA[i, 6], vA[i, 8]);      if vStatus in [csFinished, csNotPass] then        vProj.Checkers.LastChecker := vProj.Checkers.Item[iIndex];    end;    RepairOrder;  end  else  begin    sErrors := Format('无法读取审批人列表,这将会导致桌面程序崩溃!%s地址:%s%s标段ID:%s,期号:%s',      [#13#10#13#10, sURL, #13#10#13#10, IntToStr(vProj.WebID), IntToStr(vProj.PhaseIndex)]);    Application.MessageBox(PChar(sErrors), '错误', MB_OK + MB_ICONERROR);    Application.Terminate;  end;end;procedure TCheckerFrame.SetProjectData(const Value: TObject);begin  FProjectData := Value;end;function TCheckerFrame.InCheckerList(ACheckerID: Integer): Boolean;var i: Integer;begin  Result := False;  for i := 0 to FList.Count - 1 do  begin    if TOrderCheckerFrame(FList[i]).UserID = ACheckerID then    begin      Result := True;      Break;    end;  end;end;procedure TCheckerFrame.CheckerNameList(var ASL: TStringList);var i: Integer;  vFrame: TOrderCheckerFrame;begin  ASL.Clear;  for i := 0 to FList.Count - 1 do  begin    vFrame := TOrderCheckerFrame(FList[i]);    if vFrame.CheckerFrameType <> cftAdd then      ASL.Add(Format('%s', [vFrame.UserName]));  end;end;procedure TCheckerFrame.SetOwner(const Value: TObject);begin  FOwner := Value;end;procedure TCheckerFrame.RepairOrder;var i: Integer;begin  for i := 0 to FList.Count - 1 do    TOrderCheckerFrame(FList[i]).Order := i + 1;end;function TCheckerFrame.HasNormalChecker: Boolean;var i: Integer;begin  Result := False;  for i := 0 to FList.Count - 1 do  begin    if TOrderCheckerFrame(FList[i]).CheckerFrameType = cftChecker then    begin      Result := True;      Break;    end;  end;end;constructor TCheckerFrame.Create(AOwner: TComponent);begin  inherited;  FList := TObjectList.Create;end;destructor TCheckerFrame.Destroy;begin  FList.Free;  inherited;end;function TCheckerFrame.FirstChecker: TOrderCheckerFrame;begin  Result := nil;  if FList.Count > 0 then  begin    if TOrderCheckerFrame(FList[0]).CheckerFrameType <> cftAdd then      Result := TOrderCheckerFrame(FList[0])    else      Result := TOrderCheckerFrame(FList[1]);  end;end;function TCheckerFrame.NextChecker: TOrderCheckerFrame;var i: Integer;  vFrame: TOrderCheckerFrame;begin  Result := nil;  if FList.Count = 0 then Exit;  for i := 0 to FList.Count - 1 do  begin    if (TOrderCheckerFrame(FList[i]).UserID = PHPWeb.UserID) then    begin      if i = (FList.Count - 1) then Exit;     // 最后一个      Result := TOrderCheckerFrame(FList[i + 1]);      if Result.CheckerFrameType = cftAdd then        Result := TOrderCheckerFrame(FList[i + 2]);      Break;    end;  end;end;function TCheckerFrame.Me: TOrderCheckerFrame;var i: Integer;begin  Result := nil;  for i := 0 to FList.Count - 1 do  begin    if TOrderCheckerFrame(FList[i]).UserID = PHPWeb.UserID then    begin      Result := TOrderCheckerFrame(FList[i]);      Break;    end;  end;end;procedure TCheckerFrame.RepairDelete(ACanDelete: Boolean);var i: Integer;begin  for i := 0 to FList.Count - 1 do  begin    if (TOrderCheckerFrame(FList[i]) <> OwnerFrame) and      (TOrderCheckerFrame(FList[i]) <> AddFrame) then    begin      TOrderCheckerFrame(FList[i]).lblOrderStatus.Visible := (not ACanDelete);      TOrderCheckerFrame(FList[i]).btnDelete.Visible := ACanDelete;    end;  end;end;procedure TCheckerFrame.tRefreshCheckersTimer(Sender: TObject);begin  tRefreshCheckers.Enabled := False;  try    init;    RepairDelete(True);  except    ShowMessage('删除成功,这里做了异常保护');  end;end;function TCheckerFrame.HasChecker: Boolean;begin  Result := (FList.Count > 0);end;function TCheckerFrame.CheckNo(ACheckStatus: TCheckStatus): Integer;var i, iCount: Integer;begin  Result := -1;    for i := 0 to FList.Count - 1 do  begin    if TOrderCheckerFrame(FList[i]).CheckStatus = ACheckStatus then    begin      Result := i + 1;      Break;    end;  end;end;function TCheckerFrame.LastChecker: TOrderCheckerFrame;var i: Integer;begin  Result := FOwnerFrame;end;end.
 |