APP下载

品优购电商系统开发 第7章 商品修改与稽核

消息来源:baojiabao.com 作者: 发布时间:2024-04-29

报价宝综合消息品优购电商系统开发 第7章 商品修改与稽核

课程目标

目标1:完成商家后台商品列表的功能

目标2:完成商家后台商品修改的功能

目标3:完成运营商后台商品稽核的功能

目标4:完成运营商后台商品删除的功能

目标5:掌握注解式事务的配置

1.商家后台-商品管理【商品列表】

1.1需求分析

在商家后台,显示该商家的商品列表资讯,如下图:

1.2查询商家商品列表

1.2.1后端程式码

修改pinyougou-shop-web工程的GoodsController.java的search方法

@RequestMapping("/search")

public PageResult search(@RequestBody TbGoods goods, int page, int rows ){

//获取商家ID

String sellerId = SecurityContextHolder.getContext().getAuthentication().getName();

//新增查询条件

goods.setSellerId(sellerId);

return goodsService.findPage(goods, page, rows);

}

修改pinyougou-sellergoods-service 工程com.pinyougou.sellergoods.service.impl 的findPage方法,修改条件构建部分程式码,将原来的模糊匹配修改为精确匹配

if(goods.getSellerId()!=null && goods.getSellerId().length()>0){

//criteria.andSellerIdLike("%"+goods.getSellerId()+"%");

criteria.andSellerIdEqualTo(goods.getSellerId());

}

1.2.2前端程式码

修改goods.html. 引入js

新增指令

在页面上放置分页控制元件

循环列表

{{entity.id}}

{{entity.goodsName}}

{{entity.price}}

{{entity.category1Id}}

{{entity.category2Id}}

{{entity.category3Id}}

{{entity.auditStatus}}

修改

显示效果如下:

1.3显示状态

修改goodsController.js,新增state阵列

$scope.status=['未稽核','已稽核','稽核未通过','关闭'];//商品状态

修改列表显示

{{status[entity.auditStatus]}}

显示效果如下:

1.4显示分类

我们现在的列表中的分类仍然显示ID

如何才能显示分类的名称呢?

方案一:在后端程式码写关联查询语句,返回的资料中直接有分类名称。

方案二:在前端程式码用ID去查询后端,异步返回商品分类名称。

我们目前采用方案二:

(1)修改goodsController

$scope.itemCatList=[];//商品分类列表

//载入商品分类列表

$scope.findItemCatList=function(){

itemCatService.findAll().success(

function(response){

for(var i=0;i$scope.itemCatList[response[i].id]=response[i].name;

}

}

);

}

程式码解释:因为我们需要根据分类ID得到分类名称,所以我们将返回的分页结果以阵列形式再次封装。

(2)修改goods.html ,增加初始化呼叫

(3)修改goods.html , 修改列表

{{itemCatList[entity.category1Id]}}

{{itemCatList[entity.category2Id]}}

{{itemCatList[entity.category3Id]}}

1.5条件查询

根据状态和商品名称进行查询

修改goods.html

状态:

全部

未稽核

已稽核

稽核未通过

关闭

商品名称:

查询

2.商家后台-商品管理【商品修改】

2.1需求分析

在商品列表页面点选修改,进入商品编辑页面,并传递引数商品ID,商品编辑页面接受该引数后从数据库中读取商品资讯,使用者修改后储存资讯。

2.2基本资讯读取

我们首选读取商品分类、商品名称、品牌,副标题,价格等资讯

2.2.1后端程式码

(1)修改pinyougou-sellergoods-interface的GoodsService.java

/**

* 根据ID获取实体

* @param id

* @return

*/

public Goods findOne(Long id);

(2)修改pinyougou-sellergoods-service的GoodsServiceImpl.java

@Override

