云悦智销项目10_采购订单报表

一.采购订单添加

1.1 采购订单前台准备

主要讲解的是可编辑的grid

1.1.1 引入相应的插件

<!-- datagird的编辑扩展包(需要引入)-->
<script src="/easyui/plugin/cellEdit/jeasyui.extensions.datagrid.getColumnInfo.js"></script>
<script src="/easyui/plugin/cellEdit/jeasyui.extensions.datagrid.editors.js"></script>
<script src="/easyui/plugin/cellEdit/jeasyui.extensions.datagrid.edit.cellEdit.js"></script>

1.1.2 /purchasebill.js的支持

//入口函数:页面读取所有元素再执行
$(function () {

    ...
    
    //准备了相应的方法功能
    itsource = {
        //添加(只是弹出form)
        add(){
           ...
            //把明细的grid数据清空
            dg.datagrid("loadData",[])
        },
        //修改(只是弹出form)
        update () {
            ...
            //4.完成咱们的数据回显
            // 4.1 回显供应商与采购员
            if(row.supplier){
                row["supplier.id"] = row.supplier.id;
            }
            if(row.buyer){
                row["buyer.id"] = row.buyer.id;
            }
            editForm.form("load",row);
            //4.2 回显明细
            var newRows = [...row.items];
            dg.datagrid("loadData",newRows)
        },
        //保存修改功能(调用后台保存)
        save(){
           ...
            editForm.form('submit', {
                url:url, //提交的路径
                //提交前添加一些额外的参数
                onSubmit: function(params){
                    //1.获取明细中的所有行
                    var rows = dg.datagrid("getRows");
                    //2.遍历行,拼接传递的数据
                    for(var i=0;i<rows.length;i++){
                        var row = rows[i];
                        //拼接结构
                        params[`items[${i}].product.id`] = row.product.id;
                        params[`items[${i}].num`] = row.num;
                        params[`items[${i}].price`] = row.price;
                        params[`items[${i}].descs`] = row.descs;
                    }
                    return $(this).form('validate');
                },
               ...
            });
        },
        ...
    };


    /**
     * 保证页面中有一个 id为itemsGrid的table元素
     *  defaultRow:默认行数据
     *  insertPosition:插入数据的位置(bottom:下面 top:上面)
     */
    var dg = $("#itemsGrid"),
        defaultRow = { product: "", productColor: "", productImage: "", num: 0, price: 0, amount: 0, descs: "" },
        insertPosition = "bottom";

    /**
     * 初始化创建咱们的编辑datagrid
     */
    var dgInit = function () {
        //grid中所有的列
        var getColumns = function () {
            var result = [];

            var normal = [
                {
                    field: 'product', title: '产品', width: 180,
                    editor: {
                        type: "combobox",
                        options: {
                            required: true,
                            valueField:'id',
                            textField:'name',
                            panelHeight:'auto',
                            url:'/product/findAll'
                        }
                    },
                    //特别注意,这个属性和title是平级的
                    formatter:function(v){
                        //只显示产品的名称
                        return v?v.name:"";
                    }
                },
                {
                    field: 'productColor', title: '颜色', width: 100,
                    //v:当前格子数据  r:当前行数据 i:行索引
                    formatter:function(v,r,i){
                        if(r && r.product){
                            return `<div style="width: 15px;height: 15px;background-color: ${r.product.color}">`;
                        }
                    }
                },
                {
                    field: 'productImage', title: '图片', width: 100,
                    formatter:function(v,r,i){
                        if(r && r.product){
                            return `<img src="${r.product.smallPic}" width="40px" height="40px">`;
                        }
                    }
                },
                {
                    field: 'num', title: '数量', width: 100,
                    editor: {
                        type: "numberbox",
                        options: {
                            precision:2,
                            required: true
                        }
                    }
                },
                {
                    field: 'price', title: '价格', width: 100,
                    editor: {
                        type: "numberbox",
                        options: {
                            precision:1,
                            required: true
                        }
                    }
                },
                {
                    field: 'amount', title: '小计', width: 100,
                    formatter:function(v,r,i){
                        if(r && r.num && r.price){
                            return (r.num * r.price).toFixed(1);
                        }
                        return 0;
                    }
                },
                {
                    field: 'descs', title: '备注', width: 100,
                    editor: {
                        type: "text"
                    }
                }
            ];
            result.push(normal);

            return result;
        };
        //grid中的属性
        var options = {
            // idField: "ID",
            rownumbers: true, //行号
            fitColumns: true,
            fit: true,
            border: true, //边框
            //title:"明细",
            singleSelect: true,
            columns: getColumns(),
            //表示开启单元格编辑功能
            enableCellEdit: true
        };
        //创建grid
        dg.datagrid(options);
    };
    //插入的行索引
    var getInsertRowIndex = function () {
        return insertPosition == "top" ? 0 : dg.datagrid("getRows").length;
    }

    //事件注册
    var buttonBindEvent = function () {
        //添加行
        $("#btnInsert").click(function () {
            var targetIndex = getInsertRowIndex(), targetRow = $.extend({}, defaultRow);
            dg.datagrid("insertRow", { index: targetIndex, row: targetRow });
            dg.datagrid("editCell", { index: targetIndex, field: "Code" });
        });
        //删除行
        $("#btnRemove").click(function () {
            //获取到相应的行
            var row = dg.datagrid("getSelected");
            //获到这一行的索引
            var index = dg.datagrid("getRowIndex",row);
            //把这一行删除掉
            dg.datagrid("deleteRow",index);
        });
    };


    dgInit(); buttonBindEvent();

})

