校园商铺-8商品模块-10商品列表展示之后端开发

1.Dao层

1.1 Dao接口

package com.csj2018.o2o.dao;

import java.util.List;

import org.apache.ibatis.annotations.Param;

import com.csj2018.o2o.entity.Product;

public interface ProductDao {
	/**
	 * 8-10查询商品列表并分页,可输入的条件有:商品名(模糊)、商品状态,店铺ID,商品类别
	 * @param productCondition
	 * @param beginIndex
	 * @param pageSize
	 * @return
	 */
	List<Product> queryProductList(@Param("productCondition") Product productCondition, @Param("rowIndex") int rowIndex, @Param("pageSize") int pageSize);
	/**
	 * 8-10查询对应的商品总数
	 * @param productCondition
	 * @return
	 */
	int queryProductCount(@Param("productCondition") Product productCondition);
	Product queryProductById(Long productId);
	/**
	 * 插入商品
	 * @param product
	 * @return
	 */
	int insertProduct(Product product);
	/**
	 * 更新商品信息
	 * @param product
	 * @return
	 */
	int updateProduct(Product product);
	int updateProductCategoryToNull(Long productId);
	int deleteProduct(Product product);
}

1.2Dao实现mapper

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
 <mapper namespace="com.csj2018.o2o.dao.ProductDao"><!-- 对应接口类名 -->
 	<resultMap id="productMap" type="com.csj2018.o2o.entity.Product">
 		<id column="product_id" property="productId" />
 		<result column="product_name" property="productName" />
 		<result column="product_desc" property="productDesc" />
 		<result column="img_addr" property="imgAddr" />
 		<result column="normal_price" property="normalPrice" />
 		<result column="promotion_price" property="promotionPrice" />
 		<result column="priority" property="priority" />
 		<result column="create_time" property="createTime" />
 		<result column="last_edit_time" property="lastEditTime" />
 		<result column="enable_status" property="enableStatus" />
 		<association property="productCategory" column="product_category_id" javaType="com.csj2018.o2o.entity.ProductCategory">
 			<id column="product_category_id" property="productCategoryId" />
 			<result column="product_category_name" property="productCategoryName" />
 		</association>
 		<association property="shop" column="shop_id" javaType="com.csj2018.o2o.entity.Shop">
 			<id column="shop_id" property="shopId" />
 			<result column="shop_id" property="shopId" />
 		</association>
 		<collection property="productImgList" column="product_id" ofType="com.csj2018.o2o.entity.ProductImg">
 			<id column="product_img_id" property="productImgId" />
 			<result column="detail_img" property="imgAddr" /><!-- 有疑问,为什么不是img_addr -->
 			<result column="img_desc" property="imgDesc" />
 			<result column="priority" property="priority" />
 			<result column="create_time" property="createTime" />
 			<result column="product_id" property="productId" />
 		</collection>
 	</resultMap>
 	<select id="queryProductById" resultMap="productMap" parameterType="long">
 		select
 		p.product_id, p.product_name, p.product_desc, p.img_addr, p.normal_price, p.promotion_price, p.priority,
 		p.create_time, p.last_edit_time, p.enable_status, p.product_category_id, p.shop_id,
 		pm.product_img_id, pm.img_addr as detail_img, pm.img_desc, pm.priority, pm.create_time
 		from tb_product p left join tb_product_img pm 
 		on p.product_id = pm.product_id
 		where p.product_id = #{productId}
 		order by pm.priority desc
 	</select>
 	<update id="updateProduct" parameterType="com.csj2018.o2o.entity.Product" keyProperty="product_id" useGeneratedKeys="true">
 		update tb_product
 		<set>
 			<if test="productName != null">product_name = #{productName},</if>
 			<if test="productDesc != null">product_desc = #{productDesc},</if>
 			<if test="imgAddr != null">img_addr = #{imgAddr},</if>
 			<if test="normalPrice != null" >normal_price = #{normalPrice},</if>
 			<if test="promotionPrice != null">promotion_price = #{promotionPrice},</if>
 			<if test="priority != null">priority = #{priority},</if>
 			<if test="lastEditTime != null">last_edit_time = #{lastEditTime},</if>
 			<if test="enableStatus != null">enable_status = #{enableStatus},</if>
 			<if test="productCategory != null and productCategory.productCategoryId != null">product_category_id = #{productCategory.productCategoryId}</if> 
 		</set>
 		where product_id = #{productId} and shop_id = #{shop.shopId}<!--shop_id = #{shop.shopId}保证了不会操作别的店铺的商品 -->
 	</update>
    <insert id="insertProduct" parameterType="com.csj2018.o2o.entity.Product" useGeneratedKeys="true" keyProperty="productId" keyColumn="product_id">
        insert into tb_product(
            product_name,product_desc,img_addr,normal_price,promotion_price,
            priority,create_time,last_edit_time,enable_status,product_category_id,shop_id
        )values(
            #{productName},#{productDesc},#{imgAddr},#{normalPrice},#{promotionPrice},
            #{priority},#{createTime},#{lastEditTime},#{enableStatus},#{productCategory.productCategoryId},#{shop.shopId}
        )
    </insert>
	<select id="queryProductList" resultType="com.csj2018.o2o.entity.Product">
		select 
			product_id, product_name, product_desc, img_addr,
			normal_price, promotion_price, priority, create_time,
			last_edit_time, enable_status, product_category_id, shop_id
		from tb_product
		<where>
			<if test="productCondition.shop != null and productCondition.shop.shopId != null">
				and shop_id = #{productCondition.shop.shopId}	
			</if>
			<if test="productCondition.productCategory != null and productCondition.productCategory.productCategoryId != null">
				and product_category_id = #{productCondition.productCategory.productCategoryId}
			</if>
			<!-- 写like语句的时候 一般都会写成like '% %',在mybatis里面写就是like '%${name}%',而不是like '%#{name}%'。${name}是不带单引号的,#{name}是带单引号的。-->
			<if test="productCondition.productName != null ">
				and product_name like '%${productCondition.productName}%'
			</if>
			<if test="productCondition.enableStatus != null">
				and enable_status = #{productCondition.enableStatus}
			</if>
		</where>
		order by priority desc limit #{rowIndex},#{pageSize};
	</select>    
	<select id="queryProductCount" resultType="int">
		select count(1) from tb_product
		<where>
			<if test="productCondition.shop != null and productCondition.shop.shopId != null">
				and shop_id = #{productCondition.shop.shopId}	
			</if>
			<if test="productCondition.productCategory != null and productCondition.productCategory.productCategoryId != null">
				and product_category_id = #{productCondition.productCategory.productCategoryId}
			</if>
			<!-- 写like语句的时候 一般都会写成like '% %',在mybatis里面写就是like '%${name}%',而不是like '%#{name}%'。${name}是不带单引号的,#{name}是带单引号的。-->
			<if test="productCondition.productName != null">
				and product_name like '%${productCondition.productName}%'
			</if>
			<if test="productCondition.enableStatus != null">
				and enable_status = #{productCondition.enableStatus}
			</if>
		</where>
	</select>
 </mapper>

