java b2b2c商城 - 商品购买咨询功能架构以及源码分享

一、需求分析

  1. 买家可以对商品提交购买问题咨询,买家提交的商品购买咨询不单单商家可以进行回复,也应该可以将问题推送给购买过此商品的买家来进行回复。

  2. 买家提出的咨询和对其他买家咨询的回复,都应该推送消息给相应的会员用户,做到及时提醒。

二、流程图

 三、数据结构

  1. 会员问题咨询表

 

  1. 会员问题咨询回复表

 

  1. 会员咨询与回复站内消息表

 

四、类图展示

  1. 实体类展示

 

  1. 枚举类展示

 

 五、领域模型

  1. 会员问题咨询

 

  1. 会员回复问题咨询

 

  1. 会员商品咨询审核通过发送消息

 

 六、源码展示

这里以会员购买咨询为例:

会员问题咨询实体--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);
                    }
                }
            }
        }
    }
}

  以上为本次分享内容,相关商城架构源码分享,请持续关注我们!!!

猜你喜欢

转载自www.cnblogs.com/javashop-docs/p/12896281.html
今日推荐