Browse Source

增加标签、分类、banner

chunping 3 years ago
parent
commit
f01ca27fc9
29 changed files with 1324 additions and 310 deletions
  1. 135 0
      mp-admin/src/main/java/com/qs/mp/web/controller/api/admin/ExchangeBannerMgrController.java
  2. 165 0
      mp-admin/src/main/java/com/qs/mp/web/controller/api/admin/GoodsCategoryMgrController.java
  3. 298 285
      mp-admin/src/main/java/com/qs/mp/web/controller/api/admin/GoodsMgrController.java
  4. 167 0
      mp-admin/src/main/java/com/qs/mp/web/controller/api/admin/GoodsTagMgrController.java
  5. 16 1
      mp-admin/src/main/java/com/qs/mp/web/controller/api/user/UserExchangeController.java
  6. 51 0
      mp-common/src/main/java/com/qs/mp/common/enums/BannerLocationEnum.java
  7. 2 0
      mp-common/src/main/java/com/qs/mp/common/enums/ErrorCodeEnum.java
  8. 87 0
      mp-service/src/main/java/com/qs/mp/admin/domain/ExchangeBanner.java
  9. 13 1
      mp-service/src/main/java/com/qs/mp/admin/domain/GoodsCategory.java
  10. 59 0
      mp-service/src/main/java/com/qs/mp/admin/domain/GoodsTag.java
  11. 53 0
      mp-service/src/main/java/com/qs/mp/admin/domain/GoodsTagRel.java
  12. 3 0
      mp-service/src/main/java/com/qs/mp/admin/domain/param/GoodsParam.java
  13. 7 1
      mp-service/src/main/java/com/qs/mp/admin/domain/param/GoodsQueryParam.java
  14. 5 0
      mp-service/src/main/java/com/qs/mp/admin/domain/vo/GoodsVO.java
  15. 13 0
      mp-service/src/main/java/com/qs/mp/admin/mapper/ExchangeBannerMapper.java
  16. 13 0
      mp-service/src/main/java/com/qs/mp/admin/mapper/GoodsTagMapper.java
  17. 13 0
      mp-service/src/main/java/com/qs/mp/admin/mapper/GoodsTagRelMapper.java
  18. 16 0
      mp-service/src/main/java/com/qs/mp/admin/service/IExchangeBannerService.java
  19. 6 5
      mp-service/src/main/java/com/qs/mp/admin/service/IGoodsService.java
  20. 16 0
      mp-service/src/main/java/com/qs/mp/admin/service/IGoodsTagRelService.java
  21. 16 0
      mp-service/src/main/java/com/qs/mp/admin/service/IGoodsTagService.java
  22. 20 0
      mp-service/src/main/java/com/qs/mp/admin/service/impl/ExchangeBannerServiceImpl.java
  23. 43 15
      mp-service/src/main/java/com/qs/mp/admin/service/impl/GoodsServiceImpl.java
  24. 20 0
      mp-service/src/main/java/com/qs/mp/admin/service/impl/GoodsTagRelServiceImpl.java
  25. 20 0
      mp-service/src/main/java/com/qs/mp/admin/service/impl/GoodsTagServiceImpl.java
  26. 24 0
      mp-service/src/main/resources/mapper/admin/ExchangeBannerMapper.xml
  27. 4 2
      mp-service/src/main/resources/mapper/admin/GoodsCategoryMapper.xml
  28. 20 0
      mp-service/src/main/resources/mapper/admin/GoodsTagMapper.xml
  29. 19 0
      mp-service/src/main/resources/mapper/admin/GoodsTagRelMapper.xml

+ 135 - 0
mp-admin/src/main/java/com/qs/mp/web/controller/api/admin/ExchangeBannerMgrController.java

@@ -0,0 +1,135 @@
+package com.qs.mp.web.controller.api.admin;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.qs.mp.admin.domain.ExchangeBanner;
+import com.qs.mp.admin.service.IExchangeBannerService;
+import com.qs.mp.common.annotation.Log;
+import com.qs.mp.common.core.domain.AjaxResult;
+import com.qs.mp.common.core.page.TableDataInfo;
+import com.qs.mp.common.enums.BusinessType;
+import com.qs.mp.common.enums.ErrorCodeEnum;
+import com.qs.mp.common.utils.StringUtils;
+import com.qs.mp.web.controller.common.BaseApiController;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Component;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @auther zhongcp
+ * @create 2022-04-07 23:45:48
+ * @describe 商品banner管理前端控制器
+ */
+@Api("商品banner管理API")
+@RestController
+@RequestMapping("/api/v1/mp/admin/goods/banner/*")
+@Component
+public class ExchangeBannerMgrController extends BaseApiController {
+
+  @Autowired
+  private IExchangeBannerService exchangeBannerService;
+
+
+  /**
+   * 查询商品banner列表, 支持翻页
+   *
+   * @return
+   */
+  @PostMapping("/list")
+  @PreAuthorize("@ss.hasPermi('business:banner:list')")
+  public TableDataInfo list(@RequestBody JSONObject param) {
+    startPage();
+    List<ExchangeBanner> bannerList = exchangeBannerService.list(
+        new LambdaQueryWrapper<ExchangeBanner>());
+    return getDataTable(bannerList);
+  }
+
+  /**
+   * 获取商品banner详情信息
+   *
+   * @param
+   * @return
+   */
+  @PostMapping(value = "/detail")
+  @PreAuthorize("@ss.hasPermi('business:banner:query')")
+  public AjaxResult info(@RequestBody JSONObject jsonObject) {
+    Long bannerId = jsonObject.getLong("bannerId");
+    if (null == bannerId || 0 == bannerId) {
+      return error(ErrorCodeEnum.ERROR_CODE_1001);
+    }
+    ExchangeBanner banner = exchangeBannerService.getById(bannerId);
+    return AjaxResult.success(banner);
+  }
+
+
+  /**
+   * 新增商品banner信息
+   *
+   * @param
+   * @return
+   */
+  @Log(title = "新增商品banner", businessType = BusinessType.INSERT)
+  @ApiOperation(value = "新增商品banner", notes = "后台商品管理新增banner")
+  @PostMapping("/create")
+  @PreAuthorize("@ss.hasPermi('business:banner:add')")
+  public AjaxResult create(@RequestBody ExchangeBanner exchangeBanner) {
+    if (StringUtils.isBlank(exchangeBanner.getName()) || StringUtils.isBlank(
+        exchangeBanner.getPicUrl())
+        || StringUtils.isBlank(exchangeBanner.getType()) || null == exchangeBanner.getLocation()) {
+      return error(ErrorCodeEnum.ERROR_CODE_1001);
+    }
+    // 2.保存
+    exchangeBannerService.save(exchangeBanner);
+    return AjaxResult.success("保存成功");
+  }
+
+  /**
+   * 编辑商品banner信息
+   *
+   * @param
+   * @return
+   */
+  @Log(title = "修改商品banner", businessType = BusinessType.UPDATE)
+  @ApiOperation(value = "编辑商品banner信息", notes = "后台商品管理修改商品banner信息")
+  @PostMapping("/update")
+  @PreAuthorize("@ss.hasPermi('business:banner:edit')")
+  public AjaxResult update(@Validated @RequestBody ExchangeBanner exchangeBanner) {
+    if (null == exchangeBanner || null == exchangeBanner.getBannerId()
+        || 0 == exchangeBanner.getBannerId()) {
+      return error(ErrorCodeEnum.ERROR_CODE_1001);
+    }
+    // 保存数据
+    boolean rst = exchangeBannerService.updateById(exchangeBanner);
+    return rst ? AjaxResult.success("更新成功") : AjaxResult.error("更新失败");
+  }
+
+
+  /**
+   * 删除商品banner
+   *
+   * @param
+   * @return
+   */
+  @Log(title = "删除商品banner", businessType = BusinessType.DELETE)
+  @PostMapping(value = "/remove")
+  @PreAuthorize("@ss.hasPermi('business:banner:remove')")
+  public AjaxResult remove(@RequestBody ExchangeBanner exchangeBanner) {
+
+    if (null == exchangeBanner || null == exchangeBanner.getBannerId()
+        || 0 == exchangeBanner.getBannerId()) {
+      return error(ErrorCodeEnum.ERROR_CODE_1001);
+    }
+
+    boolean res = exchangeBannerService.removeById(exchangeBanner.getBannerId());
+    return res ? AjaxResult.success("删除成功") : AjaxResult.error("删除失败");
+  }
+
+}

+ 165 - 0
mp-admin/src/main/java/com/qs/mp/web/controller/api/admin/GoodsCategoryMgrController.java

