今日目标:
(1)完成商家后台商品列表的管理
(2)完成商家后台商品修改
(3)完成运营商后台商品审核
(4)完成运营商后台商品删除
(5)掌握注解式事务的配置
目录
1、商品管理-列表展示
1.1 后端
1.2 前端
2、商品管理-修改
2.1 基本信息的读取
2.2 读取商品介绍(富文本编辑器中的内容)
2.3 显示商品图片列表
2.4 显示扩展属性
2.5 显示商品规格属性
2.6 显示SKU商品列表信息
2.7 保存要修改的数据
2.8 商品管理页面点击修改按钮,进行页面跳转,并传递要修改的商品的ID
3、运营商后台审核商品
3.1 展示未审核商品列表
3.2 商品详情展示
3.3 商品审核
4、商品管理-商品删除
(1)GoodsController(shop-web),修改search方法
/**
* 查询+分页
*
* @param goods
* @param page
* @param rows
* @return
*/
@RequestMapping("/search")
public PageResult search(@RequestBody TbGoods goods, int page, int rows) {
// 设置商家ID到查询条件对象中
goods.setSellerId(SecurityContextHolder.getContext().getAuthentication().getName());
return goodsService.findPage(goods, page, rows);
}
(2)GoodsServiceImpl(sellergoods-service),修改search实现中的sellerId为精确查询
(1)引入JS文件和angular js的相关指令
(2)绑定变量,循环展示商品信息
(3)效果:
(4)状态列显示格式化
a、goodsController.js 添加代码
// 状态对应的值列表
/*
数据库中状态的值本身为:0,1,2,3,刚好对应列表的下标
*/
$scope.status = ['未审核','已审核','审核未通过','已关闭'];
b、页面绑定变量修改
c、效果
(5)分类显示格式化
a、编辑goodsController.js,新增方法
// 初始化商品分类列表
$scope.itemCatList = [];
// 查询商品分类列表,并将其赋值给itemCatList,其中id为下标,name为值
$scope.findItemCatList = function () {
itemCatService.findAll().success(
function (rtn) {
for (var i = 0; i < rtn.length; i++) {
// 以id为下标,name为值,放入商品分类列表
$scope.itemCatList[rtn[i].id] = rtn[i].name;
}
}
);
}
b、页面绑定变量修改
c、效果
(6)商品查询,页面绑定变量以及单击事件即可
(1)后端:服务层实现(sellergoods-service),修改GoodsService中的findOne方法
/**
* 根据ID获取实体
*
* @param id
* @return
*/
@Override
public Goods findOne(Long id) {
// 返回的组合实体类
Goods goods = new Goods();
// 获取商品的基本信息
TbGoods tbGoods = goodsMapper.selectByPrimaryKey(id);
// 获取商品的扩展信息
TbGoodsDesc tbGoodsDesc = goodsDescMapper.selectByPrimaryKey(id);
// 获取SKU商品列表信息
TbItemExample itemExample = new TbItemExample();
itemExample.createCriteria().andGoodsIdEqualTo(id);
List itemList = itemMapper.selectByExample(itemExample);
// 将查询到的数据保存到组合实体类中
goods.setGoods(tbGoods);
goods.setGoodsDesc(tbGoodsDesc);
goods.setItemList(itemList);
return goods;
}
(2)后端:控制层,修改findOne方法,让其返回组合实体类
(3)前端:页面跳转时,静态传参需要引入angular js的内置服务,在goodsController中注入$location服务
(4)前端:改造goodsController.js中的findOne方法
//查询实体
$scope.findOne = function () {
// 查看是否有参数传递
var id = $location.search()['id'];
if (id == null) {// 没有
return ;
}
// 有id参数传递,查询该id的数据
goodsService.findOne(id).success(
function (response) {
$scope.entity = response;
}
);
}
(5)前端:页面初始化调用findOne方法
(6)效果:
(1)前端:修改goodsController.js中的findOne方法
(2)效果:
(1)前端:修改goodsController.js中的findOne方法
(2)效果:
(1)前端:修改goodsController.js中的findOne的方法
(2)前端:修改监控模板ID的方法
(3)效果:
(1)前端:修改goodsController.js中的findOne的方法
(2)前端:编写goodsController.js,新增方法
// 根据规格选项数据选中对应复选框
$scope.checkAttributeValue = function (specName, optionName) {
// 在集合中查询是否有对应的值存在
var object = $scope.searchObjectByKey($scope.entity.goodsDesc.specificationItems, 'attributeName', specName);
// 判断是否存在
if (object != null) { // 存在该规格
// 继续判断规格中是否有该属性值
var index = object.attributeValue.indexOf(optionName);
if (index != -1) {// 存在该属性值
return true;
} else {// 不存在该属性值
return false;
}
}
// 不存在
return false;
}
(3)前端:页面使用ng-checked指令,调用新增的方法
(4)效果:
(1)前端:修改goodsController.js中的findOne方法
(2)效果:
(1)后端:服务层实现(sellergoods-service),GoodsServiceImpl中的update方法
/**
* 修改
*/
@Override
public void update(Goods goods) {
/***************************
* 保存商品基本信息到goods表 *
**************************/
// 补全商品基本信息
TbGoods tbGoods = goods.getGoods();
// 保存商品基本信息
goodsMapper.updateByPrimaryKey(tbGoods);
/*******************************
* 保存商品扩展信息到goodsdesc表 *
*******************************/
// 补全商品扩展信息数据
TbGoodsDesc tbGoodsDesc = goods.getGoodsDesc();
// 保存商品扩展信息
goodsDescMapper.updateByPrimaryKey(tbGoodsDesc);
/*******************************
* 保存SKU商品信息到 item表 *
*******************************/
// 删除原有SKU商品列表
TbItemExample itemExample = new TbItemExample();
itemExample.createCriteria().andGoodsIdEqualTo(tbGoods.getId());
itemMapper.deleteByExample(itemExample);
// 再进行保存
saveItemList(goods, tbGoods, tbGoodsDesc);
}
(2)后端:控制层(shop-web),修改GoodsController中的update方法参数类型,并加上安全性校验
/**
* 修改
*
* @param goods
* @return
*/
@RequestMapping("/update")
public Result update(@RequestBody Goods goods) {
// 判断当前商家修改的商品是否属于该商家
String sellerId = SecurityContextHolder.getContext().getAuthentication().getName();
// 查询要操作的商品组合对象
Goods _goods = goodsService.findOne(goods.getGoods().getId());
if (!sellerId.equals(_goods.getGoods().getSellerId()) &&
!sellerId.equals(goods.getGoods().getSellerId())) {// 该商品不是该商家的商品
return new Result(false, "非法操作");
}
try {
goodsService.update(goods);
return new Result(true, "修改成功");
} catch (Exception e) {
e.printStackTrace();
return new Result(false, "修改失败");
}
}
(3)前端:修改goodsController.js中的add方法为save方法
//增加商品
$scope.save = function () {
// 将富文本编辑器中的内容,赋值给商品描述对象
$scope.entity.goodsDesc.introduction = editor.html();
var serviceObject;
if($scope.entity.goods.id != null) {
serviceObject = goodsService.update($scope.entity);
} else {
serviceObject = goodsService.add($scope.entity);
}
serviceObject.success(
function (response) {
if (response.success) {
// 显示新增成功
alert("新增成功");
// 清空编辑痕迹
$scope.entity = {};
editor.html('');
$scope.specList = [];
} else {
alert(response.message);
}
}
);
}
(4)前端:页面保存按钮绑定单击事件
(1)前端:goods.html页面,修改修改按钮的链接地址
(1)前端:修改goodsController.js(manager-web),添加方法,并注入itemServivce服务
// 状态对应的值列表
/*
数据库中状态的值本身为:0,1,2,3,刚好对应列表的下标
*/
$scope.status = ['未审核', '已审核', '审核未通过', '已关闭'];
// 初始化商品分类列表
$scope.itemCatList = [];
// 查询商品分类列表,并将其赋值给itemCatList,其中id为下标,name为值
$scope.findItemCatList = function () {
itemCatService.findAll().success(
function (rtn) {
for (var i = 0; i < rtn.length; i++) {
// 以id为下标,name为值,放入商品分类列表
$scope.itemCatList[rtn[i].id] = rtn[i].name;
}
}
);
}
(2)前端:页面引入JS文件,书写angular js的相关指令,并初始化执行新添加的方法,且该方法之前设置searchEntity的状态为0
(3)前端:循环展示商品列表,注意引入分页组件
(4)效果:
(1)前端:修改修改按钮为详情按钮,并添加单击打开商品详情窗口,弹出窗口中的内容,从goods_edit.html中复制即可
(2)显示商品基本信息,给详情按钮添加单击事件,单击时执行findOne()方法
(3)显示商品的品牌,编辑goodsController.js,新增方法
// 监控品牌ID
$scope.$watch('entity.goods.brandId', function (newValue, oldValue) {
brandService.findOne(newValue).success(
function (rtn) {
$scope.brandName = rtn.name;
}
);
});
(4)显示图片列表,修改goodsController.js中的findOne方法
(5)显示扩展属性
注意:我这里只展示了基本信息、图片列表、扩展信息,不包括商品介绍、规格以及SKU商品列表,所以不包括部分的HTML代码我都删除了,其实大致的步骤和goods_edit.html差不多。
(1)后端:服务层接口(sellergoods-interface),在GoodsService中新增方法
/**
* 审核
*
* @param ids 要审核的商品id
* @param status 审核后的状态
*/
void updateStatus(Long[] ids,String status);
(2)后端:服务层实现(sellergoods-service),在GoodsServiceImpl中新增实现
@Override
public void updateStatus(Long[] ids, String status) {
for (long id : ids) {
// 按ID查询商品
TbGoods tbGoods = goodsMapper.selectByPrimaryKey(id);
// 修改状态并保存
tbGoods.setAuditStatus(status);
goodsMapper.updateByPrimaryKey(tbGoods);
}
}
(3)后端:控制层(manager-web),在GoodsController中新增方法
/**
* 批量审核商品
*
* @param ids
* @param status
*/
@RequestMapping("/updateStatus")
public Result updateStatus(Long[] ids, String status) {
try {
goodsService.updateStatus(ids,status);
return Result.success("操作成功");
}catch (Exception e){
e.printStackTrace();
return Result.error("操作失败");
}
}
(4)前端:编写goodsService.js,新增方法
//审核
this.updateStatus = function (ids,status) {
return $http.get('../goods/updateStatus.do?ids=' + ids + "&status=" + status);
}
(5)前端:编写goodsController.js,新增方法
// 修改商品状态
$scope.updateStatus = function (status) {
goodsService.updateStatus($scope.selectIds,status).success(
function (rtn) {
alert(rtn.message);
if(rtn.success){
// 刷新页面
$scope.reloadList();
}
}
);
}
(6)前端:给复选框绑定单击事件
(7)前端:给审核和驳回按钮添加单击事件
(1)后端:服务层实现(sellergoods-service),修改GoodsServiceImpl中的delete方法的实现
/**
* 批量删除
*/
@Override
public void delete(Long[] ids) {
for (Long id : ids) {
// 假删除
TbGoods tbGoods = goodsMapper.selectByPrimaryKey(id);
if (tbGoods != null && tbGoods.getIsDelete().equals(TbGoods.ISDELETE_NO)){
tbGoods.setIsDelete(TbGoods.ISDELETE_YES);
}
// 保存修改
goodsMapper.updateByPrimaryKey(tbGoods);
}
}
(2)前端:页面上删除按钮绑定单击事件