一、需求分析
买家可以对商品提交购买问题咨询,买家提交的商品购买咨询不单单商家可以进行回复,也应该可以将问题推送给购买过此商品的买家来进行回复。
买家提出的咨询和对其他买家咨询的回复,都应该推送消息给相应的会员用户,做到及时提醒。
二、流程图
三、数据结构
- 会员问题咨询表
- 会员问题咨询回复表
- 会员咨询与回复站内消息表
四、类图展示
1、实体类展示
2、枚举类展示
五、领域模型
1、会员问题咨询
2、会员回复问题咨询
3、会员商品咨询审核通过发送消息
六、源码展示
这里以会员购买咨询为例:
会员问题咨询实体--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);
}
}
}
}
}
}
以上为本次分享内容,相关商城架构源码分享,请持续关注我们!!!
易族智汇(javashop)原创文章