SSM校园商铺平台(七)

本博客详细介绍了使用SSM(Spring、SpringMVC、MyBatis)框架实现校园商铺平台的商品管理功能,包括商品的DAO层、Service层、Controller层的实现,以及前端页面和效果展示。在DAO层中,重点处理了商品图片的存储;在Service层,重构了图片上传接口,使用ProductExcution状态枚举和ProductOperationException异常来管理操作状态;Controller层实现了验证码校验和参数接收;前端部分主要涉及两个JavaScript文件的实现。
摘要由CSDN通过智能技术生成

本章实现商品类的所有操作,和shop类似

1. dao层的实现

ProductDao

public interface ProductDao {

	//插入商品
	int insertProduct(Product product);
	
	//按productId查找商品
	Product queryProductById(long productId);
	
	//按productId更新商品
	int updateProduct(Product product);
	
	//商品下架
	
	//查询所有商品,依据商品名字,店铺id,商品状态
	List<Product> queryProductList(@Param("productCondition")Product productCondition,
			@Param("rowIndex")int rowIndex,@Param("pageSize")int pageSize);
	
	//查询商品总数
	int queryProductCount(@Param("productCondition")Product productCondition);
}

ProductDao.xml

<?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.imooc.o2o.dao.ProductDao">
	<resultMap type="com.imooc.o2o.entity.Product" id="productMap">
		<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 column="product_category_id" property="productCategory"
		javaType="com.imooc.o2o.entity.ProductCategory">
			<id column="product_category_id" property="productCategoryId"/>
			<result column="product_category_name" property="productCategoryName"/>
		</association>
		
		<association column="shop_id" property="shop" javaType="com.imooc.o2o.entity.Shop">
			<id column="shop_id" property="shopId"/>
			<result column="shop_name" property="shopName"/>
		</association>
		
		<collection column="product_id" property="productImgList" ofType="com.imooc.o2o.entity.ProductImg">
			<id column="product_img_id" property="productImgId"/>
			<result column="img_addr" property="imgAddr"/>
			<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>

	<insert id="insertProduct" parameterType="com.imooc.o2o.entity.Product"
	useGeneratedKeys="true" keyColumn="product_id" keyProperty="productId"
	>
	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="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,
		
		pi.product_img_id,
		pi.img_addr,
		pi.img_desc,
		pi.priority,
		pi.create_time
		
		from tb_product p
		left join tb_product_img pi
		on p.product_id = pi.product_id
		where p.product_id=#{productId}
		order by pi.priority desc
	</select>
	
	<select id="queryProductList" resultType="com.imooc.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>
			
			<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>
			
			<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>
	
	<update id="updateProduct" parameterType="com.imooc.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}
	</update>
</mapper>

在添加商品的时候,我们通常都会添加商品的详情图,商品详情图是保存在tb_product_img中的,它和商品tb_product是依靠product_id连接起来的。

ProductImgDao

  • 批量添加商品详情图片
public interface ProductImgDao {

	List<ProductImg> queryProductImgList(long productId);
	
	//批量添加商品图片
	int batchInsertProductImg(List<ProductImg> productImgList);
	
	//删除商品图片
	int deleteProductImgByProductId(long productId);
}

ProductImgDao .xml

<?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.imooc.o2o.dao.ProductImgDao">
	<insert id="batchInsertProductImg" parameterType="java.util.List">
		insert into
		tb_product_img(
			img_addr,
			img_desc,
			priority,
			create_time,
			product_id
		)
		values
		<foreach collection="list" item="productImg"
		 index="index" separator=",">
		(
			#{productImg.imgAddr},
			#{productImg.imgDesc},
			#{productImg.priority},
			#{productImg.createTime},
			#{productImg.productId}
		)
		</foreach>
	</insert>
	
	<delete id="deleteProductImgByProductId">
		delete from tb_product_img
		where product_id=#{productId}
	</delete>
	
	<select id="queryProductImgList" resultType="com.imooc.o2o.entity.ProductImg">
		select 
		img_addr,
		img_desc,
		priority,
		create_time,
		product_id
		from tb_product_img
		where product_id=#{productId}
		order by priority
	</select>
	
</mapper>

2.service层

