一、需求分析
-
买家可以对商品提交购买问题咨询,买家提交的商品购买咨询不单单商家可以进行回复,也应该可以将问题推送给购买过此商品的买家来进行回复。
-
买家提出的咨询和对其他买家咨询的回复,都应该推送消息给相应的会员用户,做到及时提醒。
二、流程图
三、数据结构
-
会员问题咨询表
-
会员问题咨询回复表
-
会员咨询与回复站内消息表
四、类图展示
-
实体类展示
-
枚举类展示
五、领域模型
-
会员问题咨询
-
会员回复问题咨询
-
会员商品咨询审核通过发送消息
六、源码展示
这里以会员购买咨询为例:
会员问题咨询实体--Memb
/** * 会员问题咨询实体 * * @author dmy * @version v2.0 * @since v7.1.5 * 2019-09-16 */ @Table(name = "es_member_ask") @ApiModel @JsonNaming(value = PropertyNamingStrategy.SnakeCaseStrategy.class) public class MemberAsk implements Serializable { private static final long serialVersionUID = 1642694855238993L; /** * 主键 */ @Id(name = "ask_id") @ApiModelProperty(hidden = true) private Integer askId; /** * 商品id */ @Column(name = "goods_id") @ApiModelProperty(name = "goods_id", value = "商品id", required = false) private Integer goodsId; /** * 会员id */ @Column(name = "member_id") @ApiModelProperty(name = "member_id", value = "会员id", required = false) private Integer memberId; /** * 卖家id */ @Column(name = "seller_id") @ApiModelProperty(name = "seller_id", value = "卖家id", required = false) private Integer sellerId; /** * 咨询内容 */ @Column(name = "content") @ApiModelProperty(name = "content", value = "咨询内容", required = false) private String content; /** * 咨询时间 */ @Column(name = "create_time") @ApiModelProperty(name = "create_time", value = "咨询时间", required = false) private Long createTime; /** * 商家回复内容 */ @Column(name = "reply") @ApiModelProperty(name = "reply", value = "商家回复内容", required = false) private String reply; /** * 商家回复时间 */ @Column(name = "reply_time") @ApiModelProperty(name = "reply_time", value = "商家回复时间", required = false) private Long replyTime; /** * 商家是否回复 YES:是,NO:否 */ @Column(name = "reply_status") @ApiModelProperty(name = "reply_status", value = "商家是否回复 YES:是,NO:否", required = false) private String replyStatus; /** * 删除状态 DELETED:已删除 NORMAL:正常 */ @Column(name = "status") @ApiModelProperty(name = "status", value = "删除状态 DELETED:已删除 NORMAL:正常", required = false) private String status; /** * 咨询人名称 */ @Column(name = "member_name") @ApiModelProperty(name = "member_name", value = "咨询人名称", required = false) private String memberName; /** * 会员头像 */ @Column(name = "member_face") @ApiModelProperty(name = "member_face", value = "会员头像", required = false) private String memberFace; /** * 商品名称 */ @Column(name = "goods_name") @ApiModelProperty(name = "goods_name", value = "商品名称", required = false) private String goodsName; /** * 商品图片 */ @Column(name = "goods_img") @ApiModelProperty(name = "goods_img", value = "商品图片", required = false) private String goodsImg; /** * 审核状态 WAIT_AUDIT:待审核,PASS_AUDIT:审核通过,REFUSE_AUDIT:审核未通过 */ @Column(name = "auth_status") @ApiModelProperty(name = "auth_status", value = "审核状态 WAIT_AUDIT:待审核,PASS_AUDIT:审核通过,REFUSE_AUDIT:审核未通过", required = false) private String authStatus; /** * 是否匿名 YES:是,NO:否 */ @Column(name = "anonymous") @ApiModelProperty(name = "anonymous", value = "是否匿名 YES:是,NO:否", required = false) private String anonymous; /** * 会员问题咨询回复数量 * 包含商家回复 */ @Column(name = "reply_num") @ApiModelProperty(name = "reply_num", value = "会员问题咨询回复数量", required = false) private Integer replyNum; @PrimaryKeyField public Integer getAskId() { return askId; } public void setAskId(Integer askId) { this.askId = askId; } public Integer getGoodsId() { return goodsId; } public void setGoodsId(Integer goodsId) { this.goodsId = goodsId; } public Integer getMemberId() { return memberId; } public void setMemberId(Integer memberId) { this.memberId = memberId; } public Integer getSellerId() { return sellerId; } public void setSellerId(Integer sellerId) { this.sellerId = sellerId; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public Long getCreateTime() { return createTime; } public void setCreateTime(Long createTime) { this.createTime = createTime; } public String getReply() { return reply; } public void setReply(String reply) { this.reply = reply; } public Long getReplyTime() { return replyTime; } public void setReplyTime(Long replyTime) { this.replyTime = replyTime; } public String getReplyStatus() { return replyStatus; } public void setReplyStatus(String replyStatus) { this.replyStatus = replyStatus; } public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public String getMemberName() { return memberName; } public void setMemberName(String memberName) { this.memberName = memberName; } public String getMemberFace() { return memberFace; } public void setMemberFace(String memberFace) { this.memberFace = memberFace; } public String getGoodsName() { return goodsName; } public void setGoodsName(String goodsName) { this.goodsName = goodsName; } public String getGoodsImg() { return goodsImg; } public void setGoodsImg(String goodsImg) { this.goodsImg = goodsImg; } public String getAuthStatus() { return authStatus; } public void setAuthStatus(String authStatus) { this.authStatus = authStatus; } public String getAnonymous() { return anonymous; } public void setAnonymous(String anonymous) { this.anonymous = anonymous; } public Integer getReplyNum() { return replyNum; } public void setReplyNum(Integer replyNum) { this.replyNum = replyNum; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } MemberAsk memberAsk = (MemberAsk) o; return Objects.equals(askId, memberAsk.askId) && Objects.equals(goodsId, memberAsk.goodsId) && Objects.equals(memberId, memberAsk.memberId) && Objects.equals(sellerId, memberAsk.sellerId) && Objects.equals(content, memberAsk.content) && Objects.equals(createTime, memberAsk.createTime) && Objects.equals(reply, memberAsk.reply) && Objects.equals(replyTime, memberAsk.replyTime) && Objects.equals(replyStatus, memberAsk.replyStatus) && Objects.equals(status, memberAsk.status) && Objects.equals(memberName, memberAsk.memberName) && Objects.equals(memberFace, memberAsk.memberFace) && Objects.equals(goodsName, memberAsk.goodsName) && Objects.equals(goodsImg, memberAsk.goodsImg) && Objects.equals(authStatus, memberAsk.authStatus) && Objects.equals(anonymous, memberAsk.anonymous) && Objects.equals(replyNum, memberAsk.replyNum); } @Override public int hashCode() { return Objects.hash(askId, goodsId, memberId, sellerId, content, createTime, reply, replyTime, replyStatus, status, memberName, memberFace, goodsName, goodsImg, authStatus, anonymous, replyNum); } @Override public String toString() { return "MemberAsk{" + "askId=" + askId + ", goodsId=" + goodsId + ", memberId=" + memberId + ", sellerId=" + sellerId + ", content='" + content + '\'' + ", createTime=" + createTime + ", reply='" + reply + '\'' + ", replyTime=" + replyTime + ", replyStatus='" + replyStatus + '\'' + ", status='" + status + '\'' + ", memberName='" + memberName + '\'' + ", memberFace='" + memberFace + '\'' + ", goodsName='" + goodsName + '\'' + ", goodsImg='" + goodsImg + '\'' + ", authStatus='" + authStatus + '\'' + ", anonymous='" + anonymous + '\'' + ", replyNum=" + replyNum + '}'; } }
新增会员购买咨询API--MemberAskBuyerController
/** * 会员商品咨询API * * @author dmy * @version v2.0 * @since v7.1.5 * 2019-09-17 */ @RestController @RequestMapping("/members/asks") @Api(description = "会员商品咨询API") @Validated public class MemberAskBuyerController { @Autowired private MemberAskManager memberAskManager; @ApiOperation(value = "添加咨询", response = MemberAsk.class) @ApiImplicitParams({ @ApiImplicitParam(name = "ask_content", value = "咨询内容", required = true, dataType = "string", paramType = "query"), @ApiImplicitParam(name = "goods_id", value = "咨询商品id", required = true, dataType = "int", paramType = "query"), @ApiImplicitParam(name = "anonymous", value = "是否匿名 YES:是,NO:否", required = true, dataType = "string", paramType = "query", allowableValues = "YES,NO") }) @PostMapping public MemberAsk add(@NotEmpty(message = "请输入咨询内容")@ApiIgnore String askContent, @NotNull(message = "咨询商品不能为空") @ApiIgnore Integer goodsId, @NotNull(message = "请选择是否匿名提问") @ApiIgnore String anonymous) { //咨询内容敏感词过滤 askContent = SensitiveFilter.filter(askContent, CharacterConstant.WILDCARD_STAR); MemberAsk memberAsk = this.memberAskManager.add(askContent, goodsId, anonymous); return memberAsk; } }
业务层
新增会员咨询业务接口--MemberAskManager
** * 咨询业务层 * @author dmy * @version v2.0 * @since v7.1.5 * 2019-09-17 */ public interface MemberAskManager { /** * 添加咨询 * @param askContent 咨询 * @param goodsId 商品id * @param anonymous 是否匿名 YES:是,NO:否 * @return MemberAsk 咨询 */ MemberAsk add(String askContent, Integer goodsId, String anonymous); }
业务接口实现类--MemberAskManagerImpl
/** * 咨询业务类 * * @author dmy * @version v2.0 * @since v7.1.5 * 2019-09-17 */ @Service public class MemberAskManagerImpl implements MemberAskManager { @Autowired @Qualifier("memberDaoSupport") private DaoSupport daoSupport; @Autowired private GoodsClient goodsClient; @Autowired private MemberManager memberManager; @Autowired private SettingClient settingClient; @Autowired private AmqpTemplate amqpTemplate; @Override @Transactional(value = "memberTransactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class) public MemberAsk add(String askContent, Integer goodsId, String anonymous) { if (askContent.length() < 3 || askContent.length() > 120) { throw new ServiceException(MemberErrorCode.E202.code(), "咨询内容应在3到120个字符之间"); } //获取咨询的商品信息 CacheGoods goods = goodsClient.getFromCache(goodsId); //获取当前登录的会员信息 Buyer buyer = UserContext.getBuyer(); if (buyer == null) { throw new ServiceException(MemberErrorCode.E110.code(), "当前会员已经退出登录"); } //在数据库中取出最新的会员信息 Member member = memberManager.getModel(buyer.getUid()); MemberAsk memberAsk = new MemberAsk(); memberAsk.setContent(askContent); memberAsk.setMemberId(member.getMemberId()); memberAsk.setGoodsId(goodsId); memberAsk.setGoodsName(goods.getGoodsName()); memberAsk.setGoodsImg(goods.getThumbnail()); memberAsk.setCreateTime(DateUtil.getDateline()); //咨询状态默认为正常状态 memberAsk.setStatus(DeleteStatusEnum.NORMAL.value()); memberAsk.setSellerId(goods.getSellerId()); //商家回复状态默认为未回复 memberAsk.setReplyStatus(CommonStatusEnum.NO.value()); if (!CommonStatusEnum.YES.value().equals(anonymous) && !CommonStatusEnum.NO.value().equals(anonymous)) { throw new ServiceException(MemberErrorCode.E107.code(), "是否匿名参数值不正确"); } memberAsk.setAnonymous(anonymous); memberAsk.setMemberName(CommonStatusEnum.YES.value().equals(anonymous) ? "匿名" : member.getUname()); memberAsk.setMemberFace(member.getFace()); //获取商品咨询设置 String json = this.settingClient.get(SettingGroup.GOODS); GoodsSettingVO goodsSettingVO = JsonUtil.jsonToObject(json,GoodsSettingVO.class); memberAsk.setAuthStatus(goodsSettingVO.getAskAuth().intValue() == 0 ? AuditEnum.PASS_AUDIT.name() : AuditEnum.WAIT_AUDIT.name()); this.daoSupport.insert(memberAsk); memberAsk.setAskId(this.daoSupport.getLastId("")); //如果平台没有开启会员咨询审核,那么就直接发送消息 if (goodsSettingVO.getAskAuth().intValue() == 0) { List<MemberAsk> list = new ArrayList<>(); list.add(memberAsk); this.sendMessage(list); } return memberAsk; } /** * 发送rabbitmq消息 * @param memberAskList */ private void sendMessage(List<MemberAsk> memberAskList) { MemberAskMessage memberAskMessage = new MemberAskMessage(); memberAskMessage.setMemberAsks(memberAskList); memberAskMessage.setSendTime(DateUtil.getDateline()); this.amqpTemplate.convertAndSend(AmqpExchange.MEMBER_GOODS_ASK, AmqpExchange.MEMBER_GOODS_ASK + "_ROUTING", memberAskMessage); } }
处理rabbitmq消息的消费者--MemberAskConsumer
/** * 会员商品咨询消费者 * 会员提出咨询后给购买过此商品的会员发送消息 * @author dmy * @version v1.0 * @since v7.1.5 * 2019-09-16 */ @Service public class MemberAskConsumer implements MemberAskSendMessageEvent { @Autowired private MemberAskClient memberAskClient; @Autowired private OrderQueryManager orderQueryManager; @Override public void goodsAsk(MemberAskMessage memberAskMessage) { List<MemberAsk> memberAskList = memberAskMessage.getMemberAsks(); if (memberAskList != null && memberAskList.size() != 0) { for (MemberAsk memberAsk : memberAskList) { if (memberAsk == null) { break; } //获取3个月之内购买过相关商品的订单数据,获取的订单数据只限已完成和已收货并且未删除的订单 List<OrderDO> orderDOList = orderQueryManager.listOrderByGoods(memberAsk.getGoodsId(), memberAsk.getMemberId(), 3); if (orderDOList != null && orderDOList.size() != 0) { AskMessageDO askMessageDO = new AskMessageDO(); askMessageDO.setAsk(memberAsk.getContent()); askMessageDO.setAskId(memberAsk.getAskId()); askMessageDO.setAskMember(memberAsk.getMemberName()); askMessageDO.setAskAnonymous(memberAsk.getAnonymous()); askMessageDO.setGoodsId(memberAsk.getGoodsId()); askMessageDO.setGoodsName(memberAsk.getGoodsName()); askMessageDO.setGoodsImg(memberAsk.getGoodsImg()); askMessageDO.setIsDel(DeleteStatusEnum.NORMAL.value()); askMessageDO.setIsRead(CommonStatusEnum.NO.value()); askMessageDO.setSendTime(memberAskMessage.getSendTime()); askMessageDO.setReceiveTime(DateUtil.getDateline()); askMessageDO.setMsgType(AskMsgTypeEnum.ASK.value()); //循环订单获取会员信息,然后给会员发送消息 for (OrderDO orderDO : orderDOList) { askMessageDO.setMemberId(orderDO.getMemberId()); this.memberAskClient.sendMessage(askMessageDO); } } } } } }
以上为本次分享内容,相关商城架构源码分享,请持续关注我们!!!