<xmp id="63nn9"><video id="63nn9"></video></xmp>

<xmp id="63nn9"></xmp>

<wbr id="63nn9"><ins id="63nn9"></ins></wbr>

<wbr id="63nn9"></wbr><video id="63nn9"><ins id="63nn9"><table id="63nn9"></table></ins></video>

Blazor實戰——Known框架單表增刪改查導

本章介紹學習增、刪、改、查、導功能如何實現,下面以商品資料作為示例,該業務欄位如下:

類型、編碼、名稱、規格、單位、庫存下限、庫存上限、備注

1. 前后端共用

1.1. 創建實體類

  • 在KIMS項目Entities文件夾下創建KmGoods實體類
  • 該類繼承EntityBase類
  • 屬性使用Column特性描述,用于生成頁面字段和數據校驗
public class KmGoods : EntityBase
{
    [Column("商品類型", "", true, "1", "50")]
    public string? Type { get; set; }
	......
    [Column("庫存下限", "", false)]
    public decimal? MinStock { get; set; }
	......
    [Column("備注", "", false)]
    public string? Note { get; set; }
}

1.2. 創建Client類

  • 在KIMS項目Clients文件夾下創建GoodsClient類
  • 該類是前后端數據交互接口,繼承ClientBase類
  • 該類只需提供分頁查詢、刪除和保存,導入功能由框架統一異步處理
public class GoodsClient : ClientBase
{
    public GoodsClient(Context context) : base(context) { }

    public Task<PagingResult<KmGoods>> QueryGoodsesAsync(PagingCriteria criteria) => Context.QueryAsync<KmGoods>("Goods/QueryGoodses", criteria);
    public Task<Result> DeleteGoodsesAsync(List<KmGoods> models) => Context.PostAsync("Goods/DeleteGoodses", models);
    public Task<Result> SaveGoodsAsync(object model) => Context.PostAsync("Goods/SaveGoods", model);
}

2. 前端

2.1. 創建List頁面

  • 在KIMS.Razor項目BaseData文件夾下創建GoodsList類
  • 該類是數據列表頁面,繼承WebGridView<KmGoods, GoodsForm>類
  • 列表頁面按鈕和欄位在框架模塊管理中配置
class GoodsList : WebGridView<KmGoods, GoodsForm>
{
    //分頁查詢
    protected override Task<PagingResult<KmGoods>> OnQueryData(PagingCriteria criteria)
    {
        return Client.Goods.QueryGoodsesAsync(criteria);
    }
    //表格欄位格式化顯示
    protected override void FormatColumns()
    {
        Column(c => c.Type).Select(new SelectOption { Codes = AppDictionary.GoodsType });
        Column(c => c.TaxRate).Template((b, r) => b.Text(r.TaxRate?.ToString("P")));
    }

    public void New() => ShowForm();//新增按鈕方法
    public void DeleteM() => DeleteRows(Client.Goods.DeleteGoodsesAsync);//批量刪除按鈕方法
    public void Edit(KmGoods row) => ShowForm(row);//編輯操作方法
    public void Delete(KmGoods row) => DeleteRow(row, Client.Goods.DeleteGoodsesAsync);//刪除操作方法
}

2.2. 創建Form頁面

  • 在KIMS.Razor項目BaseData\Forms文件夾下創建GoodsForm類
  • 該類是數據編輯和查看明細頁面,繼承WebForm
