1.需求分析
1.1.产品模块分析
我们要求要大家完成一个产品模块的CRUD
首先,我们先看一下产品模块的表结构,其中,数据字典我们昨天已经讲过,所以今天我们只需要加上产品类型与产品这两个模块!
把表和Domain分析清楚再继续开发:
大家首先根据看到的表把产品与类型的domain设计出来:
1.1.1.Producttype参考:
/**
- 产品类型
- @author Administrator
*/
@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;
//getter,setter…
}
1.1.2.Product参考:
/**
*/
@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;// 数据字典明细:品牌
//getter,setter…
}
Domain创建好后可以使用代码生成器生成!再继续下面的步骤!
1.2.展示产品页面
效果如下(把所有内容展示出来):
1.3.小图点击展示大图
此处,大家可以完成图片放大功能(即点击小图,展示大图):
例如:我们要用鼠标点击了第一张图片,展示一张大图效果:
(注:可以在网上去找相应的控件,也可以使用easyui来进行模拟【layer】)
或者鼠标指上去就显示这种效果:
http://www.easyui-extlib.com/ 的提示框插件可以找到相应效果
1.4.添加产品
添加产品我们主要比较麻烦的功能有:
1.产品的颜色选择
大家可以自行到网上去查找相应的控件,也可以自己进行相应的自己设计。
2.产品的单位与品牌选择
这个选择和以前下拉都差不多,我们直接从数据字典的相应位置拿到数据即可。
3.产品的类型选择(二级连动)
方案一:easyui控件(组合框ComboBox- 组合框组部分)
方案二:二级连动
二级连动我们已经学习过,整体的做法和以前一样(注意:为了性能更好,大家还可以加上了缓存的设计)。
4. 产品的图片上传功能
要完成图片上传特别注意的点是:上传图片后台的处理(没有上传文件怎么办?)
1.5.修改产品
修改的时候注意回显与图片处理
如果做二级连动,回显会比较麻烦(可以好好的思考一下,这里对大家来说难度会比较大)
1.6.删除产品
删除功能并没有什么变化,大家可以尝试一下删除产品后是否可以同时删除产品对应的图片!
(去掉对应图片功能也可以在修改时完成)
配置domain层
package com.lhb.domain;
import com.lhb.domain.Systemdictionarydetail;
import java.math.BigDecimal;
import javax.persistence.*;
@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;
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;
}
@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;
}
}
package com.lhb.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(){
if(parent!=null){
return parent.getName();
}
return "";
}
}
package com.lhb.domain;
import com.lhb.domain.BaseDomain;
import javax.persistence.*;
@Entity
@Table(name = “systemdictionarydetail”)
public class Systemdictionarydetail extends BaseDomain {
private String name;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name ="types_id")
private Systemdictionarytype typesId;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Systemdictionarytype getTypesId() {
return typesId;
}
public void setTypesId(Systemdictionarytype typesId) {
this.typesId = typesId;
}
}
package com.lhb.domain;
import com.lhb.domain.BaseDomain;
import javax.persistence.*;
@Entity
@Table(name = “systemdictionarytype”)
public class Systemdictionarytype extends BaseDomain {
private String sn;
private String name;
public String getSn() {
return sn;
}
public void setSn(String sn) {
this.sn = sn;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
2.Easycode一键生成query,service等文件
package com.lhb.web.controller;
import java.io.File;
import java.math.BigDecimal;
import com.lhb.common.JsonResult;
import com.lhb.common.UIPage;
import com.lhb.domain.Product;
import com.lhb.query.ProductQuery;
import com.lhb.service.IProductService;
import org.apache.commons.io.FilenameUtils;
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.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
/**
*/
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.List;
@Controller
@RequestMapping("/product")
public class ProductController extends BaseController {
@Autowired
private IProductService productService;
@RequestMapping("/index")
public String index(){
return "product/product";
}
@RequestMapping("/page")
@ResponseBody
public UIPage<Product> page(ProductQuery query){
Page page = productService.findPageByQuery(query);
return new UIPage(page);
}
/**
*ModelAttribute:路径访问Controller的每个方法,都会先执行它里面的代码
*/
@ModelAttribute("editProduct")
public Product beforeEdit(Long id,String cmd){
if(id!=null && "_update".equals(cmd)){
//修改才执行这个代码
Product dbProduct = productService.findOne(id);
dbProduct.setTypes(null);
dbProduct.setUnit(null);
dbProduct.setBrand(null);
//解决n-to-n的问题,把关联对象设置为null
return dbProduct;
}
return null;
}
//添加
@RequestMapping("/save")
@ResponseBody
public JsonResult save(Product product, @RequestParam("empFile") CommonsMultipartFile empFile, HttpServletRequest request){
try {
//问题③路劲问题如果写死,万一盘符怎么办!
//根据路劲在磁盘位置创建目录
System.out.println("fileName:"+empFile.getOriginalFilename());
String path="D:/opensource/workSpaceIDEA/aisell/src/main/webapp/images/head/"+empFile.getOriginalFilename();
File newFile=new File(path);
//通过CommonsMultipartFile的方法直接写文件(注意这个时候)
empFile.transferTo(newFile);
product.setPic("/images/head/"+empFile.getOriginalFilename());
productService.save(product);
return new JsonResult();
} catch (Exception e) {
e.printStackTrace();
return new JsonResult(e.getMessage(),false);
}
}
//修改
@RequestMapping("/update")
@ResponseBody
public JsonResult update(@ModelAttribute("editProduct")Product product,@RequestParam("empFile") CommonsMultipartFile empFile, HttpServletRequest request){
try {
String path="D:/opensource/workSpaceIDEA/aisell/src/main/webapp/images/head/"+empFile.getOriginalFilename();
String imgpath="/images/head/"+empFile.getOriginalFilename();
File newFile=new File(path);
//通过CommonsMultipartFile的方法直接写文件(注意这个时候)
empFile.transferTo(newFile);
product.setPic(imgpath);
product.setSmallpic(imgpath);
productService.save(product);
return new JsonResult();
} catch (Exception e) {
e.printStackTrace();
return new JsonResult(e.getMessage(),false);
}
}
/**
* 删除功能,前台要求返回{success:true/false,msg:xxx}
* @return
*/
@RequestMapping("/delete")
@ResponseBody
public JsonResult delete(Long id){
try {
productService.delete(id);
return new JsonResult();
} catch (Exception e) {
e.printStackTrace();
return new JsonResult(e.getMessage(),false);
}
}
}
package com.lhb.web.controller;
import com.lhb.common.JsonResult;
import com.lhb.common.UIPage;
import com.lhb.domain.Producttype;
import com.lhb.query.ProducttypeQuery;
import com.lhb.service.IProducttypeService;
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 java.util.List;
@Controller
@RequestMapping("/productType")
public class ProducttypeController extends BaseController {
@Autowired
private IProducttypeService producttypeService;
@RequestMapping("/index")
public String index(){
return "producttype/producttype";
}
@RequestMapping("/page")
@ResponseBody
public UIPage<Producttype> page(ProducttypeQuery query){
Page page = producttypeService.findPageByQuery(query);
return new UIPage(page);
}
/**
*ModelAttribute:路径访问Controller的每个方法,都会先执行它里面的代码
*/
@ModelAttribute("editProducttype")
public Producttype beforeEdit(Long id,String cmd){
if(id!=null && "_update".equals(cmd)){
//修改才执行这个代码
Producttype dbProducttype = producttypeService.findOne(id);
//解决n-to-n的问题,把关联对象设置为null
return dbProducttype;
}
return null;
}
//添加
@RequestMapping("/save")
@ResponseBody
public JsonResult save(Producttype producttype){
try {
producttypeService.save(producttype);
return new JsonResult();
} catch (Exception e) {
e.printStackTrace();
return new JsonResult(e.getMessage(),false);
}
}
//修改
@RequestMapping("/update")
@ResponseBody
public JsonResult update(@ModelAttribute("editProducttype")Producttype producttype){
try {
producttypeService.save(producttype);
return new JsonResult();
} catch (Exception e) {
e.printStackTrace();
return new JsonResult(e.getMessage(),false);
}
}
/**
* 删除功能,前台要求返回{success:true/false,msg:xxx}
* @return
*/
@RequestMapping("/delete")
@ResponseBody
public JsonResult delete(Long id){
try {
producttypeService.delete(id);
return new JsonResult();
} catch (Exception e) {
e.printStackTrace();
return new JsonResult(e.getMessage(),false);
}
}
}
JSP页面<%–
Created by IntelliJ IDEA.
User: asus
Date: 2019/7/5
Time: 16:59
To change this template use File | Settings | File Templates.
–%>
<%–
Created by IntelliJ IDEA.
User: Administrator
Date: 2019/7/5
Time: 10:44
To change this template use File | Settings | File Templates.
–%>
<%@ page contentType=“text/html;charset=UTF-8” language=“java” %>
name | 颜色 | 图片 | 图片 | 成本价 | 售价 | 类型 | 单位 | 品牌 |
---|
<table cellpadding="5">
<tr>
<td>名称:</td>
<td><input class="easyui-validatebox" type="text" name="name"
data-options="required:true,validType:'checkName'"></input></td>
</tr>
<tr>
<td>颜色:</td>
<td><input class="easyui-validatebox" type="color" name="color"
data-options="required:true,validType:'checkName'"></input></td>
</tr>
<tr>
<td>产品图片:</td>
<td> <input class="easyui-filebox" name="empFile" data-options="prompt:'选择一个excel文件'" style="width:80%"></td>
</tr>
<tr>
<td>成本价:</td>
<td><input class="easyui-validatebox" type="text" name="costprice"
data-options="required:true,validType:'checkName'"></input></td>
</tr>
<tr>
<td>售价:</td>
<td><input class="easyui-validatebox" type="text" name="saleprice"
data-options="required:true,validType:'checkName'"></input></td>
</tr>
<tr>
<td>类型:</td>
<td> <input class="easyui-combobox" name="types.id"
data-options="groupField:'group',valueField:'id',textField:'name',panelHeight:'auto',url:'/util/findType'"> </td>
</tr>
<tr>
<td> 单位:</td>
<td> <input name="unit.id" class="easyui-combobox" panelHeight="auto"
data-options="valueField:'id',textField:'name',url:'/util/unitId',required:true" /></td>
</tr>
<tr>
<td>品牌:</td>
<td> <input name="brand.id" class="easyui-combobox" panelHeight="auto"
data-options="valueField:'id',textField:'name',url:'/util/brandId ',required:true" /></td>
</tr>
</table>
</form>
<div style="text-align:center;padding:5px">
<a href="javascript:void(0)" class="easyui-linkbutton" data-method="save">提交</a>
<a href="javascript:void(0)" class="easyui-linkbutton" data-method="closeDialog">关闭</a>
</div>
//解决单位,品牌,类型的回显问题
if(row.unit){
row["unit.id"] = row.unit.id;
}
if(row.brand){
row["brand.id"] = row.brand.id;
}
if(row.types){
row["types.id"] = row.types.id;
}
editForm.form("load", row);
editDialog.dialog("center").dialog("open");
},
save() {
var url = "/product/save";
//获得input标签下的值
var productId = $("#productId").val();
if (productId) {
url = "/product/update?cmd=_update";
}
editForm.form('submit', {
url: url,
//提交的时候检查一次
onSubmit: function () {
// 做一些检查
// 返回false可以阻止提交;
return $(this).form('validate');
},
success: function (data) {
//将后端响应的JSON格式的字符串返回到前端,前端解析成JS对象值(JSON 对象)
var result = JSON.parse(data)
if (result.success) {
productGrid.datagrid("reload")
} else {
$.messager.alert('错误', `失败了! 原因是:${result.msg}`, "error");
}
ilike.closeDialog();
}
})
},
delete() {
let row = productGrid.datagrid("getSelected");
if (!row) {
$.messager.alert('警告', '憨憨', 'warning')
}
$.messager.confirm('确认', '您确认想要删除记录吗?', function (r) {
if (r) {
$.get("/product/delete",{id:row.id}, function (data) {
if (data.success) {
productGrid.datagrid("reload")
} else {
$.messager.alert('错误', `错误! ERROR:${data.msg}`, "error")
}
})
}
});
}
}
})
//value 就是每一行的value值 比如username的名字 数据库里的图片改成了图片所在的地方
function formatimg(value, row, index) {
console.debug(value)
return value ? <img src="${value}" width="50" height="50" id="real" alt="model test picture">
: "无图片 ";
}
function formatColor(value) {
return “
}
function formatbigimg(value) {
return value?
<div class="style1" align="center" > <ul><li><img src='${value}' width="20" > </li></ul>></div>
:" ";
}
function formatTypes(value) {
return value ? value.name : “”;
}
function formatUnit(value) {
return value ? value.name : “”;
}
function formatBrand(value) {
return value ? value.name : “”;
}
function showMenu(e, rowIndex, rowData) {
//选中这个行
$("#productGrid").datagrid(“selectRow”,rowIndex);
//第0个位置的面板不支持相应功能
e.preventDefault();
$(’#gridMenu’).menu(‘show’, {
left: e.pageX,
top: e.pageY
});
}
function loadSuccess(data) {
var rows = data.rows;
for(var i=0;i<rows.length;i++){
var result = rows[i];
.
e
a
s
y
u
i
.
t
o
o
l
t
i
p
.
i
n
i
t
(
.easyui.tooltip.init(
.easyui.tooltip.init((“img[src=’”+result.smallpic+"’]"), {
position: “rigth”,
content: “<div style=“width:600px;height:480px;”>”
});
}
}