Known框架实战演练——进销存业务单据
本文介绍如何实现进销存管理系统的业务单据模块,业务单据模块包括采购进货单、采购退货单、销售出货单、销售退货单4个菜单页面。由于进销单据字段大同小异,因此设计共用一个页面组件类。
- 项目代码:JxcLite
- 开源地址: https://gitee.com/known/JxcLite
1. 配置模块
运行项目,在【系统管理-模块管理】中配置如下模块菜单,配置教程参考之前的教程。
一级模块 | 二级模块 | 代码 | 图标 | Url | 描述 |
---|---|---|---|---|---|
进货管理 | Import | import | |||
采购进货单 | ImportList | unordered-list | /bms/ImportList | 查询和维护采购进货单信息。 | |
采购退货单 | ImportReturn | unordered-list | /bms/ImportReturn | 查询和维护采购退货单信息。 | |
销货管理 | Export | export | |||
销售出货单 | ExportList | unordered-list | /bms/ExportList | 查询和维护销售出货单信息。 | |
销售退货单 | ExportReturn | unordered-list | /bms/ExportReturn | 查询和维护销售退货单信息。 |
2. 实体类
在JxcLite
项目Entities
文件夹下面添加JxBillHead.cs
和JxBillList.cs
两个实体类文件,实体类代码可以直接复制模块管理中由模型设置生成的代码。文章中只简单描述一下实体类的定义,具体代码参见开源,代码定义如下:
namespace JxcLite.Entities; /// <summary> /// 业务单据表头信息类。 /// </summary> public class JxBillHead : EntityBase { } /// <summary> /// 业务单据表体信息类。 /// </summary> public class JxBillList : EntityBase { }
3. 建表脚本
打开JxcLite.Web
项目Resources
文件夹下的Tables.sql
资源文件,复制粘贴由【模块管理-模型设置】中生成的建表脚本。文章中只简单描述一下建表脚本,具体脚本参见开源,内容如下:
CREATE TABLE [JxBillHead] ( [Id] varchar(50) NOT NULL PRIMARY KEY, ... [Files] nvarchar(500) NULL ); CREATE TABLE [JxBillList] ( [Id] varchar(50) NOT NULL PRIMARY KEY, ... [Note] ntext NULL );
4. 服务接口
在JxcLite
项目Services
文件夹下面添加业务单据模块服务接口,文件名定义为IBillService.cs
,该接口定义前后端交互的Api访问方法,包括分页查询、批量删除实体、保存实体。具体方法定义如下:
namespace JxcLite.Services; public interface IBillService : IService { //分页查询业务单据信息 Task<PagingResult<JxBillHead>> QueryBillsAsync(PagingCriteria criteria); //根据单据类型获取默认单据信息 Task<JxBillHead> GetDefaultBillAsync(string type); //根据表头ID获取单据表体信息列表 Task<List<JxBillList>> GetBillListsAsync(string headId); //批量删除业务单据信息 Task<Result> DeleteBillsAsync(List<JxBillHead> models); //保存业务单据信息 Task<Result> SaveBillAsync(UploadInfo<JxBillHead> info); }
5. 服务实现
在JxcLite.Web
项目Services
文件夹下面添加业务单据模块服务接口的实现类,文件名定义为BillService.cs
,文章中只简单描述一下实现类的定义和继承,具体实现参见开源,定义如下:
namespace JxcLite.Web.Services; class BillService(Context context) : ServiceBase(context), IBaseDataService { public Task<PagingResult<JxBillHead>> QueryBillsAsync(PagingCriteria criteria) { } public Task<JxBillHead> GetDefaultBillAsync(string type) { } public Task<List<JxBillList>> GetBillListsAsync(string headId) { } public Task<Result> DeleteBillsAsync(List<JxBillHead> models) { } public Task<Result> SaveBillAsync(UploadInfo<JxBillHead> info) { } }
双击打开JxcLite.Web
项目中的AppWeb.cs
文件,在AddJxcLiteCore
方法中注册服务类,前端组件可以通过依赖注入工厂创建服务的实例。代码如下:
public static class AppWeb { public static void AddJxcLiteCore(this IServiceCollection services) { services.AddScoped<IBillService, BillService>(); } }
6. 数据依赖
在JxcLite.Web
项目Repositories
文件夹下面添加业务单据模块数据依赖类,文件名定义为BillRepository.cs
,文章中只简单描述一下依赖类的定义,具体实现参见开源,定义如下:
namespace JxcLite.Web.Repositories; class BillRepository { internal static Task<PagingResult<JxBillHead>> QueryBillsAsync(Database db, PagingCriteria criteria) { } internal static Task<List<JxBillList>> GetBillListsAsync(Database db, string headId) { } //根据前缀获取最大业务单号 internal static Task<string> GetMaxBillNoAsync(Database db, string prefix) { } }
7. 列表页面
在JxcLite.Client
项目Pages\BillData
文件夹下面添加BillList.cs
单据列表组件,该组件是进销单及退货单的列表组件共用类,具体实现参见开源,部分代码如下:
namespace JxcLite.Client.Pages.BillData; public class BillList : BaseTablePage<JxBillHead> { private IBillService Service; //取得业务单据类型(进货、进退货、销货、销退货),由具体单据页面重写该类型 protected virtual string Type { get; } protected override async Task OnPageInitAsync() { await base.OnPageInitAsync(); Service = await CreateServiceAsync<IBillService>();//创建服务 Table.FormType = typeof(BillForm);//自定义表单类型 Table.OnQuery = QueryBillsAsync; //查询方法 //下面是设置列表栏位显示的模板 Table.Column(c => c.Status).Template((b, r) => b.Tag(r.Status)); Table.Column(c => c.BillDate).Type(FieldType.Date); } //新增 public async void New() { var row = await Service.GetDefaultBillAsync(Type); Table.NewForm(Service.SaveBillAsync, row); } //编辑 public async void Edit(JxBillHead row) { row.Lists = await Service.GetBillListsAsync(row.Id); Table.EditForm(Service.SaveBillAsync, row); } //批量删除和删除 public void DeleteM() => Table.DeleteM(Service.DeleteBillsAsync); public void Delete(JxBillHead row) => Table.Delete(Service.DeleteBillsAsync, row); //复制和退货 public void Copy() => Table.SelectRow(async row => {}); public void Return() => Table.SelectRow(async row => {}); //打印 public void Print() => Table.SelectRow(async row => { row.Lists = await Service.GetBillListsAsync(row.Id); //BillPrint为业务单据打印组件 await JS.PrintAsync<BillPrint>(f => f.Set(c => c.Model, row)); }); //导出 public async void Export() => await ExportDataAsync(); private Task<PagingResult<JxBillHead>> QueryBillsAsync(PagingCriteria criteria) { //设置单据类型查询条件 criteria.SetQuery(nameof(JxBillHead.Type), QueryType.Equal, Type); return Service.QueryBillsAsync(criteria); } }
8. 供应商和客户选择框
在JxcLite.Client
项目Shared
文件夹下面添加PartnerPicker.cs
,该组件继承BasePicker,用于弹窗选择客户和供应商信息,具体实现参见开源,部分代码如下:
namespace JxcLite.Client.Shared; public class PartnerPicker : BasePicker<JxPartner> { private IBaseDataService Service; private TableModel<JxPartner> Table; //取得弹框选择的数据列表 public override List<JxPartner> SelectedItems => Table.SelectedRows?.ToList(); //取得或设置商业伙伴类型(客户、供应商) [Parameter] public string Type { get; set; } protected override async Task OnInitAsync() {} protected override void BuildContent(RenderTreeBuilder builder) => builder.Table(Table); }
9. 商品信息选择框
在JxcLite.Client
项目Shared
文件夹下面添加GoodsPicker.cs
,该组件继承BasePicker,用于弹窗选择商品信息,具体实现参见开源,部分代码如下:
namespace JxcLite.Client.Shared; public class GoodsPicker : BasePicker<JxGoods> { private IBaseDataService Service; private TableModel<JxGoods> Table; //取得弹框选择的数据列表 public override List<JxGoods> SelectedItems => Table.SelectedRows?.ToList(); protected override async Task OnInitAsync() {} protected override void BuildContent(RenderTreeBuilder builder) => builder.Table(Table); }
10. 表单组件
首先在JxcLite.Client
项目Shared
文件夹下面添加TypeForms.cs
和TypeTables.cs
文件,添加业务单据表头类型表单组件和业务单据表体类型表格组件,代码如下:
namespace JxcLite.Client.Shared; public class BillHeadTypeForm : AntForm<JxBillHead> { } public class BillListTypeTable : AntTable<JxBillList> { }
再在JxcLite.Client
项目Pages\BillData
文件夹下面添加BillForm.razor
和BillForm.razor.cs
文件,由于单据表单组件有点复杂,代码较长,所以采用razor语法来实现,该组件是进销单及退货单的列表组件共用类,具体实现参见开源,部分代码如下:
@inherits BaseForm<JxBillHead> <BillHeadTypeForm Form="Model"> <AntRow> <DataItem Span="6" Label="业务单号" Required> <AntInput Disabled @bind-Value="@context.BillNo" /> </DataItem> <DataItem Span="6" Label="单证状态"> <KTag Text="@context.Status" /> </DataItem> <DataItem Span="6" Label="单证日期" Required> <AntDatePicker @bind-Value="@context.BillDate" /> </DataItem> <DataItem Span="6" Label="商业伙伴" Required> <PartnerPicker Value="@context.Partner" AllowClear Type="@GetPartnerPickerType(context)" /> </DataItem> </AntRow> </BillHeadTypeForm> <KToolbar> <KTitle Text="商品明细" /> <div> @if (!Model.IsView) { <Button Type="@ButtonType.Primary" Icon="plus" OnClick="OnAdd">添加</Button> } </div> </KToolbar> <BillListTypeTable DataSource="Model.Data.Lists" HidePagination ScrollX="1300px" ScrollY="200px"> <IntegerColumn Title="序号" Field="@context.SeqNo" Width="60" Fixed="left" /> <StringColumn Title="商品编码" Width="120" Fixed="left"> <AntInput @bind-Value="@context.Code" Style="width:100px" /> </StringColumn> <StringColumn Title="金额" Width="100"> <AntDecimal @bind-Value="@context.Amount" OnChange="e=>OnGoodsChange(3, context)" /> </StringColumn> @if (!Model.IsView) { <ActionColumn Title="操作" Align="ColumnAlign.Center" Width="100" Fixed="right"> <Tag Color="red-inverse" OnClick="e=>OnDelete(context)">删除</Tag> </ActionColumn> } <SummaryRow> <SummaryCell Fixed="left">合计</SummaryCell> <SummaryCell>@Model.Data.Lists.Sum(l => l.Amount)</SummaryCell> <SummaryCell /> @if (!Model.IsView) { <SummaryCell /> } </SummaryRow> </BillListTypeTable>
namespace JxcLite.Client.Pages.BillData; partial class BillForm { private KUpload upload; private static string GetPartnerPickerType(JxBillHead model) {} private async void OnFilesChanged(List<FileDataInfo> files) {} private void OnAdd() {} private void OnDelete(JxBillList row) => Model.Data.Lists.Remove(row); private void OnGoodsChange(int field, JxBillList row) {} }
11. 打印组件
在JxcLite.Client
项目Pages\BillData
文件夹下面添加BillPrint.cs
,该组件是打印业务单据内容组件,具体实现参见开源,部分代码如下:
namespace JxcLite.Client.Pages.BillData; class BillPrint : ComponentBase { //业务单据实体对象 [Parameter] public JxBillHead Model { get; set; } protected override void BuildRenderTree(RenderTreeBuilder builder) { BuildStyle(builder);//构建样式表,打印时调用浏览器的预览,选打印机打印 BuildForm(builder); //构建打印表单 } private static void BuildStyle(RenderTreeBuilder builder) { builder.Markup(@"<style> .bill-print {position:relative;} </style>"); } private void BuildForm(RenderTreeBuilder builder) {} }
Known 是基于 Blazor 轻量级、跨平台、低代码、易扩展的插件开发框架。
源码:https://gitee.com/known/Known
源码:https://github.com/known/Known
如果对您有帮助,点击⭐Star⭐关注 ,感谢支持开源!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?