1.3 Dao单元测试

package com.csj2018.o2o.dao;


import static org.junit.Assert.assertEquals;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.junit.FixMethodOrder;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runners.MethodSorters;
import org.springframework.beans.factory.annotation.Autowired;

import com.csj2018.o2o.BaseTest;
import com.csj2018.o2o.entity.Product;
import com.csj2018.o2o.entity.ProductCategory;
import com.csj2018.o2o.entity.ProductImg;
import com.csj2018.o2o.entity.Shop;

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class ProductDaoTest extends BaseTest{
	@Autowired
	private ProductDao productDao;
	@Autowired
	private ProductImgDao productImgDao;
	
	@Test
	@Ignore
	public void testAInsertProduct() throws Exception{
		Shop shop1 = new Shop();
		shop1.setShopId(1L);
		ProductCategory pc1 = new ProductCategory();
		pc1.setProductCategoryId(10L);
		Product product1 = new Product();
		product1.setProductName("商品1");
		product1.setProductDesc("商品1的描述");
		product1.setImgAddr("商品1的缩略图");
		product1.setPriority(1);
		product1.setEnableStatus(1);
		product1.setCreateTime(new Date());
		product1.setLastEditTime(new Date());
		product1.setShop(shop1);
		product1.setProductCategory(pc1);
		
		Product product2 = new Product();
		product2.setProductName("商品2");
		product2.setProductDesc("商品2的描述");
		product2.setImgAddr("商品2的缩略图");
		product2.setPriority(2);
		product2.setEnableStatus(0);
		product2.setCreateTime(new Date());
		product2.setLastEditTime(new Date());
		product2.setShop(shop1);
		product2.setProductCategory(pc1);
		
		Product product3 = new Product();
		product3.setProductName("商品3");
		product3.setProductDesc("商品3的描述");
		product3.setImgAddr("商品3的缩略图");
		product3.setPriority(3);
		product3.setEnableStatus(1);
		product3.setCreateTime(new Date());
		product3.setLastEditTime(new Date());
		product3.setShop(shop1);
		product3.setProductCategory(pc1);
		
		int effectedNum = productDao.insertProduct(product1);
		assertEquals(1,effectedNum);
		effectedNum = productDao.insertProduct(product2);
		assertEquals(1,effectedNum);
		effectedNum = productDao.insertProduct(product3);
		assertEquals(1,effectedNum);
	}
	//8-10
	@Test
	public void testBQueryProductList() {
		//product表原有9条数据,商品名包含测试的有1条
		Product productCondition = new Product();
		//分页查询,预期返回3条数据
		List<Product> productList = productDao.queryProductList(productCondition, 0, 3);
		assertEquals(3,productList.size());
		int count = productDao.queryProductCount(productCondition);
		assertEquals(9,count);
		//查询名称为测试的商品总数
		productCondition.setProductName("测试");
		productList = productDao.queryProductList(productCondition, 0, 3);
		count = productDao.queryProductCount(productCondition);
		assertEquals(1,count);
	}
	@Test
	@Ignore
	public void testCQueryProductByProductId() throws Exception{
		long productId = 1;
		//初始化两个商品详情图实例,作为productId为1的商品下的详情图片
		//批量插入到商品详情图标中
		ProductImg productImg1 = new ProductImg();
		productImg1.setImgAddr("图片1");
		productImg1.setImgDesc("测试图片1");
		productImg1.setPriority(1);
		productImg1.setCreateTime(new Date());
		productImg1.setProductId(productId);
		ProductImg productImg2 = new ProductImg();
		productImg2.setImgAddr("图片1");
		productImg2.setImgDesc("测试图片1");
		productImg2.setPriority(1);
		productImg2.setCreateTime(new Date());
		productImg2.setProductId(productId);
		List<ProductImg> productImgList = new ArrayList<>();
		productImgList.add(productImg1);
		productImgList.add(productImg2);
		int effectedNum = productImgDao.batchInsertProductImg(productImgList);
		assertEquals(2,effectedNum);
		//查询productId为1的商品信息并校验返回的详情图实例列表size是否为2
		Product product = productDao.queryProductById(productId);
		assertEquals(2,product.getProductImgList().size());
		//删除新增的这两个商品详情图示例,形成闭环
		effectedNum = productImgDao.deleteProductImgByProductId(productId);
		assertEquals(2,effectedNum);
	}
	@Test
	@Ignore
	public void testDUpdateProduct() {
		Product product = new Product();
		ProductCategory pc = new ProductCategory();
		Shop shop = new Shop();
		shop.setShopId(1L);
		pc.setProductCategoryId(12L);
		
		product.setProductId(1L);
		product.setShop(shop);
		product.setProductCategory(pc);
		product.setProductName("躺着喝的美式咖啡");
		
		int effectedNum = productDao.updateProduct(product);
		assertEquals(1,effectedNum);
	}
	@Test
	@Ignore
	public void testEUpdateProductCategoryToNull() {}
	@Test
	@Ignore
	public void testFDeleteShopAutoMap() {}
}

