1. 程式人生 > >Asp.net+Vue2構建簡單記賬WebApp之二(使用ABP迅速搭建.Net後臺)

Asp.net+Vue2構建簡單記賬WebApp之二(使用ABP迅速搭建.Net後臺)

一、ABP簡介

ABP是“ASP.NET Boilerplate Project (ASP.NET樣板專案)”的簡稱。
ASP.NET Boilerplate是一個用最佳實踐和流行技術開發現代WEB應用程式的新起點,它旨在成為一個通用的WEB應用程式框架和專案模板。詳情可以訪問官網:http://www.aspnetboilerplate.com/

二、下載模版

解壓,開啟專案
這裡寫圖片描述
其實這個框架很多內容已經封裝在dll裡面,專案結構大概就是這樣。

  1. core裡面放一些基礎的東西。
  2. EntityFramework裡面放資料訪問物件及倉儲,
  3. Application裡面通常寫服務給web和webapi呼叫
  4. web,webapi就是專案的出口最終展現給第三方或者使用者的地方

三、趕緊試試能用不

1、選擇解決方案-還原NuGet包
這裡寫圖片描述

2、 修改資料連線(這裡需要自己有資料庫服務)
web.config下面修改連線,

  <connectionStrings>
    <add name="Default" connectionString="Server=.; Database=MyBill; Trusted_Connection=True;" providerName="System.Data.SqlClient" />
  </connectionStrings
>

3、資料遷移
將web專案設為啟動專案 然後在程式管理控制檯預設專案選擇EntityFramework,輸入無法將update-database 回車。
這裡寫圖片描述
啟動看看 使用者名稱admin,密碼123qwe
這裡寫圖片描述
介面風格還是很漂亮的。
這裡寫圖片描述

四、新增我們自己的東西

1、新增實體
在core裡新增如下兩個類:
這裡寫圖片描述

using Abp.Domain.Entities;

namespace MyBill.Bills
{
    /// <summary>
    /// 記賬型別
    /// </summary>
    public class BillType : Entity
    {
        ///
<summary>
/// 名稱 /// </summary> public string Name { get; set; } /// <summary> /// font圖示 樣式名稱 /// </summary> public string FontStyle { get; set; } /// <summary> /// 圖片地址 /// </summary> public string ImgUrl { get; set; } /// <summary> /// 是否是收入 /// </summary> public bool IsCountIn { get; set; } } }
using Abp.Domain.Entities;
using Abp.Domain.Entities.Auditing;
using System;
using System.ComponentModel.DataAnnotations.Schema;
namespace MyBill.Bills
{
    /// <summary>
    /// 賬單資料
    /// </summary>
    public class Bill : Entity, IHasCreationTime
    {
        /// <summary>
        /// 建立者
        /// </summary>
        public string CreatorUser { get; set; }
        /// <summary>
        /// 建立時間
        /// </summary>
        public DateTime CreationTime { get; set; }
        /// <summary>
        /// 記賬型別
        /// </summary>
        public int BillTypeId { get; set; }
        [ForeignKey("BillTypeId")]
        public BillType BillType { get; set; }
        /// <summary>
        /// 記賬金額
        /// </summary>
        public decimal Money { get; set; }
        /// <summary>
        /// 描述
        /// </summary>
        public string Des { get; set; }
    }
}

2、新增資料集
在如下檔案的最後面新增資料集:
這裡寫圖片描述

        public MyBillDbContext(DbConnection existingConnection, bool contextOwnsConnection)
         : base(existingConnection, contextOwnsConnection)
        {

        }
        public IDbSet<Bill> Bills { get; set; } // 賬單資料集
        public IDbSet<BillType> BillTypes { get; set; } // 記賬型別資料集

我想給資料遷移時給BillType一些初始資料怎麼辦呢?
在這裡新增如下檔案 (可以參考同目錄下其他檔案寫法)
這裡寫圖片描述

using System.Linq;
using MyBill.EntityFramework;
using System.Collections.Generic;
using MyBill.Bills;

namespace MyBill.Migrations.SeedData
{
    /// <summary>
    /// 初始化資料庫中 billType資料
    /// </summary>
    public class DefaultBillTypeCreator
    {
        private readonly MyBillDbContext _context;
        public DefaultBillTypeCreator(MyBillDbContext context)
        {
            _context = context;
        }