2.1 ProductService 接口

  • 输入有三个参数,商品显示图片和商品详情图是分开的
  • 重构了原来的image输入2个参数 (inputstream,fileName),将其修改成一个参数 ImageHolder类,所以要编写ImageHolder类来存储(inputstream,fileName)
  • 返回值类型为ProductExcution,来标识返回的状态
  • 抛出异常ProductOperationException
public interface ProductService {

	//添加商品信息以及图片处理
	/**
	 *  	
	 * @param product   商品
	 * @param productImg  商品显示图片
	 * @param productImgList  商品详情图片
	 * @return
	 * @throws ProductOperationException
	 */
	ProductExcution addProduct(Product product,ImageHolder productImg,
			List<ImageHolder> productImgList) throws ProductOperationException;

	//查询商品通过id
	Product getProductById(long productId);
	
	//更新店铺
	ProductExcution updateProduct(Product product,ImageHolder productImg, 
			List<ImageHolder> productImgList) throws ProductOperationException;

	//查询店铺
	ProductExcution getProductList(Product productCondition,int pageIndex,int pageSize);
}

2.2 ImageHolder类保存图片流信息

public class ImageHolder {

	//图片流
	private InputStream image;
	//图片名字
	private String imageName;
	public ImageHolder() {

	}
	public ImageHolder(InputStream image, String imageName) {
		this.image = image;
		this.imageName = imageName;
	}
	public InputStream getImage() {
		return image;
	}
	public void setImage(InputStream image) {
		this.image = image;
	}
	public String getImageName() {
		return imageName;
	}
	public void setImageName(String imageName) {
		this.imageName = imageName;
	}
	
}

2.3 ProductExcution返回值类

public class ProductExcution {

	//结果状态
	private int state;
	//结果状态标识
	private String stateInfo;
	
	//商品数量
	private int count;
	
	//操作的商品(增删改的时候使用)
	private Product product;
	
	//商品列表(查询商品时使用)
	List<Product> productList = new ArrayList<>();

	public ProductExcution() {
		
	}
	
	//成功时调用的构造方法1
	public ProductExcution(ProductStateEnum stateEnum,Product product) {
		this.state = stateEnum.getState();
		this.stateInfo = stateEnum.getStateInfo();
		this.product = product;
	}
	//成功时调用的构造方法2
	public ProductExcution(ProductStateEnum stateEnum,List<Product> productList) {
		this.state = stateEnum.getState();
		this.stateInfo = stateEnum.getStateInfo();
		this.productList = productList;
	}
	
	//失败的构造器
	public ProductExcution(ProductStateEnum stateEnum) {
		this.state = stateEnum.getState();
		this.stateInfo = stateEnum.getStateInfo();
	}
	}

2.4 ProductStateEnum枚举类

public enum ProductStateEnum {
	OFFLINE(-1, "非法商品"), 
	SUCCESS(0, "操作成功"), 
	PASS(2, "通过认证"), 
	INNER_ERROR(-1001, "操作失败"),
	EMPTY(-1002, "商品为空");

	private int state;

	private String stateInfo;

	private ProductStateEnum(int state, String stateInfo) {
		this.state = state;
		this.stateInfo = stateInfo;
	}
	}

2.5 ProductOperationException异常类

public class ProductOperationException extends RuntimeException {


	private static final long serialVersionUID = 1L;

	public ProductOperationException(String msg) {
		super(msg);
	}
}

2.6 ProductServieImpl类

添加商品addProduct的步骤:

  1. 处理缩略图函数addProductImg,获取缩略图的相对路径并赋值给product
  2. 往tb_product写入商品信息,获取productId
  3. 结合productId批量处理商品详情图片
  4. 将商品详情图片列表批量插入tb_product_img

批量处理商品详情图片addProductImgList:

  1. 获取该商店的图片保存的地址
  2. 依次处理每一个图片流,将其保存为ProductImg 类型,并添加到list
  3. 将list添加到数据库
@Service
public class ProductServieImpl implements ProductService{

	@Autowired
	private ProductDao productDao;
	@Autowired
	private ProductImgDao productImgDao;
	
	@Override
	public Product getProductById(long productId) {
		
		return productDao.queryProductById(productId);
	}
	