2. Service层

package com.csj2018.o2o.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.csj2018.o2o.dao.ProductDao;
import com.csj2018.o2o.dao.ProductImgDao;
import com.csj2018.o2o.dto.ImageHolder;
import com.csj2018.o2o.dto.ProductExecution;
import com.csj2018.o2o.entity.Product;
import com.csj2018.o2o.entity.ProductImg;
import com.csj2018.o2o.enums.ProductStateEnum;
import com.csj2018.o2o.exceptions.ProductOperationException;
import com.csj2018.o2o.service.ProductService;
import com.csj2018.o2o.util.*;

@Service
public class ProductServiceImpl implements ProductService{
	@Autowired
	private ProductDao productDao;
	@Autowired
	private ProductImgDao productImgDao;
	//8-10
	@Override
	public ProductExecution getProductList(Product productCondition,int pageIndex,int pageSize) {
		//页码转换成数据库的行码,并调用dao层取回指定页码的商品列表
		int rowIndex = PageCalculator.calculatorRowIndex(pageIndex, pageSize);
		List<Product> productList = productDao.queryProductList(productCondition, rowIndex, pageSize);
		//基于同样的查询条件返回该查询条件下的商品总数
		int count = productDao.queryProductCount(productCondition);
		ProductExecution pe = new ProductExecution();
		pe.setCount(count);
		pe.setProductList(productList);
		return pe;
	}
	/*
	 * 1.处理缩略图,获取缩略图相对路径并赋值给product
	 * 2.往tb_product写入商品信息,获取productId
	 * 3.结合productId批量处理商品详情图
	 * 4.将商品详情图列表批量插入tb_product_img中
	 * 通过spring的事务管理去执行这4不操作,任何一步出错就回滚,不会往表里写入
	 */
	@Override
	@Transactional
	public ProductExecution addProduct(Product product, ImageHolder thumbnail, List<ImageHolder> productImgHolderList)
			throws ProductOperationException {
		//空值判断
		if(product != null && product.getShop() != null && product.getShop().getShopId() != null) {
			//给商品设置默认属性
			product.setCreateTime(new Date());
			product.setLastEditTime(new Date());
			//默认为上架的状态
			product.setEnableStatus(1);
			//若商品缩略图不为空,则添加缩略图信息到商品
			if(thumbnail != null) {
				addThumbnail(product,thumbnail);
			}
			try {
				int effectedNum = productDao.insertProduct(product);
				if(effectedNum <= 0) {
					throw new ProductOperationException("创建商品失败");
				}
			}catch (Exception e) {
				throw new ProductOperationException("创建商品失败:"+e.toString());
			}
			//若商品详情图不为空,则向tb_product_img添加商品详情图
			if(productImgHolderList != null && productImgHolderList.size() >0) {
				addProductImgList(product,productImgHolderList);
			}
			return new ProductExecution(ProductStateEnum.SUCCESS,product);
		}else {
			//传参为空,则返回控制错误信息
			return new ProductExecution(ProductStateEnum.EMPTY);
		}
	}
	/**
	 * 向product对象添加缩略图
	 * @param product
	 * @param thumbnail
	 */
	private void addThumbnail(Product product, ImageHolder thumbnail) {
		String dest = PathUtil.getShopImagePath(product.getShop().getShopId());
		String thumbnailAddr = ImageUtil.generateThumbnail(thumbnail, dest);
		product.setImgAddr(thumbnailAddr);
	}
	private void addProductImgList(Product product, List<ImageHolder> productImgHolderList) {
		//获取图片存储路径,这里直接存放到相应店铺的文件夹下,同缩略图
		String dest = PathUtil.getShopImagePath(product.getShop().getShopId());
		List<ProductImg> productImgList = new ArrayList<ProductImg>();
		//遍历,获得详情图片列表
		for(ImageHolder productImgHolder:productImgHolderList) {
			String imgAddr = ImageUtil.generateNormalImg(productImgHolder, dest);
			ProductImg productImg = new ProductImg();
			productImg.setImgAddr(imgAddr);
			productImg.setProductId(product.getProductId());
			productImg.setCreateTime(new Date());
			productImgList.add(productImg);
		}
		if(productImgList.size() > 0) {
			try {
				int effectedNum = productImgDao.batchInsertProductImg(productImgList);
				if(effectedNum <= 0) {
					throw new ProductOperationException("创建商品详情图片失败");
				}
			}catch (Exception e) {
				throw new ProductOperationException("创建商品详情图片失败:"+e.toString());
			}
		}
	}
	@Override
	public Product getProductById(long productId) {
		return productDao.queryProductById(productId);
	}
	//1.若缩略图参数有值,则处理缩略图
	//2.若原先存在缩略图则先删除再添加新图,之后获取缩略图相对路径并赋值给product
	//3.将tb_product_img下面的该商品原先的商品详情记录全部清除
	//4.更新tb_product,tb_product_img的信息
	@Override
	@Transactional
	public ProductExecution modifyProduct(Product product, ImageHolder thumbnail, List<ImageHolder> productImgList)
			throws ProductOperationException {
		//空值判断。存放商品缩略图和详情图需要用到shopId做路径,因此需要针对shop做空值判断
		if(product != null && product.getShop() != null && product.getShop().getShopId() != null) {
			//给商品设置添加默认属性
			product.setLastEditTime(new Date());
			//若商品缩略图不为空且原有缩略图不为空,则删除原有缩略图并添加
			if(thumbnail != null) {
				//先获取一遍原有信息,因为原来的信息里有原图片地址
				Product tempProduct = productDao.queryProductById(product.getProductId());
				if(tempProduct.getImgAddr() != null) {
					//从磁盘中删除缩略图
					ImageUtil.deleteFileOfPath(tempProduct.getImgAddr());
				}
				addThumbnail(product,thumbnail);
			}
			//如果有新存入的商品详情图,则将原先的删除,并添加新的图片
			if(productImgList != null && productImgList.size() > 0) {
				deleteProductImgList(product.getProductId());
				addProductImgList(product,productImgList);
			}
			try {
				//更新商品信息
				int effectedNum = productDao.updateProduct(product);
				if(effectedNum <= 0) {
					throw new ProductOperationException("更新商品信息失败");
				}
				return new ProductExecution(ProductStateEnum.SUCCESS,product);
			}catch (Exception e) {
				throw new ProductOperationException("更新商品信息失败:"+e.toString());
			}
		}else {
			return new ProductExecution(ProductStateEnum.EMPTY);
		}
	}
	/**
	 * 删除某个商品下的所有详情图
	 * @param productId
	 */
	private void deleteProductImgList(long productId) {
		//根据productId获取原来的图片
		List<ProductImg> productImgList = productImgDao.queryProductImgList(productId);
		//从磁盘删除原来的图片
		for(ProductImg productImg:productImgList) {
			ImageUtil.deleteFileOfPath(productImg.getImgAddr());
		}
		//从数据库删除原有图片的信息
		productImgDao.deleteProductImgByProductId(productId);
	}
}

