智能商贸系统11-采购报表DataGrid GroupView和Highcharts

1、效果

  • 采购报表使用DataGrid GroupView制作,重点是返回json格式的设置
  • 图表使用Highcharts制作
    智能商贸系统11-采购报表DataGrid GroupView和Highcharts_第1张图片

2、前台代码

2.1、jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@include file="/WEB-INF/views/head.jsp" %>
<html>
<head>
    <title>Titletitle>
    <%--引入EasyUI的datagrid-groupview扩展--%>
    <script type="text/javascript" src="/easyui/plugins/datagrid-groupview.js">script>
    <%--引入Highcharts支持的JS文件--%>
    <script src="https://code.highcharts.com.cn/highcharts/highcharts.js">script>
    <script src="https://code.highcharts.com.cn/highcharts/highcharts-3d.js">script>
    <script src="https://code.highcharts.com.cn/highcharts/modules/exporting.js">script>
    <script src="https://code.highcharts.com.cn/highcharts-plugins/highcharts-zh_CN.js">script>
    <script src="https://code.highcharts.com.cn/highcharts/modules/oldie.js">script>
    <script src="https://code.highcharts.com.cn/highcharts/modules/cylinder.js">script>
    <script src="https://code.highcharts.com.cn/highcharts/themes/sand-signika.js">script>
    <%--引入当前页面对应的js文件--%>
    <script src="/js/model/purchasebillitem.js">script>
head>
<body>
<table id="purchasebillitemGrid">
table>
<%--grid顶部工具栏--%>
<div id="gridTools" style="padding:5px;height:auto">
    <%--查询条--%>
    <form id="searchForm">
        日期: <input name="beginDate" class="easyui-datebox" style="width:150px">
        -  <input name="endDate" class="easyui-datebox" style="width:150px">
        状态: <select class="easyui-combobox" name="status" panelHeight="auto" style="width:100px;">
        <option value="">--所有--option>
        <option value="0">待审option>
        <option value="1">已审option>
        <option value="-1">作废option>
    select>
        分组:<select class="easyui-combobox" name="groupBy" panelHeight="auto" style="width:100px;">
            <option value="">--所有--option>
            <option value="0">供应商option>
            <option value="1">采购员option>
            <option value="2">月份option>
        select>
        <a href="#" data-method="search" class="easyui-linkbutton" iconCls="icon-search">查询a>
        <span style="color: darkblue;font-size: 16px">图表:span>
        <a href="#" data-method="chart3d" class="easyui-linkbutton" iconCls="icon-3dpie">3D饼图a>
        <a href="#" data-method="chart2d" class="easyui-linkbutton" iconCls="icon-2dpie">2D饼图a>
        <a href="#" data-method="chartZhu3d" class="easyui-linkbutton" iconCls="icon-3dbar">3D柱状图a>
        <a href="#" data-method="chartZhu2d" class="easyui-linkbutton" iconCls="icon-2dbar">2D柱状图a>
    form>
div>

<%--饼状图--%>
<div id="chartDialog" class="easyui-dialog" title="采购订单明细" style="width:800px;"
     data-options="iconCls:'icon-save',resizable:true,modal:true,closed:true">
    <div id="container" style="height: 500px">div>
div>
<%--柱状图--%>
<div id="chartDialog2" class="easyui-dialog" title="采购订单明细" style="width:800px;"
     data-options="iconCls:'icon-save',resizable:true,modal:true,closed:true">
    <div id="container2" style="min-width: 310px; height: 400px; margin: 0 auto">div>
div>
body>
html>

2.2、js

//状态的格式化
function formatStatus(v) {
     
    if (v == -1) {
     
        return `作废`
    } else if (v == 1) {
     
        return `已审`
    } else if (v == 0) {
     
        return `待审`
    }
}

