仔细仔细再仔细。注意jsp页面需要的字段和后台字段要匹配。
1.组合关系概念:
就是强聚合,整体和部分,两者不可分割,本质是双向一对多。
2.组合关系隐射配置要求
一方(主表):
cascade = CascadeType.ALL级联操作最全
mappedBy = "bill"一方放弃管理多方,多方的外键字段bill_id,一方不管
orphanRemoval = true 孤儿删除。如果在一方解除了和多方的关系,一方是可以删除掉多方
@OneToMany(cascade = CascadeType.ALL, mappedBy = "bill", fetch = FetchType.LAZY, orphanRemoval = true)
private List items = new ArrayList();
多方(从表):bill_id配置为非空
optional = false:不能为空
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "bill_id")
private Purchasebill bill;// 组合关系,非空
jsp中:
js代码来展示数据:
这里使用的三目运算。也可以上面jsp中的format名字不一样,然后一个一个的添加function方法,只不过很麻烦
//灵活显示数据。带有format的(表中的关联字段显示就用format)
function formatName(value,row,index) {
//用三目运算。--有些表关联的domain对象,用户名是username,有的是name
return value?(value.name||value.username):"";
}
审核状态
js代码:
//使用format属性展示前台的审核状态
function formatStatus(v,r,i) {
//根据不同的值展示不同的数据
if(v==0){//状态值为0
//展示待审
return "待审"
}else if(v==1){
return "已审";
}else {
//标签:展示数据中间显示一条横线(像删除状态)
return "作废";
}
}
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
public Date getVdate() {
return vdate;
}
@DateTimeFormat(pattern = "yyyy-MM-dd")
public void setVdate(Date vdate) {
this.vdate = vdate;
}
交易时间:
分析:
首先注意到时间是一个区间范围,然后写一个query,通过前台传过来的query查询对象(开始时间和结束时间和状态),到数据库中查询。
注意:
关于就收参数的时间上,有两个需要注意的点:
一个就是:查询的时间范围是,大于等于开始时间,小于结束时间加上一天。这样就能有效的避免00:00整和12:00的查询时间问题。
第二个就是;在springmvc中接收时间参数要打上相应的注解 ,否则会报日期格式错误。
@DateTimeFormat(pattern = “yyyy-MM-dd”)
//springmvc接收前台传来的时间时需要打上此注解
@DateTimeFormat(pattern = "yyyy-MM-dd")
public void setVdate(Date vdate) {
this.vdate = vdate;
}
供应商:
直接在UtilController所有下拉框中配置路径
采购员:
要根据部门拿到员工
EmployeeController层
//根据部门查到相应的员工
@Query("select o from Employee o where o.department.name=?1 ")
List findByDeptName(String deptName);
IEmployeeService
//获取到所有采购人员
List findBuyer();
部门的domain层:设置了部门常量
//准备一个采购部常量,以便于采购管理处添加的采购人员下拉框显示
public static final String BUYER="采购部";
EmployeeService
//获取到所有采购人员
@Override
public List findBuyer() {
//通过Department的domain中设置的采购部常量拿到部门
return employeeRepository.findByDeptName(Department.BUYER);
}
UtilController所有下拉controller层
//拿到采购员下拉框
@RequestMapping("/buyerList")
@ResponseBody
public List buyerList(){
return employeeService.findBuyer();
}
3.修改
下方在和grid数据表格编辑器结合在一起时解决,修改的回显。
4.删除
Title
<%@include file="/WEB-INF/views/head.jsp" %>
<%--解决咱们可编辑的grid的问题(easyui一定要用1.6.3的版本,否则可能会出现兼容问题)--%>
<%--引入purchasebill特有的js--%>
/**
* 定义一些变量:
* dg:就是咱们要操作的表格
* defaultRow:默认行(表格中的列属性)
* insertPosition:数据插入的位置(bottom/top)
*/
var dg = $("#itemEditGrid"),
defaultRow = { product: "", productColor: "", productImage: "", num: 0, price: 0, amount: 0,descs: "" },
insertPosition = "bottom";
/**
* 表格的初始化操作
*/
var dgInit = function () {
//表格中的列数据
var getColumns = function () {
var result = [];
var normal = [
{
field: 'product', title: '产品', width: 180,
editor: {
type: "combobox", //编辑器的类型
options: { //就是这个编辑器的属性
valueField:'id',
textField:'name',
url:'/util/productList',
panelHeight:"auto",
required: true
}
},
//展示产品数据
formatter:function(v){
return v?v.name:"";
}
},
{
field: 'productColor', title: '颜色', width: 100,
formatter:function(v,r,i){
if(r && r.product){//如果有值就执行下面的代码
//显示颜色
return ``;
}
}
},
{
field: 'productImage', title: '图片', width: 100,
formatter:function(v,r,i){
if(r && r.product){//如果有值
//返回图片
return ``;
}
}
},
{
field: 'num', title: '数量', width: 100,
editor: {
type: "numberbox",//只能输入数字
options: {
required: false,
//可以使输入的数字保留两位小数点
precision:2
}
}
},
{
field: 'price', title: '价格', width: 100,
editor: {
type: "numberbox",//只能输入数字
options: {
required: false,
//可以使输入的数字保留两位小数点
precision:2
}
}
}, {
field: 'amount', title: '小计', width: 180,
formatter:function(v,r,i){
if(r.num && r.price){
//小计等于数量乘以价格 toFixed:保留两位小数。(精度问题)
return (r.num * r.price).toFixed(2);
}
}
},{
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, //边框
toolbar:"#editGridTools", //按钮
singleSelect: true, //单选
columns: getColumns(), //获取到grid中的列
//表示开启单元格编辑功能
enableCellEdit: true
};
dg.datagrid(options);
};
/**
* 得到每次插入行的索引
* dg.datagrid("getRows").length:拿到最后一行的索引
* @returns {number}
*/
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() });
dg.datagrid("insertRow", { index: targetIndex, row: targetRow });
//index:第几行,field:操作哪个字段
dg.datagrid("editCell", { index:targetIndex, field: "product" });
});
//注册一个删除事件--订单明细的删除按钮
$("#btnRemove").click(function () {
//获取到你选中的行
var row = dg.datagrid("getSelected");
if(row){
var index = dg.datagrid("getRowIndex",row);
//把它直接从当前grid中干掉 deleteRow(index):删除一行
dg.datagrid("deleteRow",index);
}
});
};
//先执行的两个方法
dgInit(); buttonBindEvent();
// 一般组合关系使用List (采购单和采购明细单是组合关系:双向多对一,一对多)
@OneToMany(cascade = CascadeType.ALL, mappedBy = "billId", fetch = FetchType.LAZY, orphanRemoval = true)
private List items = new ArrayList();
//保存功能
save(){
//根据id确定是添加路径还是修改路径
var url = "/purchasebill/save";
var id = $("#purchasebillId").val();
if(id){
url = "/purchasebill/update?cmd=update";
}
purchasebillForm.form('submit', {
url:url,
//------------------------------------------
//提交表单前的方法
onSubmit: function(param){
//1.拿到编辑表格中的所有数据
var rows = dg.datagrid("getRows");
// 2.遍历rows(需要索引),拼接我们要的结构
for(let i=0;i
然后拼装成的数据
但是报错:
错误分析:
订单和明细是组合关系。然后组合关系在保存的时候,多方必须知道一方,一方也必须知道多方,否则报此错。
解决:
在Purchasebill 类中是两方都能找到对方
//添加或者修改
private JsonResult saveOrUpdate(Purchasebill purchasebill) {
try {
//purchasebill(一方,采购订单)
//-----------------------------------------------------------
List items = purchasebill.getItems();
//①.准备一个总金额与总数量
BigDecimal totalAmount = new BigDecimal("0");
BigDecimal totalNum = new BigDecimal("0");
// System.out.println("一方找多方:"+items);
for (Purchasebillitem item : items) {
item.setBillId(purchasebill);
// System.out.println("多方找一方:"+item.getBill());
//multiply:乘法(BigDecimal语法) 将小计存值到明细item集合中
item.setAmount(item.getPrice().multiply(item.getNum()));
//②.总金额与总数量相加
totalAmount = totalAmount.add(item.getAmount());
totalNum = totalNum.add(item.getNum());
}
//③.保存前设置金额与数量
purchasebill.setTotalamount(totalAmount);
purchasebill.setTotalnum(totalNum);
purchasebillService.save(purchasebill);
//------------------------------------------------------
} catch (Exception e) {
e.printStackTrace();
return new JsonResult(false, e.getMessage());
}
return new JsonResult();
}
//单独加载回显form表单下半部分的grid数据
//复制一份数据(使其不影响原来的数据,解决修改时删除一条明细,取消后再此点击修改此数据时,不显示那条数据了,但实际上数据库并没有删除那条数据)
// dg.datagrid("loadData",row.items)
var CopyItems=[...row.items];
dg.datagrid("loadData",CopyItems);