Known框架实战演练——进销存财务管理
本文介绍如何实现进销存管理系统的财务对账模块,财务对账模块包括供应商对账和客户对账2个菜单页面。供应商和客户对账字段相同,因此可共用一个页面组件类。
- 项目代码:JxcLite
- 开源地址: https://gitee.com/known/JxcLite
1. 配置模块
运行项目,在【系统管理-模块管理】中配置如下模块菜单,配置教程参考之前的教程。
一级模块 | 二级模块 | 代码 | 图标 | Url | 描述 |
---|---|---|---|---|---|
财务管理 | Finance | property-safety | |||
客户对账单 | CustomerAccount | unordered-list | /fms/CustomerAccount | 查询和维护客户对账单信息。 | |
供应商对账单 | SupplierAccount | unordered-list | /fms/SupplierAccount | 查询和维护供应商对账单信息。 |
2. 实体类
在JxcLite
项目Entities
文件夹下面添加JxAccountHead.cs
和JxAccountList.cs
两个实体类文件,实体类代码可以直接复制模块管理中由模型设置生成的代码。文章中只简单描述一下实体类的定义,具体代码参见开源,代码定义如下:
namespace JxcLite.Entities; /// <summary> /// 对账单表头信息类。 /// </summary> public class JxAccountHead : EntityBase { } /// <summary> /// 对账单表体信息类。 /// </summary> public class JxAccountList : EntityBase { }
3. 建表脚本
打开JxcLite.Web
项目Resources
文件夹下的Tables.sql
资源文件,复制粘贴由【模块管理-模型设置】中生成的建表脚本。文章中只简单描述一下建表脚本,具体脚本参见开源,内容如下:
CREATE TABLE [JxAccountHead] ( [Id] varchar(50) NOT NULL PRIMARY KEY, ... [Files] nvarchar(500) NULL ); CREATE TABLE [JxAccountList] ( [Id] varchar(50) NOT NULL PRIMARY KEY, ... [BillId] varchar(50) NOT NULL );
4. 服务接口
在JxcLite
项目Services
文件夹下面添加财务管理模块服务接口,文件名定义为IFinanceService.cs
,该接口定义前后端交互的Api访问方法,包括分页查询、批量删除实体、保存实体。具体方法定义如下:
namespace JxcLite.Services; public interface IFinanceService : IService { //分页查询客户或供应商对账单,通过查询条件Type字段筛选 Task<PagingResult<JxAccountHead>> QueryAccountsAsync(PagingCriteria criteria); //根据账单类型获取默认对账单信息 Task<JxAccountHead> GetDefaultAccountAsync(string type); //批量删除对账单表头及表体信息 Task<Result> DeleteAccountsAsync(List<JxAccountHead> models); //保存对账单表头信息 Task<Result> SaveAccountAsync(UploadInfo<JxAccountHead> info); }
5. 服务实现
在JxcLite.Web
项目Services
文件夹下面添加财务管理模块服务接口的实现类,文件名定义为FinanceService.cs
,文章中只简单描述一下实现类的定义和继承,具体实现参见开源,定义如下:
namespace JxcLite.Web.Services; class FinanceService(Context context) : ServiceBase(context), IFinanceService { public Task<PagingResult<JxAccountHead>> QueryAccountsAsync(PagingCriteria criteria) { } public Task<JxAccountHead> GetDefaultAccountAsync(string type) { } public Task<Result> DeleteAccountsAsync(List<JxAccountHead> models) { } public Task<Result> SaveAccountAsync(UploadInfo<JxAccountHead> info) { } }
双击打开JxcLite.Web
项目中的AppWeb.cs
文件,在AddJxcLiteCore
方法中注册服务类,前端组件可以通过依赖注入工厂创建服务的实例。代码如下:
public static class AppWeb { public static void AddJxcLiteCore(this IServiceCollection services) { services.AddScoped<IFinanceService, FinanceService>(); } }
6. 数据依赖
在JxcLite.Web
项目Repositories
文件夹下面添加财务管理模块数据依赖类,文件名定义为FinanceRepository.cs
,文章中只简单描述一下依赖类的定义,具体实现参见开源,定义如下:
namespace JxcLite.Web.Repositories; class FinanceRepository { internal static Task<PagingResult<JxAccountHead>> QueryAccountsAsync(Database db, PagingCriteria criteria) { } internal static Task<List<JxBillList>> GetBillListsAsync(Database db, string headId) { } //根据前缀获取最大业务单号 internal static Task<string> GetMaxAccountNoAsync(Database db, string prefix) { } internal static Task DeleteAccountListsAsync(Database db, string headId) { } internal static Task DeleteAccountListAsync(Database db, string headId, string billId) { } }
7. 列表页面
在JxcLite.Client
项目Pages\Finance
文件夹下面添加AccountList.cs
单据列表组件,该组件是客户和供应商对账单的列表组件共用类,具体实现参见开源,部分代码如下:
namespace JxcLite.Client.Pages.Finance; public class AccountList : BaseTablePage<JxAccountHead> { private IFinanceService Service; //取得对账类型(客户、供应商),由具体对账单页面重写该类型 protected virtual string Type { get; } protected override async Task OnPageInitAsync() { await base.OnPageInitAsync(); Service = await CreateServiceAsync<IFinanceService>();//创建服务 Table.FormType = typeof(AccountForm);//自定义表单类型 Table.OnQuery = QueryAccountsAsync; //查询方法 //下面是设置列表栏位显示的模板 Table.Column(c => c.Status).Template((b, r) => b.Tag(r.Status)); Table.Column(c => c.AccountDate).Type(FieldType.Date); } //新增 public async void New() { var row = await Service.GetDefaultBillAsync(Type); Table.NewForm(Service.SaveBillAsync, row); } //编辑 public void Edit(JxAccountHead row) => Table.EditForm(Service.SaveAccountAsync, row); //批量删除和删除 public void DeleteM() => Table.DeleteM(Service.DeleteAccountsAsync); public void Delete(JxAccountHead row) => Table.Delete(Service.DeleteAccountsAsync, row); //导出 public async void Export() => await ExportDataAsync(); private Task<PagingResult<JxAccountHead>> QueryAccountsAsync(PagingCriteria criteria) { //设置对账单类型查询条件 criteria.SetQuery(nameof(JxAccountHead.Type), QueryType.Equal, Type); return Service.QueryAccountsAsync(criteria); } }
8. 表头组件
首先打开JxcLite.Client
项目Shared
文件夹下面TypeForms.cs
文件,添加对账单表头类型表单组件,代码如下:
namespace JxcLite.Client.Shared; public class AccountHeadTypeForm : AntForm<JxAccountHead> { }
再在JxcLite.Client
项目Pages\Finance
文件夹下面添加AccountHead.razor
文件,具体实现参见开源,部分代码如下:
@inherits BaseForm<JxAccountHead> <AccountHeadTypeForm Form="Model" ShowAction> <AntRow> <DataItem Span="8" Label="对账单号" Required> <AntInput Disabled @bind-Value="@context.AccountNo" /> </DataItem> <DataItem Span="8" Label="单证状态"> <KTag Text="@context.Status" /> </DataItem> <DataItem Span="8" Label="对账日期" Required> <AntDatePicker @bind-Value="@context.AccountDate" /> </DataItem> </AntRow> <AntRow> <DataItem Span="8" Label="商业伙伴" Required> <PartnerPicker Value="@context.Partner" AllowClear Type="@context.Type" ValueChanged="e=>context.Partner=e[0].Name" /> </DataItem> <DataItem Span="8" Label="业务日期" Required> <AntRangePicker @bind-RangeValue="@context.BizDates" /> </DataItem> <DataItem Span="8" Label="总金额"> <AntDecimal @bind-Value="@context.TotalAmount" /> 元 </DataItem> </AntRow> <AntRow> <DataItem Span="8" Label="合同号"> <AntInput @bind-Value="@context.ContractNo" /> </DataItem> <DataItem Span="8" Label="发票号"> <AntInput @bind-Value="@context.InvoiceNo" /> </DataItem> </AntRow> <AntRow> <DataItem Span="24" Label="备注"> <AntTextArea @bind-Value="@context.Note" /> </DataItem> </AntRow> <AntRow> <DataItem Span="24" Label="附件"> <KUpload @ref="upload" ReadOnly="Model.IsView" Value="@context.Files" OpenFile IsButton="!Model.Data.IsNew" OnFilesChanged="OnFilesChanged" /> </DataItem> </AntRow> </AccountHeadTypeForm> @code { private KUpload upload; private async void OnFilesChanged(List<FileDataInfo> files) { if (Model.Data.IsNew) { Model.Files[nameof(JxAccountHead.Files)] = files; } else { Model.Files[nameof(JxAccountHead.Files)] = files; await Model.SaveAsync(d => upload.SetValue(d.Files), false); } } }
9. 业务单表格组件
再在JxcLite.Client
项目Shared
文件夹下面添加BillHeadTable.cs
文件,该组件为对账单明细列表,具体实现参见开源,部分代码如下:
namespace JxcLite.Client.Shared; public class BillHeadTable : BaseTable<JxBillHead> { private IBillService Service; [Parameter] public JxAccountHead Account { get; set; } protected override async Task OnInitAsync() { await base.OnInitAsync(); Service = await CreateServiceAsync<IBillService>(); Table.ShowPager = true; Table.OnQuery = QueryBillsAsync; if (!ReadOnly) { Table.Toolbar.AddAction(nameof(New)); Table.Toolbar.AddAction(nameof(DeleteM)); Table.SelectType = TableSelectType.Checkbox; } Table.AddColumn(c => c.BillNo, true).Width(100); Table.AddColumn(c => c.Status).Width(100).Template((b, r) => b.Tag(r.Status)); Table.AddColumn(c => c.BillDate).Width(100).Type(FieldType.Date); Table.AddColumn(c => c.Partner).Width(150); Table.AddColumn(c => c.ContractNo).Width(100); Table.AddColumn(c => c.InvoiceNo).Width(100); Table.AddColumn(c => c.TotalAmount).Width(100).Sum(); Table.AddColumn(c => c.Note).Width(200); if (!ReadOnly) { Table.AddAction(nameof(Delete)); } } public void New() { } public void DeleteM() { } public void Edit(JxBillHead row) { } public void Delete(JxBillHead row) { } private Task<PagingResult<JxBillHead>> QueryBillsAsync(PagingCriteria criteria) { criteria.Parameters[nameof(BillQueryType)] = BillQueryType.Account; criteria.SetQuery("BizId", QueryType.Equal, Account.Id); return Service.QueryBillsAsync(criteria); } }
10. 表单组件
再在JxcLite.Client
项目Pages\Finance
文件夹下面添加AccountForm.cs
文件,该组件为对账单弹窗表单组件,分表头信息和对账明细两个标签,代码如下:
namespace JxcLite.Client.Pages.Finance; class AccountForm : BaseTabForm { [Parameter] public FormModel<JxAccountHead> Model { get; set; } protected override async Task OnInitFormAsync() { await base.OnInitFormAsync(); Tab.AddTab("表头信息", BuildHead); Tab.AddTab("对账明细", BuildList); Tab.Right = b => b.Tag(Model.Data.Status); } private void BuildHead(RenderTreeBuilder builder) { builder.Component<AccountHead>().Set(c => c.Model, Model).Build(); } private void BuildList(RenderTreeBuilder builder) { builder.Component<BillHeadTable>() .Set(c => c.ReadOnly, Model.IsView) .Set(c => c.Account, Model.Data) .Build(); } }
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速度为什么快?