Java生鲜电商平台-售后模块的设计与架构

说明:任何一个的电商平台都有售后服务系统,那么对于我们这个生鲜的电商平台,售后系统需要思考以下几个维度。

1. 买家的需求维度

说明:买家在平台上没找到自己想要的东西,我们需要提供给他一个入口,告诉我们他有这个需求,我们进行改进。系统需要有记录这种情况,同时也有回复客户的情况。

2. 投诉入口

说明:有客户性子比较急,他有问题,就会马上打电话给客服,客服需要解答与回答,维护客户关系。对于系统而言,需要记录这种情况,然后分析问题与解决问题。

3. IM聊天入口

说明:客户有时候也不想写信息,也不想打电话,能否有一个时刻的IM聊天记录呢?对于系统而言需要记录这种信息,我们目前系统没处理,采用的是微信,以及销售人员的反馈机制。

4. 退货问题

说明:售后系统中,退货问题是最繁琐的,买家存在以下两种情况。

4.1 买家要钱不要货。顾名思义,有些买家就是不要货了,他需要我们退钱给他,这个配送端有一个一件退货功能,钱退到买家的余额里面,下次可以继续购买。

4.2  买家要货不要钱,顾名思义,有些买家的确需要这个货物,对于我们退钱给他,他是不接受的,因为他真的需要这种东西,你让他再去买,客户体验非常差,可能 就没有下次购物了。对于这种情况,我们用时间轴来继续整个过程。(说明,由于这个系统设计到生鲜电商方面,其他的电商方面可能会不一样。)

相关数据库的设计与架构如下:

1. 买家平台建议信息表

CREATE TABLE `suggestion` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自动增加ID',
`suggestion_content` varchar(1024) DEFAULT NULL COMMENT '建议内容',
`suggestion_imgs` varchar(255) DEFAULT NULL COMMENT '多张图片',
`user_id` bigint(20) DEFAULT NULL COMMENT '所属用户ID',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=78 DEFAULT CHARSET=utf8 COMMENT='用户对平台的建议';

说明: 平台建议表,是买家对平台的建议以及自己的需求的一个入口,可以是图片与内容两点。

比如说:他说我们送的菜有问题,很多烂的,那么他是需要拍图片证明的。

2. 平台回复信息表

CREATE TABLE `suggestion_reply` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自动增加ID',
`suggestion_id` bigint(20) DEFAULT NULL COMMENT '客户的建议ID',
`content` varchar(512) DEFAULT NULL COMMENT '回复的内容',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=utf8 COMMENT='客户建议回复信息表';

说明:作为一个平台,平台需要回复客户的信息,买家也需要看到,当然这边系统是不区分是买家还是卖家的,我们都是可以数据的处理的。

3. 售后系统时间轴的设计

说明:其实我们系统需要知道整个售后的过程的,比如买家什么时候发起的不要钱,要货,然后师傅是什么时候知道这个消息的,如何进行售后的,他们会遇到什么问题,

当然这里面有很多的问题,系统可以做的事情其实是很少的,而我们需要做的是更多的事情。

CREATE TABLE `order_timeline` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自动增加ID',
`item_id` bigint(20) DEFAULT NULL COMMENT '订单项ID',
`remarks` varchar(256) DEFAULT NULL COMMENT '备注',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1980 DEFAULT CHARSET=utf8 COMMENT='售后模块,退换货时间轴,针对的是某一个订单项';

相关时间轴运营截图如下:

整个业务不算复杂,需要的一种思路与解决思路的方案:

关于补货流程:

补货需求
业务需求:
当卖家主动点击缺货,则配送师傅看到这个异常订单项,然后他有两种选择,
第一种补货(有货,他也想补或者客户说要货不要钱)
第二种不补货(无货可补,他不想补或者客户说退钱等等)
第一种补货业务:
1. 当配送师傅点击已补货,则把这个订单项对应的金额从买家中直接扣除,前提是线上付款,如果这个订单是线下付款,则不用处理扣款逻辑,直接修改状态即可。同时记录时间轴日志。
第二种不补货业务:
2. 当师傅点击不补货,则这个订单项不做任何扣款逻辑,不管线下还是线上,直接修改状态即可,同时记录时间轴日志。
补充说明:补货与不补货属于互斥操作,即已补货后不允许再出现不补货,不补货后不再允许出现补货。按照规则来处理。

相关业务核心代码如下:

/**
* 订单项退货*/
@RestController
@RequestMapping("/delivery")
public class OrderReturnController extends BaseController { private static final Logger logger = LoggerFactory.getLogger(OrderReturnController.class); @Autowired
private OrderItemService orderItemService; @Autowired
private OrderReturnService orderReturnService; /**
* 订单项退货
*
*/
@RequestMapping(value = "/order/return/item", method = { RequestMethod.GET, RequestMethod.POST })
public JsonResult orderReturnItem(HttpServletRequest request, HttpServletResponse response,
@Param("itemId") Long itemId, @Param("deliveryId") Long deliveryId, @Param("status") int status) {
try {
if (itemId == null) {
return new JsonResult(JsonResultCode.FAILURE, "item参数有误", "");
} OrderItem orderItem = orderItemService.getOrderItemByItemId(itemId); if (orderItem == null) {
return new JsonResult(JsonResultCode.FAILURE, "无此订单项", "");
} String returnMsg = "";
if(status == BuyerStatus.THREE){
returnMsg = TimelineTemplate.return_MSG;
}if(status == BuyerStatus.FOUR){
returnMsg = TimelineTemplate.BACK_MSG;
}if(status == BuyerStatus.ZERO){
returnMsg = TimelineTemplate.OFF_MSG;
}
orderItemService.updateOrderItemStatus(itemId, status, deliveryId, returnMsg);
return new JsonResult(JsonResultCode.SUCCESS, "操作成功", "");
} catch (Exception ex) {
logger.error("[OrderReturnController][orderReturnItem] exception :", ex);
return new JsonResult(JsonResultCode.FAILURE, "系统错误,请稍后重试", "");
}
} /**
* 退还列表
*/
@RequestMapping(value = "/order/return/list", method = { RequestMethod.GET, RequestMethod.POST })
public JsonResult orderReturnList(HttpServletRequest request, HttpServletResponse response,@Param("deliveryId") Long deliveryId, @Param("status") int status) {
try
{
// 组装成为最终的列表结果
List<OrderReturnVo> listResult = new ArrayList<OrderReturnVo>(); List<OrderGoodsVo> goodsList = orderReturnService.getReturnOrderGoodsList(deliveryId,status); if (CollectionUtils.isEmpty(goodsList)) {
return new JsonResult(JsonResultCode.SUCCESS, "查询完成", listResult);
} // 临时参数,判断时间
Map<String, List<OrderReturnEntity>> paramTimeMap = new HashMap<String, List<OrderReturnEntity>>(); // 过滤卖家
Map<String, List<OrderGoodsVo>> paramSellerMap = new HashMap<String, List<OrderGoodsVo>>(); for (OrderGoodsVo vo : goodsList) {
String bestTime = DateUtil.dateToString(vo.getBestTime(), "yyyy-MM-dd"); // 时间相同
if (paramTimeMap.get(bestTime) != null) {
List<OrderReturnEntity> mapOrderReturnEntity = paramTimeMap.get(bestTime); // 组装时间
OrderReturnVo resultVo = new OrderReturnVo();
resultVo.setBestTime(bestTime); // 判断是否是同一个卖家的
if (paramSellerMap.get(vo.getSellerName()) != null)
{
OrderReturnEntity entity = new OrderReturnEntity();
List<OrderGoodsVo> listVo = paramSellerMap.get(vo.getSellerName());
listVo.add(vo);
entity.setListOrderGoodsVo(listVo);
resultVo.setListOrderReturnEntity(mapOrderReturnEntity);
}else
{
//不同买家
OrderReturnEntity entity = new OrderReturnEntity();
entity.setSellerName(vo.getSellerName()); List<OrderGoodsVo> listVo =new ArrayList<OrderGoodsVo>();
listVo.add(vo);
entity.setListOrderGoodsVo(listVo);
mapOrderReturnEntity.add(entity); paramSellerMap.put(vo.getSellerName(), listVo);
}
} else {
// 组装时间
OrderReturnVo resultVo = new OrderReturnVo();
resultVo.setBestTime(bestTime); OrderReturnEntity entity = new OrderReturnEntity();
entity.setSellerName(vo.getSellerName()); List<OrderGoodsVo> paramOrderGoodsVo = new ArrayList<OrderGoodsVo>();
paramOrderGoodsVo.add(vo);
entity.setListOrderGoodsVo(paramOrderGoodsVo); List<OrderReturnEntity> listOrderReturnEntity = new ArrayList<OrderReturnEntity>();
listOrderReturnEntity.add(entity); resultVo.setListOrderReturnEntity(listOrderReturnEntity); listResult.add(resultVo); paramSellerMap.put(vo.getSellerName(), paramOrderGoodsVo); paramTimeMap.put(bestTime, listOrderReturnEntity);
}
}
return new JsonResult(JsonResultCode.SUCCESS, "查询信息成功", listResult);
} catch (Exception ex) {
logger.error("[OrderReturnController][orderReturnItem] exception :", ex);
return new JsonResult(JsonResultCode.FAILURE, "系统错误,请稍后重试", "");
}
}

APP运营截图相对而言比较简单,我这边就不贴出来了。

Java开源生鲜电商平台-售后模块的设计与架构(源码可下载)的更多相关文章

  1. Java开源生鲜电商平台-购物车模块的设计与架构(源码可下载)

    ava开源生鲜电商平台-购物车模块的设计与架构(源码可下载) 说明:任何一个电商无论是B2C还是B2B都有一个购物车模块,其中最重要的原因就是客户需要的东西放在一起,形成一个购物清单,确认是否有问题, ...

  2. Java开源生鲜电商平台-推荐系统模块的设计与架构(源码可下载)

    Java开源生鲜电商平台-推荐系统模块的设计与架构(源码可下载) 业务需求: 对于一个B2B的生鲜电商平台,对于买家而言,他需要更加快速的购买到自己的产品,跟自己的餐饮店不相关的东西,他是不关心的,而 ...