public Goods findOne(Long id) {

Goods goods=new Goods();

TbGoods tbGoods = goodsMapper.selectByPrimaryKey(id);

goods.setGoods(tbGoods);

TbGoodsDesc tbGoodsDesc = goodsDescMapper.selectByPrimaryKey(id);

goods.setGoodsDesc(tbGoodsDesc);

return goods;

}

(3)修改pinyougou-shop-web(和pinyougou-manager-web)的GoodsController.java

/**

* 获取实体

* @param id

* @return

*/

@RequestMapping("/findOne")

public Goods findOne(Long id){

return goodsService.findOne(id);

}

2.2.2前端程式码

(1)在goodsController中引入$location服务

//商品控制层(商家后台)

app.controller('goodsController',function($scope,$controller,$location,goodsService,uploadService,item_catService,type_templateService){

......

(2)修改goodsController 新增程式码:

//查询实体

$scope.findOne=function(){

var id= $location.search()['id'];//获取引数值

if(id==null){

return ;

}

goodsService.findOne(id).success(

function(response){

$scope.entity= response;

}

);

}

在goods_edit.html页面上新增指令

测试:

位址列输入

http://localhost:9102/admin/goods_edit.html#?id=149187842867969

注意: ?前要加# ,则是angularJS的地址路由的书写形式

2.3读取商品介绍(富文字编辑器)

修改前端程式码 goodsController

//查询实体

$scope.findOne=function(){

.................

goodsService.findOne(id).success(

function(response){

$scope.entity= response;

//向富文字编辑器新增商品介绍

editor.html($scope.entity.goodsDesc.introduction);

}

);

}

2.4显示商品图片列表

修改goodsController.js ,在dataLogic方法新增程式码,将图片列表由字串转换为json集合物件

//查询实体

$scope.findOne=function(){

..............

//如果有ID,则查询实体

goodsService.findOne(id).success(

function(response){

$scope.entity= response;

//向富文字编辑器新增商品介绍

editor.html($scope.entity.goodsDesc.introduction);

//显示图片列表

$scope.entity.goodsDesc.itemImages=

JSON.parse($scope.entity.goodsDesc.itemImages);

}

);

}

2.5读取商品扩充套件属性

修改goodsController.js

//查询实体

$scope.findOne=function(){

.........

goodsService.findOne(id).success(

function(response){

.......................

//显示扩充套件属性

$scope.entity.goodsDesc.customAttributeItems= JSON.parse($scope.entity.goodsDesc.customAttributeItems);

}

);

}

经过测试,我们发现扩充套件属性值并没有读取出来,这是因为与下列程式码发生冲突

$scope.$watch('entity.goods.typeTemplateId',function(newValue,oldValue){

......

$scope.entity.goodsDesc.customAttributeItems = JSON.parse($scope.typeTemplate.customAttributeItems);//扩充套件属性

}

我们读取出来的值被覆盖了,我们需要改写程式码, 新增判断,当用户没有传递id引数时再执行此逻辑

//监控模板ID ,读取品牌列表

$scope.$watch('entity.goods.typeTemplateId',function(newValue,oldValue){

//读取品牌列表和扩充套件属性

typeTemplateService.findOne(newValue).success(

function(response){

.......

//如果没有ID,则载入模板中的扩充套件资料

if($location.search()['id']==null){

$scope.entity.goodsDesc.customAttributeItems = JSON.parse($scope.typeTemplate.customAttributeItems);//扩充套件属性

}

}

);

.......

});

2.6读取商品规格属性

修改goodsController

//查询实体

$scope.findOne=function(){

......

goodsService.findOne(id).success(

function(response){

$scope.entity= response;

editor.html($scope.entity.goodsDesc.introduction);//商品介绍

$scope.entity.goodsDesc.itemImages= JSON.parse($scope.entity.goodsDesc.itemImages);//图片列表

//扩充套件属性列表

$scope.entity.goodsDesc.customAttributeItems =JSON.parse($scope.entity.goodsDesc.customAttributeItems);

//规格 $scope.entity.goodsDesc.specificationItems=JSON.parse($scope.entity.goodsDesc.specificationItems);

}

);

}

//根据规格名称和选项名称返回是否被勾选

$scope.checkAttributeValue=function(specName,optionName){

var items= $scope.entity.goodsDesc.specificationItems;

var object= $scope.searchObjectByKey(items,'attributeName',specName);

if(object==null){

return false;

}else{

if(object.attributeValue.indexOf(optionName)>=0){

return true;

}else{

return false;

}

}

}

修改页面上规格面板的复选框,运用 ng-checked指令控制复选框的勾选状态

{{p.optionName}}

2.7读取SKU资料

显示SKU商品列表,并自动读取价格、库存等资料载入到列表中

2.7.1后端程式码

在GoodsServiceImpl的findOne方法中载入SKU商品资料

//查询SKU商品列表

TbItemExample example=new TbItemExample();

com.pinyougou.pojo.TbItemExample.Criteria criteria = example.createCriteria();

criteria.andGoodsIdEqualTo(id);//查询条件:商品ID

List itemList = itemMapper.selectByExample(example);

goods.setItemList(itemList);

2.7.2前端程式码

在goodsController.js修改findOne方法的程式码

//查询实体

$scope.findOne=function(){

........

goodsService.findOne(id).success(

function(response){

$scope.entity= response;

.........

//SKU列表规格列转换

for( var i=0;i$scope.entity.itemList[i].spec =

JSON.parse( $scope.entity.itemList[i].spec);

}

}

);

}

2.8储存资料

2.8.1后端程式码

修改 pinyougou-sellergoods-interface 的 GoodsService.java

public void update(Goods goods);

修改pinyougou-sellergoods-service的GoodsServiceImpl ,将SKU列表插入的程式码提取出来,封装到私有方法中

/**

* 插入SKU列表资料

* @param goods

*/

private void saveItemList(Goods goods){

if("1".equals(goods.getGoods().getIsEnableSpec())){

for(TbItem item :goods.getItemList()){

.........中间程式码略

}

}else{

TbItem item=new TbItem();

.........中间程式码略

itemMapper.insert(item);

}

}

在add方法中呼叫 此方法,修改如下:

public void add(Goods goods) {

goods.getGoods().setAuditStatus("0");

goodsMapper.insert(goods.getGoods()); //插入商品表

goods.getGoodsDesc().setGoodsId(goods.getGoods().getId());

goodsDescMapper.insert(goods.getGoodsDesc());//插入商品扩充套件资料

saveItemList(goods);//插入商品SKU列表资料

}

怎么样,是不是比原来更加清爽了呢?

接下来,我们修改update方法,实现修改

public void update(Goods goods){

goods.getGoods().setAuditStatus("0");//设定未申请状态:如果是经过修改的商品,需要重新设定状态

goodsMapper.updateByPrimaryKey(goods.getGoods());//储存商品表

goodsDescMapper.updateByPrimaryKey(goods.getGoodsDesc());//储存商品扩充套件表

//删除原有的sku列表资料

TbItemExample example=new TbItemExample();

com.pinyougou.pojo.TbItemExample.Criteria criteria = example.createCriteria();

criteria.andGoodsIdEqualTo(goods.getGoods().getId());

itemMapper.deleteByExample(example);

//新增新的sku列表资料

saveItemList(goods);//插入商品SKU列表资料

}

修改pinyougou-manager-web工程的GoodsController.java

@RequestMapping("/update")

public Result update(@RequestBody Goods goods){

......

}

修改pinyougou-shop-web工程的GoodsController.java

/**

* 修改

* @param goods

* @return

*/

@RequestMapping("/update")

public Result update(@RequestBody Goods goods){

//校验是否是当前商家的id

Goods goods2 = goodsService.findOne(goods.getGoods().getId());

//获取当前登入的商家ID

String sellerId = SecurityContextHolder.getContext().getAuthentication().getName();

//如果传递过来的商家ID并不是当前登入的使用者的ID,则属于非法操作

if(!goods2.getGoods().getSellerId().equals(sellerId) || !goods.getGoods().getSellerId().equals(sellerId) ){

return new Result(false, "操作非法");

}

try {

goodsService.update(goods);

return new Result(true, "修改成功");

} catch (Exception e) {

e.printStackTrace();

return new Result(false, "修改失败");

}

}

程式码解释:出于安全考虑,在商户后台执行的商品修改,必须要校验提交的商品属于该商户

2.8.2前端程式码

(1)修改goodsController.js ,新增储存的方法

//储存

$scope.save=function(){

//提取文字编辑器的值

$scope.entity.goodsDesc.introduction=editor.html();

var serviceObject;//服务层物件

if($scope.entity.goods.id!=null){//如果有ID

serviceObject=goodsService.update( $scope.entity ); //修改

}else{

serviceObject=goodsService.add( $scope.entity );//增加

}

serviceObject.success(

function(response){

if(response.success){

alert('储存成功');

$scope.entity={};

editor.html("");

}else{

alert(response.message);

}

}

);

}

(2)修改goods_edit.html 呼叫

储存

2.9页面跳转

(1)由商品列表页跳转到商品编辑页

修改goods.html表格行的修改按钮

修改

(2)由商品编辑页跳转到商品列表

修改goods_edit.html 的返回列表按钮

返回列表

(3)储存成功后返回列表页面

//储存

$scope.save=function(){

.....

serviceObject.success(

function(response){

if(response.success){

location.href="goods.html";//跳转到商品列表页

}else{

alert(response.message);

}

}

);

}

3.运营商后台-商品管理【商品稽核】

3.1待稽核商品列表

需求:参照商家后台商品列表。程式码:

(1)修改pinyougou-manager-web的goodsController.js,注入itemCatService,新增程式码

$scope.status=['未稽核','已稽核','稽核未通过','关闭'];//商品状态

$scope.itemCatList=[];//商品分类列表

//查询商品分类

$scope.findItemCatList=function(){

itemCatService.findAll().success(

function(response){

for(var i=0;i$scope.itemCatList[response[i].id ]=response[i].name;

}

}

);

}

(2)修改goods.html ,引入js

(3)指令,完成初始呼叫

(4)循环列表

{{entity.id}}

{{entity.goodsName}}

{{entity.price}}

{{itemCatList[entity.category1Id]}}

{{itemCatList[entity.category2Id]}}

{{itemCatList[entity.category3Id]}}

{{status[entity.auditStatus]}}

(5)分页控制元件

3.2商品详情展示(学员实现)

需求:点选列表右侧的“详情”按钮,弹出视窗显示商品资讯。程式码略。

3.3商品稽核与驳回

需求:商品稽核的状态值为1,驳回的状态值为2 。使用者在列表中选中ID后,点选稽核或驳回,修改商品状态,并重新整理列表。

3.3.1后端程式码

(1)在pinyougou-sellergoods-interface的GoodsService.java新增方法定义

/**

* 批量修改状态

* @param ids

* @param status

*/

public void updateStatus(Long []ids,String status);

(2)在pinyougou-sellergoods-service的GoodsServiceImpl.java实现该方法

public void updateStatus(Long[] ids, String status) {

for(Long id:ids){

TbGoods goods = goodsMapper.selectByPrimaryKey(id);

goods.setAuditStatus(status);

goodsMapper.updateByPrimaryKey(goods);

}

}

(3)在pinyougou-shop-web的GoodsController.java新增方法

/**

* 更新状态

* @param ids

* @param status

*/

@RequestMapping("/updateStatus")

public Result updateStatus(Long[] ids, String status){

try {

goodsService.updateStatus(ids, status);

return new Result(true, "成功");

} catch (Exception e) {

e.printStackTrace();

return new Result(false, "失败");

}

}

3.3.2前端程式码

(1)修改pinyougou-manager-web的goodsService.js ,增加方法

//更改状态

this.updateStatus=function(ids,status){

return $http.get('../goods/updateStatus.do?ids='+ids+"&status="+status);

}

(2)修改pinyougou-manager-web的goodsController.js ,增加方法

//更改状态

$scope.updateStatus=function(status){

goodsService.updateStatus($scope.selectIds,status).success(

function(response){

if(response.success){//成功

$scope.reloadList();//重新整理列表

$scope.selectIds=[];//清空ID集合

}else{

alert(response.message);

}

}

);

}

(3)修改pinyougou-manager-web的goods.html 页面,为复选框系结事件指令

(4)修改页面上的稽核通过和驳回按钮

稽核通过

驳回

4.运营商后台-商品管理【商品删除】

4.1需求分析

我们为商品管理提供商品删除功能,使用者选中部分商品,点选删除按钮即可实现商品删除。注意,这里的删除并非是物理删除,而是修改tb_goods表的is_delete字段为1 ,我们可以称之为“逻辑删除”

4.2逻辑删除的实现

4.2.1后端程式码

修改pinyougou-sellergoods-service工程的GoodsServiceImpl.java的delete方法

/**

* 批量删除

*/

@Override

public void delete(Long[] ids) {

for(Long id:ids){

TbGoods goods = goodsMapper.selectByPrimaryKey(id);

goods.setIsDelete("1");

goodsMapper.updateByPrimaryKey(goods);

}

}

4.2.2前端程式码

修改pinyougou-manager-web的goods.html上的删除按钮

删除

4.3排除已删除记录

修改pinyougou-sellergoods-service工程GoodsServiceImpl.java的findPage方法,新增以下程式码:

criteria.andIsDeleteIsNull();//非删除状态

5.商家后台-【商品上下架】(学员实现)

5.1需求分析

什么是商品上下架?其实上下架也是商品的一个状态,但是不同于稽核状态。稽核状态的控制权在运营商手中,而上下架的控制权在商户手中。商户可以随时将一个已稽核状态的商品上架或下架。上架表示正常销售,而下架则表示暂停销售。

5.2实现思路提示

其实商品的上下架就是对上下架状态的修改。字段为tb_goods表的is_marketable字段。1表示上架、0表示下架。

6.注解式事务配置

6.1事务异常测试

我们修改pinyougou-sellergoods-service工程GoodsServiceImpl.java的add方法

/**

* 增加

*/

@Override

public void add(Goods goods) {

goods.getGoods().setAuditStatus("0");

goodsMapper.insert(goods.getGoods()); //插入商品表

int x=1/0;

goods.getGoodsDesc().setGoodsId(goods.getGoods().getId());

goodsDescMapper.insert(goods.getGoodsDesc());//插入商品扩充套件资料

saveItemList(goods);//插入商品SKU列表资料

}

在插入商品表后,人为制造一个异常。我们执行程式,新增商品资料,观察执行结果。

通过观察,我们发现,程式发生异常 ,商品表仍然会储存记录,这是不符合我们要求的。这是因为我们目前的系统还没有配置事务。

6.2注解式事务解决方案

6.2.1配置档案

在pinyougou-sellergoods-service工程的spring目录下建立applicationContext-tx.xml

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:tx="http://www.springframework.org/schema/tx"

xmlns:mvc="http://www.springframework.org/schema/mvc"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd

http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

6.2.2在方法上添加注解

/**

* 服务实现层

* @author Administrator

*

*/

@Service

@Transactional

public class GoodsServiceImpl implements GoodsService{

........

}

经过测试,我们发现,系统发生异常,商品表不会新增记录,事务配置成功。

删除掉测试程式码int x=1/0

我们需要将所有涉及多表操作的服务类新增事务注解,例如SpecificationServiceImpl类

2019-11-08 14:58:00

相关文章