	@Override
	@Transactional
	public ProductExcution addProduct(Product product, ImageHolder productImg, List<ImageHolder> productImgList)
			throws ProductOperationException {
		//1. 处理缩略图,获取缩略图的相对路径并赋值给product
		//2. 往tb_product写入商品信息,获取productId
		//3. 结合productId批量处理商品详情图片
		//4. 将商品详情图片列表批量插入tb_product_img
		
		//这里的shopId是在controller层给它添加的
		//空值判断
		if(product!=null && product.getShop()!=null&&product.getShop().getShopId()!=null) {
			//给商品设置默认属性
			product.setCreateTime(new Date());
			product.setLastEditTime(new Date());
			//设置默认上架状态
			product.setEnableStatus(1);
			//判断商品缩略图是否为空,不为空则添加
			if(productImg!=null) {
				//创建缩略图,将返回的地址添加到product
				System.out.println(productImg.getImageName());
				addProductImg(product, productImg);
				
			}
			try {
				int effectNum = productDao.insertProduct(product);
				//插入失败,抛出runtime异常进行回滚
				if(effectNum <= 0) {
					throw new ProductOperationException("商品添加失败");
				}

			} catch (Exception e) {
				throw new ProductOperationException("addProduct error:"+e.getMessage());
			}
			
			//添加商品详情图片
			if(productImgList!=null&&productImgList.size()>0) {
				addProductImgList(product,productImgList);
			}
			//所有都添加成功
			return new ProductExcution(ProductStateEnum.SUCCESS,product);
		}
		else {
			return new ProductExcution(ProductStateEnum.EMPTY);
		}
		
	}
	
	//添加商品的缩略图
	private void addProductImg(Product product,ImageHolder thumbnail) {
		String dest = PathUtil.getShopImagePath(product.getShop().getShopId());
		String imgAddr = ImageUtil.generateThumbnail(thumbnail, dest);
		product.setImgAddr(imgAddr);
	}
	
	//批量添加商品的详情图
	private void addProductImgList(Product product,List<ImageHolder> productImgList) {
		String dest = PathUtil.getShopImagePath(product.getShop().getShopId());
		//用来保存商品详情图的对象列表
		List<ProductImg> list = new ArrayList<ProductImg>();
		for(ImageHolder imageHolder:productImgList) {
			//将每一张图片保存到店铺下面
			String imgAddr = ImageUtil.generateNormalImg(imageHolder, dest);
			
			ProductImg productImg = new ProductImg();
			productImg.setImgAddr(imgAddr);
			productImg.setCreateTime(new Date());
			productImg.setProductId(product.getProductId());
			productImg.setImgDesc(imageHolder.getImageName());
			
			list.add(productImg);
		}
		//判断商品详情图是否为空
		if(list.size() > 0) {
			//将商品详情图添加到tb_product_img
			try {
				int effectNum = productImgDao.batchInsertProductImg(list);
				if(effectNum <= 0) {
					throw new ProductOperationException("商品详情图添加失败");
				}
			} catch (Exception e) {
				throw new ProductOperationException("addProductImgList error:"+e.getMessage());
			}
		}
	}
	
	//更新商品
	@Override
	public ProductExcution updateProduct(Product product, ImageHolder productImg, List<ImageHolder> productImgList)
			throws ProductOperationException {
		//1. 如果有处理缩略图,先将原来的缩略图文件夹清除,再添加
		//2. 往tb_product写入商品信息,获取productId
		//3. 结合productId批量处理商品详情图片
		//4. 将商品详情图片列表批量插入tb_product_img
		
		//这里的shopId是在controller层给它添加的
		//空值判断
		if(product!=null && product.getShop()!=null&&product.getShop().getShopId()!=null) {
			//给商品设置默认属性
			product.setLastEditTime(new Date());
			//判断商品缩略图是否为空,不为空则更新
			if(productImg!=null) {
				//获取原来的缩略图地址,判断是否为空
				Product tempProduct = productDao.queryProductById(product.getProductId());
				if(tempProduct.getImgAddr()!=null) {
					ImageUtil.deleteFileOrPath(tempProduct.getImgAddr());
				}
				//创建缩略图,将返回的地址添加到product
				addProductImg(product, productImg);
				
			}
			
			//更新商品详情图片
			if(productImgList!=null&&productImgList.size()>0) {
				deleteProductImgList(product.getProductId());
				addProductImgList(product,productImgList);
			}
			
			//更新商品信息
			try {
				int effectNum = productDao.updateProduct(product);
				//抛出runtime异常进行回滚
				if(effectNum <= 0) {
					throw new ProductOperationException("商品更新失败");
				}

			} catch (Exception e) {
				throw new ProductOperationException("updateProduct error:"+e.getMessage());
			}
			
			
			//所有都更新成功
			return new ProductExcution(ProductStateEnum.SUCCESS,product);
		}
		else {
			return new ProductExcution(ProductStateEnum.EMPTY);
		}
	}
	
