Known框架實戰演練——進銷存基礎資料

known發表於2024-07-23

本文介紹如何實現進銷存管理系統的基礎資料模組,基礎資料模組包括商品資訊、供應商管理和客戶管理3個選單頁面。供應商和客戶欄位相同,因此可共用一個頁面元件類。

  • 專案程式碼:JxcLite
  • 開源地址: https://gitee.com/known/JxcLite

1. 配置模組

執行專案,在【系統管理-模組管理】中新增商品資訊、供應商管理、客戶管理3個模組選單,模組基本資訊、模型、頁面、表單設定之前有影片教程,這裡不再細說了。

2. 實體類

JxcLite專案Entities資料夾下面新增JxGoods.csJxPartner.cs兩個實體類檔案,實體類程式碼可以直接複製模組管理中由模型設定生成的程式碼。文章中只簡單描述一下實體類的定義,具體程式碼參見開源,程式碼定義如下:

namespace JxcLite.Entities;

/// <summary>
/// 商品資訊類。
/// </summary>
public class JxGoods : EntityBase { }

/// <summary>
/// 商業夥伴資訊類。
/// </summary>
public class JxPartner : EntityBase { }

3. 建表指令碼

最理想的情況是:在系統安裝時,透過實體類和資料庫型別自動生成建表指令碼建立實體資料庫表。這裡還是用傳統手動方式執行建表指令碼,在JxcLite.Web專案Resources資料夾下新增Tables.sql資原始檔,複製貼上由【模組管理-模型設定】中生成的建表指令碼。文章中只簡單描述一下建表指令碼,具體指令碼參見開源,內容如下:

CREATE TABLE [JxGoods] (
    [Id]         varchar(50)      NOT NULL PRIMARY KEY,
    ...
    [Files]      nvarchar(500)    NULL
);

CREATE TABLE [JxPartner] (
    [Id]         varchar(50)      NOT NULL PRIMARY KEY,
    ...
    [Note]       ntext            NULL,
    [Files]      nvarchar(500)    NULL
);

4. 服務介面

JxcLite專案Services資料夾下面新增基礎資料模組服務介面類,檔名定義為IBaseDataService.cs,該介面定義前後端互動的Api訪問方法,包括分頁查詢、批次刪除實體、儲存實體。具體方法定義如下:

namespace JxcLite.Services;

public interface IBaseDataService : IService
{
    //分頁查詢商品資訊
    Task<PagingResult<JxGoods>> QueryGoodsesAsync(PagingCriteria criteria);
    //批次刪除商品資訊
    Task<Result> DeleteGoodsesAsync(List<JxGoods> models);
    //儲存商品資訊
    Task<Result> SaveGoodsAsync(UploadInfo<JxGoods> info);

    //分頁查詢供應商和客戶資訊
    Task<PagingResult<JxPartner>> QueryPartnersAsync(PagingCriteria criteria);
    //批次刪除供應商和客戶資訊
    Task<Result> DeletePartnersAsync(List<JxPartner> models);
    //儲存供應商和客戶資訊
    Task<Result> SavePartnerAsync(UploadInfo<JxPartner> info);
}

5. 服務實現

JxcLite.Web專案Services資料夾下面新增基礎資料模組服務介面的實現類,檔名定義為BaseDataService.cs,文章中只簡單描述一下實現類的定義和繼承,具體實現參見開源,定義如下:

namespace JxcLite.Web.Services;

class BaseDataService(Context context) : ServiceBase(context), IBaseDataService
{
    public Task<PagingResult<JxGoods>> QueryGoodsesAsync(PagingCriteria criteria) { }
    public Task<Result> DeleteGoodsesAsync(List<JxGoods> models) { }
    public Task<Result> SaveGoodsAsync(UploadInfo<JxGoods> info) { }

    public Task<PagingResult<JxPartner>> QueryPartnersAsync(PagingCriteria criteria) { }
    public Task<Result> DeletePartnersAsync(List<JxPartner> models) { }
    public Task<Result> SavePartnerAsync(UploadInfo<JxPartner> info) { }
}

雙擊開啟JxcLite.Web專案中的AppWeb.cs檔案,在AddJxcLiteCore方法中註冊服務類,前端元件可以透過依賴注入工廠建立服務的例項。程式碼如下:

public static class AppWeb
{
    public static void AddJxcLiteCore(this IServiceCollection services)
    {
        services.AddScoped<IBaseDataService, BaseDataService>();
    }
}

6. 資料依賴