[Dialog(800, 420)]//設置對話框大小
class GoodsForm : WebForm<KmGoods>
{
    //表單布局
    protected override void BuildFields(FieldBuilder<KmGoods> builder)
    {
        builder.Hidden(f => f.Id);//隱藏字段
        builder.Table(table =>
        {
            table.ColGroup(15, 35, 15, 35);
            table.Tr(attr =>
            {
                table.Field<Text>(f => f.Code).Enabled(TModel.IsNew).Build();//編碼,編輯時灰顯
                table.Field<Text>(f => f.Name).Build();
            });
            table.Tr(attr =>
            {
                table.Field<Select>(f => f.Type).Set(f => f.Codes, AppDictionary.GoodsType).Build();//下拉框
                table.Field<Select>(f => f.Unit).Set(f => f.Codes, AppDictionary.GoodsUnit).Build();
            });
            table.Tr(attr => table.Field<Text>(f => f.Model).ColSpan(3).Build());
            table.Tr(attr => table.Field<RadioList>(f => f.TaxRate).ColSpan(3).Set(f => f.Items, AppDictionary.TaxRates).Build());//單選按鈕
            table.Tr(attr =>
            {
                table.Field<Number>(f => f.MinStock).Build();//數值框
                table.Field<Number>(f => f.MaxStock).Build();
            });
            table.Tr(attr => table.Field<TextArea>(f => f.Note).ColSpan(3).Build());//文本域
        });
    }
    //表單底部按鈕
    protected override void BuildButtons(RenderTreeBuilder builder)
    {
        builder.Button(FormButton.Save, Callback(OnSave), !ReadOnly);
        base.BuildButtons(builder);
    }
    //保存按鈕方法
    private void OnSave() => SubmitAsync(Client.Goods.SaveGoodsAsync);
}

3. 后端

3.1. 創建Controller類

  • 在KIMS.Core項目Controllers文件夾下創建GoodsController類
  • 該類為服務端WebApi,繼承BaseController類
[Route("[controller]")]
public class GoodsController : BaseController
{
    private GoodsService Service => new(Context);

    [HttpPost("[action]")]
    public PagingResult<KmGoods> QueryGoodses([FromBody] PagingCriteria criteria) => Service.QueryGoodses(criteria);

    [HttpPost("[action]")]
    public Result DeleteGoodses([FromBody] List<KmGoods> models) => Service.DeleteGoodses(models);

    [HttpPost("[action]")]
    public Result SaveGoods([FromBody] object model) => Service.SaveGoods(GetDynamicModel(model));//轉成dynamic類型
}

3.2. 創建Service類

  • 在KIMS.Core項目Services文件夾下創建GoodsService類
  • 該類為業務邏輯服務類,繼承ServiceBase類
class GoodsService : ServiceBase
{
    internal GoodsService(Context context) : base(context) { }
    //分頁查詢
    internal PagingResult<KmGoods> QueryGoodses(PagingCriteria criteria)
    {
        return GoodsRepository.QueryGoodses(Database, criteria);
    }
    //刪除數據
    internal Result DeleteGoodses(List<KmGoods> models)
    {
        if (models == null || models.Count == 0)
            return Result.Error(Language.SelectOneAtLeast);

        //此處增加刪除數據校驗
        return Database.Transaction(Language.Delete, db =>
        {
            foreach (var item in models)
            {
                db.Delete(item);
            }
        });
    }
    //保存數據
    internal Result SaveGoods(dynamic model)
    {
        var entity = Database.QueryById<KmGoods>((string)model.Id);
        entity ??= new KmGoods { CompNo = CurrentUser.CompNo };
        entity.FillModel(model);
        var vr = entity.Validate();
        if (vr.IsValid)
        {
            if (GoodsRepository.ExistsGoods(Database, entity))
                return Result.Error("商品編碼已存在。");
        }

        if (!vr.IsValid)
            return vr;

        return Database.Transaction(Language.Save, db =>
        {
            if (entity.IsNew)
            {
                entity.Code = GetGoodsMaxNo(db);
            }
            db.Save(entity);
        }, entity.Id);
    }
    //獲取商品最大編碼
    private static string GetGoodsMaxNo(Database db)
    {
        var prefix = "G";
        var maxNo = GoodsRepository.GetGoodsMaxNo(db, prefix);
        if (string.IsNullOrWhiteSpace(maxNo))
            maxNo = $"{prefix}0000";
        return GetMaxFormNo(prefix, maxNo);
    }
}

