This commit is contained in:
tangzh 2025-03-12 12:41:52 +08:00
parent b2fa8ca84f
commit 0ac0ea05e3
16 changed files with 367 additions and 30 deletions

View File

@ -1,5 +1,6 @@
package com.zbkj.common.model.product;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
@ -14,29 +15,49 @@ public class StoreProductProblem implements Serializable {
private static final long serialVersionUID = 1L;
/**
* ID
* 主键id
*/
@TableId
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/**
* 商品id
* 业务外键id
*/
private Integer productId;
private Integer businessId;
/**
* 问题
* 用户id
*/
private String problem;
private Integer uid;
/**
* 答案
* 内容
*/
private String answer;
private String content;
/**
* 父节点评论0为根节点
*/
private Integer parentId;
/**
* 一级评论ID0为根节点
*/
private Integer topId;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
* 是否删除: 0(未删除), 1(已删除), 2(递归删除)
*/
private Date updateTime;
private Integer isDel;
/**
* 点赞数
*/
private Integer praiseNum;
}

View File

@ -0,0 +1,28 @@
package com.zbkj.common.request;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="CommitProblemRequest对象", description="CommitProblemRequest对象")
public class CommitProblemRequest implements Serializable {
@NotNull(message = "回复内容不能为空")
@ApiModelProperty(value = "回复内容", required = true)
private String content;
@ApiModelProperty(value = "业务编号:顶级评论时必传")
private String businessId;
@ApiModelProperty(value = "回复对象标识:回复评论时必传")
private String majorId;
}

View File

@ -16,10 +16,37 @@ import java.util.List;
public class ProductProblemResponse {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "问题")
private String problem;
@ApiModelProperty(value = "编号")
private String majorId;
@ApiModelProperty(value = "答案")
private String answer;
@ApiModelProperty(value = "用户编号:不返回")
private String userId;
@ApiModelProperty(value = "用户昵称")
private String nickName;
@ApiModelProperty(value = "用户昵称")
private String imageUrl;
@ApiModelProperty(value = "时间")
private String createTime;
@ApiModelProperty(value = "内容")
private String content;
@ApiModelProperty(value = "子评论数量")
private Integer sonNum = 0;
@ApiModelProperty(value = "被回复者")
private String beReplier = "";
@ApiModelProperty(value = "点赞数")
private Integer praiseCount = 0;
@ApiModelProperty(value = "是否点赞 0没1有")
private Integer praise = 0;
@ApiModelProperty(value = "可删除标识0不可删除1可删除")
private Integer delFlag = 0;
}

View File