JxcLite.Web專案Repositories資料夾下面新增基礎資料模組資料依賴類,檔名定義為BaseDataRepository.cs,文章中只簡單描述一下依賴類的定義,具體實現參見開源,定義如下:

namespace JxcLite.Web.Repositories;

class BaseDataRepository
{
    internal static Task<PagingResult<JxGoods>> QueryGoodsesAsync(Database db, PagingCriteria criteria) { }

    internal static async Task<bool> ExistsGoodsCodeAsync(Database db, JxGoods model) { }

    internal static Task<PagingResult<JxPartner>> QueryPartnersAsync(Database db, PagingCriteria criteria) { }

    internal static async Task<bool> ExistsPartnerNameAsync(Database db, JxPartner model) { }
}

7. 資料匯入類

JxcLite.Web專案Imports資料夾下面新增商品資訊、供應商和客戶的匯入類,檔名定義為JxGoodsImport.csJxPartnerImport.cs匯入類名稱命名規範是:實體類名+Import,匯入框架自動根據名稱識別,文章中只簡單描述一下匯入類的定義,具體實現參見開源,定義如下:

namespace JxcLite.Web.Imports;

class JxGoodsImport(ImportContext context) : ImportBase<JxGoods>(context)
{
    //初始化匯入欄位,自動生成匯入規範Excel檔案
    public override void InitColumns() { }
    //執行匯入檔案
    public override async Task<Result> ExecuteAsync(SysFile file) { }
}

class JxPartnerImport(ImportContext context) : ImportBase<JxPartner>(context)
{
    public override void InitColumns() { }
    public override async Task<Result> ExecuteAsync(SysFile file) { }
}

8. 前端頁面

JxcLite.Client專案Pages\BaseData資料夾下面新增商品資訊和商業夥伴頁面類,檔名定義為GoodsList.csPartnerList.cs,這3個模組的功能和頁面非常簡單,只有單表的增刪改查導功能,表單頁面直接透過線上表單進行配置。列表頁面繼承BaseTablePage類,由於該框架類封裝了列表頁面常用的增刪改查導功能,因此具體的功能列表頁面程式碼顯得格外簡單,只需要定義各操作的服務呼叫方法即可,具體的完整程式碼如下:

  • 商品資訊頁面
namespace JxcLite.Client.Pages.BaseData;

[StreamRendering]
[Route("/bds/goods")]
public class GoodsList : BaseTablePage<JxGoods>
{
    private IBaseDataService Service;

    protected override async Task OnPageInitAsync()
    {
        await base.OnPageInitAsync();
        Service = await CreateServiceAsync<IBaseDataService>();
        Table.OnQuery = Service.QueryGoodsesAsync;
    }

    public void New() => Table.NewForm(Service.SaveGoodsAsync, new JxGoods());
    public void DeleteM() => Table.DeleteM(Service.DeleteGoodsesAsync);
    public void Edit(JxGoods row) => Table.EditForm(Service.SaveGoodsAsync, row);
    public void Delete(JxGoods row) => Table.Delete(Service.DeleteGoodsesAsync, row);
    public void Import() => ShowImportForm();
    public async void Export() => await ExportDataAsync();
}
  • 供應商和客戶頁面
[StreamRendering]
[Route("/bds/suppliers")]
public class SupplierList : PartnerList
{
    protected override string Type => PartnerType.Supplier;
}

[StreamRendering]
[Route("/bds/customers")]
public class CustomerList : PartnerList
{
    protected override string Type => PartnerType.Customer;
}

public class PartnerList : BaseTablePage<JxPartner>
{
    private IBaseDataService Service;

    //商業夥伴型別虛擬屬性,供應商和客戶頁面覆寫。
    protected virtual string Type { get; }

    protected override async Task OnPageInitAsync()
    {
        await base.OnPageInitAsync();
        Service = await CreateServiceAsync<IBaseDataService>();
        Table.OnQuery = QueryPartnersAsync;
    }

    public void New() => Table.NewForm(Service.SavePartnerAsync, new JxPartner { Type = Type });
    public void DeleteM() => Table.DeleteM(Service.DeletePartnersAsync);
    public void Edit(JxPartner row) => Table.EditForm(Service.SavePartnerAsync, row);
    public void Delete(JxPartner row) => Table.Delete(Service.DeletePartnersAsync, row);
    public void Import() => ShowImportForm();
    public async void Export() => await ExportDataAsync();

    private Task<PagingResult<JxPartner>> QueryPartnersAsync(PagingCriteria criteria)
    {
        criteria.SetQuery(nameof(JxPartner.Type), QueryType.Equal, Type);
        return Service.QueryPartnersAsync(criteria);
    }
}

相關文章