| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 | unit StandardBillsDm;interfaceuses  SysUtils, Classes, ADODB, DB, DBClient, Provider, sdIDTree,  UtilMethods, sdDB, sdProvider;type  TStandardBillsData = class(TDataModule)    sdpStdBills: TsdADOProvider;    sddStdBills: TsdDataSet;    sdvStdBills: TsdDataView;  private    FBillsTree: TsdIDTree;    procedure CreateBillsTree;    procedure OpenConnetion(AConnection: TADOConnection);    procedure ExpandFirstNode;  public    constructor Create(AOwner: TComponent); override;    destructor Destroy; override;    procedure Open(AConnection: TADOConnection);    procedure CalcCacheData(ANode:TsdIDTreeNode; AOrder: Integer; AParentPath: String);    procedure RecursiveExportBillsJson(const AFileName: string);    property BillsTree: TsdIDTree read FBillsTree;  end;implementation{$R *.dfm}{ TStandardBillsData }procedure TStandardBillsData.CalcCacheData(ANode: TsdIDTreeNode;  AOrder: Integer; AParentPath: String);var  sNodePath: string;begin  if not Assigned(ANode) then Exit;  ANode.Rec.ValueByName('BillsLevel').AsInteger := ANode.Level + 1;  ANode.Rec.ValueByName('BillsOrder').AsInteger := AOrder;  if AParentPath = '' then    sNodePath := IntToStr(ANode.ID)  else    sNodePath := AParentPath + '.' + IntToStr(ANode.ID);  ANode.Rec.ValueByName('FullPath').AsString := sNodePath;  ANode.Rec.ValueByName('IsLeaf').AsBoolean := not ANode.HasChildren;  CalcCacheData(ANode.FirstChild, 1, sNodePath);  CalcCacheData(ANode.NextSibling, AOrder + 1, AParentPath);end;constructor TStandardBillsData.Create(AOwner: TComponent);begin  inherited;  CreateBillsTree;end;procedure TStandardBillsData.CreateBillsTree;begin  FBillsTree := TsdIDTree.Create;  FBillsTree.KeyFieldName := 'ID';  FBillsTree.ParentFieldName := 'ParentID';  FBillsTree.NextSiblingFieldName := 'NextID';  FBillsTree.AutoExpand := False;end;destructor TStandardBillsData.Destroy;begin  FBillsTree.Free;  inherited;end;procedure TStandardBillsData.ExpandFirstNode;begin  if FBillsTree.FirstNode <> nil then    FBillsTree.FirstNode.Expand;end;procedure TStandardBillsData.Open(AConnection: TADOConnection);begin  OpenConnetion(AConnection);  FBillsTree.DataView := sdvStdBills;  ExpandFirstNode;end;procedure TStandardBillsData.OpenConnetion(AConnection: TADOConnection);begin  sdpStdBills.Connection := AConnection;  sdpStdBills.TableName := 'BillsTree';  sddStdBills.Open;  sdvStdBills.Open;  sddStdBills.AddIndex('idxID', 'ID');  sddStdBills.AddIndex('sdxCode', 'Code');  sddStdBills.AddIndex('sddBCode', 'B_Code');end;procedure TStandardBillsData.RecursiveExportBillsJson(  const AFileName: string);var  sgs: TStrings;  function GetNodeData(ANode: TsdIDTreeNode; AOrder: Integer; AFullPath: string): string;  const    sBillsJson = '"id": %d, "pid": %d, "order": %d, "full_path": "%s", "level": %d, "is_leaf" : %d, ' +                 '"code": "%s", "b_code": "%s", "name": "%s", "unit": "%s"';  begin    Result := Format(sBillsJson, [ANode.ID, ANode.ParentID, AOrder, AFullPath, ANode.Level + 1, Integer(not ANode.HasChildren),         ANode.Rec.ValueByName('Code').AsString, ANode.Rec.ValueByName('B_Code').AsString,         ANode.Rec.ValueByName('Name').AsString, ANode.Rec.ValueByName('Unit').AsString]);  end;  procedure ExportNode(ANode: TsdIDTreeNode; AOrder: Integer; AParentPath: string);  var    sNodePath: string;  begin    if not Assigned(ANode) then Exit;    if AParentPath = '' then      sNodePath := IntToStr(ANode.ID)    else      sNodePath := AParentPath + '-' + IntToStr(ANode.ID);    sgs.Strings[sgs.Count - 1] := sgs.Strings[sgs.Count - 1] + '{';    sgs.Add(Format('  %s', [AnsiToUtf8(GetNodeData(ANode, AOrder, sNodePath))]));    sgs.Add('}');    if Assigned(ANode.NextNode) then      sgs.Strings[sgs.Count - 1] := sgs.Strings[sgs.Count - 1] + ',';    ExportNode(ANode.FirstChild, 1, sNodePath);    ExportNode(ANode.NextSibling, AOrder + 1, AParentPath);  end;begin  sgs := TStringList.Create;  try    sgs.Add('[');    ExportNode(FBillsTree.FirstNode, 1, '');    sgs.Strings[sgs.Count - 1] := sgs.Strings[sgs.Count - 1] + ']';    sgs.SaveToFile(AFileName);  finally    sgs.Free;  end;end;end.
 |