1 课程计划
后台管理商品的添加功能
1、商品分类选择
2、上传图片
3、富文本编辑器(kindEditor)
4、实现商品的添加
5、课后作业(商品的修改、删除)
2 商品添加功能说明
3 类目选择
3.1 需求
点击类目选择按钮弹出类目选择窗口,窗口中是一个树形视图。分级展示商品分类。当选择商品分类的叶子节点后,关闭窗口并将选中的商品分类的名称显示到网页上。
1、初始化tree的url:
/item/cat/list
2、请求的参数
Id(当前节点的id,根据此id查询子节点)
3、返回数据的格式json数据:
[{
"id": 1, //当前节点的id
"text": "Node 1", //节点显示的名称
"state": "closed" //节点的状态,如果是closed就是一个文件夹形式,
// 当打开时还会 做一次请求。如果是open就显示为叶子节点。
},{
"id": 2,
"text": "Node 2",
"state": "closed"
}]
3.1 Mapper
数据中的表:
3.1.1 Sql语句
SELECT * FROM `tb_item_cat` where parent_id=父节点id;
可以使用 逆向工程生成的mapper。
3.1 Service层
功能:根据parentId查询商品分类列表。
参数:parentId
返回值:返回tree所需要的数据结构,是一个节点列表。
可以创建一个tree node的pojo表示节点的数据,也可以使用map。
List<TreeNode>
3.1.1 创建一个tree node的pojo:
是一个通用的pojo可以放到taotao-common中。
public class TreeNode { private long id; private String text; private String state; public TreeNode(long id, String text, String state) { this.id = id; this.text = text; this.state = state; } public long getId() { return id; } public void setId(long id) { this.id = id; } public String getText() { return text; } public void setText(String text) { this.text = text; } public String getState() { return state; } public void setState(String state) { this.state = state; }
} |
3.1.2 代码实现
@Service public class ItemCatServiceImpl implements ItemCatService {
@Autowired private TbItemCatMapper itemCatMapper; @Override public List<TreeNode> getItemCatList(long parentId) { //根据parentId查询分类列表 TbItemCatExample example = new TbItemCatExample(); //设置查询条件 Criteria criteria = example.createCriteria(); criteria.andParentIdEqualTo(parentId); //执行查询 List<TbItemCat> list = itemCatMapper.selectByExample(example); //分类列表转换成TreeNode的列表 List<TreeNode> resultList = new ArrayList<>(); for (TbItemCat tbItemCat : list) { //创建一个TreeNode对象 TreeNode node = new TreeNode(tbItemCat.getId(), tbItemCat.getName(), tbItemCat.getIsParent()?"closed":"open"); resultList.add(node); } return resultList; }
} |
3.2 表现层
功能:接收页面传递过来的id,作为parentId查询子节点。
参数:Long id
返回值:要返回json数据要使用@ResponseBody。List<TreeNode>
@Controller @RequestMapping("/item/cat") public class ItemCatController {
@Autowired private ItemCatService itemCatService; @RequestMapping("/list") @ResponseBody public List<TreeNode> getItemCatList(@RequestParam(value="id", defaultValue="0")Long parentId) { List<TreeNode> list = itemCatService.getItemCatList(parentId); return list; } } |
4 图片上传
4.1 图片上传实现
1.1.1 需求分析
Common.js
1、绑定事件
2、初始化参数
3、上传图片的url:
/pic/upload
4、上图片参数名称:
uploadFile
5、返回结果数据类型json
参考文档:
http://kindeditor.net/docs/upload.html
返回格式(JSON)
//成功时 { "error" : 0, "url" : "http://www.example.com/path/to/file.ext" } //失败时 { "error" : 1, "message" : "错误信息" } |
1.1.2 Service
功能:接收controller层传递过来的图片对象,把图片上传到ftp服务器。给图片生成一个新的名字。
参数:MultiPartFile uploadFile
返回值:返回一个pojo,应该是PictureResult。
1.1.2.1 PictureResult
应该把此pojo放到taotao-common工程中。
public class PictureResult {
private int error; private String url; private String message; private PictureResult(int error, String url, String message) { this.error = error; this.url = url; this.message = message; } //成功时调用的方法 public static PictureResult ok(String url) { return new PictureResult(0, url, null); } //失败时调用的方法 public static PictureResult error(String message) { return new PictureResult(1, null, message); } public int getError() { return error; } public void setError(int error) { this.error = error; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } |
1.1.2.2 Service实现
@Service public class PictureServiceImpl implements PictureService { @Value("${FTP_ADDRESS}") private String FTP_ADDRESS; @Value("${FTP_PORT}") private Integer FTP_PORT; @Value("${FTP_USER_NAME}") private String FTP_USER_NAME; @Value("${FTP_PASSWORD}") private String FTP_PASSWORD; @Value("${FTP_BASE_PATH}") private String FTP_BASE_PATH; @Value("${IMAGE_BASE_URL}") private String IMAGE_BASE_URL;
@Override public PictureResult uploadPicture(MultipartFile uploadFile) { //判断上传图片是否为空 if (null == uploadFile || uploadFile.isEmpty()) { return PictureResult.error("上传图片为空"); } //取文件扩展名 String originalFilename = uploadFile.getOriginalFilename(); String ext = originalFilename.substring(originalFilename.lastIndexOf(".")); //生成新文件名 //可以使用uuid生成新文件名。 //UUID.randomUUID() //可以是时间+随机数生成文件名 String imageName = IDUtils.genImageName(); //把图片上传到ftp服务器(图片服务器) //需要把ftp的参数配置到配置文件中 //文件在服务器的存放路径,应该使用日期分隔的目录结构 DateTime dateTime = new DateTime(); String filePath = dateTime.toString("/yyyy/MM/dd"); try { FtpUtil.uploadFile(FTP_ADDRESS, FTP_PORT, FTP_USER_NAME, FTP_PASSWORD, FTP_BASE_PATH, filePath, imageName + ext, uploadFile.getInputStream()); } catch (Exception e) { e.printStackTrace(); return PictureResult.error(ExceptionUtil.getStackTrace(e)); } //返回结果,生成一个可以访问到图片的url返回 return PictureResult.ok(IMAGE_BASE_URL + filePath + "/" + imageName + ext); }
} |
1.1.3 Controller
功能:接收页面传递过来的图片。调用service上传到图片服务器。返回结果。
参数:MultiPartFile uploadFile
返回值:返回json数据,应该返回一个pojo,PictureResult对象。
@Controller public class PictureController { @Autowired private PictureService pictureService; @RequestMapping("/pic/upload") @ResponseBody public PictureResult upload(MultipartFile uploadFile) { PictureResult result = pictureService.uploadPicture(uploadFile); return result; } } |
1.1.4 Springmvc.xml
<!-- 定义文件上传解析器 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 设定默认编码 --> <property name="defaultEncoding" value="UTF-8"></property> <!-- 设定文件上传的最大值5MB,5*1024*1024 --> <property name="maxUploadSize" value="5242880"></property> </bean> |
2 富文本编辑器
2.1 使用方法
第一步:在jsp中加入富文本编辑器js的引用。
第二步:在富文本编辑器出现的位置添加一个input 类型为textarea
第三步:调用js方法初始化富文本编辑器。
第四步:提交表单时,调用富文本编辑器的同步方法sync,把富文本编辑器中的内容同步到textarea中。
6、商品添加功能实现
1.1 功能分析
1、请求的url
/item/save
2、返回结果,自定义。
TaotaoResult,参见参考资料。
1.2 Dao层
1.2.1 数据库
商品表、商品描述表。
分开的目的是为了提高查询效率。
1.1.1 Mapper文件
逆向工程生成的mapper可以使用。
1.1 Service层
功能分析:接收controller传递过来的对象一个是item一个是itemDesc对象。需要生成商品的id。把不为空的字段都补全。分别向两个表中插入数据。
参数:TbItem,TbItemDesc
返回值:TaotaoResult
@Override public TaotaoResult addItem(TbItem item, TbItemDesc itemDesc) { try { //生成商品id //可以使用redis的自增长key,在没有redis之前使用时间+随机数策略生成 Long itemId = IDUtils.genItemId(); //补全不完整的字段 item.setId(itemId); item.setStatus((byte) 1); Date date = new Date(); item.setCreated(date); item.setUpdated(date); //把数据插入到商品表 itemMapper.insert(item); //添加商品描述 itemDesc.setItemId(itemId); itemDesc.setCreated(date); itemDesc.setUpdated(date); //把数据插入到商品描述表 itemDescMapper.insert(itemDesc); } catch (Exception e) { e.printStackTrace(); return TaotaoResult.build(500, ExceptionUtil.getStackTrace(e)); } return TaotaoResult.ok(); } |
1.2 Controller
功能分析:接收页面传递过来的数据包括商品和商品描述。
参数:TbItem、TbItemDesc。
返回值:TaotaoResult
@RequestMapping("/save") @ResponseBody public TaotaoResult addItem(TbItem item, String desc) { TbItemDesc itemDesc = new TbItemDesc(); itemDesc.setItemDesc(desc); TaotaoResult result = itemService.addItem(item, itemDesc); return result; } |