- A+
所属分类:.NET技术
C#TMS系统代码-联表报表学习
领导被裁了之后很快就有人上任了,几乎是无缝衔接,很难让我不想到这早就决定好了。我的职责没有任何变化。感受下来这个系统封装程度很高,我只要会调用方法就行。这个系统交付之后不会有太多问题,更多应该是做小需求,有大的开发任务应该也是第二期的事,嗯?怎么感觉我变成运维了?而且为啥没有技术主管来把把关呢?做好了之后我就直接接手了
还有另外一个PLM系统还没有开发好,只能先着手这个了,不然天天看上去没事做
whatcanisay
费用结算查询-客户汇总
统计客户 的 发货单/寄递单 产生的费用
之前没怎么使用过mysql中的pivot,所以对这里的ToPivotTable()不清楚,花些时间了解一下挺好
//获取报表为啥这里是Post,我只能猜测因为参数太多然后不想把参数放在url上面? [HttpPost("GetCustomerReport")] //这个控制器或动作方法不需要身份验证或授权 [AllowAnonymous] //省略日志记录 [IgnoreLog] //[FromBody]-请求正文,看来参数真的很多了 public async Task<dynamic> GetCustomerReport([FromBody] TmsBusiCustomerReportListQueryInput input) { //获取数据权限 //50733 id为表的主键 //整个系统都是用这个id直接去查,为什么不搞一个枚举类呢? var authorizeWhere = new List<IConditionalModel>(); authorizeWhere = await _userManager.GetConditionAsync<TmsBusiCustomerReportOutput>("50733", "it.F_Id"); //获取登录人CompanyCode var loginUserCompany = new List<string>(); if (!_userManager.IsAdministrator) { loginUserCompany = await _repository.Context.Queryable<TmsBaseCompanyEmployeeEntity>().Where(x => x.DeleteMark == null && x.EnabledMark == 1 && x.UserId == _userManager.UserId).GroupBy(x => x.CompanyCode).Select(x => x.CompanyCode).ToListAsync(); } //获取字典项费用类型为一般费用的id var dictionarydata = await _repository.Context.Queryable<DictionaryDataEntity>().Where(it => it.DictionaryTypeId == "5183653" && it.DeleteMark == null && it.EnabledMark == 1 && it.FullName == "一般费用").Select(it => it.Id).FirstAsync(); //获取费用明细 var CostCheckDetailData = GetData(); //开查 //TmsBaseExpenseEntity => 费用类型(跟 费用明细 的 费用类型 不是同一个) var data = _db.Queryable<TmsBaseExpenseEntity>() //左连接 费用类型=>a 费用明细=>d 条件:费用类型Code = 费用明细的费用代码 .LeftJoin(CostCheckDetailData, (a, d) => a.Code == d.F_ExpenseCode) //内连接 费用单=>it(费用单与费用明细为主子关系) 条件:费用单Id = 费用明细主表Id //连一个加一个,不过取名...我也不好说...叫我来取我估计我直接abcdef按顺序来了 .InnerJoin<TmsBusiCostCheckEntity>((a, d, it) => it.Id == d.F_CostId) //左连接 寄递单=>b 条件:寄递单单号 = 费用单的来源单号 .LeftJoin<TmsBusiMailingDeliveryEntity>((a, d, it, b) => b.No == it.SourceNo) //左连接 付款明细=>e 条件:费用单单号 = 付款明细的取货单号(数据字典里这样写的,应该叫来源单号吧?费用怎么取货呢?) .LeftJoin<TmsBuisPaymentDetailEntity>((a, d, it, b, e) => it.No == e.PickupNo) //左连接 付款单=>f(付款单与付款明细为主子表关系) 条件:付款单Id = 付款明细主表Id .LeftJoin<TmsBusiPaymentEntity>((a, d, it, b, e, f) => e.PaymentId == f.Id) //左连接 取货单=>j 条件:取货单单号 = 费用单的来源单号 .LeftJoin<TmsBusiPickupEntity>((a, d, it, b, e, f, j) => it.SourceNo == j.No) //费用单状态 .Where((a, d, it, b, e, f, j) => it.Status == 2) //加上数据权限 .Where(authorizeWhere) //删除是修改删除标记来实现,所以这里要查 非删除单据 .Where((a, d, it, b, e, f, j) => a.DeleteMark == null && d.F_DeleteMark == null && it.DeleteMark == null && b.DeleteMark == null && e.DeleteMark == null && f.DeleteMark == null && j.DeleteMark == null) //费用明细 的 费用类型 = 一般费用 (费用明细里面的 费用类型 跟 费用代码 没有任何关系) .Where((a, d, it, b, e, f, j) => d.F_ExpenseType == dictionarydata) //管理员查看全部,其他看本公司数据 .WhereIF(!_userManager.IsAdministrator, (a, d, it, b, e, f, j) => loginUserCompany.Contains(it.CompanyNo)) //groupby一下,报表是按照使用客户来分组的 .GroupBy((a, d, it, b, e, f, j) => new { it.CompanyName, it.CustomerName, f.Currency, a.Code, }) //select数据成TmsBusiCustomerReportOutput .Select((a, d, it, b, e, f, j) => new TmsBusiCustomerReportOutput { companyName = it.CompanyName, customerName =SqlFunc.IIF(it.CustomerName.Contains(".,"), SqlFunc.Replace(it.CustomerName, ".,", ".,"), it.CustomerName), ...... netWeight = SqlFunc.AggregateSum(it.SourceNo.Contains("JD") ? b.NetWeight : j.NetWeight), code = a.Code, amount = Convert.ToDecimal(SqlFunc.AggregateSum(it.Amount)) }) //别忘记MergeTable,一般用了select之后就要想起来 .MergeTable() .WhereIF(!string.IsNullOrEmpty(input.companyName), a => a.companyName.Contains(input.companyName)) //一大堆查询条件 ...... .WhereIF(!string.IsNullOrEmpty(input.amountMin) && !string.IsNullOrEmpty(input.amountMax), a => SqlFunc.Between(a.amount, input.amountMin, input.amountMax)) //Pivot 行转列 直接看接口方法 //DataTable ToPivotTable<TColumn, TRow, TData>(Func<T, TColumn> columnSelector, Expression<Func<T, TRow>> rowSelector, Func<IEnumerable<T>, TData> dataSelector); //三个参数 //columnSelector 行转成的扩列 //rowSelector 保留列 //dataSelector 数值列(对应扩列的数据,所以sum) //个人理解就是把 code的值变成列了,例子随便写的 /* 之前是 companyName customerName code discountAmount 公司01 客户01 费用code01 1 公司01 客户01 费用code02 1 公司01 客户01 费用code03 1 变成了 companyName customerName 费用code01 费用code02 费用code03 公司01 客户01 1 1 1 这里的1是sum(discountAmount),因为这里只有一条 */ .ToPivotTable(it => it.code, it => new { it.companyName, it.customerName, ...... it.amount }, it => it.Sum(x => x.discountAmount) ); //排除结算币种为空 DataRow[] foundRow; foundRow = data.Select("currency=''"); foreach (var item in foundRow) { data.Rows.Remove(item); } //保存一下 data.AcceptChanges(); //下面都是分页操作 List放数据,totalCount总条数 var list = new List<Dictionary<string, object?>>(); var totalCount = 0; //数据放进List foreach (DataRow dr in data.Rows) { var result = new Dictionary<string, object?>(); foreach (DataColumn dc in data.Columns) { result.Add(dc.ColumnName, dr[dc]); } totalCount++; list.Add(result); } //排序 if (!string.IsNullOrEmpty(input.sidx)) { switch (input.sidx) { case "companyName": case "customerCode": case "customerName": case "currency": if (input.sort == "desc") list = list.OrderByDescending(x => x[input.sidx]?.ToString()).ToList(); else list = list.OrderBy(x => x[input.sidx]?.ToString()).ToList(); break; default: if (input.sort == "desc") list = list.OrderByDescending(x => x[input.sidx].ObjToDecimal()).ToList(); else list = list.OrderBy(x => x[input.sidx].ObjToDecimal()).ToList(); break; } } //获取当页内容放入list list = list.Skip(input.pageSize * (input.currentPage - 1)).Take(input.pageSize).ToList(); //组装数据返回前台 return new { pagination = new { pageIndex = input.currentPage, input.pageSize, total = totalCount }, list = list }; }