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

一、需求分析

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

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

二、流程图

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

 

 三、数据结构

  1. 会员问题咨询表

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

  1. 会员问题咨询回复表

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

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

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

四、类图展示

  1. 实体类展示

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

  1. 枚举类展示

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

 

 五、领域模型

  1. 会员问题咨询

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

  1. 会员回复问题咨询

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

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

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

 

 六、源码展示

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

会员问题咨询实体--Memb

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

/**

 * 会员问题咨询实体

 *

 * @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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

/**

 * 会员商品咨询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

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

**

 * 咨询业务层

 @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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

/**

 * 咨询业务类

 *

 * @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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

/**

 * 会员商品咨询消费者

 * 会员提出咨询后给购买过此商品的会员发送消息

 * @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)原创文章 

分类: 电商架构

标签: 电商源码分享电商系统源码分享java电商系统源码b2b2c系统源码分享