@@ -0,0 +1,165 @@
+package com.qs.mp.web.controller.api.admin;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.qs.mp.admin.domain.Goods;
+import com.qs.mp.admin.domain.GoodsCategory;
+import com.qs.mp.admin.service.IGoodsCategoryService;
+import com.qs.mp.admin.service.IGoodsService;
+import com.qs.mp.common.annotation.Log;
+import com.qs.mp.common.core.domain.AjaxResult;
+import com.qs.mp.common.core.page.TableDataInfo;
+import com.qs.mp.common.enums.BusinessType;
+import com.qs.mp.common.enums.ErrorCodeEnum;
+import com.qs.mp.web.controller.common.BaseApiController;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import java.util.Arrays;
+import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Component;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @auther zhongcp
+ * @create 2022-04-07 23:45:48
+ * @describe 商品分类管理前端控制器
+ */
+@Api("商品分类管理API")
+@RestController
+@RequestMapping("/api/v1/mp/admin/goods/category/*")
+@Component
+public class GoodsCategoryMgrController extends BaseApiController {
+
+  @Autowired
+  private IGoodsCategoryService goodsCategoryService;
+
+  @Autowired
+  private IGoodsService goodsService;
+
+
+  /**
+   * 查询商品分类列表, 支持翻页
+   *
+   * @return
+   */
+  @PostMapping("/list")
+  @PreAuthorize("@ss.hasPermi('business:category:list')")
+  public TableDataInfo list(@RequestBody JSONObject param) {
+    startPage();
+    List<GoodsCategory> categoryList = goodsCategoryService.list(
+        new LambdaQueryWrapper<GoodsCategory>());
+    return getDataTable(categoryList);
+  }
+
+  /**
+   * 查询商品分类列表, 支持翻页
+   *
+   * @return
+   */
+  @PostMapping("/items")
+  @PreAuthorize("@ss.hasPermi('business:category:list')")
+  public AjaxResult items(@RequestBody JSONObject param) {
+    List<GoodsCategory> categoryList = goodsCategoryService.list(
+        new LambdaQueryWrapper<GoodsCategory>());
+    return AjaxResult.success(categoryList);
+  }
+
+  /**
+   * 获取商品分类详情信息
+   *
+   * @param
+   * @return
+   */
+  @PostMapping(value = "/detail")
+  @PreAuthorize("@ss.hasPermi('business:category:query')")
+  public AjaxResult info(@RequestBody JSONObject jsonObject) {
+    Long categoryId = jsonObject.getLong("categoryId");
+    if (null == categoryId || 0 == categoryId) {
+      return error(ErrorCodeEnum.ERROR_CODE_1001);
+    }
+    GoodsCategory category = goodsCategoryService.getById(categoryId);
+    return AjaxResult.success(category);
+  }
+
+
+  /**
+   * 新增商品分类信息
+   *
+   * @param
+   * @return
+   */
+  @Log(title = "新增商品分类", businessType = BusinessType.INSERT)
+  @ApiOperation(value = "新增商品分类", notes = "后台商品管理新增分类")
+  @PostMapping("/create")
+  @PreAuthorize("@ss.hasPermi('business:category:add')")
+  public AjaxResult create(@Validated @RequestBody GoodsCategory goodsCategory) {
+    // 1、校验名称是否重复
+    int cnt = goodsCategoryService.count(new LambdaQueryWrapper<GoodsCategory>()
+        .eq(GoodsCategory::getName, goodsCategory.getName()));
+    if (cnt > 0) {
+      return AjaxResult.error("分类名称已存在!");
+    }
+    // 2.保存
+    goodsCategory.setParentId(0L);
+    goodsCategoryService.save(goodsCategory);
+    return AjaxResult.success("保存成功");
+  }
+
+  /**
+   * 编辑商品分类信息
+   *
+   * @param
+   * @return
+   */
+  @Log(title = "修改商品分类", businessType = BusinessType.UPDATE)
+  @ApiOperation(value = "编辑商品分类信息", notes = "后台商品管理修改商品分类信息")
+  @PostMapping("/update")
+  @PreAuthorize("@ss.hasPermi('business:category:edit')")
+  public AjaxResult update(@Validated @RequestBody GoodsCategory goodsCategory) {
+    if (null == goodsCategory || null == goodsCategory.getCategoryId()
+        || 0 == goodsCategory.getCategoryId()) {
+      return error(ErrorCodeEnum.ERROR_CODE_1001);
+    }
+    int cnt = goodsCategoryService.count(new LambdaQueryWrapper<GoodsCategory>()
+        .eq(GoodsCategory::getName, goodsCategory.getName()).notIn(GoodsCategory::getCategoryId,
+            Arrays.asList(goodsCategory.getCategoryId())));
+    if (cnt > 0) {
+      return AjaxResult.error("分类名称已存在!");
+    }
+    // 保存数据
+    boolean rst = goodsCategoryService.updateById(goodsCategory);
+    return rst ? AjaxResult.success("更新成功") : AjaxResult.error("更新失败");
+  }
+
+
+  /**
+   * 删除商品分类
+   *
+   * @param
+   * @return
+   */
+  @Log(title = "删除商品分类", businessType = BusinessType.DELETE)
+  @PostMapping(value = "/remove")
+  @PreAuthorize("@ss.hasPermi('business:category:remove')")
+  public AjaxResult remove(@RequestBody GoodsCategory goodsCategory) {
+
+    if (null == goodsCategory.getCategoryId() || 0 == goodsCategory.getCategoryId()) {
+      return error(ErrorCodeEnum.ERROR_CODE_1001);
+    }
+    int cnt = goodsService.count(new LambdaQueryWrapper<Goods>()
+        .eq(Goods::getCategoryId, goodsCategory.getCategoryId()).eq(Goods::getIsDeleted, 1));
+    if (cnt > 0) {
+      return error(ErrorCodeEnum.ERROR_CODE_1024);
+    }
+
+    boolean res = goodsCategoryService.removeById(goodsCategory.getCategoryId());
+    return res ? AjaxResult.success("删除成功") : AjaxResult.error("删除失败");
+  }
+
+}

+ 298 - 285
mp-admin/src/main/java/com/qs/mp/web/controller/api/admin/GoodsMgrController.java

@@ -6,11 +6,13 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.qs.mp.admin.domain.Goods;
 import com.qs.mp.admin.domain.GoodsSku;
+import com.qs.mp.admin.domain.GoodsTagRel;
 import com.qs.mp.admin.domain.param.GoodsParam;
 import com.qs.mp.admin.domain.param.GoodsQueryParam;
 import com.qs.mp.admin.domain.vo.GoodsVO;
 import com.qs.mp.admin.service.IGoodsService;
 import com.qs.mp.admin.service.IGoodsSkuService;
+import com.qs.mp.admin.service.IGoodsTagRelService;
 import com.qs.mp.common.annotation.Log;
 import com.qs.mp.common.core.domain.AjaxResult;
 import com.qs.mp.common.core.page.TableDataInfo;
@@ -23,11 +25,9 @@ import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import java.net.URLDecoder;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.List;
-import java.util.Map;
 import java.util.stream.Collectors;
 import ma.glasnost.orika.MapperFacade;
 import org.apache.commons.lang3.StringUtils;