3.controller层

package com.csj2018.o2o.web.shopadmin;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.MultipartRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import com.csj2018.o2o.dto.ImageHolder;
import com.csj2018.o2o.dto.ProductExecution;
import com.csj2018.o2o.entity.Product;
import com.csj2018.o2o.entity.ProductCategory;
import com.csj2018.o2o.entity.Shop;
import com.csj2018.o2o.enums.ProductStateEnum;
import com.csj2018.o2o.service.ProductCategoryService;
import com.csj2018.o2o.service.ProductService;
import com.csj2018.o2o.util.CodeUtil;
import com.csj2018.o2o.util.HttpServletRequestUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;

@Controller
@RequestMapping("/shopadmin")
public class ProductManagementController {
	Logger logger = LoggerFactory.getLogger(ProductManagementController.class);
	@Autowired
	private ProductService productService;
	@Autowired
	private ProductCategoryService productCategoryService;
	
	@RequestMapping(value="/getproductlistbyshop",method=RequestMethod.GET)
	@ResponseBody
	private Map<String,Object> getProductListByShop(HttpServletRequest request){
		Map<String,Object> modelMap = new HashMap<String,Object>();
		//获取从前台传过来的页码
		int pageIndex = HttpServletRequestUtil.getInt(request, "pageIndex");
		//获取从前台传过来的每页要求返回的商品数上线
		int pageSize = HttpServletRequestUtil.getInt(request, "pageSize");
		//从当前session中获取店铺信息,主要是shopId
		Shop currentShop = (Shop)request.getSession().getAttribute("currentShop");
		
		//控制判断
		if((pageIndex > -1) && (pageSize > -1)&& (currentShop != null) && (currentShop.getShopId() != null)) {
			//获取传入的需要检索的条件,包括是否需要从某个商品类别以及模糊查找商品,去筛选某个店铺下的商品列表
			//筛选的条件可以进行排列组合
			long productCategoryId = HttpServletRequestUtil.getLong(request, "productCategoryId");
			String productName = HttpServletRequestUtil.getString(request, "productName");
			Product productCondition = compactProductCondition(currentShop.getShopId(),productCategoryId,productName);
			//传入查询条件以及分页信息进行查询,返回相应商品列表以及总数
			ProductExecution pe = productService.getProductList(productCondition, pageIndex, pageSize);
			modelMap.put("productList", pe.getProductList());
			modelMap.put("count", pe.getCount());
			modelMap.put("success", true);
		}else {
			modelMap.put("success", false);
			modelMap.put("errMsg", "empty pageSize or pageIndex or shopId");
			logger.info("页码"+pageIndex+"\t"+pageSize);
			logger.info("店铺"+currentShop.getShopId());
		}
		return modelMap;
		}
	//支持上传图片详情图的最大数值
	private static final int IMAGEMAXCOUNT = 6;
	