	//删除商品详情图
	public void deleteProductImgList(long productId) {
		List<ProductImg> productImgList = productImgDao.queryProductImgList(productId);
		//删除原来的图片
		for (ProductImg list:productImgList) {
			ImageUtil.deleteFileOrPath(list.getImgAddr());
		}
		//删除数据库中的所有详情图
		productImgDao.deleteProductImgByProductId(productId);
	}
	
	//查询所有的productList
	@Override
	public ProductExcution getProductList(Product productCondition, int pageIndex, int pageSize) {
		//页码转换成数据库的行码
		int rowIndex = PageCalculator.calculateRowIndex(pageIndex, pageSize);
		List<Product> productList = productDao.queryProductList(productCondition, rowIndex, pageSize);
		int count = productDao.queryProductCount(productCondition);
		ProductExcution pe = new ProductExcution();
		pe.setProductList(productList);
		pe.setCount(count);
		return pe;
	}
}

3.coontroller层

  1. 验证码校验
  2. 通过request接受前端返回的参数,获取缩略图和详情图
  3. 将字符串productStr转换成product对象
  4. 如果商品,商品缩略图,商品详情图都为非空才添加
  5. 给商品添加shopId,从session中获取
@Controller
@RequestMapping("/shop")
public class ProductManagementController {
	@Autowired
	private ProductService productService;
	@Autowired
	private ProductCategoryService productCategoryService;
	
	//支持上传的商品详情图的最大数量
	private static final int IMAGE_MAX_COUNT=6;
	