        public void Create()
        {
            CreateBillTypes();
        }

        private void CreateBillTypes()
        {
            List<BillType> list = new List<BillType> {
                new BillType { IsCountIn= false, Name = "食物",FontStyle="fa-cutlery"},
                new BillType { IsCountIn= false, Name = "衣物",FontStyle="fa-columns"},
                new BillType { IsCountIn= false, Name = "生活日用",FontStyle="fa-umbrella"},
                new BillType { IsCountIn= false, Name = "交通出行",FontStyle="fa-car"},
                new BillType { IsCountIn= false, Name = "旅遊",FontStyle="fa-fighter-jet"},
                new BillType { IsCountIn= false, Name = "節日禮物",FontStyle="fa-gift"},
                new BillType { IsCountIn= false, Name = "聚會聚餐",FontStyle="fa-users"},
                new BillType { IsCountIn= false, Name = "醫療健康",FontStyle="fa-plus-square"},
                new BillType { IsCountIn= false, Name = "寵物",FontStyle="fa-github-alt"},
                new BillType { IsCountIn= false, Name = "書籍資料",FontStyle="fa-file-excel-o"},
                new BillType { IsCountIn= false, Name = "工具",FontStyle="fa-wrench"},
                new BillType { IsCountIn= false, Name = "運動",FontStyle="fa-frown-o"},
                new BillType { IsCountIn= false, Name = "培訓學習",FontStyle="fa-pied-piper-alt"},
                new BillType { IsCountIn= false, Name = "孩子",FontStyle="fa-child"},
                new BillType { IsCountIn= false, Name = "住房居家",FontStyle="fa-home"},
                new BillType { IsCountIn= false, Name = "電影演出",FontStyle="fa-film"},
                new BillType { IsCountIn= false, Name = "休閒娛樂",FontStyle="fa-coffee"},
                new BillType { IsCountIn= false, Name = "紅包分子",FontStyle="fa-bomb"},
                new BillType { IsCountIn= false, Name = "借款",FontStyle="fa-skype"},
                new BillType { IsCountIn= false, Name = "其他",FontStyle="fa-globe"},
            };
            foreach (var billType in list)
            {
                AddBillTypesIfNotExists(billType);
            }


        }
        private void AddBillTypesIfNotExists(BillType billType)
        {
            if (_context.BillTypes.Any(l => l.Name == billType.Name))
            {
                return;
            }

            _context.BillTypes.Add(billType);

            _context.SaveChanges();
        }
    }
}

修改Configuration 中 seed()方法


        protected override void Seed(MyBill.EntityFramework.MyBillDbContext context)
        {
            context.DisableAllFilters();

            if (Tenant == null)
            {
                //Host seed
                new InitialHostDbBuilder(context).Create();

                //Default tenant seed (in host database).
                new DefaultTenantCreator(context).Create();
                new TenantRoleAndUserBuilder(context, 1).Create();
            }
            else
            {
                //You can add seed for tenant databases and use Tenant property...
            }
            new DefaultBillTypeCreator(context).Create();// 新增自己初始資料執行
            context.SaveChanges();
        }

執行 Add-Migration Add_Bills 新增遷移
這裡寫圖片描述
執行 update-database 遷移資料
開啟資料庫可以看見
新建的表
這裡寫圖片描述
3、寫服務
服務寫在Application中,建立如下檔案
這裡寫圖片描述

using System;

namespace MyBill.Bills.Dto
{
    public class BillDto
    {
        public int Id { get; set; }
        /// <summary>
        /// 建立時間
        /// </summary>
        public DateTime CreationTime { get; set; }
        /// <summary>
        /// 記賬金額
        /// </summary>
        public decimal Money { get; set; }
        /// <summary>
        /// 名稱
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// font圖示 樣式名稱
        /// </summary>
        public string FontStyle { get; set; }
    }
}

namespace MyBill.Bills.Dto
{
    public class ChartNumDto
    {
        public string Name { get; set; }
        public decimal Value { get; set; }

    }
}
using Abp.AutoMapper;
using System;
using System.ComponentModel.DataAnnotations;


namespace MyBill.Bills.Dto
{
    [AutoMapTo(typeof(Bill))]
    public class CreateBillDto
    {
        /// <summary>
        /// 建立者
        /// </summary>
        public string CreatorUser { get; set; }
        /// <summary>
        /// 建立時間
        /// </summary>
        public DateTime CreationTime { get; set; }
        /// <summary>
        /// 記賬型別
        /// </summary>
        [Required]
        public int BillTypeId { get; set; }
        /// <summary>
        /// 記賬金額
        /// </summary>
        [Required]
        public decimal Money { get; set; }
        /// <summary>
        /// 描述
        /// </summary>
        public string Des { get; set; }

