Product类
package cn.itsource.aisell.domain;
import javax.persistence.*;
import java.math.BigDecimal;
@Entity
@Table(name = "product")
public class Product extends BaseDomain {
private String name; //产品名称
private String color; //产品颜色
private String pic; //大图片
private String smallPic;//小图片
private BigDecimal costPrice;//成本价
private BigDecimal salePrice;//销售价
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "types_id")
private ProductType types;// 对应的二级产品类型
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "unit_id")
private Systemdictionarydetail unit;// 数据字典明细:单位
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "brand_id")
private Systemdictionarydetail brand;// 数据字典明细:品牌
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getPic() {
return pic;
}
public void setPic(String pic) {
this.pic = pic;
}
public String getSmallPic() {
return smallPic;
}
public void setSmallPic(String smallPic) {
this.smallPic = smallPic;
}
public BigDecimal getCostPrice() {
return costPrice;
}
public void setCostPrice(BigDecimal costPrice) {
this.costPrice = costPrice;
}
public BigDecimal getSalePrice() {
return salePrice;
}
public void setSalePrice(BigDecimal salePrice) {
this.salePrice = salePrice;
}
public ProductType getTypes() {
return types;
}
public void setTypes(ProductType types) {
this.types = types;
}
public Systemdictionarydetail getUnit() {
return unit;
}
public void setUnit(Systemdictionarydetail unit) {
this.unit = unit;
}
public Systemdictionarydetail getBrand() {
return brand;
}
public void setBrand(Systemdictionarydetail brand) {
this.brand = brand;
}
}
Producttype产品类型
package cn.itsource.aisell.domain;
import javax.persistence.*;
@Entity
@Table(name = "producttype")
public class ProductType extends BaseDomain {
private String name;//名称
private String descs;//描述
//类型分两级,有一个自关联
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="parent_id")
private ProductType parent;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescs() {
return descs;
}
public void setDescs(String descs) {
this.descs = descs;
}
public ProductType getParent() {
return parent;
}
public void setParent(ProductType parent) {
this.parent = parent;
}
//通过这个字段分组查询
public String getGroup(){
//parent不能为空
if(parent != null){
return parent.getName();
}
return null;
}
}
ProductQury
package cn.itsource.aisell.query;
import cn.itsource.aisell.domain.Product;
import cn.itsource.aisell.domain.Systemdictionarydetail;
import com.github.wenhao.jpa.Specifications;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.jpa.domain.Specification;
public class ProductQuery extends BaseQuery{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public Specification createSpecification() {
//不写死 根据name进行高级查询
Specification<Product> specification = Specifications.<Product>and()
.like(StringUtils.isNotBlank(this.getName()),"name", "%"+this.getName()+"%")
.build();
return specification;
}
}
ProducttypeQuery
package cn.itsource.aisell.query;
import cn.itsource.aisell.domain.ProductType;
import com.github.wenhao.jpa.Specifications;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.jpa.domain.Specification;
public class ProductTpyeQuery extends BaseQuery {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public Specification createSpecification() {
//不写死 根据name进行高级查询
Specification<ProductType> specification = Specifications.<ProductType>and()
.like(StringUtils.isNotBlank(this.getName()),"name", "%"+this.getName()+"%")
.build();
return specification;
}
}
package cn.itsource.aisell.repository;
import cn.itsource.aisell.domain.Product;
public interface ProductRepository extends BaseRepository<Product,Long>{
}
在产品类型里面写入一个子查询方法,在后台需要二级联动查询
package cn.itsource.aisell.repository;
import cn.itsource.aisell.domain.ProductType;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
public interface ProductTypeRepository extends BaseRepository<ProductType,Long> {
//查询子的选项
@Query("select o from ProductType o where o.parent is not null")
List<ProductType> findChildTypes();
}
产品里面有图片上传,需要在Service写入方法
package cn.itsource.aisell.service;
import cn.itsource.aisell.domain.Product;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public interface IProductService extends IBaseService<Product,Long> {
void save(Product product, MultipartFile fileImage, HttpServletRequest request) throws IOException;
}
写入二级联动查询方法
package cn.itsource.aisell.service;
import cn.itsource.aisell.domain.ProductType;
import java.util.List;
public interface IProductTypeService extends IBaseService<ProductType,Long> {
//二级查询
List<ProductType> findChildTypes();
}
图片文件上传
package cn.itsource.aisell.service.impl;
import cn.itsource.aisell.domain.Product;
import cn.itsource.aisell.service.IProductService;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@Service
public class ProductServiceImpl extends BaseServiceImpl<Product,Long> implements IProductService {
@Override
public void save(Product product, MultipartFile fileImage, HttpServletRequest request) throws IOException {
//如果fileImage不为空就证明在上传
if(fileImage.getSize() != 0L){
//获取application上下文 四大作用域
ServletContext servletContext = request.getServletContext();
//获取upload的根路径
String rootPath = servletContext.getRealPath("/");
//如果产品类型不为空,证明是修改图片
if(product.getId() != null && StringUtils.isNotBlank(product.getPic())){
//删除大图
File file = new File(rootPath, product.getPic());
file.delete();
//删除小图
file = new File(rootPath, product.getSmallPic());
file.delete();
}
//随机产生名字 UUID 当前时间毫秒数
long name = System.currentTimeMillis();//3434543534534534
//获取上传附件的名字
String filename = fileImage.getOriginalFilename();//a.png
//获取文件的后缀名
String extension = FilenameUtils.getExtension(filename);//png
//最终生成小图的名字
String smallFileName = name + "_small." + extension;//3434543534534534_small.png
//最终生成文件的名字(大图)
String bigFileName = name + "." + extension;//3434543534534534.png
//存储大图的路径
String filePath = "/upload/" + bigFileName;// /upload/3434543534534534.png
//存储小图的路径
String smallFilePath = "/upload/" + smallFileName;// /upload/3434543534534534_small.png
//大图的绝对路径
File file = new File(rootPath, filePath);// E:\ideaProject\target\aisell/upload/3434543534534534.png
//如果图片的父文件夹不存在,则创建
if(!file.getParentFile().exists()){
file.getParentFile().mkdirs();
}
//获取输出流
FileOutputStream fileOutputStream = new FileOutputStream(file);
//上传的核心代码
IOUtils.copy(fileImage.getInputStream(),fileOutputStream);
//大图上传完毕之后,则把路径设置到product中
product.setPic(filePath);
//压缩小图 --压缩小图 scale 压缩比例
Thumbnails.of(fileImage.getInputStream()).scale(0.2f).toFile(new File(rootPath,smallFilePath));//E:\ideaProject\aisell\target/upload/3434543534534534_small.png
//小图设置完毕之后,把路径设置到product中
product.setSmallPic(smallFilePath);
fileOutputStream.close();
}
super.save(product);
}
}
实现二级联动查询 调用Repository方法
package cn.itsource.aisell.service.impl;
import cn.itsource.aisell.domain.ProductType;
import cn.itsource.aisell.repository.ProductTypeRepository;
import cn.itsource.aisell.service.IProductTypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class ProductTypeServiceImpl extends BaseServiceImpl<ProductType,Long>
implements IProductTypeService{
//导入二级查询
@Autowired
ProductTypeRepository productTypeRepository;
@Override
public List<ProductType> findChildTypes() {
return productTypeRepository.findChildTypes();
}
}
package cn.itsource.aisell.web.controller;
import cn.itsource.aisell.common.JsonResult;
import cn.itsource.aisell.domain.Product;
import cn.itsource.aisell.query.ProductQuery;
import cn.itsource.aisell.service.IProductService;
import cn.itsource.aisell.util.AjaxResult;
import cn.itsource.aisell.util.PageFind;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.util.WebUtils;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
@Controller
@RequestMapping("/product")
public class ProductController {
@Autowired
IProductService productService;
@RequestMapping("/index")
public String index(){
return "product";
}
/**
* 获取列表
* @return
*/
@RequestMapping("/page")
@ResponseBody
public PageFind datagrid(ProductQuery query){
Page page = productService.findPageByQuery(query);
//把Page对象转为UIPage
PageFind pageFind = new PageFind(page);
return pageFind;
}
//当你在方法上面打上此注解之后,意思就是,在执行任何方法之前,都要先执行@ModelAttribute对应的方法
@ModelAttribute("updateProduct")
public Product beforeEdit(Product product,String cmd){
if(product.getId()!= null && StringUtils.isNotBlank(cmd)){
product = productService.findOne(product.getId());
//凡是关联对象都必须清空,否则会报n2n问题
product.setTypes(null);
product.setUnit(null);
product.setBrand(null);
}
return product;
}
/**
* 保存数据
* @param product
* @return
*/
@RequestMapping("/save")
@ResponseBody
public AjaxResult save(Product product, HttpServletRequest request){
return saveOrUpdate(product,request);
}
@RequestMapping("/update")
@ResponseBody
public AjaxResult update(@ModelAttribute("updateProduct") Product product,HttpServletRequest request){
return saveOrUpdate(product,request);
}
private AjaxResult saveOrUpdate(Product product, HttpServletRequest request){
try {
//下面是解决上传文件为空报错的问题
MultipartFile fileImage = null;
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (isMultipart){
MultipartHttpServletRequest multipartRequest = WebUtils.getNativeRequest(request, MultipartHttpServletRequest.class);
fileImage = multipartRequest.getFile("file");
}
productService.save(product,fileImage,request);
return new AjaxResult();
} catch (Exception e) {
e.printStackTrace();
return new AjaxResult( "操作失败" + e.getMessage());
}
}
/**
* 删除数据
* @param ids
* @return
*/
@RequestMapping("/delete")
@ResponseBody
public AjaxResult delete(Long[] ids,HttpServletRequest request){
try {
for (Long id : ids) {
Product product = productService.findOne(id);
ServletContext servletContext = request.getServletContext();
//获取upload的根路径
String rootPath = servletContext.getRealPath("/");
if(StringUtils.isNotBlank(product.getPic())){
//删除大图
File file = new File(rootPath, product.getPic());
file.delete();
//删除小图
file = new File(rootPath, product.getSmallPic());
file.delete();
}
//删除数据
productService.delete(id);
}
return new AjaxResult();
} catch (Exception e) {
e.printStackTrace();
return new AjaxResult( "删除失败!" + e.getMessage());
}
}
}
package cn.itsource.aisell.web.controller;
import cn.itsource.aisell.common.JsonResult;
import cn.itsource.aisell.domain.ProductType;
import cn.itsource.aisell.query.ProductTpyeQuery;
import cn.itsource.aisell.service.IProductTypeService;
import cn.itsource.aisell.util.PageFind;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("productType")
public class ProductTypeController {
@Autowired
private IProductTypeService productTypeService;
/**
* 跳到主页面
* @return
*/
@RequestMapping("/index")
public String index(){
return "producttype";
}
/**
* 获取列表
* @return
*/
@RequestMapping("/page")
@ResponseBody
public PageFind page(ProductTpyeQuery productTpyeQuery){
return new PageFind(productTypeService.findPageByQuery(productTpyeQuery));
}
}
product.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<%@include file="/WEB-INF/head.jsp" %>
<script type="text/javascript" src="/js/product.js"></script>
<script type="text/javascript" src="/easyui/plugin/tooltip/jeasyui.extensions.base.tooltip.js"></script>
</head>
<body>
<%--弹出框对应的按钮--%>
<div id="bb">
<a href="javascript:void(0);" data-method="saveData" class="easyui-linkbutton c3" data-options="plain:true">保存</a>
<a href="javascript:void(0);" onclick="$('#dlg').dialog('close')" class="easyui-linkbutton c4"
data-options="plain:true">关闭</a>
</div>
<%--
easyui的时候,查看默认属性与事件
$.fn.{plugin}.defaults
弹出框html代码
--%>
<div id="dlg" class="easyui-dialog" data-options="width:300,height:310,buttons:'#bb',closed:true">
<form id="ff" method="post" enctype="multipart/form-data">
<input id="eid" type="hidden" name="id">
<table cellpadding="5">
<tr>
<td>名称:</td>
<td><input class="easyui-textbox" type="text" name="name"></input></td>
</tr>
<tr>
<td>颜色:</td>
<td>
<input class="easyui-textbox" type="color" name="color"></input>
</td>
</tr>
<tr>
<td>成本价:</td>
<td><input class="easyui-textbox" type="text" name="costPrice"></input></td>
</tr>
<tr>
<td>销售价:</td>
<td><input class="easyui-textbox" type="text" name="salePrice"></input></td>
</tr>
<tr>
<td>单位:</td>
<td>
<input class="easyui-combobox" name="unit.id"
data-options="
url: '/util/findUnits',
method: 'get',
valueField:'id',
textField:'name',
panelHeight:'auto' <%--自适应高度--%>
">
</td>
</tr>
<tr>
<td>品牌:</td>
<td>
<input class="easyui-combobox" name="brand.id"
data-options="
url: '/util/findBrands',
method: 'get',
valueField:'id',
textField:'name',
panelHeight:'auto' <%--自适应高度--%>
">
</td>
</tr>
<tr>
<td>类型:</td>
<td>
<input class="easyui-combobox" name="types.id"
data-options="
url: '/util/findTypes',
method: 'get',
valueField:'id',
textField:'name',
groupField:'group'
">
</td>
</tr>
<tr>
<td>产品图片:</td>
<td>
<input class="easyui-filebox" name="file" data-options="prompt:'图片', buttonText: '选择图片'">
</td>
</tr>
</table>
</form>
</div>
<%--查询工具栏--%>
<div id="tb" style="padding:10px;height:auto">
<div>
<form id="searchForm">
姓名: <input name="name" class="easyui-textbox" style="width:120px">
<a href="javascript:void(0);" data-method="search" class="easyui-linkbutton" iconCls="icon-search">搜索</a>
</form>
</div>
<div style="margin-bottom:5px">
<a href="javascript:void(0);" data-method="add" class="easyui-linkbutton" iconCls="icon-add" plain="true"></a>
<a href="javascript:void(0);" data-method="edit" class="easyui-linkbutton" iconCls="icon-edit" plain="true"></a>
<a href="javascript:void(0);" data-method="delete" class="easyui-linkbutton" iconCls="icon-remove"
plain="true"></a>
</div>
</div>
<table id="dg" class="easyui-datagrid" title="员工管理"
data-options="url:'/product/page',
fit:true,
pagination:true,
rownumbers:true,
toolbar:'#tb',
onLoadSuccess:loadSuccess <%-- 当页面渲染完毕之后才执行onLoadSuccess对应的函数--%>
">
<thead>
<tr>
<th data-options="field:'id',checkbox:true,width:'2%'">ID</th>
<th data-options="field:'name',width:'12%',align:'center'">名称</th>
<th data-options="field:'color',width:'12%',align:'center',formatter:formatColor">颜色</th>
<th data-options="field:'smallPic',width:'14%',align:'center',formatter:formatImg">图片</th>
<th data-options="field:'costPrice',width:'12%',align:'center'">成本价</th>
<th data-options="field:'salePrice',width:'12%',align:'center'">销售价</th>
<th data-options="field:'types',width:'12%',align:'center',formatter:formatterTypes">类型</th>
<th data-options="field:'unit',width:'12%',align:'center',formatter:formatterTypes">单位</th>
<th data-options="field:'brand',width:'12%',align:'center',formatter:formatterTypes">品牌</th>
</tr>
</thead>
</table>
</body>
</html>
producttype.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<%@include file="/WEB-INF/head.jsp"%>
<script type="text/javascript" src="/js/producttype.js"></script>
</head>
<body>
<%--弹出框对应的按钮--%>
<div id="bb">
<a href="javascript:void(0);" data-method="saveData" class="easyui-linkbutton c3" data-options="plain:true">保存</a>
<a href="javascript:void(0);" onclick="$('#dlg').dialog('close')" class="easyui-linkbutton c4" data-options="plain:true">关闭</a>
</div>
<%--
easyui的时候,查看默认属性与事件
$.fn.{plugin}.defaults
弹出框html代码
--%>
<div id="dlg" class="easyui-dialog" data-options="width:300,height:310,buttons:'#bb'" >
<form id="ff" method="post">
<input id="eid" type="hidden" name="id">
<table cellpadding="5">
<tr>
<td>name:</td>
<td><input class="easyui-textbox" type="text" name="name" ></input></td>
</tr>
<tr>
<td>descs:</td>
<td><input class="easyui-textbox" type="text" name="descs" ></input></td>
</tr>
<tr>
<td>parentId:</td>
<td><input class="easyui-textbox" type="text" name="parentId" ></input></td>
</tr>
</table>
</form>
</div>
<%--查询工具栏--%>
<div id="tb" style="padding:10px;height:auto">
<div>
<form id="searchForm">
姓名: <input name="name" class="easyui-textbox" style="width:120px">
<a href="javascript:void(0);" data-method="search" class="easyui-linkbutton" iconCls="icon-search">搜索</a>
</form>
</div>
<div style="margin-bottom:5px">
<a href="javascript:void(0);" data-method="add" class="easyui-linkbutton" iconCls="icon-add" plain="true"></a>
<a href="javascript:void(0);" data-method="edit" class="easyui-linkbutton" iconCls="icon-edit" plain="true"></a>
<a href="javascript:void(0);" data-method="delete" class="easyui-linkbutton" iconCls="icon-remove" plain="true"></a>
</div>
</div>
<table id="dg" class="easyui-datagrid" title="员工管理"
data-options="url:'/productType/page',
fit:true,
pagination:true,
rownumbers:true,
toolbar:'#tb'
">
<thead>
<tr>
<th data-options="field:'id',checkbox:true,width:'2%'">ID</th>
<th data-options="field:'name',width:'16%',align:'center'">name</th>
<th data-options="field:'descs',width:'16%',align:'center'">descs</th>
<th data-options="field:'parentId',width:'16%',align:'center'">parentId</th>
</tr>
</thead>
</table>
</body>
</html>