1.2 采购订单后台支持

复习了组合关系的操作
组合就是强聚合(整体与部分不可分割)
聚合就是双向的多对一,一对多
组合关系一般都会配置级联
组合关系保存要求:双方都可以找到对方
1.2.1 级联配置(昨天已经配好)

PurchaseBill
/**
 * 采购订单
 */
@Entity
@Table(name = "purchasebill")
public class PurchaseBill extends BaseDomain{
    ...
    // 一般组合关系使用List
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "bill", fetch = FetchType.LAZY, orphanRemoval = true)
    private List<PurchaseBillItem> items = new ArrayList<PurchaseBillItem>();
    ...
}
PurchaseBillItem
/**
 * 采购订单的明细
 */
@Entity
@Table(name = "purchasebillitem")
public class PurchaseBillItem extends  BaseDomain {

    ...
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "bill_id")
    @JsonIgnore //生成json的时候忽略这个属性
    private PurchaseBill bill;// 组合关系,非空
1.2.2 PurchaseBillController

...
@ModelAttribute("editPurchaseBill")
public PurchaseBill beforeUpdate(Long id,String cmd){
    //我想要的是,只有修改执行相应功能
    if(id!=null && "update".equals(cmd)) {
       //根据id拿到相应的对象
        PurchaseBill purchaseBill = purchaseBillService.findOne(id);
        //把关连对应的值设置为空,就可以解决n-to-n的问题
        purchaseBill.getItems().clear();
        purchaseBill.setSupplier(null);
        purchaseBill.setBuyer(null);
        return purchaseBill;
    }
    return null;
}
...
//添加或者修改 一方:采购订单  多方:明细
public JsonResult saveOrUpdate(PurchaseBill purchaseBill){
    //一.准备总金额与总数量
    BigDecimal totalAmount = new BigDecimal(0);
    BigDecimal totalNum = new BigDecimal(0);
    try {
        List<PurchaseBillItem> items = purchaseBill.getItems();
        for (PurchaseBillItem item : items) {
            item.setBill(purchaseBill); //让多方找到一方的数据
            //计算小计(价格*数量)
            BigDecimal amount =item.getPrice().multiply(item.getNum());
            item.setAmount(amount);
            //二.计算总金额与总数量(注意:不改变原来的值)
            totalAmount = totalAmount.add(amount);
            totalNum = totalNum.add(item.getNum());
        }
        //三.把金额与数量添加进去
        purchaseBill.setTotalAmount(totalAmount);
        purchaseBill.setTotalNum(totalNum);
        purchaseBillService.save(purchaseBill);
        return new JsonResult();
    } catch (Exception e) {
        e.printStackTrace();
        return new JsonResult(false,e.getMessage());
    }
}

