1、组合关系
组合就是强聚合 ,聚合就是双向的多对一,一对多
强:最强级联 一方放弃关系维护
单据都会用到组合关系
保存的时候双方都能找到对象
//一方的配置/**
cascade = CascadeType.ALL:包含所有级联(增删改)
orphanRemoval = true:孤儿删除
mappedBy = "bill":放弃关系维护
*/@OneToMany(cascade = CascadeType.ALL, mappedBy = "bill", fetch = FetchType.LAZY, orphanRemoval = true)
private List<Purchasebillitem> items = new ArrayList<Purchasebillitem>();
//多方的配置@ManyToOne(fetch = FetchType.LAZY, optional = false)@JoinColumn(name = "bill_id")@JsonIgnore
private Purchasebill bill;// 组合关系,非空
2、日期查询问题
2.1 SpringMVC获取与设置日期
get -> @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
set -> @DateTimeFormat(pattern = "yyyy-MM-dd")
2.2 easyui的日期控件
<div id="cc" class="easyui-calendar"></div>
<input name="beginDate" class="easyui-datebox" data-options="sharedCalendar:'#cc'"
style="width:120px">
2.3 怎么解决查询有时分秒的问题
结束时间加一/大于等于开始时间,小于结束时间
//准备一个方法,创建相应的条件规则
public Specification createSpec(){
//结束时间加一天
Date tempDate = null;
if(endDate!=null){
tempDate = DateUtils.addDays(endDate, 1);
}
//gt:大于 ge:大于等于
//lt:小于 le:小于等于
Specification<Purchasebill> spec = Specifications.<Purchasebill>and()
.ge(beginDate!=null,"vdate",beginDate)
.lt(endDate!=null,"vdate",tempDate)
.eq(status!=null,"status",status)
.build();
return spec;
}
3、明细的问题
控件:http://www.easyui-extlib.com/ ->Datagrid-Edit -单元格编辑
3.1 研究控件的代码含义
//设置一些基本数据
var dg = $("#dg1"),
defaultRow = { ID: "", Code: "", Name: "", StandardModel: "", ApplyCount: "", Remark: "", Stocks: "" },
insertPosition = "bottom";//做一些基本的配置(创建datagrid控件)
var dgInit = function () {...//拿到刚添加的行数var getInsertRowIndex = function () { ...//绑定相应的事件var buttonBindEvent = function () {//进入页面先执行相应的代码
dgInit(); buttonBindEvent();
3.2 数据修改
//完成editgrid的功能//定义定量//dg:拿到编辑的grid defaultRow:默认有哪些数据 insertPosition:插入数据的位置(底部)
var dg = $("#itemsGrid"),
defaultRow = { product: "", productColor: "", productImg: "", num: 0, price: 0, amount: 0, descs: "" },
insertPosition = "bottom";
// 对grid的初始化设置var dgInit = function () {
var getColumns = function () {
var result = [];
//商品搞成下拉框,从后台获取到商品数据
var normal = [
{
field: 'product', title: '商品', width: 80,
editor: {
type: "combobox",
options: {
required: true,
panelHeight:'auto',
valueField:'id',
textField:'name',
url:'/util/findProducts'
}
},
//加上format显示产品的名称
formatter:function (v,r,i) {
if(v)return v.name;
}
},
{
field: 'productColor', title: '颜色', width: 40,
formatter: function (v, r, i) {
if(r && r.product){
return `<div style="height: 20px;width: 20px;background: ${r.product.color}"></div>`;
}
}
},
{
field: 'productImg', title: '图片', width: 100,
formatter: function (v, r, i) {
if(r && r.product){
return "<img src='"+r.product.smallpic+"' alt='没有图片' />";
}
}
},
{
field: 'num', title: '数量', width: 100,
editor: {
type: "numberbox", //只允许输入数字
options: {
precision:2, //保留两位小数
required: true
}
}
},
{
field: 'price', title: '价格', width: 100,
editor: {
type: "numberbox",
options: {
precision:2,
required: true
}
}
},
{
field: 'amount', title: '小计', width: 100,
formatter: function (v, r, i) {
if(r.num && r.price){
//toFixed:保存几位小数
return (r.num * r.price).toFixed(2);
}
return 0;
}
},
{
field: 'descs', title: '备注', width: 100,
editor: {
type: "text"
}
}
];
result.push(normal);
return result;
};
var options = {
idField: "ID",
rownumbers: true,
fitColumns: true,
fit: true,
border: true,
title:"明细编辑",
singleSelect: true,
toolbar:"#itemsBtns",
columns: getColumns(),
//表示开启单元格编辑功能
enableCellEdit: true
};
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, { ID: $.util.guid() });
//在datagrid中插入一行数据
dg.datagrid("insertRow", { index: targetIndex, row: targetRow });
//哪一行的哪一列要进行编辑
dg.datagrid("editCell", { index: targetIndex, field: "product" });
});
//删除一行数据
$("#btnRemove").click(function () {
//获取选中的行
var row = dg.datagrid("getSelected");
//获取这一行的索引
var index = dg.datagrid("getRowIndex",row);
//根据索引删除这一行
dg.datagrid("deleteRow",index);
});
};
//调用是相应的方法
dgInit(); buttonBindEvent();
3.3 添加与修改
添加时清空明细
dg.datagrid("loadData",[]);
修改时回显明细
//回显咱们的明细数据//复制一个明细数据
var newItems = [...row.items];
dg.datagrid("loadData",newItems);
保存时提交明细数据
//items[index].
editForm.form('submit', {
//form提交的路径
url:url,
//提交之前你要做什么事件
onSubmit: function(param){
// 加一些自己的参数过去
//1.拿到编辑明细的所有数据
var rows = dg.datagrid("getRows");
//2.遍历所有数据,拼接成咱们需要的格式的参数
//items[0].product.id=1
for(let i=0;i<rows.length;i++){
var json = rows[i];
param[`items[${i}].product.id`] = json.product.id;
param[`items[${i}].num`] = json.num;
param[`items[${i}].price`] = json.price;
param[`items[${i}].descs`] = json.descs;
}
// return false to prevent submit; 返回false阻止提交
return $(this).form('validate');
},
3.4 后台保存与计算
双向找到对方,并且进行计算
private JsonResult saveOrUpdate(Purchasebill purchasebill){
JsonResult jsonResult = new JsonResult();
try {
//拿到采购订单的所有明细
List<Purchasebillitem> items = purchasebill.getItems();
//System.out.println("一方获取多方:"+items);
//①.准备总金额与总数量
BigDecimal totalamount = new BigDecimal(0);
BigDecimal totalnum = new BigDecimal(0);
for (Purchasebillitem item : items) {
//System.out.println("多方拿一方:"+item.getBill());
//设置明细对应的订单
item.setBill(purchasebill);
//计算每一个明细的小计
item.setAmount(item.getNum().multiply(item.getPrice()));
//②.总金额与总数量进行累加
totalamount = totalamount.add(item.getAmount());
totalnum = totalnum.add(item.getNum());
}
//③.把值设置到订单中去
purchasebill.setTotalamount(totalamount);
purchasebill.setTotalnum(totalnum);
purchasebillService.save(purchasebill);
} catch (Exception e) {
e.printStackTrace();
//代表出错
jsonResult.setSuccess(false);
jsonResult.setMsg(e.getMessage());
}
return jsonResult;
}
n-to-n:关连对象清空
@ModelAttribute("editPurchasebill")
public Purchasebill beforeEdit(Long id,String cmd){
//修改的时候才查询(只要有id会就进行一次查询,这是不对的)
if(id!=null && "update".equals(cmd)) {
Purchasebill purchasebill = purchasebillService.findOne(id);
//把要传过来的关联对象都清空,就可以解决n-to-n的问题
purchasebill.setSupplier(null);
purchasebill.setBuyer(null);
purchasebill.getItems().clear();
return purchasebill;
}
return null;
}