	@RequestMapping(value="/addproduct",method=RequestMethod.POST)
	@ResponseBody
	private Map<String,Object> addProduct(HttpServletRequest request){
		Map<String, Object> modelMap = new HashMap<String,Object>();
		//验证码校验
		if(!CodeUtil.checkVerifyCode(request)) {
			modelMap.put("success", false);
			modelMap.put("errMsg", "输入了错误的验证码");
			return modelMap;
		}
		//接收前端参数的变量的初始化,包括商品、缩略图、详情图列表实体类
		ObjectMapper mapper = new ObjectMapper();
		Product product = null;
		String productStr = HttpServletRequestUtil.getString(request, "productStr");
		MultipartHttpServletRequest multipartRequest = null;
		ImageHolder thumbnail = null;
		List<ImageHolder> productImgList = new ArrayList<ImageHolder>();
		CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
		
		try {
			//若请求中存在文件流,则取出相关的文件(包括缩略图和详情图)
			if(multipartResolver.isMultipart(request)) {
				
				multipartRequest = (MultipartHttpServletRequest) request;
				//取出缩略图并构建ImageHolder的对象
				CommonsMultipartFile thumbnailFile = (CommonsMultipartFile) multipartRequest.getFile("thumbnail");
				if(thumbnailFile != null) {
					thumbnail = handleImage(request,thumbnail,productImgList);
				}
			}else {
				modelMap.put("success", false);
				modelMap.put("errMsg", "上传图片不为空");
				return modelMap;
			}
		}catch (Exception e) {
			modelMap.put("success", false);
			modelMap.put("errMsg", e.toString());
			return modelMap;
		}
		
		try {
			//
			product = mapper.readValue(productStr,Product.class);
			
		}catch(Exception e) {
			modelMap.put("success", false);
			modelMap.put("errMsg", e.toString());
			return modelMap;
		}
		//若product信息,缩略图、详情图不为空,则开始进行商品添加操作
		if(product != null && thumbnail != null &&productImgList.size() != 0) {
			try {
				//从session中获取当前店铺的ID,并赋值给product,减少对前端数据的依赖
				Shop currentShop = (Shop) request.getSession().getAttribute("currentShop");
				product.setShop(currentShop);
				//执行添加操作
				ProductExecution pe = productService.addProduct(product, thumbnail, productImgList);
				if(pe.getState() == ProductStateEnum.SUCCESS.getState()) { 
					modelMap.put("success", true);
				}else {
					modelMap.put("success", false);
					modelMap.put("errMsg", pe.getStateInfo());
				}
			}catch (RuntimeException e) {
				modelMap.put("success", false);
				modelMap.put("errMsg", e.toString());
				return modelMap;
			}
		}else {
			modelMap.put("success",false);
			modelMap.put("errMsg", "请输入商品信息");
		}
		return modelMap;
	}
	/**
	 * 8-7
	 * @param productId
	 * @return
	 */
	@RequestMapping(value="/getproductbyid", method=RequestMethod.GET)
	@ResponseBody
	private Map<String,Object> getProductById(@RequestParam Long productId){
		Map<String, Object> modelMap = new HashMap<>();
		//非空判断
		if(productId > -1) {
			//获取商品信息
			Product product = productService.getProductById(productId);
			System.out.println(product.getShop().getShopId());
			//获取该店铺下的商品类别列表
			List<ProductCategory> productCategoryList = productCategoryService.getProductCategoryList(product.getShop().getShopId());
			modelMap.put("product", product);
			modelMap.put("productCategoryList", productCategoryList);
			modelMap.put("success", true);
		}else {
			modelMap.put("success", false);
			modelMap.put("errMsg", "empty productId");
		}
		return modelMap;
	}
	@RequestMapping(value="/modifyproduct", method=RequestMethod.POST)
	@ResponseBody
	private Map<String,Object> modifyProduct(HttpServletRequest request){
		Map<String, Object> modelMap = new HashMap<String, Object>();
		//是商品编辑时候调用,还是上下架操作时候调用
		//若为前者则进行验证码判断,后者则跳过验证码判断
		boolean statusChange = HttpServletRequestUtil.getBoolean(request, "statusChange");
		//验证码判断
		if(!statusChange && !CodeUtil.checkVerifyCode(request)) {
			modelMap.put("success", false);
			modelMap.put("errMsg", "输入了错误的验证码");
			return modelMap;
		}
		//接收前端参数的变量的初始化,包括商品,缩略图,详情图列表实体类
		ObjectMapper mapper = new ObjectMapper();
		Product product = null;
		ImageHolder thumbnail = null;
		List<ImageHolder> productImgList = new ArrayList<ImageHolder>();
		CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
		//若请求中存在文件流,则取出相关的文件(包括缩略图和详情图)
		try {
			if(multipartResolver.isMultipart(request)) {
				thumbnail = handleImage(request, thumbnail, productImgList);
				logger.info("详情图长度:"+productImgList.size());
			}
		}catch (Exception e) {
			modelMap.put("success", false);
			modelMap.put("errMsg", e.toString());
			return modelMap;
		}
		try {
			String productStr = HttpServletRequestUtil.getString(request, "productStr");
			//尝试获取从前端传过来的表单String流,并将其转化为Product对象
			product = mapper.readValue(productStr, Product.class);
		}catch(Exception e) {
			modelMap.put("success", false);
			modelMap.put("errMsg", e.toString());
			return modelMap;
		}
		//非空判断
		if(product != null) {
			try {
				//从session中获取当前店铺的ID并赋值给product,减少对前端数据的依赖
				Shop currentShop = (Shop) request.getSession().getAttribute("currentShop");
				product.setShop(currentShop);
				//开始进行商品信息变更操作
				logger.info("193");
				ProductExecution pe = productService.modifyProduct(product, thumbnail, productImgList);
				logger.info("195");
				if(pe.getState() == ProductStateEnum.SUCCESS.getState()) {
					modelMap.put("success", true);
				}else {
					modelMap.put("false", false);
					modelMap.put("errMsg", pe.getStateInfo());
				}
			}catch(RuntimeException e) {
				modelMap.put("success", false);
				modelMap.put("errMsg", e.toString());
				return modelMap;
			}
		}
		return modelMap;
	}
	private ImageHolder handleImage(HttpServletRequest request, ImageHolder thumbnail, List<ImageHolder> productImgList) throws IOException{
		MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
		//取出缩略图并构建ImageHolder对象
		CommonsMultipartFile thumbnailFile = (CommonsMultipartFile) multipartRequest.getFile("thumbnail");
		if(thumbnailFile != null) {
			thumbnail = new ImageHolder(thumbnailFile.getOriginalFilename(), thumbnailFile.getInputStream());
		}
		//取出详情图并构建List<ImageHolder>列表对象,最多支持6张图片上传
		for(int i=0;i<IMAGEMAXCOUNT;i++) {
			CommonsMultipartFile productImgFile = (CommonsMultipartFile) multipartRequest.getFile("productImg"+i);
			if(productImgFile != null) {
				//若取出的第i个详情图片流不为空,则将其加入详情图列表
				ImageHolder productImg = new ImageHolder(productImgFile.getOriginalFilename(),productImgFile.getInputStream());
				productImgList.add(productImg);
			}else {
				//若取出的第i个图片文件流为空,则终止循环
				break;
			}
		}
		return thumbnail;
	}
	//8-10
	private Product compactProductCondition(long shopId,long productCategoryId,String productName) {
		Product productCondition = new Product();
		Shop shop = new Shop();
		shop.setShopId(shopId);
		productCondition.setShop(shop);
		//若有指定类别的要求,则添加进入
		if(productCategoryId != -1L) {
			ProductCategory productCategory = new ProductCategory();
			productCategory.setProductCategoryId(productCategoryId);
			productCondition.setProductCategory(productCategory);
		}
		//若有商品名模糊查询的要求,则添加进去
		if(productName != null) {
			productCondition.setProductName(productName);
		}
		return productCondition;
	}
}

4.验证

1.先访问http://127.0.0.1:18080/o2o/shopadmin/shopmanagement?shopId=1,获取currentShop
2.再访问http://127.0.0.1:18080/o2o/shopadmin/getproductlistbyshop?pageIndex=1&pageSize=999,验证结果

posted on 2020-03-21 11:58  singleSpace  阅读(287)  评论(0编辑  收藏  举报