一、需求分析
-
買家可以對商品提交購買問題諮詢,買家提交的商品購買諮詢不單單商家可以進行回覆,也應該可以將問題推送給購買過此商品的買家來進行回覆。
-
買家提出的諮詢和對其他買家諮詢的回覆,都應該推送消息給相應的會員用戶,做到及時提醒。
二、流程圖
三、數據結構
- 會員問題諮詢表
- 會員問題諮詢回覆表
- 會員諮詢與回覆站內消息表
四、類圖展示
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)原創文章