$(function () {
     

    var purchasebillitemGrid = $('#purchasebillitemGrid');
    var searchForm = $('#searchForm');
    var chartDialog = $('#chartDialog');
    var chartDialog2 = $('#chartDialog2');

    purchasebillitemGrid.datagrid({
     
        rownumbers: true, // 行号
        remoteSort: false, //远程排序
        nowrap: false,
        fit: true,
        fitColumns: true,
        toolbar: "#gridTools",
        url: '/purchasebillitem/findItems', //获取数据的路径
        //所有的列的字段 【需要修改成我们自己的数据:编号,采购员,供应商....】
        columns: [[
            {
     field: 'id', title: '编号', width: 100},
            {
     field: 'supplierName', title: '供应商', width: 100},
            {
     field: 'buyerName', title: '采购员', width: 100},
            {
     field: 'productName', title: '产品', width: 100},
            {
     field: 'productTypeName', title: '产品类型', width: 100},
            {
     field: 'vdate', title: '日期', width: 100},
            {
     field: 'price', title: '单价', width: 100},
            {
     field: 'num', title: '数量', width: 100},
            {
     field: 'amount', title: '小计', width: 100},
            {
     field: 'status', title: '状态', formatter: formatStatus, width: 100}
        ]],
        //分组字段
        groupField: 'groupField',
        view: groupview, //支持分组视图功能
        //分组格式化
        // value:就是当前groupField分组的值
        // rows:当前这一组的所有行
        groupFormatter: function (value, rows) {
     
            var totalNum = 0;
            var totalAmount = 0;
            for (let r of rows) {
     
                totalNum += r.num;
                totalAmount += r.amount;
            }
            //成都供应商 - 10 条数据 共34商品 总金额:344
            return `${
       value} - ${
       rows.length}条数据 ${
       totalNum}个商品
                    总金额:${
       totalAmount}`;
        }
    });

    $("*[data-method]").on("click", function () {
     
        var methodName = $(this).data("method");
        window.itsource[methodName]();
    })
    itsource = {
     
        //查询
        search() {
     
            //serializeObject:拿到一个form中的所有数据,封装成json对象
            var params = searchForm.serializeObject();
            purchasebillitemGrid.datagrid("load", params);
        },
        //查询3D图片
        chart3d() {
     
            //获取到表单中的所有值
            var params = searchForm.serializeObject();
            if (params.groupBy == "") {
     
                $.messager.alert('提示', '请选择 分组 条件', 'info');
                return;
            }
            //打开弹出框
            chartDialog.dialog("center").dialog("open");
            //请求的时候把值传到后台
            $.post("/purchasebillitem/findCharts", params, function (result) {
     
                //展示图表
                Highcharts.chart('container', {
     
                    chart: {
     
                        type: 'pie',
                        options3d: {
     
                            enabled: true,
                            alpha: 45, //倾斜度
                            beta: 0
                        }
                    },
                    title: {
     
                        text: '采购订单总金额'
                    },
                    //鼠标移上去后显示的数据
                    tooltip: {
     
                        pointFormat: '{series.name}: {point.percentage:.1f}%'
                    },
                    plotOptions: {
     
                        pie: {
     
                            //是否自己可以选择
                            allowPointSelect: true,
                            //鼠标指上来后的样式
                            cursor: 'pointer',
                            depth: 35, //深度
                            dataLabels: {
     
                                enabled: true,
                                format: '{point.name}'
                            }
                        }
                    },
                    series: [{
     
                        type: 'pie',
                        name: '占比',
                        data: result
                    }]
                });
            })
        },
        //查询2D图片
        chart2d() {
     
            //获取到表单中的所有值
            var params = searchForm.serializeObject();
            if (params.groupBy == "") {
     
                $.messager.alert('提示', '请选择 分组 条件', 'info');
                return;
            }
            //打开弹出框
            chartDialog.dialog("center").dialog("open");
            //请求的时候把值传到后台
            $.post("/purchasebillitem/findCharts", params, function (result) {
     
                Highcharts.chart('container', {
     
                    chart: {
     
                        plotBackgroundColor: null,
                        plotBorderWidth: null,
                        plotShadow: false,
                        type: 'pie'
                    },
                    title: {
     
                        text: '采购订单总金额'
                    },
                    tooltip: {
     
                        pointFormat: '{series.name}: {point.percentage:.1f}%'
                    },
                    plotOptions: {
     
                        pie: {
     
                            allowPointSelect: true,
                            cursor: 'pointer',
                            dataLabels: {
     
                                enabled: true,
                                format: '{point.name}: {point.percentage:.1f} %',
                                style: {
     
                                    color: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black'
                                }
                            }
                        }
                    },
                    series: [{
     
                        name: '占比',
                        colorByPoint: true,
                        data: result
                    }]
                });
            })
        },
        chartZhu2d() {
     
            //获取到表单中的所有值
            var params = searchForm.serializeObject();
            if (params.groupBy == "") {
     
                $.messager.alert('提示', '请选择 分组 条件', 'info');
                return;
            }
            //打开弹出框
            chartDialog2.dialog("center").dialog("open");
            //请求的时候把值传到后台
            $.post("/purchasebillitem/findCharts", params, function (result) {
     
                //展示图表
                Highcharts.chart('container2', {
     
                    chart: {
     
                        type: 'column'
                    },
                    title: {
     
                        text: '采购订单总金额'
                    },
                    subtitle: {
     
                        text: '可切换分组查看'
                    },
                    xAxis: {
     
                        type: 'category'
                    },
                    yAxis: {
     
                        title: {
     
                            text: '采购订单总金额'
                        }
                    },
                    legend: {
     
                        enabled: false
                    },
                    plotOptions: {
     
                        series: {
     
                            borderWidth: 0,
                            dataLabels: {
     
                                enabled: true,
                                format: '{point.name}: {point.y:.1f}',
                            }
                        }
                    },
                    tooltip: {
     
                        headerFormat: '{series.name}
'
, pointFormat: '{point.name}: {point.y:.1f}
'
}, series: [{ name: '总金额', colorByPoint: true, data: result }] }); }) }, chartZhu3d() { //获取到表单中的所有值 var params = searchForm.serializeObject(); if (params.groupBy == "") { $.messager.alert('提示', '请选择 分组 条件', 'info'); return; } //打开弹出框 chartDialog2.dialog("center").dialog("open"); //请求的时候把值传到后台 $.post("/purchasebillitem/findCharts", params, function (result) { Highcharts.chart('container2', { chart: { type: 'cylinder', options3d: { enabled: true, alpha: 15, beta: 15, depth: 50, viewDistance: 25 } }, title: { text: '采购订单总金额' }, plotOptions: { series: { depth: 25, colorByPoint: true } }, series: [{ data: result, name: '总金额', showInLegend: false }] }); }); } } })

3、后台代码

3.1、domain.vo

3.1.1、ItemChartVo
public class ItemChartVo {
     

    private Object name;
    private Object y;

    public ItemChartVo() {
     }
    public ItemChartVo(Object name, Object y) {
     
        this.name = name;
        this.y = y;
    }
    public ItemChartVo(String name, Object y) {
     
        this.name = name;
        this.y = y;
    }
    //get set
}
3.1.2、PurchaseBillItemVo
package com.xuxusheng.aisell.domain.vo;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.xuxusheng.aisell.domain.Purchasebillitem;
import com.xuxusheng.aisell.query.PurchasebillitemQuery;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
//List -》 List
public class PurchaseBillItemVo {
     

    private Long id; //编号
    private String supplierName; //供应商
    private String buyerName;//采购员
    private String productName; //产品
    private String productTypeName; //产品类型
    private Date vdate;//日期
    private BigDecimal price;//单价
    private BigDecimal num;//数量
    private BigDecimal amount;//小计
    private Integer status; //状态

    private String groupField; //分组字段

    /**
     * 把一个Purchasebillitem对象变成咱们的vo对象
     * @param item
     */
    public PurchaseBillItemVo(Purchasebillitem item, PurchasebillitemQuery query) {
     
        this.id = item.getId();
        this.supplierName = item.getBill().getSupplier().getName();
        this.buyerName = item.getBill().getBuyer().getUsername();
        this.productName = item.getProduct().getName();
        this.productTypeName = item.getProduct().getTypes().getName();
        this.vdate = item.getBill().getVdate();
        this.price = item.getPrice();
        this.num = item.getNum();
        this.amount = item.getAmount();
        this.status = item.getBill().getStatus();

        Integer groupBy = query.getGroupBy();
        if(groupBy==1){
      //采购员分组
            this.groupField = buyerName;
        }else if(groupBy==2){
     //月份
            Calendar cal = Calendar.getInstance();
            cal.setTime(vdate);
            String month = (cal.get(Calendar.MONTH)+1) + "";
            this.groupField = month;
        }else{
     
            //供应商分组
            this.groupField = supplierName;
        }

    }
    @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")
    public Date getVdate() {
     
        return vdate;
    }
    //get set
}

3.2、repository

3.2.1、BaseRepository

新增加两条自定义的查询

@NoRepositoryBean
public interface BaseRepository<T,ID extends Serializable> extends JpaRepository<T,ID>,JpaSpecificationExecutor<T> {
     
    //根据Query拿到对应的所有数据(不分页)

    List<T> findByQuery(BaseQuery baseQuery);

    //根据jpql与对应的参数拿到数据
    List findByJpql(String jpql,Object... values);
}
3.2.2、BaseRepositoryImpl
public class BaseRepositoryImpl<T,ID extends Serializable> extends SimpleJpaRepository<T,ID> implements BaseRepository<T,ID> {
     

    private final EntityManager entityManager;

    //必需要实现父类的这个构造器
    public BaseRepositoryImpl(Class<T> domainClass, EntityManager em) {
     
        super(domainClass, em);
        this.entityManager = em;
    }
    @Override
    public List<T> findByQuery(BaseQuery baseQuery) {
     
        //第一步:拿到所有高级查询条件
        Specification spec = baseQuery.createSpecification();
        //第二步:拿到排序的值
        Sort sort = baseQuery.createSort();
        //第三步:拿到数据返回
        return  super.findAll(spec, sort);
    }

    //select ...  where xxx =? and yy =? ...
    @Override
    public List findByJpql(String jpql, Object... values) {
     
        //第一步:创建Query对象
        Query query = entityManager.createQuery(jpql);
        //第二步:把值设置到Query对象中去
        if (values!=null) {
     
            for (int i = 0; i < values.length; i++) {
     
                query.setParameter(i + 1, values[i]);
            }
        }
        //第三步:返回数据
        return query.getResultList();
    }
}

3.2.3、BaseRepositoryImpl
public class BaseRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable> extends JpaRepositoryFactoryBean<T,S,ID> {
     

    @Override
    protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
     
        return new MyRepositoryFactory<T,ID>(entityManager); //注:这里创建是我们的自定义类
    }

    //继承JpaRepositoryFactory后,把返回的对象修改成我们自己的实现
    private static  class MyRepositoryFactory<T,ID extends Serializable>   extends JpaRepositoryFactory {
     
        private final EntityManager entityManager;
        /**
         * Creates a new {@link JpaRepositoryFactory}.
         *
         * @param entityManager must not be {@literal null}
         */
        public MyRepositoryFactory(EntityManager entityManager) {
     
            super(entityManager);
            this.entityManager = entityManager;
        }
        //这里返回最后的功能对象
        @Override
        protected Object getTargetRepository(RepositoryInformation information) {
     
            return new BaseRepositoryImpl<T,ID>((Class<T>)information.getDomainType(),entityManager);
        }
        //确定功能对象的类型
        @Override
        protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
     
            return BaseRepositoryImpl.class;
        }
    }
}
3.2.4、applicationContext.xml

较之前新增加一个条factory-class

 <tx:annotation-driven transaction-manager="transactionManager" />
    <jpa:repositories base-package="com.xuxusheng.aisell.repository"
                      entity-manager-factory-ref="entityManagerFactory"
                      transaction-manager-ref="transactionManager"
                      factory-class="com.xuxusheng.aisell.repository.BaseRepositoryFactoryBean"
    />

3.3、query

3.3.1、PurchasebillitemQuery
public class PurchasebillitemQuery extends BaseQuery {
     

    //开始时间
    private Date beginDate;
    //结束时间
    private Date endDate;
    //状态
    private Integer status;

    //分组条件(默认供应商分组)
    private Integer groupBy = 1;
    private Long isdelete;
    @Override
    public Specification createSpecification() {
     
        Date tempDate = null;
        if(endDate!=null) {
     
            tempDate = DateUtils.addDays(endDate, 1);
        }
        Specification<Purchasebillitem> specification = Specifications.<Purchasebillitem>and()
                .ge(beginDate!=null,"bill.vdate",beginDate)
                //注意:这里设计成小于
                .lt(tempDate!=null,"bill.vdate",tempDate)
                .eq(status!=null,"bill.status",status)
                .eq(true,"isdelete",1L)
                .build();
        return specification;
    }
    @Override
    public Specification createSpecificationRe() {
     
        Date tempDate = null;
        if(endDate!=null) {
     
            tempDate = DateUtils.addDays(endDate, 1);
        }
        Specification<Purchasebillitem> specification = Specifications.<Purchasebillitem>and()
                .ge(beginDate!=null,"bill.vdate",beginDate)
                //注意:这里设计成小于
                .lt(tempDate!=null,"bill.vdate",tempDate)
                .eq(status!=null,"bill.status",status)
                .eq(true,"isdelete",2L)
                .build();
        return specification;
    }
    public Specification createSpecification2() {
     
        Specification<Purchasebillitem> specification = Specifications.<Purchasebillitem>and().build();
        return specification;
    }

    //查询的参数
    private List<Object> params = new ArrayList<>();
    //获取到where条件的JPQL
    public String getWhereJpql(){
     
        StringBuilder jpql =  new StringBuilder();
        if(beginDate!=null){
     
            jpql.append(" and o.bill.vdate >= ? ");
            params.add(beginDate);
        }
        if(endDate!=null){
     
            //返回新的值,就是加一天的值
            Date tempDate = DateUtils.addDays(endDate, 1);
            jpql.append(" and o.bill.vdate < ? ");
            params.add(tempDate);
        }
        if(status!=null){
     
            jpql.append(" and o.bill.status =? ");
            params.add(status);
        }
        return jpql.toString().replaceFirst("and","where");
    }

    //获取到分组的字符串
    public String getGroupByStr(){
     
        if(groupBy==1){
     
            //根据采购员分组
            return "o.bill.buyer.username";
        }else if(groupBy==2){
     
            //根据月份分组
            return "MONTH(o.bill.vdate)";
        }else{
     
            //根据供应商分组
            return "o.bill.supplier.name";
        }
    }
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    public void setEndDate(Date endDate) {
     
        this.endDate = endDate;
    }
//get set

3.4、service

3.4.1、IPurchasebillitemService
    //根据Query拿到对应的所有数据(不分页)
    List<T> findByQuery(BaseQuery baseQuery);
    //根据jpql与对应的参数拿到数据
    List findByJpql(String jpql,Object... values);
3.4.2、PurchasebillitemServiceImpl
@Service
public class PurchasebillitemServiceImpl extends BaseServiceImpl<Purchasebillitem,Long> implements IPurchasebillitemService{
     
    @Autowired
    private PurchasebillitemRepository purchasebillitemRepository;
   @Override
    public List<PurchaseBillItemVo> findItems(PurchasebillitemQuery query) {
     
        //获取到所有数据
       List<Purchasebillitem> items = purchasebillitemRepository.findByQuery(query);
       //准备vo集合,用到装数据
       List<PurchaseBillItemVo> vos = new ArrayList<>();
       for (Purchasebillitem item : items) {
     
           //把item变成vo,放到vos里面
           PurchaseBillItemVo vo = new PurchaseBillItemVo(item,query);
           vos.add(vo);
       }
        return vos;
    }
    @Override
    public List<ItemChartVo> findCharts(PurchasebillitemQuery query) {
     

        //1.获取到分组的条件
        String groupByStr = query.getGroupByStr();
        //2.获取到相应的JPQL
        String whereJpql = query.getWhereJpql();
        //3.获取到JPQL中?对应的值
        List<Object> params = query.getParams();
        //注意;这里必需使用全限定名
        String jpql = "select new com.xuxusheng.aisell.domain.vo.ItemChartVo("+groupByStr
                +",sum(amount)) from Purchasebillitem o "+whereJpql+" group by "+groupByStr;
        //如果我们获取单独的一些值,那么就会变成一个Object数组
        List<ItemChartVo> vos = super.findByJpql(jpql,params.toArray());
        return vos;
    }
}

3.5、controller

@Controller
@RequestMapping("/purchasebillitem")
public class PurchasebillitemController extends BaseController {
     
    @Autowired
    private IPurchasebillitemService purchasebillitemService;

    @RequestMapping("/index")
    public String index() {
     
        return "purchasebillitem/index";
    }
    @RequestMapping("/findItems")
    @ResponseBody
    public List<PurchaseBillItemVo> page(PurchasebillitemQuery query) {
     
        System.out.println(query);
        return purchasebillitemService.findItems(query);
    }
    @RequestMapping("/findCharts")
    @ResponseBody
    public List<ItemChartVo> findChart(PurchasebillitemQuery itemQuery) {
     
        return purchasebillitemService.findCharts(itemQuery);
    }
}

你可能感兴趣的:(Java,#SpringDataJpa,datagridview,java)