@ -1,7 +1,5 @@
package com.zbkj.common.response;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ -9,17 +7,11 @@ import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;
/**
* 申请退款订单响应对象
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="ProductRelationResponse对象", description="关联商品响应对象")
@ApiModel(value="ProductRelationResponse对象", description="ProductRelationResponse对象")
public class ProductRelationResponse implements Serializable {
private static final long serialVersionUID = 1387727608277207652L;

View File

@ -83,6 +83,8 @@ public class WebConfig implements WebMvcConfigurer {
excludePathPatterns("/api/front/image/domain").
excludePathPatterns("/api/front/product/leaderboard").
excludePathPatterns("/api/front/setMeal/**").
excludePathPatterns("/api/front/problem/*").
excludePathPatterns("/api/front/problem/son/*").
excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**");
}

View File

@ -0,0 +1,70 @@
package com.zbkj.front.controller;
import com.zbkj.common.page.CommonPage;
import com.zbkj.common.request.*;
import com.zbkj.common.response.*;
import com.zbkj.common.vo.CategoryTreeVo;
import com.zbkj.front.service.ProductService;
import com.zbkj.service.service.StoreProductProblemService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Slf4j
@RestController("ProblemController")
@RequestMapping("api/front")
@Api(tags = "商品常见问题")
public class ProblemController {
@Autowired private StoreProductProblemService storeProductProblemService;
@ApiOperation(value = "常见问题列表")
@RequestMapping(value = "/problem/{productId}", method = RequestMethod.GET)
public CommonResult<CommonPage<ProductProblemResponse>> getResponseList(@PathVariable Integer productId, @Validated PageParamRequest pageParamRequest) {
return CommonResult.success(storeProductProblemService.getResponseList(productId, pageParamRequest));
}
@ApiOperation(value = "常见问题列表-子回复列表")
@RequestMapping(value = "/problem/son/{majorId}", method = RequestMethod.GET)
public CommonResult<CommonPage<ProductProblemResponse>> getSonResponseList(@PathVariable Integer majorId, @Validated PageParamRequest pageParamRequest) {
return CommonResult.success(storeProductProblemService.getSonResponseList(majorId, pageParamRequest));
}
@ApiOperation(value = "常见问题-提问/回复")
@PostMapping("/problem/commit")
public CommonResult<Void> commitProblem(@RequestBody CommitProblemRequest request) {
if (storeProductProblemService.commitProblem(request) > 0) {
return CommonResult.success();
}
return CommonResult.failed("提交失败");
}
@ApiOperation(value = "常见问题-点赞/取消点赞")
@RequestMapping(value = "/problem/praise/{majorId}", method = RequestMethod.GET)
public CommonResult<Void> praise(@PathVariable Integer majorId) {
if (storeProductProblemService.praiseProblem(majorId) > 0) {
return CommonResult.success();
}
return CommonResult.failed("操作失败");
}
@ApiOperation(value = "常见问题列表-删除")
@RequestMapping(value = "/problem/del/{majorId}", method = RequestMethod.GET)
public CommonResult<Void> delProblem(@PathVariable Integer majorId) {
if (storeProductProblemService.delProblem(majorId) > 0) {
return CommonResult.success();
}
return CommonResult.failed("删除失败");
}
}

View File

@ -2,13 +2,11 @@ package com.zbkj.front.controller;
import com.zbkj.common.page.CommonPage;
import com.zbkj.common.request.GetReplyListRequest;
import com.zbkj.common.request.PageParamRequest;
import com.zbkj.common.request.ProductListRequest;
import com.zbkj.common.request.ProductRequest;
import com.zbkj.common.request.*;
import com.zbkj.common.response.*;
import com.zbkj.common.vo.CategoryTreeVo;
import com.zbkj.front.service.ProductService;
import com.zbkj.service.service.StoreProductProblemService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
@ -30,8 +28,7 @@ import java.util.List;
@Api(tags = "商品")
public class ProductController {
@Autowired
private ProductService productService;
@Autowired private ProductService productService;
/**
* 1.购物车/我的为你推荐是否热卖

View File

@ -96,4 +96,5 @@ public interface ProductService {
* @return
*/
CommonPage<IndexProductResponse> getProductListByType(Integer type, PageParamRequest pageParamRequest);
}

View File