@@ -53,304 +53,317 @@ import org.springframework.web.bind.annotation.RestController;
 @Component
 public class GoodsMgrController extends BaseApiController {
 
-	@Autowired
-	private IGoodsService goodsService;
+  @Autowired
+  private IGoodsService goodsService;
 
-	@Autowired
-	private IGoodsSkuService goodsSkuService;
+  @Autowired
+  private IGoodsSkuService goodsSkuService;
 
-	@Autowired
-	private MapperFacade mapperFacade;
+  @Autowired
+  private IGoodsTagRelService goodsTagRelService;
 
+  @Autowired
+  private MapperFacade mapperFacade;
 
-	/**
-	 * 查询商品列表, 支持翻页
-	 *
-	 * @return
-	 */
-	@PostMapping("/list")
-	@PreAuthorize("@ss.hasPermi('business:goods:list')")
-	public TableDataInfo list(@RequestBody GoodsQueryParam queryParam) {
-		startPage();
-		QueryWrapper<Goods> queryWrapper = new QueryWrapper<Goods>();
-		queryWrapper.lambda().like(null != queryParam && StringUtils.isNotBlank(queryParam.getTitle()), Goods::getTitle, queryParam.getTitle());
-		queryWrapper.lambda()
-					.eq(null != queryParam && null != queryParam.getGoodsId() && 0 != queryParam.getGoodsId(),
-							Goods::getGoodsId, queryParam.getGoodsId());
-		// 成本
-		queryWrapper.lambda().ge(null != queryParam && null != queryParam.getMinCost(), Goods::getCost, queryParam.getMinCost());
-		queryWrapper.lambda().le(null != queryParam && null != queryParam.getMaxCost(), Goods::getCost, queryParam.getMaxCost());
-		// 价格
-		queryWrapper.lambda().ge(null != queryParam && null != queryParam.getMinValue(), Goods::getValue, queryParam.getMinValue());
-		queryWrapper.lambda().le(null != queryParam && null != queryParam.getMaxValue(), Goods::getValue, queryParam.getMaxValue());
-		// 状态
-		queryWrapper.lambda().eq(null != queryParam && null != queryParam.getStatus(), Goods::getStatus, queryParam.getStatus());
-		// 是否支持兑换
-		queryWrapper.lambda().eq(null != queryParam && null != queryParam.getExchangeShow(), Goods::getExchangeShow, queryParam.getExchangeShow());
-		queryWrapper.lambda().eq(Goods::getIsDeleted, 0);
-		queryWrapper.orderByAsc("FIELD(`status`, 'init', 'on', 'off')");
-		queryWrapper.lambda().orderByDesc(Goods::getGoodsId);
-		List<Goods> goodsList = goodsService.list(queryWrapper);
-		TableDataInfo res = getDataTable(goodsList);
-		res.setRows(goodsList);
-		return res;
-	}
 
-	/**
-	 * 获取商品详情信息
-	 *
-	 * @param
-	 * @return
-	 */
-	@PostMapping(value = "/detail")
-	@PreAuthorize("@ss.hasPermi('business:goods:query')")
-	public AjaxResult getGoodsDetail(@RequestBody JSONObject jsonObject) {
-		Long goodsId = jsonObject.getLong("goodsId");
-	    if (null == goodsId || 0 == goodsId){
-	      return error(ErrorCodeEnum.ERROR_CODE_1001);
-	    }
-		Goods goods = goodsService.getById(goodsId);
-		if(null == goods) {
-			 return error(ErrorCodeEnum.ERROR_CODE_1001);
-		}
-		GoodsVO goodsVo = new GoodsVO();
-		BeanUtils.copyProperties(goods, goodsVo);
-		// 查询SKU列表
-		List<GoodsSku> skuList = new ArrayList<>();
-		LambdaQueryWrapper<GoodsSku> queryWrapper = new LambdaQueryWrapper<>();
-		queryWrapper.eq(GoodsSku::getGoodsId, goods.getGoodsId());
-		queryWrapper.orderByDesc(GoodsSku::getCreatedTime);
-		skuList = goodsSkuService.list(queryWrapper);
-		if(null != skuList && skuList.size() > 0) {
-			goodsVo.setSkuList(skuList);
-		}
-		return AjaxResult.success(goodsVo);
-	}
+  /**
+   * 查询商品列表, 支持翻页
+   *
+   * @return
+   */
+  @PostMapping("/list")
+  @PreAuthorize("@ss.hasPermi('business:goods:list')")
+  public TableDataInfo list(@RequestBody GoodsQueryParam queryParam) {
+    startPage();
+    QueryWrapper<Goods> queryWrapper = new QueryWrapper<Goods>();
+    queryWrapper.lambda()
+        .like(null != queryParam && StringUtils.isNotBlank(queryParam.getTitle()), Goods::getTitle,
+            queryParam.getTitle());
+    queryWrapper.lambda()
+        .eq(null != queryParam.getGoodsId() && 0 != queryParam.getGoodsId(),
+            Goods::getGoodsId, queryParam.getGoodsId());
+    // 成本
+    queryWrapper.lambda()
+        .ge(null != queryParam.getMinCost(), Goods::getCost, queryParam.getMinCost());
+    queryWrapper.lambda()
+        .le(null != queryParam.getMaxCost(), Goods::getCost, queryParam.getMaxCost());
+    // 价格
+    queryWrapper.lambda()
+        .ge(null != queryParam.getMinValue(), Goods::getValue, queryParam.getMinValue());
+    queryWrapper.lambda()
+        .le(null != queryParam.getMaxValue(), Goods::getValue, queryParam.getMaxValue());
+    // 状态
+    queryWrapper.lambda()
+        .eq(null != queryParam.getStatus(), Goods::getStatus, queryParam.getStatus());
+    // 是否支持兑换
+    queryWrapper.lambda().eq(null != queryParam.getExchangeShow(), Goods::getExchangeShow,
+        queryParam.getExchangeShow());
+    // 商品分类
+    queryWrapper.lambda()
+        .eq(null != queryParam.getCategoryId(), Goods::getCategoryId, queryParam.getCategoryId());
+    // 商品标签
+    if (null != queryParam.getTagId()) {
+      List<GoodsTagRel> goodsTagRelList = goodsTagRelService.list(
+          new LambdaQueryWrapper<GoodsTagRel>().eq(GoodsTagRel::getTagId, queryParam.getTagId()));
+      List<Long> goodsIds = goodsTagRelList.stream().map(GoodsTagRel::getGoodsId)
+          .collect(Collectors.toList());
+      queryWrapper.lambda().eq(!CollectionUtils.isEmpty(goodsIds), Goods::getGoodsId, goodsIds);
+    }
+    queryWrapper.lambda().eq(Goods::getIsDeleted, 0);
+    queryWrapper.orderByAsc("FIELD(`status`, 'init', 'on', 'off')");
+    queryWrapper.lambda().orderByDesc(Goods::getGoodsId);
+    List<Goods> goodsList = goodsService.list(queryWrapper);
+    TableDataInfo res = getDataTable(goodsList);
+    res.setRows(goodsList);
+    return res;
+  }
 
+  /**
+   * 获取商品详情信息
+   *
+   * @param
+   * @return
+   */
+  @PostMapping(value = "/detail")
+  @PreAuthorize("@ss.hasPermi('business:goods:query')")
+  public AjaxResult getGoodsDetail(@RequestBody JSONObject jsonObject) {
+    Long goodsId = jsonObject.getLong("goodsId");
+    if (null == goodsId || 0 == goodsId) {
+      return error(ErrorCodeEnum.ERROR_CODE_1001);
+    }
+    Goods goods = goodsService.getById(goodsId);
+    if (null == goods) {
+      return error(ErrorCodeEnum.ERROR_CODE_1001);
+    }
+    GoodsVO goodsVo = new GoodsVO();
+    BeanUtils.copyProperties(goods, goodsVo);
+    // 查询SKU列表
+    List<GoodsSku> skuList = new ArrayList<>();
+    LambdaQueryWrapper<GoodsSku> queryWrapper = new LambdaQueryWrapper<>();
+    queryWrapper.eq(GoodsSku::getGoodsId, goods.getGoodsId());
+    queryWrapper.orderByDesc(GoodsSku::getCreatedTime);
+    skuList = goodsSkuService.list(queryWrapper);
+    if (null != skuList && skuList.size() > 0) {
+      goodsVo.setSkuList(skuList);
+    }
+    // 查询标签ID列表
+    List<GoodsTagRel> goodsTagRelList = goodsTagRelService.list(
+        new LambdaQueryWrapper<GoodsTagRel>().eq(GoodsTagRel::getGoodsId, goods.getGoodsId()));
+    List<Long> tagIds = goodsTagRelList.stream().map(GoodsTagRel::getTagId)
+        .collect(Collectors.toList());
+    goodsVo.setTagIds(tagIds);
 
-	/**
-	 * 新增商品信息
-	 * @param
-	 * @return
-	 */
-	@Log(title = "新增商品", businessType = BusinessType.INSERT)
-	@ApiOperation(value = "新增商品信息", notes = "后台商品管理新增商品")
-	@PostMapping("/create")
-	@PreAuthorize("@ss.hasPermi('business:goods:add')")
-	public AjaxResult goodsCreate(@Validated @RequestBody GoodsParam goodsParam) {
-		Goods goods = mapperFacade.map(goodsParam, Goods.class);
-		// 1、校验名称是否重复(商品表)
-		LambdaQueryWrapper<Goods> queryWrapper = new LambdaQueryWrapper<>();
-		queryWrapper.eq(Goods::getTitle, goods.getTitle());
-		queryWrapper.eq(Goods::getIsDeleted, 0);
-		int titleCount = goodsService.count(queryWrapper);
-		if(titleCount > 0) {
-			return AjaxResult.error("商品名称" + goods.getTitle() + "已存在!");
-		}
-		String description = URLDecoder.decode(goodsParam.getDescription());
-		goods.setDescription(description);
-		goods.setStatus(GoodsStatusEnum.PUT_INIT);
-		// 多SKU
-		List<GoodsSku> skuList = goodsParam.getSkuList();
-		if(goods.getMultiSku() == 1) { //
-			if((null == skuList || skuList.size() == 0)) {
-				return AjaxResult.error("商品" + goods.getTitle() + "不满足多SKU条件!");
-			}else {
-				GoodsSku firstGoodsSku = skuList.get(0);
-				goods.setOriginPrice(firstGoodsSku.getOriginPrice());
-				goods.setExchangePrice(firstGoodsSku.getExchangePrice());
-				goods.setValue(firstGoodsSku.getValue());
-				goods.setCost(firstGoodsSku.getCost());
-				// 累计库存
-				int totalQuantity = skuList.stream().mapToInt(GoodsSku::getQuantity).sum();
-				goods.setQuantity(totalQuantity);
-			}
-		}
-		if(null == goods.getOriginPrice()) {
-			goods.setOriginPrice(goods.getExchangePrice());
-		}
-		// 3.插入数据
-		try {
-			goods.setSkuProp(getSkuProp(skuList));
-			goodsService.saveGoods(goods, skuList);
-		} catch (Exception e) {
-			LogUtil.error(logger, e, "商品新增失败。");
-			return AjaxResult.error("商品'" + goods.getTitle() + "'新增失败");
-		}
-		return AjaxResult.success("商品'" + goods.getTitle() + "'新增成功");
-	}
+    return AjaxResult.success(goodsVo);
+  }
 
-	/**
-	 * 编辑商品信息
-	 * @param
-	 * @return
-	 */
-	@Log(title = "修改商品", businessType = BusinessType.UPDATE)
-	@ApiOperation(value = "编辑商品信息", notes = "后台商品管理修改商品信息")
-	@PostMapping("/update")
-	@PreAuthorize("@ss.hasPermi('business:goods:edit')")
-	public AjaxResult goodsUpdate(@Validated @RequestBody GoodsParam goodsParam) {
-		if (null == goodsParam || null == goodsParam.getGoodsId() || 0 == goodsParam.getGoodsId()) {
-			return error(ErrorCodeEnum.ERROR_CODE_1001);
-		}
-		Goods oldGoods = goodsService.getById(goodsParam.getGoodsId());
-		if(null == oldGoods || null == oldGoods.getGoodsId()) {
-			return AjaxResult.error("商品'" + oldGoods.getTitle() + "'编辑失败,商品ID异常");
-		}
-		Goods goods = mapperFacade.map(goodsParam, Goods.class);
-		// 1、校验名称是否重复(商品表)
-		if(!goods.getTitle().equals(oldGoods.getTitle())) {
-			LambdaQueryWrapper<Goods> queryWrapper = new LambdaQueryWrapper<>();
-			queryWrapper.eq(Goods::getTitle, goods.getTitle());
-			queryWrapper.eq(Goods::getIsDeleted, 0);
-			int titleCount = goodsService.count(queryWrapper);
-			if(titleCount > 0) {
-				return AjaxResult.error("商品名称" + goods.getTitle() + "已存在!");
-			}
-		}
-		String description = URLDecoder.decode(goodsParam.getDescription());
-		goods.setDescription(description);
-		// 多SKU
-		List<GoodsSku> skuList = goodsParam.getSkuList();
-		if(goods.getMultiSku() == 1) {
-			if((null == skuList || skuList.size() == 0)) {
-				return AjaxResult.error("商品" + goods.getTitle() + "不满足多SKU条件!");
-			}else {
-				GoodsSku firstGoodsSku = skuList.get(0);
-				goods.setExchangePrice(firstGoodsSku.getExchangePrice());
-				goods.setValue(firstGoodsSku.getValue());
-				goods.setCost(firstGoodsSku.getCost());
-				if(null == firstGoodsSku.getOriginPrice()) {
-					goods.setOriginPrice(firstGoodsSku.getExchangePrice());
-				}else {
-					goods.setOriginPrice(firstGoodsSku.getOriginPrice());
-				}
-				// 累计库存
-				int totalQuantity = skuList.stream().mapToInt(GoodsSku::getQuantity).sum();
-				goods.setQuantity(totalQuantity);
-			}
-		}
-		// 3.插入数据
-		try {
-			goods.setSkuProp(getSkuProp(skuList));
-			goodsService.updateGoods(goods, skuList);
-		} catch (Exception e) {
-			LogUtil.error(logger, e, "商品更新失败。");
-			return AjaxResult.error("商品'" + goods.getTitle() + "'更新失败");
-		}
-		return AjaxResult.success("商品'" + goods.getTitle() + "'更新成功");
-	}
 
-	// 获取商品的sku
-	public String getSkuProp(List<GoodsSku> skuList) {
-		if (CollectionUtils.isEmpty(skuList)) {
-			return null;
-		}
-		LinkedHashMap<String, HashSet<String>> skuProp = new LinkedHashMap<>();
-		for (GoodsSku sku : skuList) {
-			if (StringUtils.isNotBlank(sku.getProperties())) {
-				String[] skuAry = sku.getProperties().split(";");
-				for (int i = 0; i < skuAry.length; i++) {
-					String item = skuAry[i];
-					String[] itemAry = item.split(":");
-					String key = itemAry[0];
-					String value = itemAry[1];
-					HashSet<String> valueSet = skuProp.get(key);
-					if (null == valueSet) {
-						valueSet = new HashSet<>();
-						skuProp.put(key, valueSet);
-					}
-					valueSet.add(value);
-				}
-			}
-		}
-		List<JSONObject> skuPropList = new ArrayList<>();
-		for (String key : skuProp.keySet()) {
-			JSONObject jsonObject = new JSONObject();
-			jsonObject.put("name", key);
-			jsonObject.put("value", skuProp.get(key));
-			skuPropList.add(jsonObject);
-		}
-		return JSONObject.toJSONString(skuPropList);
-	}
+  /**
+   * 新增商品信息
+   *
+   * @param
+   * @return
+   */
+  @Log(title = "新增商品", businessType = BusinessType.INSERT)
+  @ApiOperation(value = "新增商品信息", notes = "后台商品管理新增商品")
+  @PostMapping("/create")
+  @PreAuthorize("@ss.hasPermi('business:goods:add')")
+  public AjaxResult goodsCreate(@Validated @RequestBody GoodsParam goodsParam) {
+    Goods goods = mapperFacade.map(goodsParam, Goods.class);
+    // 1、校验名称是否重复(商品表)
+    LambdaQueryWrapper<Goods> queryWrapper = new LambdaQueryWrapper<>();
+    queryWrapper.eq(Goods::getTitle, goods.getTitle());
+    queryWrapper.eq(Goods::getIsDeleted, 0);
+    int titleCount = goodsService.count(queryWrapper);
+    if (titleCount > 0) {
+      return AjaxResult.error("商品名称" + goods.getTitle() + "已存在!");
+    }
+    String description = URLDecoder.decode(goodsParam.getDescription());
+    goods.setDescription(description);
+    goods.setStatus(GoodsStatusEnum.PUT_INIT);
+    // 多SKU
+    List<GoodsSku> skuList = goodsParam.getSkuList();
+    if (goods.getMultiSku() == 1) { //
+      if ((null == skuList || skuList.size() == 0)) {
+        return AjaxResult.error("商品" + goods.getTitle() + "不满足多SKU条件!");
+      } else {
+        GoodsSku firstGoodsSku = skuList.get(0);
+        goods.setOriginPrice(firstGoodsSku.getOriginPrice());
+        goods.setExchangePrice(firstGoodsSku.getExchangePrice());
+        goods.setValue(firstGoodsSku.getValue());
+        goods.setCost(firstGoodsSku.getCost());
+        // 累计库存
+        int totalQuantity = skuList.stream().mapToInt(GoodsSku::getQuantity).sum();
+        goods.setQuantity(totalQuantity);
+      }
+    }
+    if (null == goods.getOriginPrice()) {
+      goods.setOriginPrice(goods.getExchangePrice());
+    }
+    // 3.插入数据
+    try {
+      goods.setSkuProp(getSkuProp(skuList));
+      goodsService.saveGoods(goods, skuList, goodsParam.getTagIds());
+    } catch (Exception e) {
+      LogUtil.error(logger, e, "商品新增失败。");
+      return AjaxResult.error("商品'" + goods.getTitle() + "'新增失败");
+    }
+    return AjaxResult.success("商品'" + goods.getTitle() + "'新增成功");
+  }
 
+  /**
+   * 编辑商品信息
+   *
+   * @param
+   * @return
+   */
+  @Log(title = "修改商品", businessType = BusinessType.UPDATE)
+  @ApiOperation(value = "编辑商品信息", notes = "后台商品管理修改商品信息")
+  @PostMapping("/update")
+  @PreAuthorize("@ss.hasPermi('business:goods:edit')")
+  public AjaxResult goodsUpdate(@Validated @RequestBody GoodsParam goodsParam) {
+    if (null == goodsParam || null == goodsParam.getGoodsId() || 0 == goodsParam.getGoodsId()) {
+      return error(ErrorCodeEnum.ERROR_CODE_1001);
+    }
+    Goods oldGoods = goodsService.getById(goodsParam.getGoodsId());
+    if (null == oldGoods || null == oldGoods.getGoodsId()) {
+      return AjaxResult.error("商品'" + oldGoods.getTitle() + "'编辑失败,商品ID异常");
+    }
+    Goods goods = mapperFacade.map(goodsParam, Goods.class);
+    // 1、校验名称是否重复(商品表)
+    if (!goods.getTitle().equals(oldGoods.getTitle())) {
+      LambdaQueryWrapper<Goods> queryWrapper = new LambdaQueryWrapper<>();
+      queryWrapper.eq(Goods::getTitle, goods.getTitle());
+      queryWrapper.eq(Goods::getIsDeleted, 0);
+      int titleCount = goodsService.count(queryWrapper);
+      if (titleCount > 0) {
+        return AjaxResult.error("商品名称" + goods.getTitle() + "已存在!");
+      }
+    }
+    String description = URLDecoder.decode(goodsParam.getDescription());
+    goods.setDescription(description);
+    // 多SKU
+    List<GoodsSku> skuList = goodsParam.getSkuList();
+    if (goods.getMultiSku() == 1) {
+      if ((null == skuList || skuList.size() == 0)) {
+        return AjaxResult.error("商品" + goods.getTitle() + "不满足多SKU条件!");
+      } else {
+        GoodsSku firstGoodsSku = skuList.get(0);
+        goods.setExchangePrice(firstGoodsSku.getExchangePrice());
+        goods.setValue(firstGoodsSku.getValue());
+        goods.setCost(firstGoodsSku.getCost());
+        if (null == firstGoodsSku.getOriginPrice()) {
+          goods.setOriginPrice(firstGoodsSku.getExchangePrice());
+        } else {
+          goods.setOriginPrice(firstGoodsSku.getOriginPrice());
+        }
+        // 累计库存
+        int totalQuantity = skuList.stream().mapToInt(GoodsSku::getQuantity).sum();
+        goods.setQuantity(totalQuantity);
+      }
+    }
+    // 3.插入数据
+    try {
+      goods.setSkuProp(getSkuProp(skuList));
+      goodsService.updateGoods(goods, skuList, goodsParam.getTagIds());
+    } catch (Exception e) {
+      LogUtil.error(logger, e, "商品更新失败。");
+      return AjaxResult.error("商品'" + goods.getTitle() + "'更新失败");
+    }
+    return AjaxResult.success("商品'" + goods.getTitle() + "'更新成功");
+  }
 
-	private Object getObjValue(Object a, Object b){
-		boolean isa = (a instanceof List<?>);
-		boolean isb = (b instanceof List<?>);
-		System.out.println("isa == " + isa);
-		System.out.println("isb == " + isb);
-		List<Object> list = new ArrayList<>();
-		if (isa) {
-			list.addAll((List<?>) a);
-		} else {
-			list.add(a+"");
-		}
-		if (isb) {
-			list.addAll((List<?>) b);
-		} else {
-			list.add(b+"");
-		}
-		return list.stream().distinct().collect(Collectors.toList());
-	}
+  // 获取商品的sku
+  public String getSkuProp(List<GoodsSku> skuList) {
+    if (CollectionUtils.isEmpty(skuList)) {
+      return null;
+    }
+    LinkedHashMap<String, HashSet<String>> skuProp = new LinkedHashMap<>();
+    for (GoodsSku sku : skuList) {
+      if (StringUtils.isNotBlank(sku.getProperties())) {
+        String[] skuAry = sku.getProperties().split(";");
+        for (int i = 0; i < skuAry.length; i++) {
+          String item = skuAry[i];
+          String[] itemAry = item.split(":");
+          String key = itemAry[0];
+          String value = itemAry[1];
+          HashSet<String> valueSet = skuProp.get(key);
+          if (null == valueSet) {
+            valueSet = new HashSet<>();
+            skuProp.put(key, valueSet);
+          }
+          valueSet.add(value);
+        }
+      }
+    }
+    List<JSONObject> skuPropList = new ArrayList<>();
+    for (String key : skuProp.keySet()) {
+      JSONObject jsonObject = new JSONObject();
+      jsonObject.put("name", key);
+      jsonObject.put("value", skuProp.get(key));
+      skuPropList.add(jsonObject);
+    }
+    return JSONObject.toJSONString(skuPropList);
+  }
 
 
-	/**
-	 * 上下架商品
-	 * @param
-	 * @return
-	 */
-	@Log(title = "上下架商品", businessType = BusinessType.UPDATE)
-	@ApiOperation(value = "上下架商品", notes = "上下架商品")
-	@PostMapping("/status")
-	@PreAuthorize("@ss.hasPermi('business:goods:on')")
-	public AjaxResult goodsStatus(@RequestBody JSONObject jsonObject) {
-		String goodsId = jsonObject.getString("goodsId");
+  /**
+   * 上下架商品
+   *
+   * @param
+   * @return
+   */
+  @Log(title = "上下架商品", businessType = BusinessType.UPDATE)
+  @ApiOperation(value = "上下架商品", notes = "上下架商品")
+  @PostMapping("/status")
+  @PreAuthorize("@ss.hasPermi('business:goods:on')")
+  public AjaxResult goodsStatus(@RequestBody JSONObject jsonObject) {
+    String goodsId = jsonObject.getString("goodsId");
 
-		GoodsStatusEnum status = GoodsStatusEnum.getStatusEnum(jsonObject.getString("status"));
-		if (StringUtils.isBlank(goodsId) || null == status) {
-			return error(ErrorCodeEnum.ERROR_CODE_1001);
-		}
-		try {
-			goodsService.lambdaUpdate().set(Goods::getStatus, status).eq(Goods::getGoodsId, goodsId).update();
-			// 查询代金券信息
-		} catch (Exception e) {
-			return AjaxResult.error("操作失败");
-		}
-		return AjaxResult.success("操作成功");
-	}
+    GoodsStatusEnum status = GoodsStatusEnum.getStatusEnum(jsonObject.getString("status"));
+    if (StringUtils.isBlank(goodsId) || null == status) {
+      return error(ErrorCodeEnum.ERROR_CODE_1001);
+    }
+    try {
+      goodsService.lambdaUpdate().set(Goods::getStatus, status).eq(Goods::getGoodsId, goodsId)
+          .update();
+      // 查询代金券信息
+    } catch (Exception e) {
+      return AjaxResult.error("操作失败");
+    }
+    return AjaxResult.success("操作成功");
+  }
 
 
-	/**
-	 * 删除商品(假删)
-	 *
-	 * @param
-	 * @return
-	 */
-	@Log(title = "删除商品", businessType = BusinessType.DELETE)
-	@PostMapping(value = "/remove")
-	@PreAuthorize("@ss.hasPermi('business:goods:remove')")
-	public AjaxResult removeGoods(@RequestBody JSONObject jsonObject) {
-		Long goodsId = jsonObject.getLong("goodsId");
-	    if (null == goodsId || 0 == goodsId){
-	      return error(ErrorCodeEnum.ERROR_CODE_1001);
-	    }
-		Goods goods = goodsService.getById(goodsId);
-		if(null == goods || null == goods.getGoodsId() || 0 == goods.getGoodsId()) {
-			 return error(ErrorCodeEnum.ERROR_CODE_1001);
-		}
-		// 商品未下架, 不允许删除
-		if(goods.getStatus().equals("on")) {
-			return AjaxResult.error("商品未下架,不允许删除");
-		}
-		LambdaUpdateWrapper<Goods> updateWrapper = new LambdaUpdateWrapper<>();
-		updateWrapper.set(Goods::getIsDeleted, 1);
-		updateWrapper.eq(Goods::getGoodsId, goods.getGoodsId());
-		boolean res = goodsService.update(updateWrapper);
-		if(!res) {
-			return AjaxResult.error("商品删除失败");
-		}
-		return AjaxResult.success("商品删除成功");
-	}
+  /**
+   * 删除商品(假删)
+   *
+   * @param
+   * @return
+   */
+  @Log(title = "删除商品", businessType = BusinessType.DELETE)
+  @PostMapping(value = "/remove")
+  @PreAuthorize("@ss.hasPermi('business:goods:remove')")
+  public AjaxResult removeGoods(@RequestBody JSONObject jsonObject) {
+    Long goodsId = jsonObject.getLong("goodsId");
+    if (null == goodsId || 0 == goodsId) {
+      return error(ErrorCodeEnum.ERROR_CODE_1001);
+    }
+    Goods goods = goodsService.getById(goodsId);
+    if (null == goods || null == goods.getGoodsId() || 0 == goods.getGoodsId()) {
+      return error(ErrorCodeEnum.ERROR_CODE_1001);
+    }
+    // 商品未下架, 不允许删除
+    if (goods.getStatus().equals("on")) {
+      return AjaxResult.error("商品未下架,不允许删除");
+    }
+    LambdaUpdateWrapper<Goods> updateWrapper = new LambdaUpdateWrapper<>();
+    updateWrapper.set(Goods::getIsDeleted, 1);
+    updateWrapper.eq(Goods::getGoodsId, goods.getGoodsId());
+    boolean res = goodsService.update(updateWrapper);
+    if (!res) {
+      return AjaxResult.error("商品删除失败");
+    }
+    return AjaxResult.success("商品删除成功");
+  }
 
 }