	@SuppressWarnings("unused")
	@RequestMapping(value="addproduct",method= {RequestMethod.POST})
	@ResponseBody
	public Map<String,Object> addProduct(HttpServletRequest request){
		Map<String,Object> modelMap = new HashMap<String, Object>();
		//验证码校验
		if(!CodeUtil.cheackVerifyCode(request)) {
			modelMap.put("success", false);
			modelMap.put("errMsg", "验证码错误");
			return modelMap;
		}
		//通过request接受前端参数
		ObjectMapper mapper = new ObjectMapper();
		Product product = null;
		String productStr = HttpServletRequestUtil.getString(request, "productStr");
		
		MultipartHttpServletRequest multipartRequest = null;
		ImageHolder productImg = null;
		List<ImageHolder> productImgList = new ArrayList<ImageHolder>();
		//从session中获取文件流
		CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
				request.getSession().getServletContext());
		try {
			//如果请求中存在文件流,则取出(包含缩略图和详情图)
			if(multipartResolver.isMultipart(request)) {
				productImg = handelImage(request, productImgList);
			}
			else {
				modelMap.put("success", false);
				modelMap.put("errMsg", "上传图片不能为空");
				return modelMap;
			}
		} catch (Exception e) {
			modelMap.put("success", false);
			modelMap.put("errMsg", e.getMessage());
			return modelMap;
		}
		try {
			//将字符串productStr转换成product对象
			product = mapper.readValue(productStr, Product.class);
		} catch (Exception e) {
			modelMap.put("success", false);
			modelMap.put("errMsg", e.getMessage());
			return modelMap;
		}
		//如果商品,商品缩略图,商品详情图都为非空才添加
		if(product!=null&&productImg!=null&&productImgList.size()>0) {
			try {
				//从session中获取当前店铺的id,并将其赋值给product
				Shop currentShop = (Shop) request.getSession().getAttribute("currentShop");
				product.setShop(currentShop);
				
				//执行添加操作
				ProductExcution pe = productService.addProduct(product, productImg, productImgList);
				if(pe.getState()==ProductStateEnum.SUCCESS.getState()) {
					modelMap.put("success", true);
				}
				else {
					modelMap.put("success", true);
					modelMap.put("errMsg", pe.getStateInfo());
				}
			} catch (ProductOperationException e) {
				modelMap.put("success", false);
				modelMap.put("errMsg", e.getMessage());
				return modelMap;
			}
		}
		else {
			modelMap.put("success", false);
			modelMap.put("errMsg", "请输入商品信息");
			return modelMap;
		}
		return modelMap;
	}
	
	@RequestMapping(value="/getproductcategorylistbyshopId",method = {RequestMethod.GET})
	@ResponseBody
	public Map<String,Object> getProductCategoryList(HttpServletRequest request){
		Map<String,Object> modelMap = new HashMap<String, Object>();
		//从session中获取shopid
		Shop currentShop = (Shop) request.getSession().getAttribute("currentShop");
		List<ProductCategory> productCategoryList = null;
		if(currentShop!=null && currentShop.getShopId()>0) {
			productCategoryList = productCategoryService.getProductCategoryList(currentShop.getShopId());
			modelMap.put("success", true);
			modelMap.put("productCategoryList", productCategoryList);
		}
		else {
			modelMap.put("success", false);
			modelMap.put("errMsg", "商品类别为空");
		}
		return modelMap;
	}
	
	//根据id查询product
	@RequestMapping(value="/getproductbyid",method= {RequestMethod.GET})
	@ResponseBody
	public Map<String,Object> getProductById(HttpServletRequest request){
		Map<String,Object> modelMap = new HashMap<String, Object>();
		long productId = HttpServletRequestUtil.getLong(request, "productId");
		if(productId>=0) {
			try {
				Product product = productService.getProductById(productId);
				
				List<ProductCategory> productCategoryList = productCategoryService
						.getProductCategoryList(product.getShop().getShopId());
				modelMap.put("success", true);
				modelMap.put("product", product);
				modelMap.put("productCategoryList", productCategoryList);
			} catch (Exception e) {
				modelMap.put("success", false);
				modelMap.put("errMsg", e.getMessage());
				return modelMap;
			}
			
		}
		else {
			modelMap.put("success", false);
			modelMap.put("errMsg", "empty productId");
		}
		return modelMap;
	}
	
	//更新店铺
	@RequestMapping(value="/modifyproduct",method= {RequestMethod.POST})
	@ResponseBody
	public Map<String,Object> updateProduct(HttpServletRequest request){
		boolean statusChange = HttpServletRequestUtil.getBoolean(request, "statusChange");
		Map<String,Object> modelMap = new HashMap<String, Object>();
		//验证码校验
		if(!statusChange && !CodeUtil.cheackVerifyCode(request)) {
			modelMap.put("success", false);
			modelMap.put("errMsg", "验证码错误");
			return modelMap;
		}
		//通过request接受前端参数
		ObjectMapper mapper = new ObjectMapper();
		Product product = null;
		String productStr = HttpServletRequestUtil.getString(request, "productStr");
		
		ImageHolder productImg = null;
		List<ImageHolder> productImgList = new ArrayList<ImageHolder>();
		//从session中获取文件流
		CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
				request.getSession().getServletContext());
		try {
			//如果请求中存在文件流,则取出(包含缩略图和详情图)
			if(multipartResolver.isMultipart(request)) {
				productImg = handelImage(request, productImgList);
			}

		} catch (Exception e) {
			modelMap.put("success", false);
			modelMap.put("errMsg", e.getMessage());
			return modelMap;
		}
		try {
			//将字符串productStr转换成product对象
			product = mapper.readValue(productStr, Product.class);
		} catch (Exception e) {
			modelMap.put("success", false);
			modelMap.put("errMsg", e.getMessage());
			return modelMap;
		}
		//如果商品为非空才添加
		if(product!=null) {
			try {
				//从session中获取当前店铺的id,并将其赋值给product
				Shop currentShop = (Shop) request.getSession().getAttribute("currentShop");
				product.setShop(currentShop);
				
				//执行添加操作
				ProductExcution pe = productService.updateProduct(product, productImg, productImgList);
				if(pe.getState()==ProductStateEnum.SUCCESS.getState()) {
					modelMap.put("success", true);
				}
				else {
					modelMap.put("success", true);
					modelMap.put("errMsg", pe.getStateInfo());
				}
			} catch (ProductOperationException e) {
				modelMap.put("success", false);
				modelMap.put("errMsg", e.getMessage());
				return modelMap;
			}
		}
		else {
			modelMap.put("success", false);
			modelMap.put("errMsg", "请输入商品信息");
			return modelMap;
		}
		return modelMap;
	}

	//从request中取出图片流
	private ImageHolder handelImage(HttpServletRequest request, List<ImageHolder> productImgList) throws IOException {
		MultipartHttpServletRequest multipartRequest = null;
		ImageHolder productImg;
		multipartRequest = (MultipartHttpServletRequest) request;
		//取出缩略图
		CommonsMultipartFile imgFile = (CommonsMultipartFile) multipartRequest.getFile("thumbnail");
		productImg = new ImageHolder(imgFile.getInputStream(),imgFile.getOriginalFilename());
		
		//取出详情图,最多取出 IMAGE_MAX_COUNT张
		for (int i = 0; i < IMAGE_MAX_COUNT; i++) {
			CommonsMultipartFile file = (CommonsMultipartFile) multipartRequest.getFile("productImg"+i);
			if(file!=null)
				productImgList.add(new ImageHolder(file.getInputStream(),file.getOriginalFilename()));
			else
				break;
		}
		return productImg;
	}
	
	@RequestMapping(value = "/listproductsbyshop",method = {RequestMethod.GET})
	@ResponseBody
	private Map<String,Object> getProductList(HttpServletRequest request){
		Map<String,Object> modelMap = new HashMap<String, Object>();
		int pageIndex = HttpServletRequestUtil.getInt(request, "pageIndex");
		int pageSize = HttpServletRequestUtil.getInt(request, "pageSize");
		
		//采用session获取shop
		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) ;
			ProductExcution 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");
		}
		
		return modelMap;
	}
	
	private Product compactProductCondition(long shopId,long productCategoryId,String productName) {
		Product product = new Product();
		Shop shop = new Shop();
		shop.setShopId(shopId);
		product.setShop(shop);
		if(productCategoryId!=-1L) {
			ProductCategory productCategory = new ProductCategory();
			productCategory.setProductCategoryId(productCategoryId);
			product.setProductCategory(productCategory);
		}
		if(productName!=null) {
			product.setProductName(productName);
		}
		return product;
	}
}

