Browse Source

优化地址,商品详情 的查询速度

Hong 7 years ago
parent
commit
12786648d9

+ 1 - 0
litemall-db/src/main/java/org/linlinjava/litemall/db/service/LitemallRegionService.java

@@ -12,6 +12,7 @@ import java.util.List;
 
 @Service
 public class LitemallRegionService {
+
     @Resource
     private LitemallRegionMapper regionMapper;
 

+ 1 - 0
litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/service/GetRegionService.java

@@ -13,6 +13,7 @@ import java.util.List;
  **/
 @Component
 public class GetRegionService {
+
 	@Autowired
 	private LitemallRegionService regionService;
 

+ 204 - 202
litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxAddressController.java

@@ -28,206 +28,208 @@ import java.util.concurrent.*;
 @RestController
 @RequestMapping("/wx/address")
 @Validated
-public class WxAddressController extends GetRegionService{
-    private final Log logger = LogFactory.getLog(WxAddressController.class);
-
-    @Autowired
-    private LitemallAddressService addressService;
-    @Autowired
-    private LitemallRegionService regionService;
-
-    private final static ArrayBlockingQueue<Runnable> WORK_QUEUE = new ArrayBlockingQueue<>(6);
-
-    private final static RejectedExecutionHandler HANDLER = new ThreadPoolExecutor.CallerRunsPolicy();
-
-    private static ThreadPoolExecutor executorService = new ThreadPoolExecutor(3, 6, 1000, TimeUnit.MILLISECONDS, WORK_QUEUE, HANDLER);
-
-    /**
-     * 用户收货地址列表
-     *
-     * @param userId 用户ID
-     * @return 收货地址列表
-     */
-    @GetMapping("list")
-    public Object list(@LoginUser Integer userId) {
-        if (userId == null) {
-            return ResponseUtil.unlogin();
-        }
-        List<LitemallAddress> addressList = addressService.queryByUid(userId);
-        List<Map<String, Object>> addressVoList = new ArrayList<>(addressList.size());
-        List<LitemallRegion> regionList = getLitemallRegions();
-        for (LitemallAddress address : addressList) {
-            Map<String, Object> addressVo = new HashMap<>();
-            addressVo.put("id", address.getId());
-            addressVo.put("name", address.getName());
-            addressVo.put("mobile", address.getMobile());
-            addressVo.put("isDefault", address.getIsDefault());
-            Callable<String> provinceCallable = ()->regionList.stream().filter(region->region.getId().equals(address.getProvinceId())).findAny().orElse(null).getName();
-            Callable<String> cityCallable = ()->regionList.stream().filter(region->region.getId().equals(address.getCityId())).findAny().orElse(null).getName();
-            Callable<String> areaCallable = ()->regionList.stream().filter(region->region.getId().equals(address.getAreaId())).findAny().orElse(null).getName();
-            FutureTask<String> provinceNameCallableTask = new FutureTask<>(provinceCallable);
-            FutureTask<String> cityNameCallableTask = new FutureTask<>(cityCallable);
-            FutureTask<String> areaNameCallableTask = new FutureTask<>(areaCallable);
-            executorService.submit(provinceNameCallableTask);
-            executorService.submit(cityNameCallableTask);
-            executorService.submit(areaNameCallableTask);
-            String detailedAddress="";
-            try {
-                String province=provinceNameCallableTask.get();
-                String city =cityNameCallableTask.get();
-                String area =areaNameCallableTask.get();
-                String addr = address.getAddress();
-                detailedAddress = province + city + area + " " + addr;
-            }catch (Exception e){
-                e.printStackTrace();
-            }
-            addressVo.put("detailedAddress", detailedAddress);
-
-            addressVoList.add(addressVo);
-        }
-        return ResponseUtil.ok(addressVoList);
-    }
-
-    /**
-     * 收货地址详情
-     *
-     * @param userId 用户ID
-     * @param id     收货地址ID
-     * @return 收货地址详情
-     */
-    @GetMapping("detail")
-    public Object detail(@LoginUser Integer userId, @NotNull Integer id) {
-        if (userId == null) {
-            return ResponseUtil.unlogin();
-        }
-
-        LitemallAddress address = addressService.findById(id);
-        if (address == null) {
-            return ResponseUtil.badArgumentValue();
-        }
-
-        Map<Object, Object> data = new HashMap<Object, Object>();
-        data.put("id", address.getId());
-        data.put("name", address.getName());
-        data.put("provinceId", address.getProvinceId());
-        data.put("cityId", address.getCityId());
-        data.put("areaId", address.getAreaId());
-        data.put("mobile", address.getMobile());
-        data.put("address", address.getAddress());
-        data.put("isDefault", address.getIsDefault());
-        String pname = regionService.findById(address.getProvinceId()).getName();
-        data.put("provinceName", pname);
-        String cname = regionService.findById(address.getCityId()).getName();
-        data.put("cityName", cname);
-        String dname = regionService.findById(address.getAreaId()).getName();
-        data.put("areaName", dname);
-        return ResponseUtil.ok(data);
-    }
-
-    private Object validate(LitemallAddress address) {
-        String name = address.getName();
-        if (StringUtils.isEmpty(name)) {
-            return ResponseUtil.badArgument();
-        }
-
-        // 测试收货手机号码是否正确
-        String mobile = address.getMobile();
-        if (StringUtils.isEmpty(mobile)) {
-            return ResponseUtil.badArgument();
-        }
-        if (!RegexUtil.isMobileExact(mobile)) {
-            return ResponseUtil.badArgument();
-        }
-
-        Integer pid = address.getProvinceId();
-        if (pid == null) {
-            return ResponseUtil.badArgument();
-        }
-        if (regionService.findById(pid) == null) {
-            return ResponseUtil.badArgumentValue();
-        }
-
-        Integer cid = address.getCityId();
-        if (cid == null) {
-            return ResponseUtil.badArgument();
-        }
-        if (regionService.findById(cid) == null) {
-            return ResponseUtil.badArgumentValue();
-        }
-
-        Integer aid = address.getAreaId();
-        if (aid == null) {
-            return ResponseUtil.badArgument();
-        }
-        if (regionService.findById(aid) == null) {
-            return ResponseUtil.badArgumentValue();
-        }
-
-        String detailedAddress = address.getAddress();
-        if (StringUtils.isEmpty(detailedAddress)) {
-            return ResponseUtil.badArgument();
-        }
-
-        Boolean isDefault = address.getIsDefault();
-        if (isDefault == null) {
-            return ResponseUtil.badArgument();
-        }
-        return null;
-    }
-
-    /**
-     * 添加或更新收货地址
-     *
-     * @param userId  用户ID
-     * @param address 用户收货地址
-     * @return 添加或更新操作结果
-     */
-    @PostMapping("save")
-    public Object save(@LoginUser Integer userId, @RequestBody LitemallAddress address) {
-        if (userId == null) {
-            return ResponseUtil.unlogin();
-        }
-        Object error = validate(address);
-        if (error != null) {
-            return error;
-        }
-
-        if (address.getIsDefault()) {
-            // 重置其他收获地址的默认选项
-            addressService.resetDefault(userId);
-        }
-
-        if (address.getId() == null || address.getId().equals(0)) {
-            address.setId(null);
-            address.setUserId(userId);
-            addressService.add(address);
-        } else {
-            address.setUserId(userId);
-            if (addressService.update(address) == 0) {
-                return ResponseUtil.updatedDataFailed();
-            }
-        }
-        return ResponseUtil.ok(address.getId());
-    }
-
-    /**
-     * 删除收货地址
-     *
-     * @param userId  用户ID
-     * @param address 用户收货地址,{ id: xxx }
-     * @return 删除操作结果
-     */
-    @PostMapping("delete")
-    public Object delete(@LoginUser Integer userId, @RequestBody LitemallAddress address) {
-        if (userId == null) {
-            return ResponseUtil.unlogin();
-        }
-        Integer id = address.getId();
-        if (id == null) {
-            return ResponseUtil.badArgument();
-        }
-
-        addressService.delete(id);
-        return ResponseUtil.ok();
-    }
+public class WxAddressController extends GetRegionService {
+	private final Log logger = LogFactory.getLog(WxAddressController.class);
+
+	@Autowired
+	private LitemallAddressService addressService;
+
+	@Autowired
+	private LitemallRegionService regionService;
+
+	private final static ArrayBlockingQueue<Runnable> WORK_QUEUE = new ArrayBlockingQueue<>(6);
+
+	private final static RejectedExecutionHandler HANDLER = new ThreadPoolExecutor.CallerRunsPolicy();
+
+	private static ThreadPoolExecutor executorService = new ThreadPoolExecutor(3, 6, 1000, TimeUnit.MILLISECONDS, WORK_QUEUE, HANDLER);
+
+	/**
+	 * 用户收货地址列表
+	 *
+	 * @param userId 用户ID
+	 * @return 收货地址列表
+	 */
+	@GetMapping("list")
+	public Object list(@LoginUser Integer userId) {
+		if (userId == null) {
+			return ResponseUtil.unlogin();
+		}
+		List<LitemallAddress> addressList = addressService.queryByUid(userId);
+		List<Map<String, Object>> addressVoList = new ArrayList<>(addressList.size());
+		List<LitemallRegion> regionList = getLitemallRegions();
+		for (LitemallAddress address : addressList) {
+			Map<String, Object> addressVo = new HashMap<>();
+			addressVo.put("id", address.getId());
+			addressVo.put("name", address.getName());
+			addressVo.put("mobile", address.getMobile());
+			addressVo.put("isDefault", address.getIsDefault());
+			Callable<String> provinceCallable = () -> regionList.stream().filter(region -> region.getId().equals(address.getProvinceId())).findAny().orElse(null).getName();
+			Callable<String> cityCallable = () -> regionList.stream().filter(region -> region.getId().equals(address.getCityId())).findAny().orElse(null).getName();
+			Callable<String> areaCallable = () -> regionList.stream().filter(region -> region.getId().equals(address.getAreaId())).findAny().orElse(null).getName();
+			FutureTask<String> provinceNameCallableTask = new FutureTask<>(provinceCallable);
+			FutureTask<String> cityNameCallableTask = new FutureTask<>(cityCallable);
+			FutureTask<String> areaNameCallableTask = new FutureTask<>(areaCallable);
+			executorService.submit(provinceNameCallableTask);
+			executorService.submit(cityNameCallableTask);
+			executorService.submit(areaNameCallableTask);
+			String detailedAddress = "";
+			try {
+				String province = provinceNameCallableTask.get();
+				String city = cityNameCallableTask.get();
+				String area = areaNameCallableTask.get();
+				String addr = address.getAddress();
+				detailedAddress = province + city + area + " " + addr;
+			}
+			catch (Exception e) {
+				e.printStackTrace();
+			}
+			addressVo.put("detailedAddress", detailedAddress);
+
+			addressVoList.add(addressVo);
+		}
+		return ResponseUtil.ok(addressVoList);
+	}
+
+	/**
+	 * 收货地址详情
+	 *
+	 * @param userId 用户ID
+	 * @param id     收货地址ID
+	 * @return 收货地址详情
+	 */
+	@GetMapping("detail")
+	public Object detail(@LoginUser Integer userId, @NotNull Integer id) {
+		if (userId == null) {
+			return ResponseUtil.unlogin();
+		}
+
+		LitemallAddress address = addressService.findById(id);
+		if (address == null) {
+			return ResponseUtil.badArgumentValue();
+		}
+
+		Map<Object, Object> data = new HashMap<Object, Object>();
+		data.put("id", address.getId());
+		data.put("name", address.getName());
+		data.put("provinceId", address.getProvinceId());
+		data.put("cityId", address.getCityId());
+		data.put("areaId", address.getAreaId());
+		data.put("mobile", address.getMobile());
+		data.put("address", address.getAddress());
+		data.put("isDefault", address.getIsDefault());
+		String pname = regionService.findById(address.getProvinceId()).getName();
+		data.put("provinceName", pname);
+		String cname = regionService.findById(address.getCityId()).getName();
+		data.put("cityName", cname);
+		String dname = regionService.findById(address.getAreaId()).getName();
+		data.put("areaName", dname);
+		return ResponseUtil.ok(data);
+	}
+
+	private Object validate(LitemallAddress address) {
+		String name = address.getName();
+		if (StringUtils.isEmpty(name)) {
+			return ResponseUtil.badArgument();
+		}
+
+		// 测试收货手机号码是否正确
+		String mobile = address.getMobile();
+		if (StringUtils.isEmpty(mobile)) {
+			return ResponseUtil.badArgument();
+		}
+		if (!RegexUtil.isMobileExact(mobile)) {
+			return ResponseUtil.badArgument();
+		}
+
+		Integer pid = address.getProvinceId();
+		if (pid == null) {
+			return ResponseUtil.badArgument();
+		}
+		if (regionService.findById(pid) == null) {
+			return ResponseUtil.badArgumentValue();
+		}
+
+		Integer cid = address.getCityId();
+		if (cid == null) {
+			return ResponseUtil.badArgument();
+		}
+		if (regionService.findById(cid) == null) {
+			return ResponseUtil.badArgumentValue();
+		}
+
+		Integer aid = address.getAreaId();
+		if (aid == null) {
+			return ResponseUtil.badArgument();
+		}
+		if (regionService.findById(aid) == null) {
+			return ResponseUtil.badArgumentValue();
+		}
+
+		String detailedAddress = address.getAddress();
+		if (StringUtils.isEmpty(detailedAddress)) {
+			return ResponseUtil.badArgument();
+		}
+
+		Boolean isDefault = address.getIsDefault();
+		if (isDefault == null) {
+			return ResponseUtil.badArgument();
+		}
+		return null;
+	}
+
+	/**
+	 * 添加或更新收货地址
+	 *
+	 * @param userId  用户ID
+	 * @param address 用户收货地址
+	 * @return 添加或更新操作结果
+	 */
+	@PostMapping("save")
+	public Object save(@LoginUser Integer userId, @RequestBody LitemallAddress address) {
+		if (userId == null) {
+			return ResponseUtil.unlogin();
+		}
+		Object error = validate(address);
+		if (error != null) {
+			return error;
+		}
+
+		if (address.getIsDefault()) {
+			// 重置其他收获地址的默认选项
+			addressService.resetDefault(userId);
+		}
+
+		if (address.getId() == null || address.getId().equals(0)) {
+			address.setId(null);
+			address.setUserId(userId);
+			addressService.add(address);
+		} else {
+			address.setUserId(userId);
+			if (addressService.update(address) == 0) {
+				return ResponseUtil.updatedDataFailed();
+			}
+		}
+		return ResponseUtil.ok(address.getId());
+	}
+
+	/**
+	 * 删除收货地址
+	 *
+	 * @param userId  用户ID
+	 * @param address 用户收货地址,{ id: xxx }
+	 * @return 删除操作结果
+	 */
+	@PostMapping("delete")
+	public Object delete(@LoginUser Integer userId, @RequestBody LitemallAddress address) {
+		if (userId == null) {
+			return ResponseUtil.unlogin();
+		}
+		Integer id = address.getId();
+		if (id == null) {
+			return ResponseUtil.badArgument();
+		}
+
+		addressService.delete(id);
+		return ResponseUtil.ok();
+	}
 }

+ 322 - 270
litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxGoodsController.java

@@ -10,6 +10,7 @@ import org.linlinjava.litemall.core.validator.Sort;
 import org.linlinjava.litemall.db.domain.*;
 import org.linlinjava.litemall.db.service.*;
 import org.linlinjava.litemall.wx.annotation.LoginUser;
+import org.linlinjava.litemall.wx.service.GetRegionService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -22,6 +23,7 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.*;
 
 /**
  * 商品服务
@@ -30,275 +32,325 @@ import java.util.Map;
 @RequestMapping("/wx/goods")
 @Validated
 public class WxGoodsController {
-    private final Log logger = LogFactory.getLog(WxGoodsController.class);
-
-    @Autowired
-    private LitemallGoodsService goodsService;
-    @Autowired
-    private LitemallGoodsProductService productService;
-    @Autowired
-    private LitemallIssueService goodsIssueService;
-    @Autowired
-    private LitemallGoodsAttributeService goodsAttributeService;
-    @Autowired
-    private LitemallBrandService brandService;
-    @Autowired
-    private LitemallCommentService commentService;
-    @Autowired
-    private LitemallUserService userService;
-    @Autowired
-    private LitemallCollectService collectService;
-    @Autowired
-    private LitemallFootprintService footprintService;
-    @Autowired
-    private LitemallCategoryService categoryService;
-    @Autowired
-    private LitemallSearchHistoryService searchHistoryService;
-    @Autowired
-    private LitemallGoodsSpecificationService goodsSpecificationService;
-    @Autowired
-    private LitemallGrouponRulesService rulesService;
-
-
-    /**
-     * 商品详情
-     * <p>
-     * 用户可以不登录。
-     * 如果用户登录,则记录用户足迹以及返回用户收藏信息。
-     *
-     * @param userId 用户ID
-     * @param id     商品ID
-     * @return 商品详情
-     */
-    @GetMapping("detail")
-    public Object detail(@LoginUser Integer userId, @NotNull Integer id) {
-        // 商品信息
-        LitemallGoods info = goodsService.findById(id);
-
-        // 商品属性
-        List<LitemallGoodsAttribute> goodsAttributeList = goodsAttributeService.queryByGid(id);
-
-        // 商品规格
-        // 返回的是定制的GoodsSpecificationVo
-        Object specificationList = goodsSpecificationService.getSpecificationVoList(id);
-
-        // 商品规格对应的数量和价格
-        List<LitemallGoodsProduct> productList = productService.queryByGid(id);
-
-        // 商品问题,这里是一些通用问题
-        List<LitemallIssue> issue = goodsIssueService.query();
-
-        // 商品品牌商
-        Integer brandId = info.getBrandId();
-        LitemallBrand brand = null;
-        if (brandId == 0) {
-            brand = new LitemallBrand();
-        } else {
-            brand = brandService.findById(info.getBrandId());
-        }
-
-        // 评论
-        List<LitemallComment> comments = commentService.queryGoodsByGid(id, 0, 2);
-        List<Map<String, Object>> commentsVo = new ArrayList<>(comments.size());
-        int commentCount = commentService.countGoodsByGid(id, 0, 2);
-        for (LitemallComment comment : comments) {
-            Map<String, Object> c = new HashMap<>();
-            c.put("id", comment.getId());
-            c.put("addTime", comment.getAddTime());
-            c.put("content", comment.getContent());
-            LitemallUser user = userService.findById(comment.getUserId());
-            c.put("nickname", user.getNickname());
-            c.put("avatar", user.getAvatar());
-            c.put("picList", comment.getPicUrls());
-            commentsVo.add(c);
-        }
-        Map<String, Object> commentList = new HashMap<>();
-        commentList.put("count", commentCount);
-        commentList.put("data", commentsVo);
-
-        //团购信息
-        List<LitemallGrouponRules> rules = rulesService.queryByGoodsId(id);
-
-        // 用户收藏
-        int userHasCollect = 0;
-        if (userId != null) {
-            userHasCollect = collectService.count(userId, id);
-        }
-
-        // 记录用户的足迹
-        if (userId != null) {
-            LitemallFootprint footprint = new LitemallFootprint();
-            footprint.setUserId(userId);
-            footprint.setGoodsId(id);
-            footprintService.add(footprint);
-        }
-
-        Map<String, Object> data = new HashMap<>();
-        data.put("info", info);
-        data.put("userHasCollect", userHasCollect);
-        data.put("issue", issue);
-        data.put("comment", commentList);
-        data.put("specificationList", specificationList);
-        data.put("productList", productList);
-        data.put("attribute", goodsAttributeList);
-        data.put("brand", brand);
-        data.put("groupon", rules);
-
-        //商品分享图片地址
-        data.put("shareImage", info.getShareUrl());
-        return ResponseUtil.ok(data);
-    }
-
-    /**
-     * 商品分类类目
-     *
-     * @param id 分类类目ID
-     * @return 商品分类类目
-     */
-    @GetMapping("category")
-    public Object category(@NotNull Integer id) {
-        LitemallCategory cur = categoryService.findById(id);
-        LitemallCategory parent = null;
-        List<LitemallCategory> children = null;
-
-        if (cur.getPid() == 0) {
-            parent = cur;
-            children = categoryService.queryByPid(cur.getId());
-            cur = children.size() > 0 ? children.get(0) : cur;
-        } else {
-            parent = categoryService.findById(cur.getPid());
-            children = categoryService.queryByPid(cur.getPid());
-        }
-        Map<String, Object> data = new HashMap<>();
-        data.put("currentCategory", cur);
-        data.put("parentCategory", parent);
-        data.put("brotherCategory", children);
-        return ResponseUtil.ok(data);
-    }
-
-    /**
-     * 根据条件搜素商品
-     * <p>
-     * 1. 这里的前五个参数都是可选的,甚至都是空
-     * 2. 用户是可选登录,如果登录,则记录用户的搜索关键字
-     *
-     * @param categoryId 分类类目ID,可选
-     * @param brandId    品牌商ID,可选
-     * @param keyword    关键字,可选
-     * @param isNew      是否新品,可选
-     * @param isHot      是否热买,可选
-     * @param userId     用户ID
-     * @param page       分页页数
-     * @param size       分页大小
-     * @param sort       排序方式,支持"add_time", "retail_price"或"name"
-     * @param order      排序类型,顺序或者降序
-     * @return 根据条件搜素的商品详情
-     */
-    @GetMapping("list")
-    public Object list(Integer categoryId, Integer brandId, String keyword, Boolean isNew, Boolean isHot,
-                       @LoginUser Integer userId,
-                       @RequestParam(defaultValue = "1") Integer page,
-                       @RequestParam(defaultValue = "10") Integer size,
-                       @Sort(accepts = {"add_time", "retail_price", "name"}) @RequestParam(defaultValue = "add_time") String sort,
-                       @Order @RequestParam(defaultValue = "desc") String order) {
-
-        //添加到搜索历史
-        if (userId != null && !StringUtils.isNullOrEmpty(keyword)) {
-            LitemallSearchHistory searchHistoryVo = new LitemallSearchHistory();
-            searchHistoryVo.setKeyword(keyword);
-            searchHistoryVo.setUserId(userId);
-            searchHistoryVo.setFrom("wx");
-            searchHistoryService.save(searchHistoryVo);
-        }
-
-        //查询列表数据
-        List<LitemallGoods> goodsList = goodsService.querySelective(categoryId, brandId, keyword, isHot, isNew, page, size, sort, order);
-        int total = goodsService.countSelective(categoryId, brandId, keyword, isHot, isNew, page, size, sort, order);
-
-        // 查询商品所属类目列表。
-        List<Integer> goodsCatIds = goodsService.getCatIds(brandId, keyword, isHot, isNew);
-        List<LitemallCategory> categoryList = null;
-        if (goodsCatIds.size() != 0) {
-            categoryList = categoryService.queryL2ByIds(goodsCatIds);
-        } else {
-            categoryList = new ArrayList<>(0);
-        }
-
-        Map<String, Object> data = new HashMap<>();
-        data.put("goodsList", goodsList);
-        data.put("filterCategoryList", categoryList);
-        data.put("count", total);
-        return ResponseUtil.ok(data);
-    }
-
-    /**
-     * 新品首发页面的横幅
-     *
-     * @return 新品首发页面的横幅
-     */
-    @GetMapping("new")
-    public Object newGoods() {
-        Map<String, String> bannerInfo = new HashMap<>();
-        bannerInfo.put("url", "");
-        bannerInfo.put("name", SystemConfig.getNewBannerTitle());
-        bannerInfo.put("imgUrl", SystemConfig.getNewImageUrl());
-
-        Map<String, Object> data = new HashMap<>();
-        data.put("bannerInfo", bannerInfo);
-        return ResponseUtil.ok(data);
-    }
-
-    /**
-     * 人气推荐页面的横幅
-     *
-     * @return 人气推荐页面的横幅
-     */
-    @GetMapping("hot")
-    public Object hotGoods() {
-        Map<String, String> bannerInfo = new HashMap<>();
-        bannerInfo.put("url", "");
-        bannerInfo.put("name", SystemConfig.getHotBannerTitle());
-        bannerInfo.put("imgUrl", SystemConfig.getHotImageUrl());
-        Map<String, Object> data = new HashMap<>();
-        data.put("bannerInfo", bannerInfo);
-        return ResponseUtil.ok(data);
-    }
-
-    /**
-     * 商品详情页面“大家都在看”推荐商品
-     *
-     * @param id, 商品ID
-     * @return 商品详情页面推荐商品
-     */
-    @GetMapping("related")
-    public Object related(@NotNull Integer id) {
-        LitemallGoods goods = goodsService.findById(id);
-        if (goods == null) {
-            return ResponseUtil.badArgumentValue();
-        }
-
-        // 目前的商品推荐算法仅仅是推荐同类目的其他商品
-        int cid = goods.getCategoryId();
-
-        // 查找六个相关商品
-        int related = 6;
-        List<LitemallGoods> goodsList = goodsService.queryByCategory(cid, 0, related);
-        Map<String, Object> data = new HashMap<>();
-        data.put("goodsList", goodsList);
-        return ResponseUtil.ok(data);
-    }
-
-    /**
-     * 在售的商品总数
-     *
-     * @return 在售的商品总数
-     */
-    @GetMapping("count")
-    public Object count() {
-        Integer goodsCount = goodsService.queryOnSale();
-        Map<String, Object> data = new HashMap<>();
-        data.put("goodsCount", goodsCount);
-        return ResponseUtil.ok(data);
-    }
+	private final Log logger = LogFactory.getLog(WxGoodsController.class);
+
+	@Autowired
+	private LitemallGoodsService goodsService;
+
+	@Autowired
+	private LitemallGoodsProductService productService;
+
+	@Autowired
+	private LitemallIssueService goodsIssueService;
+
+	@Autowired
+	private LitemallGoodsAttributeService goodsAttributeService;
+
+	@Autowired
+	private LitemallBrandService brandService;
+
+	@Autowired
+	private LitemallCommentService commentService;
+
+	@Autowired
+	private LitemallUserService userService;
+
+	@Autowired
+	private LitemallCollectService collectService;
+
+	@Autowired
+	private LitemallFootprintService footprintService;
+
+	@Autowired
+	private LitemallCategoryService categoryService;
+
+	@Autowired
+	private LitemallSearchHistoryService searchHistoryService;
+
+	@Autowired
+	private LitemallGoodsSpecificationService goodsSpecificationService;
+
+	@Autowired
+	private LitemallGrouponRulesService rulesService;
+
+	private final static ArrayBlockingQueue<Runnable> WORK_QUEUE = new ArrayBlockingQueue<>(9);
+
+	private final static RejectedExecutionHandler HANDLER = new ThreadPoolExecutor.CallerRunsPolicy();
+
+	private static ThreadPoolExecutor executorService = new ThreadPoolExecutor(16, 16, 1000, TimeUnit.MILLISECONDS, WORK_QUEUE, HANDLER);
+
+	/**
+	 * 商品详情
+	 * <p>
+	 * 用户可以不登录。
+	 * 如果用户登录,则记录用户足迹以及返回用户收藏信息。
+	 *
+	 * @param userId 用户ID
+	 * @param id     商品ID
+	 * @return 商品详情
+	 */
+	@GetMapping("detail")
+	public Object detail(@LoginUser Integer userId, @NotNull Integer id) {
+		// 商品信息
+		LitemallGoods info = goodsService.findById(id);
+
+		// 商品属性
+		Callable<List> goodsAttributeListCallable = () -> goodsAttributeService.queryByGid(id);
+
+		// 商品规格 返回的是定制的GoodsSpecificationVo
+		Callable<Object> objectCallable = () -> goodsSpecificationService.getSpecificationVoList(id);
+
+		// 商品规格对应的数量和价格
+		Callable<List> productListCallable = () -> productService.queryByGid(id);
+
+		// 商品问题,这里是一些通用问题
+		Callable<List> issueCallable = () -> goodsIssueService.query();
+
+		// 商品品牌商
+		Callable<LitemallBrand> brandCallable = ()->{
+			Integer brandId = info.getBrandId();
+			LitemallBrand brand;
+			if (brandId == 0) {
+				brand = new LitemallBrand();
+			} else {
+				brand = brandService.findById(info.getBrandId());
+			}
+			return brand;
+		};
+
+		// 评论
+		Callable<Map> commentsCallable = () -> {
+			List<LitemallComment> comments = commentService.queryGoodsByGid(id, 0, 2);
+			List<Map<String, Object>> commentsVo = new ArrayList<>(comments.size());
+			int commentCount = commentService.countGoodsByGid(id, 0, 2);
+			for (LitemallComment comment : comments) {
+				Map<String, Object> c = new HashMap<>();
+				c.put("id", comment.getId());
+				c.put("addTime", comment.getAddTime());
+				c.put("content", comment.getContent());
+				LitemallUser user = userService.findById(comment.getUserId());
+				c.put("nickname", user.getNickname());
+				c.put("avatar", user.getAvatar());
+				c.put("picList", comment.getPicUrls());
+				commentsVo.add(c);
+			}
+			Map<String, Object> commentList = new HashMap<>();
+			commentList.put("count", commentCount);
+			commentList.put("data", commentsVo);
+			return commentList;
+		};
+
+		//团购信息
+		Callable<List> grouponRulesCallable = () ->rulesService.queryByGoodsId(id);
+
+		// 用户收藏
+		int userHasCollect = 0;
+		if (userId != null) {
+			userHasCollect = collectService.count(userId, id);
+		}
+
+		// 记录用户的足迹 异步处理
+		if (userId != null) {
+			executorService.execute(()->{
+				LitemallFootprint footprint = new LitemallFootprint();
+				footprint.setUserId(userId);
+				footprint.setGoodsId(id);
+				footprintService.add(footprint);
+			});
+		}
+		FutureTask<List> goodsAttributeListTask = new FutureTask<>(goodsAttributeListCallable);
+		FutureTask<Object> objectCallableTask = new FutureTask<>(objectCallable);
+		FutureTask<List> productListCallableTask = new FutureTask<>(productListCallable);
+		FutureTask<List> issueCallableTask = new FutureTask<>(issueCallable);
+		FutureTask<Map> commentsCallableTsk = new FutureTask<>(commentsCallable);
+		FutureTask<LitemallBrand> brandCallableTask = new FutureTask<>(brandCallable);
+        FutureTask<List> grouponRulesCallableTask = new FutureTask<>(grouponRulesCallable);
+
+		executorService.submit(goodsAttributeListTask);
+		executorService.submit(objectCallableTask);
+		executorService.submit(productListCallableTask);
+		executorService.submit(issueCallableTask);
+		executorService.submit(commentsCallableTsk);
+		executorService.submit(brandCallableTask);
+		executorService.submit(grouponRulesCallableTask);
+
+		Map<String, Object> data = new HashMap<>();
+
+		try {
+			data.put("info", info);
+			data.put("userHasCollect", userHasCollect);
+			data.put("issue", issueCallableTask.get());
+			data.put("comment", commentsCallableTsk.get());
+			data.put("specificationList", objectCallableTask.get());
+			data.put("productList", productListCallableTask.get());
+			data.put("attribute", goodsAttributeListTask.get());
+			data.put("brand", brandCallableTask.get());
+			data.put("groupon", grouponRulesCallableTask.get());
+		}
+		catch (Exception e) {
+			e.printStackTrace();
+		}
+
+		//商品分享图片地址
+		data.put("shareImage", info.getShareUrl());
+		return ResponseUtil.ok(data);
+	}
+
+	/**
+	 * 商品分类类目
+	 *
+	 * @param id 分类类目ID
+	 * @return 商品分类类目
+	 */
+	@GetMapping("category")
+	public Object category(@NotNull Integer id) {
+		LitemallCategory cur = categoryService.findById(id);
+		LitemallCategory parent = null;
+		List<LitemallCategory> children = null;
+
+		if (cur.getPid() == 0) {
+			parent = cur;
+			children = categoryService.queryByPid(cur.getId());
+			cur = children.size() > 0 ? children.get(0) : cur;
+		} else {
+			parent = categoryService.findById(cur.getPid());
+			children = categoryService.queryByPid(cur.getPid());
+		}
+		Map<String, Object> data = new HashMap<>();
+		data.put("currentCategory", cur);
+		data.put("parentCategory", parent);
+		data.put("brotherCategory", children);
+		return ResponseUtil.ok(data);
+	}
+
+	/**
+	 * 根据条件搜素商品
+	 * <p>
+	 * 1. 这里的前五个参数都是可选的,甚至都是空
+	 * 2. 用户是可选登录,如果登录,则记录用户的搜索关键字
+	 *
+	 * @param categoryId 分类类目ID,可选
+	 * @param brandId    品牌商ID,可选
+	 * @param keyword    关键字,可选
+	 * @param isNew      是否新品,可选
+	 * @param isHot      是否热买,可选
+	 * @param userId     用户ID
+	 * @param page       分页页数
+	 * @param size       分页大小
+	 * @param sort       排序方式,支持"add_time", "retail_price"或"name"
+	 * @param order      排序类型,顺序或者降序
+	 * @return 根据条件搜素的商品详情
+	 */
+	@GetMapping("list")
+	public Object list(
+		Integer categoryId,
+		Integer brandId,
+		String keyword,
+		Boolean isNew,
+		Boolean isHot,
+		@LoginUser Integer userId,
+		@RequestParam(defaultValue = "1") Integer page,
+		@RequestParam(defaultValue = "10") Integer size,
+		@Sort(accepts = {"add_time", "retail_price", "name"}) @RequestParam(defaultValue = "add_time") String sort,
+		@Order @RequestParam(defaultValue = "desc") String order) {
+
+		//添加到搜索历史
+		if (userId != null && !StringUtils.isNullOrEmpty(keyword)) {
+			LitemallSearchHistory searchHistoryVo = new LitemallSearchHistory();
+			searchHistoryVo.setKeyword(keyword);
+			searchHistoryVo.setUserId(userId);
+			searchHistoryVo.setFrom("wx");
+			searchHistoryService.save(searchHistoryVo);
+		}
+
+		//查询列表数据
+		List<LitemallGoods> goodsList = goodsService.querySelective(categoryId, brandId, keyword, isHot, isNew, page, size, sort, order);
+		int total = goodsService.countSelective(categoryId, brandId, keyword, isHot, isNew, page, size, sort, order);
+
+		// 查询商品所属类目列表。
+		List<Integer> goodsCatIds = goodsService.getCatIds(brandId, keyword, isHot, isNew);
+		List<LitemallCategory> categoryList = null;
+		if (goodsCatIds.size() != 0) {
+			categoryList = categoryService.queryL2ByIds(goodsCatIds);
+		} else {
+			categoryList = new ArrayList<>(0);
+		}
+
+		Map<String, Object> data = new HashMap<>();
+		data.put("goodsList", goodsList);
+		data.put("filterCategoryList", categoryList);
+		data.put("count", total);
+		return ResponseUtil.ok(data);
+	}
+
+	/**
+	 * 新品首发页面的横幅
+	 *
+	 * @return 新品首发页面的横幅
+	 */
+	@GetMapping("new")
+	public Object newGoods() {
+		Map<String, String> bannerInfo = new HashMap<>();
+		bannerInfo.put("url", "");
+		bannerInfo.put("name", SystemConfig.getNewBannerTitle());
+		bannerInfo.put("imgUrl", SystemConfig.getNewImageUrl());
+
+		Map<String, Object> data = new HashMap<>();
+		data.put("bannerInfo", bannerInfo);
+		return ResponseUtil.ok(data);
+	}
+
+	/**
+	 * 人气推荐页面的横幅
+	 *
+	 * @return 人气推荐页面的横幅
+	 */
+	@GetMapping("hot")
+	public Object hotGoods() {
+		Map<String, String> bannerInfo = new HashMap<>();
+		bannerInfo.put("url", "");
+		bannerInfo.put("name", SystemConfig.getHotBannerTitle());
+		bannerInfo.put("imgUrl", SystemConfig.getHotImageUrl());
+		Map<String, Object> data = new HashMap<>();
+		data.put("bannerInfo", bannerInfo);
+		return ResponseUtil.ok(data);
+	}
+
+	/**
+	 * 商品详情页面“大家都在看”推荐商品
+	 *
+	 * @param id, 商品ID
+	 * @return 商品详情页面推荐商品
+	 */
+	@GetMapping("related")
+	public Object related(@NotNull Integer id) {
+		LitemallGoods goods = goodsService.findById(id);
+		if (goods == null) {
+			return ResponseUtil.badArgumentValue();
+		}
+
+		// 目前的商品推荐算法仅仅是推荐同类目的其他商品
+		int cid = goods.getCategoryId();
+
+		// 查找六个相关商品
+		int related = 6;
+		List<LitemallGoods> goodsList = goodsService.queryByCategory(cid, 0, related);
+		Map<String, Object> data = new HashMap<>();
+		data.put("goodsList", goodsList);
+		return ResponseUtil.ok(data);
+	}
+
+	/**
+	 * 在售的商品总数
+	 *
+	 * @return 在售的商品总数
+	 */
+	@GetMapping("count")
+	public Object count() {
+		Integer goodsCount = goodsService.queryOnSale();
+		Map<String, Object> data = new HashMap<>();
+		data.put("goodsCount", goodsCount);
+		return ResponseUtil.ok(data);
+	}
 
 }