+ 167 - 0
mp-admin/src/main/java/com/qs/mp/web/controller/api/admin/GoodsTagMgrController.java

@@ -0,0 +1,167 @@
+package com.qs.mp.web.controller.api.admin;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.qs.mp.admin.domain.Goods;
+import com.qs.mp.admin.domain.GoodsCategory;
+import com.qs.mp.admin.domain.GoodsTag;
+import com.qs.mp.admin.domain.GoodsTagRel;
+import com.qs.mp.admin.service.IGoodsCategoryService;
+import com.qs.mp.admin.service.IGoodsService;
+import com.qs.mp.admin.service.IGoodsTagRelService;
+import com.qs.mp.admin.service.IGoodsTagService;
+import com.qs.mp.common.annotation.Log;
+import com.qs.mp.common.core.domain.AjaxResult;
+import com.qs.mp.common.core.page.TableDataInfo;
+import com.qs.mp.common.enums.BusinessType;
+import com.qs.mp.common.enums.ErrorCodeEnum;
+import com.qs.mp.web.controller.common.BaseApiController;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import java.util.Arrays;
+import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Component;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @auther zhongcp
+ * @create 2022-04-07 23:45:48
+ * @describe 商品标签管理前端控制器
+ */
+@Api("商品标签管理API")
+@RestController
+@RequestMapping("/api/v1/mp/admin/goods/tag/*")
+@Component
+public class GoodsTagMgrController extends BaseApiController {
+
+  @Autowired
+  private IGoodsTagService goodsTagService;
+
+  @Autowired
+  private IGoodsTagRelService goodsTagRelService;
+
+
+  /**
+   * 查询商品标签列表, 支持翻页
+   *
+   * @return
+   */
+  @PostMapping("/list")
+  @PreAuthorize("@ss.hasPermi('business:tag:list')")
+  public TableDataInfo list(@RequestBody JSONObject param) {
+    startPage();
+    List<GoodsTag> tagList = goodsTagService.list(new LambdaQueryWrapper<GoodsTag>());
+    return getDataTable(tagList);
+  }
+
+  /**
+   * 查询商品标签列表
+   *
+   * @return
+   */
+  @PostMapping("/items")
+  @PreAuthorize("@ss.hasPermi('business:tag:list')")
+  public AjaxResult items(@RequestBody JSONObject param) {
+    List<GoodsTag> tagList = goodsTagService.list(new LambdaQueryWrapper<GoodsTag>());
+    return AjaxResult.success(tagList);
+  }
+
+  /**
+   * 获取商品标签详情信息
+   *
+   * @param
+   * @return
+   */
+  @PostMapping(value = "/detail")
+  @PreAuthorize("@ss.hasPermi('business:tag:query')")
+  public AjaxResult info(@RequestBody JSONObject jsonObject) {
+    Long tagId = jsonObject.getLong("tagId");
+    if (null == tagId || 0 == tagId) {
+      return error(ErrorCodeEnum.ERROR_CODE_1001);
+    }
+    GoodsTag goodsTag = goodsTagService.getById(tagId);
+    return AjaxResult.success(goodsTag);
+  }
+
+
+  /**
+   * 新增商品标签信息
+   *
+   * @param
+   * @return
+   */
+  @Log(title = "新增商品标签", businessType = BusinessType.INSERT)
+  @ApiOperation(value = "新增商品标签", notes = "后台商品管理新增标签")
+  @PostMapping("/create")
+  @PreAuthorize("@ss.hasPermi('business:tag:add')")
+  public AjaxResult create(@Validated @RequestBody GoodsTag goodsTag) {
+    // 1、校验名称是否重复
+    int cnt = goodsTagService.count(new LambdaQueryWrapper<GoodsTag>()
+        .eq(GoodsTag::getName, goodsTag.getName()));
+    if (cnt > 0) {
+      return AjaxResult.error("标签名称已存在!");
+    }
+    // 2.保存
+    goodsTagService.save(goodsTag);
+    return AjaxResult.success("保存成功");
+  }
+
+  /**
+   * 编辑商品标签信息
+   *
+   * @param
+   * @return
+   */
+  @Log(title = "修改商品标签", businessType = BusinessType.UPDATE)
+  @ApiOperation(value = "编辑商品标签信息", notes = "后台商品管理修改商品标签信息")
+  @PostMapping("/update")
+  @PreAuthorize("@ss.hasPermi('business:tag:edit')")
+  public AjaxResult update(@Validated @RequestBody GoodsTag goodsTag) {
+    if (null == goodsTag || null == goodsTag.getTagId()
+        || 0 == goodsTag.getTagId()) {
+      return error(ErrorCodeEnum.ERROR_CODE_1001);
+    }
+    int cnt = goodsTagService.count(new LambdaQueryWrapper<GoodsTag>()
+        .eq(GoodsTag::getName, goodsTag.getName()).notIn(GoodsTag::getTagId,
+            Arrays.asList(goodsTag.getTagId())));
+    if (cnt > 0) {
+      return AjaxResult.error("标签名称已存在!");
+    }
+    // 保存数据
+    boolean rst = goodsTagService.updateById(goodsTag);
+    return rst ? AjaxResult.success("更新成功") : AjaxResult.error("更新失败");
+  }
+
+
+  /**
+   * 删除商品标签
+   *
+   * @param
+   * @return
+   */
+  @Log(title = "删除商品标签", businessType = BusinessType.DELETE)
+  @PostMapping(value = "/remove")
+  @PreAuthorize("@ss.hasPermi('business:tag:remove')")
+  public AjaxResult remove(@RequestBody GoodsTag goodsTag) {
+
+    if (null == goodsTag || null == goodsTag.getTagId()
+        || 0 == goodsTag.getTagId()) {
+      return error(ErrorCodeEnum.ERROR_CODE_1001);
+    }
+    int cnt = goodsTagRelService.count(new LambdaQueryWrapper<GoodsTagRel>()
+        .eq(GoodsTagRel::getTagId, goodsTag.getTagId()));
+    if (cnt > 0) {
+      return error(ErrorCodeEnum.ERROR_CODE_1025);
+    }
+
+    boolean res = goodsTagService.removeById(goodsTag.getTagId());
+    return res ? AjaxResult.success("删除成功") : AjaxResult.error("删除失败");
+  }
+
+}