4.前端实现

productedit.js


$(function() {
	var productId = getQueryString('productId');
	//
	var infoUrl = '/o2o/shop/getproductbyid?productId=' + productId;
	//获取商品种类列表
	var categoryUrl = '/o2o/shop/getproductcategorylistbyshopId';
	//表单提交
	var productPostUrl = '/o2o/shop/modifyproduct';
	var isEdit = false;
	if (productId) {
		getInfo(productId);
		isEdit = true;
	} else {
		getCategory(shopId);
		productPostUrl = '/o2o/shop/addproduct';
	}

	function getInfo(id) {
		$.getJSON(
						infoUrl,
						function(data) {
							if (data.success) {
								var product = data.product;
								$('#product-name').val(product.productName);
								$('#product-desc').val(product.productDesc);
								$('#priority').val(product.priority);
								$('#normal-price').val(product.normalPrice);
								$('#promotion-price').val(
										product.promotionPrice);

								var optionHtml = '';
								var optionArr = data.productCategoryList;
								var optionSelected = product.productCategory.productCategoryId;
								optionArr
										.map(function(item, index) {
											var isSelect = optionSelected === item.productCategoryId ? 'selected'
													: '';
											optionHtml += '<option data-value="'
													+ item.productCategoryId
													+ '"'
													+ isSelect
													+ '>'
													+ item.productCategoryName
													+ '</option>';
										});
								$('#category').html(optionHtml);
							}
						});
	}

	function getCategory() {
		$.getJSON(categoryUrl, function(data) {
			if (data.success) {
				var productCategoryList = data.productCategoryList;
				var optionHtml = '';
				productCategoryList.map(function(item, index) {
					optionHtml += '<option data-value="'
							+ item.productCategoryId + '">'
							+ item.productCategoryName + '</option>';
				});
				$('#category').html(optionHtml);
			}
		});
	}

	$('.detail-img-div').on('change', '.detail-img:last-child', function() {
		if ($('.detail-img').length < 6) {
			$('#detail-img').append('<input type="file" class="detail-img">');
		}
	});

	$('#submit').click(
			function() {
				var product = {};
				product.productName = $('#product-name').val();
				product.productDesc = $('#product-desc').val();
				product.priority = $('#priority').val();
				product.normalPrice = $('#normal-price').val();
				product.promotionPrice = $('#promotion-price').val();
				product.productCategory = {
					productCategoryId : $('#category').find('option').not(
							function() {
								return !this.selected;
							}).data('value')
				};
				product.productId = productId;

				var thumbnail = $('#small-img')[0].files[0];
				console.log(thumbnail);
				var formData = new FormData();
				formData.append('thumbnail', thumbnail);
				$('.detail-img').map(
						function(index, item) {
							if ($('.detail-img')[index].files.length > 0) {
								formData.append('productImg' + index,
										$('.detail-img')[index].files[0]);
							}
						});
				formData.append('productStr', JSON.stringify(product));
				var verifyCodeActual = $('#j_captcha').val();
				if (!verifyCodeActual) {
					$.toast('请输入验证码!');
					return;
				}
				formData.append("verifyCodeActual", verifyCodeActual);
				$.ajax({
					url : productPostUrl,
					type : 'POST',
					data : formData,
					contentType : false,
					processData : false,
					cache : false,
					success : function(data) {
						if (data.success) {
							$.toast('提交成功!');
							$('#captcha_img').click();
						} else {
							$.toast('提交失败!');
							$('#captcha_img').click();
						}
					}
				});
			});

});