        public CreateBillDto()
        {
            this.CreationTime = DateTime.Now;
        }
    }
}
using Abp.Application.Services.Dto;
using System;
using System.ComponentModel.DataAnnotations;

namespace MyBill.Bills.Dto
{
    public class GetBillDto : IPagedResultRequest, ISortedResultRequest
    {
        [Range(0, 1000)]
        public int MaxResultCount { get; set; }

        public int SkipCount { get; set; }

        public string Sorting { get; set; }

        public DateTime? Date { get; set; }
        public string User { get; set; }
        /// <summary>
        /// 資料型別,0 按年,1按月,
        /// </summary>
        public int Type { get; set; }
        /// <summary>
        /// 分組依據 0,消費型別,1 月
        /// </summary>
        public int GroupBy { get; set; }

    }
}
using Abp.Application.Services;
using Abp.Application.Services.Dto;
using MyBill.Bills.Dto;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace MyBill.Bills
{
    public interface IBillAppServer : IApplicationService
    {
        /// <summary>
        /// 新增一條記錄
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        Task CreatBill(CreateBillDto input);
        /// <summary>
        /// 刪除一條記錄
        /// </summary>
        /// <param name="key"></param>
        Task DeleteBill(int key);
        /// <summary>
        /// 獲取消費型別
        /// </summary>
        /// <returns></returns>
        IList<BillType> GetBillType();
        /// <summary>
        /// 獲取統計資訊
        /// </summary>
        /// <param name="date">時間</param>
        /// <param name="type">型別,0 按年統計,1 按月統計</param>
        /// <returns></returns>
        IList<ChartNumDto> GetCount(GetBillDto input);
        /// <summary>
        /// 獲取列表
        /// </summary>
        /// <param name="getBillDto"></param>
        /// <returns></returns>
        PagedResultDto<BillDto> GetBills(GetBillDto input);
        /// <summary>
        /// 獲取記賬總額
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        decimal GetTotallCount(GetBillDto input);
    }
}
using Abp;
using Abp.Application.Services.Dto;
using Abp.Domain.Repositories;
using MyBill.Bills.Dto;
using System;
using System.Collections.Generic;
using System.Linq;
using Abp.Linq.Extensions;
using System.Threading.Tasks;
using System.Data.Entity;

namespace MyBill.Bills
{
    public class BillAppServer : AbpServiceBase, IBillAppServer
    {
        private readonly IRepository<Bill> _billRepository;
        private readonly IRepository<BillType> _billTypeRepository;
        public BillAppServer(IRepository<Bill> billRepository,
            IRepository<BillType> billTypeRepository
            )
        {
            _billRepository = billRepository;
            _billTypeRepository = billTypeRepository;
        }

        public async Task DeleteBill(int key)
        {
            await _billRepository.DeleteAsync(key);
        }

        public async Task CreatBill(CreateBillDto input)
        {
            var bill = ObjectMapper.Map<Bill>(input);
            await _billRepository.InsertAsync(bill);
        }

