学习MVC也有一段时间了,这里对自己做一些学习总结,因才疏学浅,若不对之处,望各位能指正。
《商贸系统 -------"财务管理、期初录入"模块》项目总结
开发工具:SQL Server 2017、Visual Studio 2017、PowerDesigner
财务管理主要包括账户余额、利润报表、资金流水、客户应收欠款、供应商应付欠款、日常收支、账户转账。
(1)账户余额:
账户余额主要功能有:账户信息的录入、编辑、删除、筛选、导出以及余额的统计等。
(2)账户信息的录入:
点击账户新增按钮可进行账户信息录入操作,录入信息后如没有重复的账户信息即可保存成功。图(2)
账户信息的编辑:点击操作列的编辑图标进行当前账户信息的修改。图(3)
其中当修改账户状态为停用的时候,该表格行会标记为已停用,如下图。
账户信息的筛选:可根据账户名称以及开户银行来进行数据筛选,如下图。
账户信息的导出:可根据需求导出多种格式,如Excel、TXT等。
(2)利润报表:如下图
主要功能为时间段查询统计利润,收入以及支出分类的统计。
(3)资金流水(图4)
主要功能:统计每一笔资金的支出和收入、数据导出可支持Excel、txt等格式、可设置是否显示作废的数据、基本数据筛选以及高级条件筛选(图5)
(4)客户应收欠款以及供应商应付欠款
主要功能:统计应收客户欠款以及供应商应付欠款,可表格、图表数据可视化。也可时间段筛选统计数据以及条件查询。
(5)日常收支 图(6)
主要功能:统计每一笔的收入以及支出的资金流水明细,可多条件筛选数据、可录入收入以及支出的资金流水明细、导出数据等。
(6)账户转账 图(7)
主要功能:可对账户之间进行金额转账、转账记录的作废、表格名片格式显示,基本的查询、导出等。
点击新增转账可进行转账操作。如下图
期初录入
期初录入主要包括仓库、商品资料、客户、供应商、结算账户期初信息录入的功能模块。
仓库、商品、结算账户、供应商、客户期初录入 其中主要功能有查询筛选信息、期初信息录入、导出、导入以及详细信息查看、修改、删除等。
仓库期初录入
对仓库信息新增、修改、删除、以及条件筛选。
商品期初录入
主要功能:新增商品信息以及组合新增商品。导入、导出商品信息,对商品信息进行修改、删除、停用、详细信息查看。
结算账户期初录入
主要功能:对账户信息进行新增、编辑、删除,账户余额统计、账户信息导出以及筛选等。
客户期初录入
主要功能:客户期初信息的新增、导入、修改、删除、导出、查询,期初欠款的统计、高级筛选。
二、相关业务表和关系(部分)
三、经典代码
JS Bootstrap-table初始化
// 表格初始化
$(function () {
//1.初始化Table
var oTable = new TableInit();
oTable.Init();
//2.初始化Button的点击事件
var oButtonInit = new ButtonInit();
oButtonInit.Init();
//2.初始化select的change事件
$("#sel_exportoption").change(function () {
$('#tb_departments').bootstrapTable('refreshOptions', {
exportDataType: $(this).val(),
});
});
});
var curRow = {};
var TableInit = function () {
var oTableInit = new Object();
//初始化Table
oTableInit.Init = function () {
$('#tb_departments').bootstrapTable({
url: 'SelectTransfer', //请求后台的URL(*)
method: 'post', //请求方式(*)
toolbar: '#toolbar', //工具按钮用哪个容器
striped: true, //是否显示行间隔色
cache: false, //是否使用缓存,默认为true,所以一般情况下需要设置一下这个属性(*)
pagination: true, //是否显示分页(*)
sortable: true, //是否启用排序
sortOrder: "asc", //排序方式
queryParams: oTableInit.queryParams,//传递参数(*)
sidePagination: "server", //分页方式:client客户端分页,server服务端分页(*)
pageNumber: 1, //初始化加载第一页,默认第一页
pageSize: 8, //每页的记录行数(*)
pageList: [10, 25, 50, 100], //可供选择的每页的行数(*)
search: false, //是否显示表格搜索,此搜索是客户端搜索,不会进服务端,所以,个人感觉意义不大
strictSearch: true,
showColumns: true, //是否显示所有的列
showRefresh: true, //是否显示刷新按钮
clickToSelect: true, //是否启用点击选中行
maintainColSwitch: true, //保持显示隐藏列参数,使用默认参数传入 true 即可
locale: "zh-CN",
minimumCountColumns: 2, //最少允许的列数
height: false, //行高,如果没有设置height属性,表格自动根据记录条数改变表格高度
uniqueId: "TransferDetailsID", //每一行的唯一标识,一般为主键列
showToggle: true, //是否显示详细视图和列表视图的切换按钮
cardView: false, //是否显示详细视图
detailView: true, //是否显示父子表
showExport: true, //显示导出按钮
exportDataType: "basic", //basic', 'all', 'selected'.
showToggle: true, //名片格式
cardView: false,//设置为True时显示名片(card)布局
showFooter: true,//统计
paginationFirstText: "首页",
paginationPreText: '上一页',
paginationNextText: '下一页',
paginationLastText: '最后一页',
sortName: 'AmountPaid',
rowStyle: function (row, index) {
if (row.State == '停用') {
return { css: { "color": "#eee" } }
} else {
return { css: { "background-color": "white" } }
}
},
columns: [{
checkbox: true,
},
{
field: 'TransferDetailsID',
title: 'ID',
// editable: true,
visible: false,
},
{
field: 'Button',
title: ' ',
align: 'center',
width: '2%',
formatter: SetStates,
},
{
field: 'sno',
title: '编号',
width: '3%',
formatter: function (value, row, index) {
//return index + 1;
return '' + (index + 1) + '';
}
},
{
field: 'TransferAccounts',
title: '转出账户',
// editable: true,
//footerFormatter: '合计',
////checkbox: true,
//align: 'center',
}, {
field: 'ZhuanChuDate',
title: '转出日期',
// editable: true
align: 'center',
}, {
field: 'ShiftToAccounts',
title: '转入账户',
align: 'center',
},
{
field: 'ZhuanRuiDate',
title: '到账日期',
align: 'center',
},
{
field: 'FeePayment',
title: '手续费(元)',
align: 'center',
footerFormatter: function (value) {
var count = 0;
for (var i in value) {
count += value[i].FeePayment;
}
return '¥' + count;
}
},
{
field: 'FeePay',
title: '手续费支付方',
align: 'center',
formatter:SetPay,
},
{
field: 'TransferAmount',
title: '金额(元)',
align: 'center',
sortable: true,//是否启用排序
footerFormatter: function (value) {
var count = 0;
for (var i in value) {
count += value[i].TransferAmount;
}
return '¥' + count;
}
},
{
field: 'UserName',
title: '经手人',
align: 'center',
},
{
field: 'TransferAccountsRemark',
title: '备注',
width: '200px',
align: 'center',
//formatter: operateOpinionFormatter,
cellStyle: formatTableUnit,
},
{
field: 'State',
title: '状态',
align: 'center',
visible: false,
},
{
field: 'Button',
title: '操作',
align: 'center',
events: "operateEvents",
formatter: addfuntion,
},
],
//注册加载子表的事件。注意下这里的三个参数!
onExpandRow : function (index, row, $detail) {
console.log(index);
console.log(row);
onclick = row.TransferDetailsID;
var parentId = row.TransferDetailsID;
var prjLogBookProblemTable = $detail.html('
').find('table');
$(prjLogBookProblemTable).bootstrapTable({
columns : [{
field: 'TransferAccounts',
title : '转出账户',
align : 'center',
},
{
field: 'ShiftToAccounts',
title: '转入账户',
align: 'center',
},
{
field: 'ZhuanChuDate',
title: '转出日期',
align: 'center',
},
{
field: 'ZhuanRuiDate',
title: '到账日期',
align: 'center',
},
{
field: 'UserName',
title : '经手人',
align : 'center',
},{
field:'TransferAmount',
title : '转账金额(元)',
align: 'center',
},
{
field: 'UserName',
title: '制单人',
align: 'center',
},
{
field: 'FeePay',
title: '手续费支付方',
align: 'center',
formatter: SetPay,
},
{
field: 'ZhuanRuiDate',
title: '制单时间',
align: 'center',
}, {
field: 'FeePayment',
title: '手续费(元)',
align : 'center',
}],
url: 'SelectTran',
method : 'POST', //请求方式(*)
sortable : true, //是否启用排序
sortName: 'TransferDetailsID',
sortOrder: 'asc', //排序方式
cardView: true, //是否显示详细视图
clickToSelect : true, //是否启用点击选中行
uniqueId: "TransferDetailsID", //每一行的唯一标识,一般为主键列
ajaxOptions: { parentId: parentId },
queryParams: { parentId: parentId },
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
cellStyle: function cellStyle(value, row, index) {
return {
css: {
"font-size": "15px"
}
};
},
onLoadError: function(){ //加载失败时执行
layer.msg("加载数据出错!", {time : 1500, icon : 5});
}
});
},
onClickRow: function (row, $element) {
curRow = row;
},
});
};
//得到查询的参数
oTableInit.queryParams = function (params) {
var temp = { //这里的键的名字和控制器的变量名必须一样,这边改动,控制器也需要改成一样的
limit: params.limit, //页面大小
offset: params.offset, //页码
Payparams: $("#SearchKeyWord").val(),
IsTranfer: $("#check").val()
//sort: params.sort, //排序列名
//sortOrder: params.order//排位命令(desc,asc)
};
return temp;
};
return oTableInit;
};
C# Controller 账户之间简单转账
public ActionResult InserttransferAccounts(int ClearingAccountIDs, DateTime ZhuanChuDate, int ClearingAccountID, DateTime ZhuanRuiDate, decimal TransferAmount, decimal FeePayment,string TransferAccountsRemark,int UserID,int StateID,int ZhuanChuPay,int ZhuanRuiPay)
{
string strMsg = "failed";
try
{
SYS_TransferAccounts TransferAccounts = new SYS_TransferAccounts();//转账表
TransferAccounts.UserID = UserID;//经手人ID
TransferAccounts.TransferAccountsRemark = TransferAccountsRemark; //备注
TransferAccounts.FeePayment = FeePayment;//手续费
if (ZhuanChuPay == 1)
{
TransferAccounts.FeePay = 1;
}
if(ZhuanRuiPay==3)
{
TransferAccounts.FeePay = 3;
}
myModel.SYS_TransferAccounts.Add(TransferAccounts);//插入表
myModel.SaveChanges();//保存
int TransferAccountsid = TransferAccounts.TransferAccountsID;
//转出记录表
SYS_Transfer sysTransfer = new SYS_Transfer();
sysTransfer.ClearingAccountID = ClearingAccountIDs;//转出账户ID
sysTransfer.ZhuanChuDate = ZhuanChuDate;//转出日期
sysTransfer.TransferAmount = TransferAmount;//金额
PW_ClearingAccount dbClearingAccount = (from tbClearingAccount in myModel.PW_ClearingAccount
where tbClearingAccount.ClearingAccountID == ClearingAccountIDs
select tbClearingAccount).Single();
if (ZhuanChuPay == 1)
{
dbClearingAccount.InitialRemaining = dbClearingAccount.InitialRemaining - (sysTransfer.TransferAmount + FeePayment);
}
else
{
dbClearingAccount.InitialRemaining = dbClearingAccount.InitialRemaining - sysTransfer.TransferAmount;
}
myModel.Entry(dbClearingAccount).State = System.Data.Entity.EntityState.Modified;
myModel.SaveChanges();//保存
//myModel.PW_ClearingAccount.Add(dbClearingAccount);
myModel.SYS_Transfer.Add(sysTransfer);//插入表
myModel.SaveChanges();//保存
int Transferid = sysTransfer.TransferID;
//转入记录表
SYS_ShiftTo sysShiftTo = new SYS_ShiftTo();
sysShiftTo.ClearingAccountID = ClearingAccountID;//转入账户ID
sysShiftTo.ShiftToDate = ZhuanRuiDate;//到账日期
PW_ClearingAccount pwAccount = new PW_ClearingAccount();
PW_ClearingAccount dbAccount = (from tbClearingAccount in myModel.PW_ClearingAccount
where tbClearingAccount.ClearingAccountID == ClearingAccountID
select tbClearingAccount).Single();
if (ZhuanRuiPay ==3)
{
dbAccount.InitialRemaining = (dbAccount.InitialRemaining + sysTransfer.TransferAmount) - FeePayment;
}
else
{
dbAccount.InitialRemaining = dbAccount.InitialRemaining + sysTransfer.TransferAmount;
}
// myModel.PW_ClearingAccount.Add(dbAccount);
myModel.Entry(dbAccount).State = System.Data.Entity.EntityState.Modified;
myModel.SaveChanges();//保存
myModel.SYS_ShiftTo.Add(sysShiftTo);//插入表
myModel.SaveChanges();//保存
int ShiftToid = sysShiftTo.ShiftToID;
PW_TransferDetails pwTransferDetails = new PW_TransferDetails();
pwTransferDetails.TransferAccountsID = TransferAccountsid;//转账表ID
pwTransferDetails.TransferID = Transferid;//转入记录ID
pwTransferDetails.ShiftToID = ShiftToid;//转出表ID
pwTransferDetails.StateID = StateID;//状态ID
myModel.PW_TransferDetails.Add(pwTransferDetails);
myModel.SaveChanges();//保存
strMsg = "转账成功";
}
catch (Exception e)
{
Console.WriteLine(e);
strMsg = "数据异常";
}
return Json(strMsg, JsonRequestBehavior.AllowGet);
}
四、开发总结
接触MVC也有一段时间了,谈谈对使用这种的设计模式开发项目的理解和总结,MVC即是模型(Model)、视图(View)、Controller(控制器),主要目的是Model和View的实现代码分离,简单理解就是Model、View、Controller各自处理自己的部分。要正确使用MVC来设计开发项目还需要精心计划,因为它没有一个明确的定义。不同的平台语言框架对MVC定义不同。像我刚开始把所有的业务逻辑代码放在控制层,这样就造成Controller的代码很浮肿,而Model层却没有发挥它真正的作用。既要使用了这个模式就尽量发挥出它这种模式的所有优点,如降低代码的耦合性、提高代码的重用性以及代码的维护性。在编码的时候尽量从框架的角度上考虑,比如方法的重用、类的封装、接口的使用。不管是MVC框架,还是MVP、MVVM等框架,都是为了降低代码的耦合性。想要发挥出框架的优点,首先要深入理解透切这种框架模式,如理解它的工作原理,对于自己编写的代码也要注意规范,因为MVC模式中的每个部分分工是明确的、清晰的,就像操作数据的逻辑代码在Model,Controller负责将不同的View和Model组织在一起,响应用户的操作。View为数据作可视化。将视图和逻辑代码尽可能分离才是使用MVC的目的。理论知识是要有的,对于一些自己不熟悉的知识点多一些实践更有助于理解,将平时遇到的问题以及问题的解决方法记录下来,每一学习阶段总结下知识和开发经验。