productmanager.js

$(function() {
	var listUrl = '/o2o/shop/listproductsbyshop?pageIndex=1&pageSize=9999';
	var deleteUrl = '/o2o/shop/modifyproduct';

	function getList() {
		$.getJSON(listUrl, function(data) {
			if (data.success) {
				var productList = data.productList;
				var tempHtml = '';
				productList.map(function(item, index) {
					var textOp = "下架";
					var contraryStatus = 0;
					if (item.enableStatus == 0) {
						textOp = "上架";
						contraryStatus = 1;
					} else {
						contraryStatus = 0;
					}
					tempHtml += '' + '<div class="row row-product">'
							+ '<div class="col-30">'
							+ item.productName
							+ '</div>'
							+ '<div class="col-20">'
							+ item.priority
							+ '</div>'
							+ '<div class="col-50">'
							+ '<a href="#" class="edit" data-id="'
							+ item.productId
							+ '" data-status="'
							+ item.enableStatus
							+ '">编辑</a>'
							+ '<a href="#" class="delete" data-id="'
							+ item.productId
							+ '" data-status="'
							+ contraryStatus
							+ '">'
							+ textOp
							+ '</a>'
							+ '<a href="#" class="preview" data-id="'
							+ item.productId
							+ '" data-status="'
							+ item.enableStatus
							+ '">预览</a>'
							+ '</div>'
							+ '</div>';
				});
				$('.product-wrap').html(tempHtml);
			}
		});
	}

	getList();

	function deleteItem(id, enableStatus) {
		var product = {};
		product.productId = id;
		product.enableStatus = enableStatus;
		$.confirm('确定么?', function() {
			$.ajax({
				url : deleteUrl,
				type : 'POST',
				data : {
					productStr : JSON.stringify(product),
					statusChange : true
				},
				dataType : 'json',
				success : function(data) {
					if (data.success) {
						$.toast('操作成功!');
						getList();
					} else {
						$.toast('操作失败!');
					}
				}
			});
		});
	}

	$('.product-wrap')
			.on(
					'click',
					'a',
					function(e) {
						var target = $(e.currentTarget);
						if (target.hasClass('edit')) {
							window.location.href = '/o2o/shopadmin/productedit?productId='
									+ e.currentTarget.dataset.id;
						} else if (target.hasClass('delete')) {
							deleteItem(e.currentTarget.dataset.id,
									e.currentTarget.dataset.status);
						} else if (target.hasClass('preview')) {
							window.location.href = '/o2o/frontend/productdetail?productId='
									+ e.currentTarget.dataset.id;
						}
					});

	$('#new').click(function() {
		window.location.href = '/o2o/shopadmin/productedit';
	});
});

5.效果图

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值