二.报表认识与展示

2.1 报表的认识

报表:给上级报告情况的表格
分两种(表格/图表)
表格:信息详尽
图表:数据直观 image
2.2 我们在玩前后端分离

给大家准备好了前端
要求大家返回以下格式

[
{"id":2,supplier:"成都供应商",buyer:"张三",product:"农夫山泉",productType:"水",vdate:"2018-08-12 00:00:00",num:5,price,20,amount:100,status:0,groupField:"成都供应商"},
{"id":3,supplier:"成都供应商",buyer:"张三",product:"农夫山泉",productType:"水",vdate:"2018-08-12 00:00:00",num:5,price,20,amount:100,status:0,groupField:"成都供应商"},
{"id":4,supplier:"成都供应商",buyer:"张三",product:"农夫山泉",productType:"水",vdate:"2018-08-12 00:00:00",num:5,price,20,amount:100,status:0,groupField:"成都供应商"}
]

2.3 报表的后台支持

2.3.1 创建Qurey对象

public class PurchaseBillItemQuery extends BaseQuery {
    //开始时间
    private Date beginDate;
    //结束时间
    private Date endDate;
    //状态
    private Integer status;
    //分组的值
    private Integer groupBy = 1;

    //查询的规则应该在查询对象中来创建
    @Override
    public Specification createSpec(){
        //如果结束时间存在,就要加一天
        if(endDate!=null){
            //生成一个新的值,会加一天
            endDate = DateUtils.addDays(endDate,1);
        }
        Specification<PurchaseBillItem> specification = Specifications.<PurchaseBillItem>and()
                .ge(beginDate!=null,"bill.vdate",beginDate)
                //注意:结束时间加了一天(只需要小于它即可)
                .lt(endDate!=null,"bill.vdate",endDate)
                .eq(status!=null,"bill.status",status)
                .build();
        return specification;
    }
    ...
}

2.3.2 创建一个VO PurchaseBillItemVo

保存数据与返回的结构一致
public class PurchaseBillItemVo {

    private Long id;
    //供应商
    private String supplier;
    //采购员
    private String buyer;
    //产品
    private String product;
    //产品类型
    private String productType;
    //时间
    private Date vdate;
    //数量
    private BigDecimal num;
    //单价
    private BigDecimal price;
    //小计
    private BigDecimal amount;
    //状态
    private Integer status;
    //分组字段
    private String groupField;

    //构造器,把item中的值放到vo中
    public PurchaseBillItemVo(PurchaseBillItem item,Integer groupBy){
        this.id = item.getId();
        this.supplier = item.getBill().getSupplier().getName();
        this.buyer = item.getBill().getBuyer().getUsername();
        this.product = item.getProduct().getName();
        this.productType = item.getProduct().getTypes().getName();
        this.vdate = item.getBill().getVdate();
        this.num = item.getNum();
        this.price = item.getPrice();
        this.amount = item.getAmount();
        this.status = item.getBill().getStatus();
        switch (groupBy) {
            case 1: this.groupField =this.supplier;break;
            case 2: this.groupField = this.buyer;break;
            case 3: this.groupField = DateFormatUtils.format(this.vdate,"MM") +"月";break;
        }
    }
    ...
}

2.3.3 创建一个VO

@Service
public class PurchaseBillItemServiceImpl extends BaseServiceImpl<PurchaseBillItem,Long>
        implements IPurchaseBillItemService {

    @Autowired
    private PurchaseBillItemRepository purchaseBillItemRepository;

    @Override
    public List<PurchaseBillItemVo> findVos(PurchaseBillItemQuery query) {
        //1.准备装vo的容器
        List<PurchaseBillItemVo> vos = new ArrayList<>();
        //2.获取到所有的明细(根据条件查询)
        List<PurchaseBillItem> items = super.queryAll(query);
        //3.循环明细,把里面的item变成vo,再放到容器中
        for (PurchaseBillItem item : items) {
            PurchaseBillItemVo vo = new PurchaseBillItemVo(item,query.getGroupBy());
            vos.add(vo);
        }
        return vos;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值