        public IList<BillType> GetBillType()
        {
            return _billTypeRepository.GetAllList();
        }

        public IList<ChartNumDto> GetCount(GetBillDto input)
        {
            if (!input.Date.HasValue) return null;
            string date = "";
            DateTime startDate, endDate;
            if (input.Type == 1)
            {
                date = input.Date.Value.ToString("yyyy-MM");
                startDate = DateTime.Parse(date);
                endDate = startDate.AddMonths(1);
            }
            else
            {
                date = input.Date.Value.Year + "-01-01";
                startDate = DateTime.Parse(date);
                endDate = startDate.AddYears(1);
            }

            if (input.GroupBy == 1)
            {
                var bills = _billRepository.GetAll().Where(m => m.CreationTime >= startDate && m.CreationTime < endDate && m.CreatorUser == input.User);
                return bills.GroupBy(m => m.CreationTime.Month).Select(m => new ChartNumDto
                {
                    Name = m.Key + "月",
                    Value = m.Sum(n => n.Money)
                }).ToList();
            }
            else
            {
                var bills = _billRepository.GetAll().Where(m => m.CreationTime >= startDate && m.CreationTime < endDate && m.CreatorUser == input.User).Include(m => m.BillType);
                return bills.GroupBy(m => m.BillType.Name).Select(m => new ChartNumDto
                {
                    Name = m.Key,
                    Value = m.Sum(n => n.Money)
                }).ToList();
            }


        }

