• 开始前要谢谢群里的大牛:@༺ཌༀཉི熊༒猫༃ༀད༻ 🤞笑笑🤞
  • 在系统开发时,使用统计报表,肯定是必须的拉,这也是前后台的展示功能,后台管理基本,比如XLS导入修改,前台管显示,普通角色的访问页面。
  • 进去看见最直接简单的报表,而不是全部的上万清单,根据自己的选择查看清单。

    分析号卡表结构

    我们对需要统计报表的表进行分析,

1.先肯定按部门来进行grouy.by了
(部门 总数 其中大于1个月的)
image.png

  • 大体这个样子拉,开始工作。
  • 说明一下呀,这个是我想当然设计的,不知道对不对,思路
  • 先在后台建一个listcard的方法 ,然后生成listcard视图,因为这个是我理解的前台,所以要引用默认布局页,不在后台操作拉

    开始建模

    开始前要谢谢群里的大牛:@༺ཌༀཉི熊༒猫༃ༀད༻ 🤞笑笑🤞

  • 个人理解要先建一个模型,就是显示的模型

  • 在根目录下的Models下,建一个型型HomeListCard.cs

    1. public partial class HomeListCard
    2. {
    3. //区域就是支局之类的
    4. public String Region { get; set; }
    5. //接收人,除非他们发了接收人,否则默认支局长,就是Region起作用
    6. public String Receiver { get; set; }
    7. /// <summary>
    8. /// 总的张数,可用的
    9. /// </summary>
    10. public Int32 TotalCard { get; set; }
    11. //1个月前的卡
    12. public Int32 OldCard { get; set; }
    13. }
  • 就是四个字段列表。

  • 开始测试后台,听说xcode不支持join,对于其中的1个月前的,要需再group.by后,用sql join,先做来看,这个XCODE有自动的简洁语句,也可以直接接行SQL,先用XCODE自带的
  • 新建一个

    [HttpGet]
    public ActionResult ListCard()
    {}

  • 然后进行生成listcard视图。

  • 后台: ``` [HttpGet]

      public ActionResult ListCard()
      {
          var exp1 = new WhereExpression();
          exp1 &= UimCard._.CardState.Contains("0");
          var ke = UimCard.FindAll(exp1.GroupBy(UimCard._.Region), null, UimCard._.CardId.Count() & UimCard._.Region);
    
          var endlistcard = new List<HomeListCard>();
          foreach (var temp in ke)
          {
              HomeListCard listcradid = new HomeListCard();
              listcradid.Region = temp.Region;
              listcradid.Receiver = "";
              listcradid.CardState = "";
              listcradid.TotalCard = Convert.ToInt32(temp.CardId);
              endlistcard.Add(listcradid);
    
             }               
        return View(endlistcard);

       }

- uimcard.findall(exp.GroupBy)这一句是模板句,我也整不明白,每一项的说明,比着写就成。
- 然后对取出的ke值进行foreach,同时写时我要展示的HomeListCard 模板
- 注意 UimCard._.CardId.Count()的值就默认的为CardId,所以还需要转为Convert.ToInt32(temp.CardId);
- 前台效果

![image.png](https://cdn.nlark.com/yuque/0/2021/png/1174002/1617197842108-e8bc1974-707b-4c99-b378-8625ccfb113f.png#align=left&display=inline&height=496&margin=%5Bobject%20Object%5D&name=image.png&originHeight=496&originWidth=880&size=21778&status=done&style=none&width=880)

- 但我还需要将出门情况这个统计表中的数量,取其中1个月前的,然后两个表进行join,可是。。。真没学会在XCODE中扫行SQL,石头的教程太精少了。
- 但笑哥教我弄会直接执行SQL拉
- 方法二,用直接执行SQL
- 下面是xcode的模板

var dal=DAL.Create(“member”); var db=dal.Query(“select a., b. from member a left join department b on a.did=b.id where enable=1”); var list=Member.LoadData(db);


- 首先第一个var dal=DAL.Create("member");的member是指连接名,是你的xml,就是model建表中的第一行的用dal的话要填UimCard里面的那个connname',

![image.png](https://cdn.nlark.com/yuque/0/2021/png/1174002/1617199965969-d86ade42-3e29-4633-9b92-31f1766185fe.png#align=left&display=inline&height=104&margin=%5Bobject%20Object%5D&name=image.png&originHeight=104&originWidth=425&size=4851&status=done&style=none&width=425)<br />然后第二行就是写SQL拉,因为我新建的显示模型不一样,笑哥教我的,直按写在SQL中,太高级了。<br />上完整的

[HttpGet] public ActionResult ListCard() { var dal = DAL.Create(“Membership”); var endlistcard = dal.Query(“SELECT Region,COUNT(CardId) as TotalCard FROM UimCard WHERE CardState == 0 GROUP BY Region; “).ToList(); //var ke = UimCard.LoadData(db);

        return View(endlistcard);

       }

- 这里面就是精华拉,太牛叉了。
- 但怎么在这个SQL中,再加一个CONUT进去,还是有WHERE的哩?还是需要WHERE另一个来JOIN?有点蒙。
- 在百度找到了一篇我需要的例子

create table abc(A int,B int)

Select A,count(B) as total from ABC group by A

Select A,count(B) as total1 from ABC where B > 30 group by A

Select A,count(B) as totlal2 from ABC where B > 20 group by A

如何合并这三个查询?

得到一个查询结果:

A,total,total1,total2

答:

Select A,

count(B) as total,

sum(case when B > 30 then 1 else 0 end) as total1,

sum(case when B > 20 then 1 else 0 end) as total2

from ABC group by A ———————————————— 版权声明:本文为CSDN博主「从夏」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/weixin_29357243/article/details/113423955


- 然后根据我的情况马上改写SQL测试,不同的数据库对datetime的操作不一样的,现在是sqlite
        var endlistcard = dal.Query<HomeListCard>("SELECT Region,COUNT(CardId) as TotalCard,sum(case when  date(CreateTime) <= strftime('%Y-%m-%d %H:%M:%f','now', '-30 day') then 1 else 0 end) as OldCard  FROM UimCard WHERE CardState == 0 GROUP BY Region; ").ToList();
            var endlistcard = dal.Query<HomeListCard>("SELECT Region,COUNT(CardId) as TotalCard,sum(case when  date(CreateTime) <= strftime('%Y-%m-%d %H:%M:%f','now', '-30 day') then 1 else 0 end) as OldCard  FROM UimCard WHERE CardState == 0 GROUP BY Region; ").ToList();

- 结果如下

![image.png](https://cdn.nlark.com/yuque/0/2021/png/1174002/1617204623397-2bf495be-2abb-4176-8aef-8d15f3223414.png#align=left&display=inline&height=394&margin=%5Bobject%20Object%5D&name=image.png&originHeight=394&originWidth=410&size=21053&status=done&style=none&width=410)

这节完成拉。
<a name="4yPgA"></a>
## 导出清单

- 个人感觉,统计报表和导出是成正比的,但我不一定需要只导30天前的,本来数据就不大,就全部导出来拉
- XCODE是自带导出功能的,先测试
- 在前台增加一个按钮

导出


- 后台。

//用来获取路径相关,.net core3的获取wootroot根目录 private readonly IWebHostEnvironment _webHostEnvironment; public UimCardController(IWebHostEnvironment webHostEnvironment) { _webHostEnvironment = webHostEnvironment; }


- 然后再做方法 ,这个方法 还没有完成哟,return是错的,我现在是看这个自带的导出能否成功
    public ActionResult ListCardOut()
    {
        var list = UimCard.FindAll();
       // _webHostEnvironment对象的ContentRootPath属性就是内容根目录;
        //_webHostEnvironment对象的WebRootPath属性就是web根目录;
        string web_path = _webHostEnvironment.WebRootPath;//D:\work\_BASE\pspb\pspb\src\pspb\wwwroot
        string fileth = web_path+"/img/abc.csv";
        list.SaveCsv(fileth);
        return View( ); 
    }

- 成功了,但他的wwwroot是bing下面的,而不是静态下面的,也不是域名根目录,我好郁闷。关于这个目录的事,我得再找办法百度,先完成导出来再。下面研究怎么让他送abc.csv到下载保存

![image.png](https://cdn.nlark.com/yuque/0/2021/png/1174002/1617234620188-a54844e7-b2c9-4f83-922c-17409c7d3c02.png#align=left&display=inline&height=229&margin=%5Bobject%20Object%5D&name=image.png&originHeight=229&originWidth=644&size=10785&status=done&style=none&width=644)

- 改写控制器方法 ,实现下载

public ActionResult ListCardOut() { var list = UimCard.FindAll(); // _webHostEnvironment对象的ContentRootPath属性就是内容根目录; //_webHostEnvironment对象的WebRootPath属性就是web根目录; string web_path = _webHostEnvironment.WebRootPath;//D:\work_BASE\pspb\pspb\src\pspb\wwwroot string fileth = web_path+”/img/abc.csv”; list.SaveCsv(fileth); //如何下载 //return File(fileth, “text/csv”, “abc.csv”); //welcome.txt是客户端保存的名字 return File(new FileStream(fileth, FileMode.Open), “text/csv”, “abc.csv”); }

其实使用的就是那个return file,同时 "text/csv"是文件的CSV MIME类型。

<a name="NFkjV"></a>
## 批量删除

- 其实魔方自带批量删除,的,但我想整个更简单的。输入状态类弄,删除就全OKD
- 建一个方法 ,并生成视图

[HttpGet] public IActionResult BatchDel() { ViewBag.error1 = “”; var xx = new List(); ViewBag.errortext2 = xx; return View(); }

后台

[HttpGet] public IActionResult BatchDel() { ViewBag.error1 = “”;

        return View();
    }

    [HttpPost]
    public IActionResult BatchDel(string sringstatename)
    {
        //当这个不为空,即是不点击按按的时候
        if (!String.IsNullOrEmpty(sringstatename))
        {
            var xx = UimCard.FindAll(UimCard._.CardState.Contains(sringstatename));
            if (xx.Count() >0 )
            {
                ViewBag.error1 = "已完成批删!共删:"+ xx.Count().ToString()+"条!";
                xx.Delete();
            }
            else
            {
                ViewBag.error1 = "你输入的状态不存在!";
                return View();
            }

        }
        else
        {
            ViewBag.error1 = "请输入内容!";
            return View();
        }


        return View();
    }

```

  • 然后测试成功。