3.3. 創建Repository類

  • 在KIMS.Core項目Repositories文件夾下創建GoodsRepository類
  • 該類為數據訪問類
class GoodsRepository
{
    //分頁查詢
    internal static PagingResult<KmGoods> QueryGoodses(Database db, PagingCriteria criteria)
    {
        var sql = "select * from KmGoods where CompNo=@CompNo";
        return db.QueryPage<KmGoods>(sql, criteria);//查詢條件自動綁定
    }
    //獲取商品最大編碼
    internal static string GetGoodsMaxNo(Database db, string prefix)
    {
        var sql = $"select max(Code) from KmGoods where CompNo=@CompNo and Code like '{prefix}%'";
        return db.Scalar<string>(sql, new { db.User.CompNo });
    }
    //判斷商品是否已存在
    internal static bool ExistsGoods(Database db, KmGoods entity)
    {
        var sql = "select count(*) from KmGoods where Id<>@Id and Code=@Code";
        return db.Scalar<int>(sql, new { entity.Id, entity.Code }) > 0;
    }
}

3.4. 創建Import類

  • 在KIMS.Core項目Imports文件夾下創建KmGoodsImport類(約定:類名以實體類名+Import)
  • 該類為數據異步導入處理類,由框架自動調用,繼承BaseImport類
class KmGoodsImport : BaseImport
{
    public KmGoodsImport(Database database) : base(database) { }
    //定義導入欄位,自動生成導入規范
    public override List<ImportColumn> Columns
    {
        get
        {
            return new List<ImportColumn>
            {
                new ImportColumn("商品類型", true),
                new ImportColumn("商品編碼", true),
                new ImportColumn("商品名稱", true),
                new ImportColumn("計量單位", true),
                new ImportColumn("規格型號", true),
                new ImportColumn("稅率"),
                new ImportColumn("庫存下限"),
                new ImportColumn("庫存上限"),
                new ImportColumn("備注")
            };
        }
    }
    //異步導入處理邏輯
    public override Result Execute(SysFile file)
    {
        var models = new List<KmGoods>();
        var result = ImportHelper.ReadFile(file, row =>
        {
            var model = new KmGoods
            {
                CompNo = file.CompNo,
                Type = row.GetValue("商品類型"),
                Code = row.GetValue("商品編碼"),
                Name = row.GetValue("商品名稱"),
                Unit = row.GetValue("計量單位"),
                Model = row.GetValue("規格型號"),
                TaxRate = row.GetValue<decimal?>("稅率"),
                MinStock = row.GetValue<decimal?>("庫存下限"),
                MaxStock = row.GetValue<decimal?>("庫存上限"),
                Note = row.GetValue("備注")
            };
            var vr = model.Validate();
            if (vr.IsValid)
            {
                if (models.Exists(m => m.Code == model.Code))
                    vr.AddError("商品編碼不能重復!");
                else if (GoodsRepository.ExistsGoods(Database, model))
                    vr.AddError($"系統已經存在該商品編碼!");
            }

            if (!vr.IsValid)
                row.ErrorMessage = vr.Message;
            else
                models.Add(model);
        });

        if (!result.IsValid)
            return result;

        return Database.Transaction("導入", db =>
        {
            foreach (var item in models)
            {
                db.Save(item);
            }
        });
    }
}

4. 運行測試

  • 運行效果如下
    輸入圖片說明
    輸入圖片說明

5. 相關資料

posted @ 2023-05-25 08:36  known  閱讀(423)  評論(2編輯  收藏  舉報
人碰人摸人爱免费视频播放

<xmp id="63nn9"><video id="63nn9"></video></xmp>

<xmp id="63nn9"></xmp>

<wbr id="63nn9"><ins id="63nn9"></ins></wbr>

<wbr id="63nn9"></wbr><video id="63nn9"><ins id="63nn9"><table id="63nn9"></table></ins></video>