        public PagedResultDto<BillDto> GetBills(GetBillDto input)
        {
            if (!input.Date.HasValue) return null;
            var date = input.Date.Value.ToString("yyyy-MM");
            var startDate = DateTime.Parse(date);
            var endDate = startDate.AddMonths(1);
            var bills = _billRepository.GetAll().Where(m => m.CreationTime >= startDate && m.CreationTime < endDate && m.CreatorUser == input.User);
            var count = bills.Count();
            var billsPage = bills
                                        .Include(q => q.BillType)
                                        .OrderBy(q => q.CreationTime)
                                        .PageBy(input)
                                        .Select(m => new BillDto
                                        {
                                            Name = m.BillType.Name,
                                            FontStyle = m.BillType.FontStyle,
                                            Money = m.Money,
                                            Id = m.Id,
                                            CreationTime = m.CreationTime
                                        })
                                        .ToList();
            return new PagedResultDto<BillDto>
            {
                TotalCount = count,
                Items = billsPage
            };
        }
        public decimal GetTotallCount(GetBillDto input)
        {
            var bills = _billRepository.GetAll().Where(m => m.CreatorUser == input.User);
            return bills.Sum(m => m.Money);
        }
    }
}

abp封裝的有公共的倉儲IRepository,所以一般不用單獨寫倉儲了。

4、寫controller
在web專案中新增
這裡寫圖片描述

using Abp.Web.Security.AntiForgery;
using MyBill.Bills;
using MyBill.Bills.Dto;
using System;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace MyBill.Web.Controllers
{
    public class BillController : MyBillControllerBase
    {
        private readonly IBillAppServer _billAppService;

        public BillController(IBillAppServer billAppService)
        {
            _billAppService = billAppService;
        }
        [DisableAbpAntiForgeryTokenValidation]
        public ActionResult GetBillType()
        {
            try
            {
                var result = _billAppService.GetBillType();
                return Json(new { result = true, data = result }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                return Json(new { result = false, data = e.Message }, JsonRequestBehavior.AllowGet);
            }

        }
        [DisableAbpAntiForgeryTokenValidation]
        public ActionResult GetBills(GetBillDto input)
        {
            input.MaxResultCount = 10;
            try
            {
                var result = _billAppService.GetBills(input);
                return Json(new { result = true, data = result }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                return Json(new { result = false, data = e.Message }, JsonRequestBehavior.AllowGet);
            }
        }
        [DisableAbpAntiForgeryTokenValidation]
        public ActionResult GetCount(GetBillDto input)
        {
            try
            {
                var result = _billAppService.GetCount(input);
                return Json(new { result = true, data = result }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                return Json(new { result = false, data = e.Message }, JsonRequestBehavior.AllowGet);
            }
        }
        [DisableAbpAntiForgeryTokenValidation]
        public async Task<JsonResult> AddBills(CreateBillDto bill)
        {
            try
            {
                if (string.IsNullOrEmpty(bill.CreatorUser)) bill.CreatorUser = "1";
                await _billAppService.CreatBill(bill);
                return Json(new { result = true, data = "success" }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                return Json(new { result = false, data = e.Message }, JsonRequestBehavior.AllowGet);
            }
        }
        [DisableAbpAntiForgeryTokenValidation]
        public ActionResult GetTotallCount(GetBillDto input)
        {
            try
            {
                var result = _billAppService.GetTotallCount(input);
                return Json(new { result = true, data = result }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                return Json(new { result = false, data = e.Message }, JsonRequestBehavior.AllowGet);
            }
        }
        [DisableAbpAntiForgeryTokenValidation]
        public async Task<ActionResult> DeleteBill(int key)
        {
            try
            {
                await _billAppService.DeleteBill(key);
                return Json(new { result = true, data = "" }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception e)
            {
                return Json(new { result = false, data = e.Message }, JsonRequestBehavior.AllowGet);
            }
        }
    }
}

注意 新增[DisableAbpAntiForgeryTokenValidation]標籤,是因為abp框架對應post請求有防偽驗證,加上這個標籤可以不用防偽驗證,不然需要post請求時修改協議頭,或者使用abp自己封裝的ajax請求。

5、試試controler
位址列輸入對應地址;
這裡寫圖片描述

五、後臺完成

把介面api寫好扔給前臺吧
1、獲取記賬型別:
路徑:/bill/GetBillType
方法:get
引數:無
返回 :正確 {“result”:true,”data”:[]} 錯誤{“result”:false,”data”:[]}
其中[] 表示陣列。陣列元素參考:{“name”:”食物”,”fontStyle”:null,”imgUrl”:null,”isCountIn”:false,”id”:1}
2、新增賬單資料:
路徑:/bill/AddBills
方法:post
引數:{CreatorUser:使用者的名稱或id標識,BillTypeId:方法1中返回資料的id,Money:記賬金額,Des:描述,可不要}
返回:成功{ result = true, data = “success” } 失敗:{ result = false, data = 錯誤內容 }
3,獲取賬單資料:
路徑:/bill/GetBills
方法:get
引數:{User:使用者的名稱或id標識,Date:資料的時間,Type:‘資料型別0表示一年的資料,1表示一個月的資料根據’,SkipCount:跳過前多少資料用於分頁}
返回 :正確 {“result”:true,”data”:{TotalCount:資料總數,items:[]}} 錯誤{“result”:false,”data”:錯誤內容}
其中[] 表示陣列。陣列元素參考:{“id”:1,”creationTime”:”2017-09-12T13:13:32.03”,”money”:123.00,”name”:”生活日用”,”fontStyle”:null}]}
4,刪除賬單資料:
路徑:/bill/DeleteBill
方法:post
引數:{key:方法3中返回資料的id}
返回:成功{ result = true, data = “success” } 失敗:{ result = false, data = 錯誤內容 }
5,獲取總的記賬數
路徑:/bill/GetTotallCount
方法:get
引數:{CreatorUser:使用者的名稱或id標識}
返回:成功{ result = true, data = 數值 } 失敗:{ result = false, data = 錯誤內容 }
6,獲取統計資料
路徑:/bill/GetCount
方法:get
引數:{User:使用者的名稱或id標識,Date:資料的時間,Type:‘資料型別0表示一年的資料,1表示一個月的資料根據’,GroupBy:分組依據 0,消費型別,1 月}
返回:成功{ result = true, data = [] } 失敗:{ result = false, data = 錯誤內容 }
其中[] 表示陣列為圖表所需資料。陣列元素參考:{“name”:”生活日用”,”value”:123.00}] 或者{“name”:”9月”,”value”:123.00}]