• 业务逻辑与界面元素分离的一次小尝试


    项目中有一个需求,为单据的表头增加自定义项。受制于现在的架构和表头布局自定义的实现机制,自定义项的内容只能预先在IDE里面创建好,而不能通过代码动态创建,只好在单据基类里面预先放入一组控件。由于自定义项本身需要提供编辑、参照、配置、读取与保存等操作,而基类本身已经臃肿不堪,接这个机会尝试一次界面与业务逻辑分离的尝试。因为架构中本身没有数据访问曾的设计和实现,而这个仅仅是作为一个尝试,因此控制类里面并没有对数据访问这块进行分离。类图如下:

    单据表头自定义项控制类

    因为自定义项目前支持的是3个,所以定义了一个常量来描述自定义项的个数,以后如果有扩充,修改这个常量即可。

    详细代码如下:

      1 {
      2   该类用于控制单据表头自定义项。
      3   created by fhying@2012.05.04
      4 }
      5 unit BillTitleCustomItemClass;
      6 
      7 interface
      8 
      9 uses
     10   SysUtils, Classes, Controls, Variants, Dialogs, DB, DBClient, cxEdit, cxDBEdit,
     11   Forms, Messages;
     12 
     13 const
     14   Const_BillTitleCustomItem_MAX = 3;
     15 
     16 type
     17   TBillTitleCustomItem = record
     18         itemindex : Integer; {自定义项序号(1-3)}
     19         itemtype : Integer; {自定义项类型(0编辑、1参照)}
     20         itemdatasource : string; {参照的话,数据来源(目前考虑的是基本信息表,如附加说明)}
     21         itemdatafield : string; {参照的话,数据来源的字段}
     22   end;
     23   TBillTitleCustomItems = array[1..Const_BillTitleCustomItem_MAX] of TBillTitleCustomItem;
     24 
     25   TBillTitleCustomItemClass = class(TComponent)
     26   private
     27     FcdsSQL : TClientDataSet;
     28     FBillType: Integer;
     29     FBillTitleCustomItems : TBillTitleCustomItems;
     30     FBillTitleCustomDataSource: TDataSource;
     31     function GetBillTitleCustomItems: TBillTitleCustomItems;
     32     procedure SetBillTitleCustomDataSource(const Value: TDataSource);
     33   protected
     34     { 根据索引获取自定义项的编辑组件 }
     35     function GetButtonEdit(AItemIndex : Integer) : TcxDBButtonEdit; virtual;
     36     { 初始化自定义项内容 }
     37     procedure InitBillTitleCustomItems;
     38     { 创建cds,用于执行sql语句 }
     39     procedure CreateCDS;
     40     { 保存自定义项配置到数据库 }
     41     function SaveBillTitleCustomItems(AItemIndex : Integer = 0) : Boolean;
     42     { 从数据库读取自定义项配置 }
     43     procedure LoadBillTitleCustomItems;
     44     { 为自定义项编辑组件进行事件绑定 }
     45     procedure BindcxButtonEdits(AItemIndex : Integer = 0); virtual;
     46     { 绑定自定义项组件的按钮单击事件 }
     47     procedure PropertiesButtonClick(Sender: TObject; AButtonIndex: Integer);
     48     { 执行自定义项编辑组件的参照功能 }
     49     procedure Reference(AItemIndex : Integer);
     50     { 打开自定义项的配置界面 }
     51     procedure CustomConfig(AItemIndex : Integer);
     52     { 绑定数据源 }
     53     procedure SetEditDataSource;
     54   public
     55     { 自定义构造函数,传入单据类型。 }
     56     constructor CreateMy(AOwnerForm : TComponent; ABillType : Integer); virtual;
     57     destructor Destroy; override;
     58     { 对外部调用者公布自定义项配置内容 }
     59     property BillTitleCustomItems : TBillTitleCustomItems read GetBillTitleCustomItems;
     60     { 外部调用者给对象设置数据源 }
     61     property BillTitleCustomDataSource : TDataSource read FBillTitleCustomDataSource write SetBillTitleCustomDataSource;
     62   end;
     63 
     64 implementation
     65 
     66 uses BillTitleCustomItemForm, un_DM, un_ShowForm, Main, PDWizard,
     67   BaseBillA, ProdDw, un_ToolsLC;
     68 
     69 { TBillTitleCustomItemClass }
     70 
     71 procedure TBillTitleCustomItemClass.BindcxButtonEdits(AItemIndex : Integer);
     72 var
     73   i : Integer;
     74   procedure BindcxButtonEdit(AItemIndex : Integer);
     75   var
     76     AItemType : Integer;
     77     AEdit : TcxDBButtonEdit;
     78   begin
     79     AItemType := FBillTitleCustomItems[AItemIndex].itemtype;
     80     AEdit := GetButtonEdit(AItemIndex);
     81     if AEdit = nil then
     82       Exit;
     83     case AItemType of
     84     0 : { 编辑 }
     85       begin
     86         AEdit.Properties.Buttons[0].Visible := False;
     87         AEdit.Properties.ReadOnly := False;
     88       end;
     89     1 : { 参照 }
     90       begin
     91         AEdit.Properties.Buttons[0].Visible := True;
     92         AEdit.Properties.ReadOnly := True;      
     93       end;
     94     end;
     95     { 用tag来标记是哪个自定义项 }
     96     AEdit.Tag := AItemIndex;
     97     { 与内置事件绑定 }
     98     AEdit.Properties.OnButtonClick := PropertiesButtonClick;
     99   end;
    100 begin
    101   if AItemIndex = 0 then
    102   begin
    103     for i := 1 to Const_BillTitleCustomItem_MAX do
    104     begin
    105       BindcxButtonEdit(i);
    106     end;
    107   end
    108   else
    109   begin
    110     BindcxButtonEdit(AItemIndex);
    111   end;
    112 end;
    113 
    114 procedure TBillTitleCustomItemClass.CreateCDS;
    115 begin
    116   if FcdsSQL = nil then
    117   begin
    118     FcdsSQL := TClientDataSet.Create(nil);
    119     FcdsSQL.RemoteServer := DM.Con_SubWork;
    120     FcdsSQL.ProviderName := 'dsp_Oper';
    121   end;
    122 end;
    123 
    124 constructor TBillTitleCustomItemClass.CreateMy(AOwnerForm: TComponent;
    125   ABillType: Integer);
    126 begin
    127   inherited Create(AOwnerForm);
    128   FBillType := ABillType;
    129   InitBillTitleCustomItems;
    130   LoadBillTitleCustomItems;
    131   BindcxButtonEdits;
    132 end;
    133 
    134 procedure TBillTitleCustomItemClass.CustomConfig(AItemIndex : Integer);
    135 var
    136   frmBillTitleCustomItem: TfrmBillTitleCustomItem;
    137 begin
    138   frmBillTitleCustomItem := TfrmBillTitleCustomItem.Create(Application);
    139   with frmBillTitleCustomItem do
    140   begin
    141     try
    142       ItemType := FBillTitleCustomItems[ItemIndex].itemtype;
    143       ShowModal;
    144       if ModalResult = mrOK then
    145       begin
    146         FBillTitleCustomItems[AItemIndex].itemtype := ItemType; // 现在只能设置类型。
    147         if SaveBillTitleCustomItems(AItemIndex) then
    148         begin
    149           { 保存前,已经更新了本地变量,所以不需要再从数据库获取一次。及时性要求不需要这样高。 }
    150           {LoadBillTitleCustomItems;}
    151           BindcxButtonEdits(AItemIndex);
    152         end;
    153       end;
    154     finally
    155       Free;
    156     end;
    157   end;
    158 end;
    159 
    160 destructor TBillTitleCustomItemClass.Destroy;
    161 begin
    162   if FcdsSQL <> nil then
    163   begin
    164     FcdsSQL.Close;
    165     FcdsSQL.Free;
    166   end;
    167   inherited;
    168 end;
    169 
    170 function TBillTitleCustomItemClass.GetBillTitleCustomItems: TBillTitleCustomItems;
    171 begin
    172   Result := FBillTitleCustomItems;
    173 end;
    174 
    175 function TBillTitleCustomItemClass.GetButtonEdit(
    176   AItemIndex: Integer): TcxDBButtonEdit;
    177 var
    178   AEditName : string;
    179   AEdit : TComponent;
    180 begin
    181   AEditName := 'edtBillTitleCustomItem' + IntToStr(AItemIndex);
    182   AEdit := TForm(Owner).FindComponent(AEditName);
    183   if (AEdit <> nil) and (AEdit is TcxDBButtonEdit) then
    184     Result := TcxDBButtonEdit(AEdit)
    185   else
    186     Result := nil;
    187 end;
    188 
    189 procedure TBillTitleCustomItemClass.InitBillTitleCustomItems;
    190 var
    191   i : Integer;
    192 begin
    193   for i := 1 to Const_BillTitleCustomItem_MAX do
    194   begin
    195     FBillTitleCustomItems[i].itemindex := i;
    196     FBillTitleCustomItems[i].itemtype := 0;
    197     FBillTitleCustomItems[i].itemdatasource := 'commoninfo';
    198     FBillTitleCustomItems[i].itemdatafield := 'u_Remark';
    199   end;
    200 end;
    201 
    202 procedure TBillTitleCustomItemClass.LoadBillTitleCustomItems;
    203 begin
    204   CreateCDS;
    205   FcdsSQL.CommandText :=
    206     'select * from BillTitleCustomItem where billtype = '+IntToStr(FBillType)+' order by ItemIndex';
    207   FcdsSQL.Open;
    208   with FcdsSQL do
    209   begin
    210     if RecordCount > Const_BillTitleCustomItem_MAX then
    211     begin
    212       Exit;
    213     end;
    214     First;
    215     while not Eof do
    216     begin
    217       FBillTitleCustomItems[RecNo].itemindex := FieldByName('ItemIndex').AsInteger;
    218       FBillTitleCustomItems[RecNo].itemtype := FieldByName('itemtype').AsInteger;
    219       FBillTitleCustomItems[RecNo].itemdatasource := FieldByName('itemdatasource').AsString;
    220       FBillTitleCustomItems[RecNo].itemdatafield := FieldByName('itemdatafield').AsString;
    221 
    222       Next;
    223     end;
    224   end;
    225 end;
    226 
    227 procedure TBillTitleCustomItemClass.PropertiesButtonClick(Sender: TObject;
    228   AButtonIndex: Integer);
    229 begin
    230   case AButtonIndex of
    231   0 : Reference(TcxDBButtonEdit(Sender).Tag);
    232   1 : CustomConfig(TcxDBButtonEdit(Sender).Tag);
    233   end;
    234 end;
    235 
    236 { 因为现在这里只是针对进货单和销售单,且参照仅针对附加说明,所以先这样处理。 }
    237 procedure TBillTitleCustomItemClass.Reference(AItemIndex : Integer);
    238 var
    239   szFieldName : string;
    240 begin
    241   if tclientdataset(BillTitleCustomDataSource.DataSet).ReadOnly then
    242     Exit;
    243 
    244   fm_main.vpSingleType := 13;
    245 
    246   fm_ProdDw := Tfm_ProdDw.create(application);
    247   try
    248     with fm_ProdDw do
    249     begin
    250       fm_ProdDw.vpCalltype := 3;
    251 
    252       T1_Showmodal(fm_ProdDw);
    253       if modalresult = mrok then
    254       begin
    255         szFieldName := 'Item' + IntToStr(AItemIndex);
    256         tclientdataset(BillTitleCustomDataSource.DataSet).Edit;
    257         tclientdataset(BillTitleCustomDataSource.DataSet).FieldByName(szFieldName).AsString := cds_SingleList.FieldByName('U_Remark').AsString;
    258         tclientdataset(BillTitleCustomDataSource.DataSet).Post;
    259       end;
    260     end;
    261   finally
    262     gl_Trans.Info1 := '';
    263     fm_ProdDw.free;
    264   end;
    265 end;
    266 
    267 function TBillTitleCustomItemClass.SaveBillTitleCustomItems(AItemIndex : Integer): Boolean;
    268 var
    269   szSQL : string;
    270   function MakeSaveSQL : string;
    271   var
    272     i : Integer;
    273     szDelete : string;
    274     szTmp : string;
    275   begin
    276     Result := '';
    277     if AItemIndex = 0 then
    278     begin
    279       szDelete := ' delete from BillTitleCustomItem where BillType = '+IntToStr(FBillType);
    280 
    281       for i := 1 to Const_BillTitleCustomItem_MAX do
    282       begin
    283         szTmp := ' insert into BillTitleCustomItem (BillType, itemindex, itemtype, itemdatasource, itemdatafield) values (%d,%d,%d,'+Char(39)+'%s'+Char(39)+','+Char(39)+'%s'+Char(39)+')';
    284         with FBillTitleCustomItems[i] do
    285           szTmp := Format(szTmp, [FBillType, itemindex, itemtype, itemdatasource, itemdatafield]);
    286 
    287         Result := Result + szTmp ;//+ Char(13)+Char(10);
    288       end;
    289     end
    290     else
    291     begin
    292       szDelete := ' delete from BillTitleCustomItem where BillType = '+IntToStr(FBillType) + ' and itemindex =' + IntToStr(AItemIndex);
    293       szTmp := ' insert into BillTitleCustomItem (BillType, itemindex, itemtype, itemdatasource, itemdatafield) values (%d,%d,%d,'+Char(39)+'%s'+Char(39)+','+Char(39)+'%s'+Char(39)+')';
    294       with FBillTitleCustomItems[AItemIndex] do
    295         szTmp := Format(szTmp, [FBillType, AItemIndex, itemtype, itemdatasource, itemdatafield]);
    296       Result := Result + szTmp ;
    297     end;
    298 
    299     Result := szDelete + Result;
    300   end;
    301 begin
    302   szSQL := MakeSaveSQL;
    303   FcdsSQL.CommandText := szSQL;
    304   try
    305     FcdsSQL.Execute;
    306 
    307     Result := True;
    308   except
    309     on e : Exception do
    310     begin
    311       Result := False;
    312       ShowDlg(1, '保存单据表头自定义项设置失败。'+#13+'错误信息:'+#13+e.Message);
    313     end;
    314   end;
    315 end;          
    316 
    317 procedure TBillTitleCustomItemClass.SetBillTitleCustomDataSource(
    318   const Value: TDataSource);
    319 begin
    320   FBillTitleCustomDataSource := Value;
    321   SetEditDataSource;
    322 end;
    323 
    324 procedure TBillTitleCustomItemClass.SetEditDataSource;
    325 var
    326   i : Integer;
    327   AEdit : TcxDBButtonEdit;
    328 begin
    329   for i := 1 to Const_BillTitleCustomItem_MAX do
    330   begin
    331     AEdit := GetButtonEdit(i);
    332     AEdit.DataBinding.DataSource := BillTitleCustomDataSource;
    333     AEdit.DataBinding.DataField := 'Item'+IntToStr(i);
    334   end;
    335 end;
    336 
    337 end.

    此外,对于多账户支付的功能,我也用类似的思路设计了一个类,但是感觉里面比较紊乱,应该能够分得更清晰,降低耦合,增强内聚。请达者指教。谢谢。

    多账户支付控制类

  • 相关阅读:
    安卓触摸事件探究
    android关于canvas,path,paint非常好的讲解
    android的Shader
    android中view的生命周期
    JAVA的Random类(转)
    lniux 64位导致adb无法运行解决方案
    [转]Android中attrs.xml文件的使用详解
    FlowLayout
    大数据平台架构技术选型与场景运用(转)
    mysql--java类型对应表
  • 原文地址:https://www.cnblogs.com/codingnote/p/2491373.html
Copyright © 2020-2023  润新知