@ -6,6 +6,7 @@ import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zbkj.common.constants.CategoryConstants;
import com.zbkj.common.constants.Constants;
@ -90,6 +91,9 @@ public class ProductServiceImpl implements ProductService {
@Autowired
private UserVisitRecordService userVisitRecordService;
@Autowired
private StoreProductProblemService storeProductProblemService;
@Override
public List<CategoryTreeVo> getCategoryTop() {
LambdaQueryWrapper<Category> lq = new LambdaQueryWrapper<>();

View File

@ -2,7 +2,14 @@ package com.zbkj.service.dao;
import com.zbkj.common.model.product.StoreProductProblem;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zbkj.common.response.ProductProblemResponse;
import java.util.List;
public interface StoreProductProblemDao extends BaseMapper<StoreProductProblem> {
List<ProductProblemResponse> getResponseList(Integer productId);
List<ProductProblemResponse> getSonResponseList(Integer majorId);
}

View File

@ -3,7 +3,24 @@ package com.zbkj.service.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zbkj.common.model.product.StoreProductProblem;
import com.zbkj.common.page.CommonPage;
import com.zbkj.common.request.CommitProblemRequest;
import com.zbkj.common.request.PageParamRequest;
import com.zbkj.common.response.ProductProblemResponse;
import java.util.List;
public interface StoreProductProblemService extends IService<StoreProductProblem> {
CommonPage<ProductProblemResponse> getResponseList(Integer productId, PageParamRequest page);
CommonPage<ProductProblemResponse> getSonResponseList(Integer majorId, PageParamRequest page);
Integer commitProblem(CommitProblemRequest request);
Integer delProblem(Integer majorId);
Integer praiseProblem(Integer majorId);
}

View File

@ -1,12 +1,146 @@
package com.zbkj.service.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.util.StringUtil;
import com.zbkj.common.exception.CrmebException;
import com.zbkj.common.model.product.StoreProductProblem;
import com.zbkj.common.model.user.User;
import com.zbkj.common.page.CommonPage;
import com.zbkj.common.request.CommitProblemRequest;
import com.zbkj.common.request.PageParamRequest;
import com.zbkj.common.response.ProductProblemResponse;
import com.zbkj.common.utils.RedisUtil;
import com.zbkj.service.dao.StoreProductProblemDao;
import com.zbkj.service.service.StoreProductProblemService;
import com.zbkj.service.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class StoreProductProblemServiceImpl extends ServiceImpl<StoreProductProblemDao, StoreProductProblem> implements StoreProductProblemService {
@Resource private StoreProductProblemDao dao;
@Autowired private UserService userService;
@Autowired private RedisUtil redisUtil;
private static final String praise_key = "RESPONSE_PRAISE:";
@Override
public CommonPage<ProductProblemResponse> getResponseList(Integer productId, PageParamRequest page) {
User user = userService.getInfo();
PageHelper.startPage(page.getPage(), page.getLimit());
List<ProductProblemResponse> list = dao.getResponseList(productId);
for (ProductProblemResponse vo : list) {
Long praiseCount = redisUtil.getHashSize(praise_key + vo.getMajorId());
vo.setDelFlag(user == null ? 0 : user.getUid().toString().equals(vo.getUserId()) ? 1 : 0);
vo.setPraiseCount(null == praiseCount ? 0 : praiseCount.intValue());
if (null != praiseCount && praiseCount > 0 && null != user) {
Object o = redisUtil.hmGet(praise_key + vo.getMajorId(), user.getUid().toString());
vo.setPraise(null == o ? 0 : 1);
}
vo.setUserId(null);
}
return CommonPage.restPage(list);
}
@Override
public CommonPage<ProductProblemResponse> getSonResponseList(Integer majorId, PageParamRequest page) {
User user = userService.getInfo();
PageHelper.startPage(page.getPage(), page.getLimit());
List<ProductProblemResponse> list = dao.getSonResponseList(majorId);
for (ProductProblemResponse vo : list) {
Long praiseCount = redisUtil.getHashSize(praise_key + vo.getMajorId());
vo.setDelFlag(user == null ? 0 : user.getUid().toString().equals(vo.getUserId()) ? 1 : 0);
vo.setPraiseCount(null == praiseCount ? 0 : praiseCount.intValue());
if (null != praiseCount && praiseCount > 0 && null != user) {
Object o = redisUtil.hmGet(praise_key + vo.getMajorId(), user.getUid().toString());
vo.setPraise(null == o ? 0 : 1);
}
vo.setUserId(null);
}
return CommonPage.restPage(list);
}
@Override
public Integer commitProblem(CommitProblemRequest request) {
User user = userService.getInfo();
if (null == user) {
throw new CrmebException("请先登录");
}
Integer pId = 0;
Integer topId = 0;
String businessId = request.getBusinessId();
// 说明不是一级评论
if (StringUtil.isNotEmpty(request.getMajorId())) {
StoreProductProblem problem = dao.selectById(Integer.parseInt(request.getMajorId()));
if (null == problem) {
throw new CrmebException("未找到您要回复的对象,可能对方已删除");
}
pId = problem.getId();
businessId = problem.getBusinessId() + "";
topId = (problem.getParentId() == 0L ? problem.getId() : problem.getTopId());
} else if (StringUtil.isEmpty(businessId)) {
throw new CrmebException("请选择您要提问的商品");
}
StoreProductProblem add = new StoreProductProblem();
add.setBusinessId(Integer.parseInt(businessId));
add.setUid(user.getUid());
add.setContent(request.getContent());
add.setParentId(pId);
add.setIsDel(0);
add.setTopId(topId);
return dao.insert(add);
}
@Override
public Integer delProblem(Integer majorId) {
User user = userService.getInfo();
StoreProductProblem problem = dao.selectById(majorId);
if (null == problem) {
throw new CrmebException("未查询到记录");
}
if (!problem.getUid().toString().equals(user.getUid().toString())) {
throw new CrmebException("您无权限操作");
}
StoreProductProblem upd = new StoreProductProblem();
upd.setId(problem.getId());
upd.setIsDel(1);
dao.updateById(upd);
recursionDel(new ArrayList() {{ add(problem.getId()); }});
return 1;
}
@Override
public Integer praiseProblem(Integer majorId) {
User user = userService.getInfo();
Object o = redisUtil.hmGet(praise_key + majorId, user.getUid().toString());
if (null != o) {
redisUtil.hmDelete(praise_key + majorId, user.getUid().toString());
} else {
redisUtil.hmSet(praise_key + majorId, user.getUid().toString(), 1);
}
return 1;
}
private void recursionDel(List<Integer> ids) {
if (ids.isEmpty()) { return; }
LambdaQueryWrapper<StoreProductProblem> lq = new LambdaQueryWrapper<>();
lq.select(StoreProductProblem::getId);
lq.in(StoreProductProblem::getParentId, ids);
List<StoreProductProblem> problems = dao.selectList(lq);
for (StoreProductProblem problem : problems) {
StoreProductProblem upd = new StoreProductProblem();
upd.setId(problem.getId());
upd.setIsDel(2);
dao.updateById(upd);
}
ids = problems.stream().map(StoreProductProblem::getId).collect(Collectors.toList());
recursionDel(ids);
}
}

View File

@ -317,7 +317,7 @@ public class StoreProductReplyServiceImpl extends ServiceImpl<StoreProductReplyD
// 查询一条问题
LambdaQueryWrapper<StoreProductProblem> lqwSpp = new LambdaQueryWrapper<>();
lqwSpp.eq(StoreProductProblem::getProductId, proId);
lqwSpp.eq(StoreProductProblem::getBusinessId, proId);
int problemNum = storeProductProblemService.count(lqwSpp);
lqw.last(" limit 1");
StoreProductProblem one = storeProductProblemService.getOne(lqwSpp);

View File

@ -0,0 +1,37 @@
<?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.zbkj.service.dao.StoreProductProblemDao">
<select id="getResponseList" resultType="com.zbkj.common.response.ProductProblemResponse">
select
c.id majorId,
u.uid userId,
u.nickname nickName,
u.avatar imageUrl,
c.content,
DATE_FORMAT(c.create_time, '%Y-%m-%d %H:%i:%s') createTime,
(select count(1) from eb_store_product_problem c1 where c1.top_id = c.id and c1.top_id <![CDATA[ <> ]]> 0 and c1.is_del = 0) sonNum
from eb_store_product_problem c
LEFT JOIN eb_user u on c.uid = u.uid
where business_id = #{id} and parent_id = 0 and c.is_del = 0 ORDER BY c.create_time DESC
</select>
<select id="getSonResponseList" resultType="com.zbkj.common.response.ProductProblemResponse">
select
a.id majorId,
u.uid userId,
u.nickname nickName,
u.avatar imageUrl,
a.content,
DATE_FORMAT(a.create_time, '%Y-%m-%d %H:%i:%s') createTime,
u1.nickname beReplier
from eb_store_product_problem as a
left join eb_store_product_problem a1 on a.parent_id = a1.id
left join eb_user u on a.uid = u.uid
left join eb_user u1 on a1.uid = u1.uid
where a.top_id = #{id} and a.is_del = 0
order by a.create_time
</select>
</mapper>