+ 16 - 1
mp-admin/src/main/java/com/qs/mp/web/controller/api/user/UserExchangeController.java

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.qs.mp.admin.domain.Goods;
 import com.qs.mp.admin.domain.GoodsSku;
+import com.qs.mp.admin.domain.GoodsTagRel;
 import com.qs.mp.admin.domain.Ticket;
 import com.qs.mp.admin.domain.TicketAwardsPrize;
 import com.qs.mp.admin.domain.TicketBox;
@@ -17,6 +18,7 @@ import com.qs.mp.admin.domain.vo.TicketBoxVO;
 import com.qs.mp.admin.domain.vo.TicketVO;
 import com.qs.mp.admin.service.IGoodsService;
 import com.qs.mp.admin.service.IGoodsSkuService;
+import com.qs.mp.admin.service.IGoodsTagRelService;
 import com.qs.mp.admin.service.ITicketAwardsPrizeService;
 import com.qs.mp.admin.service.ITicketBoxService;
 import com.qs.mp.admin.service.ITicketService;
@@ -37,11 +39,14 @@ import com.qs.mp.web.controller.common.BaseApiController;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
+import java.util.stream.Collectors;
 import lombok.AllArgsConstructor;
 import ma.glasnost.orika.MapperFacade;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.CollectionUtils;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -64,6 +69,8 @@ public class UserExchangeController extends BaseApiController {
   @Autowired
   private IUserExchangeOrderService userExchangeOrderService;
 
+  @Autowired
+  private IGoodsTagRelService goodsTagRelService;
 
   @Autowired
   private MapperFacade mapperFacade;
@@ -75,16 +82,24 @@ public class UserExchangeController extends BaseApiController {
   @ApiOperation(value = "商品列表" , notes = "获取所有可兑换商品")
   public TableDataInfo list(@RequestBody JSONObject param) {
     Long categoryId = param.getLong("categoryId");
+    String tagIds = param.getString("tagIds");
     Integer startPrice = param.getInteger("startPrice");
     Integer endPrice = param.getInteger("endPrice");
 
+    List<Long> goodsIds = new ArrayList<>();
+    if (StringUtils.isNotBlank(tagIds)) {
+      List<GoodsTagRel> goodsTagRelList = goodsTagRelService.list(new LambdaQueryWrapper<GoodsTagRel>()
+          .in(GoodsTagRel::getTagId, Arrays.asList(tagIds.split(","))));
+      goodsIds = goodsTagRelList.stream().map(GoodsTagRel::getGoodsId).collect(Collectors.toList());
+    }
     startPage();
     List<Goods> goodsList = goodsService.list(new LambdaQueryWrapper<Goods>()
         .eq(null != categoryId && 0 != categoryId, Goods::getCategoryId, categoryId)
         .ge(null != startPrice && 0 != startPrice, Goods::getExchangePrice, startPrice)
         .le(null != endPrice && 0 != endPrice, Goods::getExchangePrice, endPrice)
         .eq(Goods::getStatus, GoodsStatusEnum.PUT_ON)
-        .eq(Goods::getExchangeShow, 1));
+        .eq(Goods::getExchangeShow, 1)
+        .in(!CollectionUtils.isEmpty(goodsIds), Goods::getGoodsId, goodsIds));
     List<GoodsListVO> goodsListVOList = mapperFacade.mapAsList(goodsList, GoodsListVO.class);
     TableDataInfo rspData = getDataTable(goodsList);
     rspData.setRows(goodsListVOList);

+ 51 - 0
mp-common/src/main/java/com/qs/mp/common/enums/BannerLocationEnum.java

@@ -0,0 +1,51 @@
+package com.qs.mp.common.enums;
+
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.annotation.JSONType;
+import com.baomidou.mybatisplus.annotation.IEnum;
+import com.qs.mp.common.json.EnumValueDeserializer;
+
+/**
+ *
+ * banner位置
+ *
+ */
+@JSONType(deserializer = EnumValueDeserializer.class)
+public enum BannerLocationEnum implements IEnum<String> {
+
+  PUT_ON("top", "顶部轮播"),;
+
+  private final String value;
+  private final String desc;
+
+  public static BannerLocationEnum getStatusEnum(String value) {
+    for (BannerLocationEnum statusEnum : BannerLocationEnum.values()) {
+      if (statusEnum.getValue().equals(value)) {
+        return statusEnum;
+      }
+    }
+    return null;
+  }
+
+  BannerLocationEnum(final String value, final String desc) {
+    this.value = value;
+    this.desc = desc;
+  }
+
+  @Override
+  public String getValue() {
+    return value;
+  }
+
+  /**
+   * 重写toString,单个转化成json
+   * @return
+   */
+  @Override
+  public String toString() {
+    JSONObject object = new JSONObject();
+    object.put("value",value);
+    object.put("desc", desc);
+    return object.toString();
+  }
+}

+ 2 - 0
mp-common/src/main/java/com/qs/mp/common/enums/ErrorCodeEnum.java

@@ -30,6 +30,8 @@ public enum ErrorCodeEnum {
   ERROR_CODE_1021(1021, "盲豆余额不足"),
   ERROR_CODE_1022(1022, "订单支付中"),
   ERROR_CODE_1023(1023, "盲票未激活"),
+  ERROR_CODE_1024(1024, "删除失败,分类下存在商品"),
+  ERROR_CODE_1025(1025, "删除失败,标签下存在商品"),
   ;
   private int code;
   private String msg;

+ 87 - 0
mp-service/src/main/java/com/qs/mp/admin/domain/ExchangeBanner.java

@@ -0,0 +1,87 @@
+package com.qs.mp.admin.domain;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.alibaba.fastjson.serializer.SerializerFeature;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.qs.mp.common.enums.BannerLocationEnum;
+import java.io.Serializable;
+import java.util.Date;
+import lombok.Data;
+
+/**
+ * @describe 兑换大厅推广区设置实体类
+ * @auther quanshu
+ * @create 2022-04-07 11:42:42
+ */
+@TableName("mp_exchange_banner")
+@Data
+public class ExchangeBanner implements Serializable {
+
+  private static final long serialVersionUID = 1L;
+
+  /**
+   * 主键
+   */
+  @TableId(value = "banner_id", type = IdType.AUTO)
+  private Long bannerId;
+
+  /**
+   * banner名
+   */
+  @TableField("name")
+  private String name;
+
+  /**
+   * 图片
+   */
+  @TableField("pic_url")
+  private String picUrl;
+
+  /**
+   * 位置
+   */
+  @TableField("location")
+  @JSONField(serialzeFeatures = SerializerFeature.WriteEnumUsingToString)
+  private BannerLocationEnum location;
+
+  /**
+   * 顺序
+   */
+  @TableField("sort")
+  private Integer sort;
+
+  /**
+   * 类型,链接link,标签tag
+   */
+  @TableField("type")
+  private String type;
+
+  /**
+   * 链接url
+   */
+  @TableField("link_url")
+  private String linkUrl;
+
+  /**
+   * 标签列表,逗号隔开
+   */
+  @TableField("goods_tags")
+  private String goodsTags;
+
+  /**
+   * 创建时间
+   */
+  @TableField("created_time")
+  private Date createdTime;
+
+  /**
+   * 更新时间
+   */
+  @TableField("updated_time")
+  private Date updatedTime;
+
+
+}

+ 13 - 1
mp-service/src/main/java/com/qs/mp/admin/domain/GoodsCategory.java

@@ -31,11 +31,17 @@ public class GoodsCategory implements Serializable {
   @TableField("name")
   private String name;
 
+  /**
+   * 图片
+   */
+  @TableField("pic_url")
+  private String picUrl;
+
   /**
    * 父级类目ID
    */
   @TableField("parent_id")
-  private String parentId;
+  private Long parentId;
 
   /**
    * 排序
@@ -43,6 +49,12 @@ public class GoodsCategory implements Serializable {
   @TableField("sort")
   private Integer sort;
 
+  /**
+   * 是否显示
+   */
+  @TableField("is_show")
+  private Integer isShow;
+
   /**
    * 创建时间
    */

+ 59 - 0
mp-service/src/main/java/com/qs/mp/admin/domain/GoodsTag.java

@@ -0,0 +1,59 @@
+package com.qs.mp.admin.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.util.Date;
+import lombok.Data;
+
+/**
+ * @describe 商品标签实体类
+ * @auther quanshu
+ * @create 2022-04-07 11:42:42
+ */
+@TableName("mp_goods_tag")
+@Data
+public class GoodsTag implements Serializable {
+
+  private static final long serialVersionUID = 1L;
+
+  /**
+   * 主键
+   */
+  @TableId(value = "tag_id", type = IdType.AUTO)
+  private Long tagId;
+
+  /**
+   * 标签名
+   */
+  @TableField("name")
+  private String name;
+
+  /**
+   * 顺序
+   */
+  @TableField("sort")
+  private Integer sort;
+
+  /**
+   * 是否在兑换大厅里显示
+   */
+  @TableField("is_show")
+  private Integer isShow;
+
+  /**
+   * 创建时间
+   */
+  @TableField("created_time")
+  private Date createdTime;
+
+  /**
+   * 更新时间
+   */
+  @TableField("updated_time")
+  private Date updatedTime;
+
+
+}

+ 53 - 0
mp-service/src/main/java/com/qs/mp/admin/domain/GoodsTagRel.java

@@ -0,0 +1,53 @@
+package com.qs.mp.admin.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.util.Date;
+import lombok.Data;
+
+/**
+ * @describe 商品和标签的关系实体类
+ * @auther quanshu
+ * @create 2022-04-07 11:42:42
+ */
+@TableName("mp_goods_tag_rel")
+@Data
+public class GoodsTagRel implements Serializable {
+
+  private static final long serialVersionUID = 1L;
+
+  /**
+   * 主键
+   */
+  @TableId(value = "id", type = IdType.AUTO)
+  private Long id;
+
+  /**
+   * 商品ID
+   */
+  @TableField("goods_id")
+  private Long goodsId;
+
+  /**
+   * 标签ID
+   */
+  @TableField("tag_id")
+  private Long tagId;
+
+  /**
+   * 创建时间
+   */
+  @TableField("created_time")
+  private Date createdTime;
+
+  /**
+   * 更新时间
+   */
+  @TableField("updated_time")
+  private Date updatedTime;
+
+
+}

+ 3 - 0
mp-service/src/main/java/com/qs/mp/admin/domain/param/GoodsParam.java

@@ -109,4 +109,7 @@ public class GoodsParam {
 	@ApiModelProperty(value = "商品多SKU列表", required = false)
 	private List<GoodsSku> skuList;
 
+	@ApiModelProperty(value = "商品标签ID列表", required = false)
+	private List<Long> tagIds;
+
 }

+ 7 - 1
mp-service/src/main/java/com/qs/mp/admin/domain/param/GoodsQueryParam.java

@@ -23,6 +23,12 @@ public class GoodsQueryParam {
 	@ApiModelProperty(value = "商品ID", required = false)
 	private Long goodsId;
 
+	@ApiModelProperty(value = "分类ID", required = false)
+	private Long categoryId;
+
+	@ApiModelProperty(value = "标签ID", required = false)
+	private Long tagId;
+
 	@NotNull(message = "商品名称不能为空")
 	@ApiModelProperty(value = "商品名称", required = true)
 	private String title;
@@ -50,7 +56,7 @@ public class GoodsQueryParam {
 	 */
 	@ApiModelProperty(value = "最高价格", required = false)
 	private Integer maxValue;
-	
+
 	/**
 	 * 兑换大厅是否展示,0不展示,1展示
 	 */

+ 5 - 0
mp-service/src/main/java/com/qs/mp/admin/domain/vo/GoodsVO.java

@@ -100,6 +100,11 @@ public class GoodsVO {
 	 */
 	private Integer isDeleted;
 
+	/**
+	 * 标签ID列表
+	 */
+	private List<Long> tagIds;
+
 	/**
 	 * 创建时间
 	 */

+ 13 - 0
mp-service/src/main/java/com/qs/mp/admin/mapper/ExchangeBannerMapper.java

@@ -0,0 +1,13 @@
+package com.qs.mp.admin.mapper;
+
+import com.qs.mp.admin.domain.ExchangeBanner;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * @auther quanshu
+ * @create 2022-04-07 11:42:42
+ * @describe 兑换大厅推广区设置mapper类
+ */
+public interface ExchangeBannerMapper extends BaseMapper<ExchangeBanner> {
+
+}

+ 13 - 0
mp-service/src/main/java/com/qs/mp/admin/mapper/GoodsTagMapper.java

@@ -0,0 +1,13 @@
+package com.qs.mp.admin.mapper;
+
+import com.qs.mp.admin.domain.GoodsTag;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * @auther quanshu
+ * @create 2022-04-07 11:42:42
+ * @describe 商品标签mapper类
+ */
+public interface GoodsTagMapper extends BaseMapper<GoodsTag> {
+
+}

+ 13 - 0
mp-service/src/main/java/com/qs/mp/admin/mapper/GoodsTagRelMapper.java

@@ -0,0 +1,13 @@
+package com.qs.mp.admin.mapper;
+
+import com.qs.mp.admin.domain.GoodsTagRel;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * @auther quanshu
+ * @create 2022-04-07 11:42:42
+ * @describe 商品和标签的关系mapper类
+ */
+public interface GoodsTagRelMapper extends BaseMapper<GoodsTagRel> {
+
+}

+ 16 - 0
mp-service/src/main/java/com/qs/mp/admin/service/IExchangeBannerService.java

@@ -0,0 +1,16 @@
+package com.qs.mp.admin.service;
+
+import com.qs.mp.admin.domain.ExchangeBanner;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * 兑换大厅推广区设置 服务类
+ * </p>
+ *
+ * @author quanshu
+ * @since 2022-04-07
+ */
+public interface IExchangeBannerService extends IService<ExchangeBanner> {
+
+}

+ 6 - 5
mp-service/src/main/java/com/qs/mp/admin/service/IGoodsService.java

@@ -18,15 +18,16 @@ public interface IGoodsService extends IService<Goods> {
 
 	/**
 	 * 新增商品信息
-	 * @param goods
-     * @param skuList
-     */
-    public void saveGoods(Goods goods, List<GoodsSku> skuList);
+   * @param goods
+* @param skuList
+   * @param tagIds
+   */
+    void saveGoods(Goods goods, List<GoodsSku> skuList, List<Long> tagIds);
 
     /**
      * 编辑商品信息
      * @param goods
      * @param skuList
      */
-    public void updateGoods(Goods goods, List<GoodsSku> skuList);
+    void updateGoods(Goods goods, List<GoodsSku> skuList, List<Long> tagIds);
 }

+ 16 - 0
mp-service/src/main/java/com/qs/mp/admin/service/IGoodsTagRelService.java

@@ -0,0 +1,16 @@
+package com.qs.mp.admin.service;
+
+import com.qs.mp.admin.domain.GoodsTagRel;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * 商品和标签的关系 服务类
+ * </p>
+ *
+ * @author quanshu
+ * @since 2022-04-07
+ */
+public interface IGoodsTagRelService extends IService<GoodsTagRel> {
+
+}

+ 16 - 0
mp-service/src/main/java/com/qs/mp/admin/service/IGoodsTagService.java

@@ -0,0 +1,16 @@
+package com.qs.mp.admin.service;
+
+import com.qs.mp.admin.domain.GoodsTag;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * 商品标签 服务类
+ * </p>
+ *
+ * @author quanshu
+ * @since 2022-04-07
+ */
+public interface IGoodsTagService extends IService<GoodsTag> {
+
+}

+ 20 - 0
mp-service/src/main/java/com/qs/mp/admin/service/impl/ExchangeBannerServiceImpl.java

@@ -0,0 +1,20 @@
+package com.qs.mp.admin.service.impl;
+
+import com.qs.mp.admin.domain.ExchangeBanner;
+import com.qs.mp.admin.mapper.ExchangeBannerMapper;
+import com.qs.mp.admin.service.IExchangeBannerService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 兑换大厅推广区设置 服务实现类
+ * </p>
+ *
+ * @author quanshu
+ * @since 2022-04-07
+ */
+@Service
+public class ExchangeBannerServiceImpl extends ServiceImpl<ExchangeBannerMapper, ExchangeBanner> implements IExchangeBannerService {
+
+}

+ 43 - 15
mp-service/src/main/java/com/qs/mp/admin/service/impl/GoodsServiceImpl.java

@@ -1,21 +1,24 @@
 package com.qs.mp.admin.service.impl;
 
-import com.qs.mp.admin.domain.CouponTicket;
 import com.qs.mp.admin.domain.Goods;
 import com.qs.mp.admin.domain.GoodsSku;
+import com.qs.mp.admin.domain.GoodsTagRel;
 import com.qs.mp.admin.mapper.GoodsMapper;
 import com.qs.mp.admin.service.IGoodsService;
 import com.qs.mp.admin.service.IGoodsSkuService;
+import com.qs.mp.admin.service.IGoodsTagRelService;
 import com.qs.mp.common.exception.ServiceException;
 import com.qs.mp.system.service.id.BizIdGenerator;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 
+import java.util.ArrayList;
 import java.util.List;
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
 
 /**
  * <p>
@@ -34,18 +37,17 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
 	@Autowired
 	private IGoodsSkuService goodsSkuService;
 
-    @Autowired
-    private BizIdGenerator bizIdGenerator;
+	@Autowired
+	private IGoodsTagRelService goodsTagRelService;
 
 	@Override
 	@Transactional
-	public void saveGoods(Goods goods, List<GoodsSku> skuList) {
+	public void saveGoods(Goods goods, List<GoodsSku> skuList, List<Long> tagIds) {
 		boolean res = goodsService.save(goods);
 		if(!res) {
-			throw new ServiceException("请联系管理员");
+			throw new ServiceException("保存商品失败,请联系管理员");
 		}
-		if(res && null != skuList
-				&& skuList.size() > 0) {
+		if(null != skuList && skuList.size() > 0) {
 			for(GoodsSku goodsSku:skuList) {
 				if(null != goodsSku) {
 					goodsSku.setGoodsId(goods.getGoodsId());
@@ -56,21 +58,36 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
 			}
 			boolean skuRes = goodsSkuService.saveBatch(skuList);
 			if(!skuRes) {
-				throw new ServiceException("请联系管理员");
+				throw new ServiceException("保存sku失败,请联系管理员");
+			}
+		}
+
+		if (!CollectionUtils.isEmpty(tagIds)) {
+			List<GoodsTagRel> goodsTagRelList = new ArrayList<>();
+			for (Long tagId : tagIds) {
+				GoodsTagRel goodsTagRel = new GoodsTagRel();
+				goodsTagRel.setGoodsId(goods.getGoodsId());
+				goodsTagRel.setTagId(tagId);
+				goodsTagRelList.add(goodsTagRel);
+			}
+			boolean tagRes = goodsTagRelService.saveBatch(goodsTagRelList);
+			if (!tagRes) {
+				throw new ServiceException("保存标签失败,请联系管理员");
 			}
 		}
 	}
 
 	@Override
 	@Transactional
-	public void updateGoods(Goods goods, List<GoodsSku> skuList) {
+	public void updateGoods(Goods goods, List<GoodsSku> skuList, List<Long> tagIds) {
 		boolean res = goodsService.updateById(goods);
 		if(!res) {
 			throw new ServiceException("请联系管理员");
 		}
+
 		// 多SKU
-		if(res && null != skuList
-				&& skuList.size() > 0) {
+		goodsSkuService.remove(new LambdaQueryWrapper<GoodsSku>().eq(GoodsSku::getGoodsId, goods.getGoodsId()));
+		if(res && null != skuList && skuList.size() > 0) {
 			for(GoodsSku goodsSku:skuList) {
 				if(null != goodsSku) {
 					goodsSku.setGoodsId(goods.getGoodsId());
@@ -79,14 +96,25 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
 					}
 				}
 			}
-			// TODO 未完待续
-			LambdaQueryWrapper<GoodsSku> queryWrapper = new LambdaQueryWrapper<>();
-			queryWrapper.eq(GoodsSku::getGoodsId, goods.getGoodsId());
-			boolean delRes = goodsSkuService.remove(queryWrapper);
 			boolean skuRes = goodsSkuService.saveBatch(skuList);
 			if(!skuRes) {
 				throw new ServiceException("请联系管理员");
 			}
 		}
+		// 标签
+		goodsTagRelService.remove(new LambdaQueryWrapper<GoodsTagRel>().eq(GoodsTagRel::getGoodsId, goods.getGoodsId()));
+		if (!CollectionUtils.isEmpty(tagIds)) {
+			List<GoodsTagRel> goodsTagRelList = new ArrayList<>();
+			for (Long tagId : tagIds) {
+				GoodsTagRel goodsTagRel = new GoodsTagRel();
+				goodsTagRel.setGoodsId(goods.getGoodsId());
+				goodsTagRel.setTagId(tagId);
+				goodsTagRelList.add(goodsTagRel);
+			}
+			boolean tagRes = goodsTagRelService.saveBatch(goodsTagRelList);
+			if (!tagRes) {
+				throw new ServiceException("保存标签失败,请联系管理员");
+			}
+		}
 	}
 }

+ 20 - 0
mp-service/src/main/java/com/qs/mp/admin/service/impl/GoodsTagRelServiceImpl.java

@@ -0,0 +1,20 @@
+package com.qs.mp.admin.service.impl;
+
+import com.qs.mp.admin.domain.GoodsTagRel;
+import com.qs.mp.admin.mapper.GoodsTagRelMapper;
+import com.qs.mp.admin.service.IGoodsTagRelService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 商品和标签的关系 服务实现类
+ * </p>
+ *
+ * @author quanshu
+ * @since 2022-04-07
+ */
+@Service
+public class GoodsTagRelServiceImpl extends ServiceImpl<GoodsTagRelMapper, GoodsTagRel> implements IGoodsTagRelService {
+
+}

+ 20 - 0
mp-service/src/main/java/com/qs/mp/admin/service/impl/GoodsTagServiceImpl.java

@@ -0,0 +1,20 @@
+package com.qs.mp.admin.service.impl;
+
+import com.qs.mp.admin.domain.GoodsTag;
+import com.qs.mp.admin.mapper.GoodsTagMapper;
+import com.qs.mp.admin.service.IGoodsTagService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 商品标签 服务实现类
+ * </p>
+ *
+ * @author quanshu
+ * @since 2022-04-07
+ */
+@Service
+public class GoodsTagServiceImpl extends ServiceImpl<GoodsTagMapper, GoodsTag> implements IGoodsTagService {
+
+}

+ 24 - 0
mp-service/src/main/resources/mapper/admin/ExchangeBannerMapper.xml

@@ -0,0 +1,24 @@
+<?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.qs.mp.admin.mapper.ExchangeBannerMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.qs.mp.admin.domain.ExchangeBanner">
+        <id column="banner_id" property="bannerId" />
+        <result column="name" property="name" />
+        <result column="pic_url" property="picUrl" />
+        <result column="location" property="location" />
+        <result column="sort" property="sort" />
+        <result column="type" property="type" />
+        <result column="link_url" property="linkUrl" />
+        <result column="goods_tags" property="goodsTags" />
+        <result column="created_time" property="createdTime" />
+        <result column="updated_time" property="updatedTime" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        banner_id, name, pic_url, location, sort, type, link_url, goods_tags, created_time, updated_time
+    </sql>
+
+</mapper>

+ 4 - 2
mp-service/src/main/resources/mapper/admin/GoodsCategoryMapper.xml

@@ -6,15 +6,17 @@
     <resultMap id="BaseResultMap" type="com.qs.mp.admin.domain.GoodsCategory">
         <id column="category_id" property="categoryId" />
         <result column="name" property="name" />
+        <result column="pic_url" property="picUrl" />
         <result column="parent_id" property="parentId" />
         <result column="sort" property="sort" />
+        <result column="is_show" property="isShow" />
         <result column="created_time" property="createdTime" />
         <result column="updated_time" property="updatedTime" />
     </resultMap>
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        category_id, name, parent_id, sort, created_time, updated_time
+        category_id, name, pic_url, parent_id, sort, is_show, created_time, updated_time
     </sql>
 
-</mapper>
+</mapper>

+ 20 - 0
mp-service/src/main/resources/mapper/admin/GoodsTagMapper.xml

@@ -0,0 +1,20 @@
+<?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.qs.mp.admin.mapper.GoodsTagMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.qs.mp.admin.domain.GoodsTag">
+        <id column="tag_id" property="tagId" />
+        <result column="name" property="name" />
+        <result column="sort" property="sort" />
+        <result column="is_show" property="isShow" />
+        <result column="created_time" property="createdTime" />
+        <result column="updated_time" property="updatedTime" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        tag_id, name, sort, is_show, created_time, updated_time
+    </sql>
+
+</mapper>

+ 19 - 0
mp-service/src/main/resources/mapper/admin/GoodsTagRelMapper.xml

@@ -0,0 +1,19 @@
+<?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.qs.mp.admin.mapper.GoodsTagRelMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.qs.mp.admin.domain.GoodsTagRel">
+        <id column="id" property="id" />
+        <result column="goods_id" property="goodsId" />
+        <result column="tag_id" property="tagId" />
+        <result column="created_time" property="createdTime" />
+        <result column="updated_time" property="updatedTime" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, goods_id, tag_id, created_time, updated_time
+    </sql>
+
+</mapper>