  3. Java开源生鲜电商平台-支付模块的设计与架构(源码可下载)

    Java开源生鲜电商平台-支付模块的设计与架构(源码可下载) 开源生鲜电商平台支付目前支持支付宝与微信.针对的是APP端(android or IOS)   1. 数据库表设计. 说明:无论是支付宝还 ...

  4. Java开源生鲜电商平台-异常模块的设计与架构(源码可下载)

    Java开源生鲜电商平台-异常模块的设计与架构(源码可下载) 说明:任何一个软件系统都会出现各式各样的异常与错误,我们需要根据异常的情况进行捕获与分析,改善自己的代码,让其更加的稳定的,快速的运行,那 ...

  5. Java开源生鲜电商平台-账单模块的设计与架构(源码可下载)

    Java开源生鲜电商平台-账单模块的设计与架构(源码可下载) 补充说明:Java开源生鲜电商平台-账单模块的设计与架构,即用户的账单形成过程. 由于系统存在一个押账功能的需求,(何为押账,就是形成公司 ...

  6. Java开源生鲜电商平台-搜索模块的设计与架构(源码可下载)

    Java开源生鲜电商平台-搜索模块的设计与架构(源码可下载) 说明:搜索模块针对的是买家用户,在找菜品找的很费劲下的一种查询方面.目前也是快速的检索商品. 对于移动端的APP买家用户而言,要求的速度在 ...

  7. Java生鲜电商平台-供应链模块的设计与架构

    Java生鲜电商平台-供应链模块的设计与架构 说明:Java开源生鲜电商平台中供应链模块属于卖家的行为,也就是卖家如何管理他们自己的供应商,包括结算方式,压款方式,结算周期等等,超出了我这个B2B平台 ...

  8. Java开源生鲜电商平台-用户表的设计(源码可下载)

    Java开源生鲜电商平台-用户表的设计(源码可下载) 说明:由于该系统属于B2B平台,不设计到B2C的架构. 角色分析:买家与卖家. 由于买家与卖家所填写的资料都不一样,需要建立两站表进行维护,比如: ...

  9. Java开源生鲜电商平台-商品表的设计(源码可下载)

    Java开源生鲜电商平台-商品表的设计(源码可下载) 任何一个电商,无论是B2C还是B2B的电商,商品表的设计关系到整个系统架构的核心. 1. 商品基本信息表:用单词:goods做为商品表 2. 商品 ...

随机推荐

  1. Shell Script - 追踪与debug

    [root@www ~]# sh [-nvx] scripts.sh 选项与参数: -n :不要运行 script,仅查询语法的问题: -v :再运行 sccript 前,先将 scripts 的内容 ...

  2. Herriot

    Herriot测试框架是Hadoop-0.21.0及以后版本中新加入的测试框架,它的出现主要是为了尽可能地模拟真实的大规模分布式系统,并且对该系统实现自动化测试.和Hadoop以前的测试框架MiniD ...

  3. 部署与管理ZooKeepe

    1.部署 本章节主要讲述如何部署ZooKeeper,包括以下三部分的内容: 1. 系统环境 2. 集群模式的配置 3. 单机模式的配置 系统环境和集群模式配置这两节内容大体讲述了如何部署一个能够用于生 ...

  4. 配置SharePoint环境加域提示网络名不可用[已解决]

    今天去客户给机器做备机,带着装好SharePoint07的机器跑过去了,先做个LAN,然后连上机器开始工作:首先当然是改ip地址,然后都改好了开始加域,加了好几次,发现都不行,提示"指定的网 ...

  5. leetCode之旅(12)-反转二叉树

    背景描述 Homebrew 是 OS X 平台上的包管理工具.用其官网的话说就是: the missing package manager for OS X | OS X 平台遗失的包管理器. 相信在 ...

  6. 深入浅出理解python 装饰器

    之前就了解到了装饰器, 但是就会点皮毛, 而且对其调用方式感到迷茫,正好现在的项目我想优化,就想到了用装饰器, 因此深入研究了下装饰器.先看下代码: import time # 将函数作为参数传入到此 ...

  7. json的命名空间

    <script>var zgz={}; zgz.common={ getByClass: function () { }, myAddEvent: function () { }}; zg ...

  8. Spring Cloud入门教程 - Zuul实现API网关和请求过滤

    简介 Zuul是Spring Cloud提供的api网关和过滤组件,它提供如下功能: 认证 过滤 压力测试 Canary测试 动态路由 服务迁移 负载均衡 安全 静态请求处理 动态流量管理 在本教程中 ...

  9. 分布式文件系统MFS、Ceph、GlusterFS、Lustre的比较

    原文:http://blog.csdn.net/metaxen/article/details/7108958 MooseFS(MFS) Ceph GlusterFS Lustre Metadata ...

  10. Java自学?Java编程资源大放送

    黑马程序员 北京JavaEE就业班32期教程视频+源码+资料 链接: https://pan.baidu.com/s/1VCXyNVD-LvlZyReVgzKXGg 密码:cike 黑马:Java基础 ...