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. 内核调试神器SystemTap — 探测点与语法(二)

    a linux trace/probe tool. 官网:https://sourceware.org/systemtap/ 探测点 SystemTap脚本主要是由探测点和探测点处理函数组成的,来看下 ...

  2. DB Query Analyzer 6.02 is released, 71 articles concerned have been published

    DB Query Analyzer is presented by Master Genfeng, Ma from Chinese Mainland. It has English version n ...

  3. J2EE架构师之路

    不经意的回首,工作进入第五个年头了,发现走过了从Java程序员到J2EE架构师的历程. 发现电脑上安装了各种各样的J2EE工具:JBuilder, WSAD, Eclipse, Rose, Toget ...

  4. Mybatis 系列1

    第一篇教程, 就先简单地写个demo, 一起来认识一下mybatis吧. 为了方便,我使用了maven, 至于maven怎么使用, 我就不做介绍了.没用过maven的, 也不影响阅读. 一.Mybat ...

  5. [C#]使用 C# 编写自己的区块链挖矿算法

    [C#] 使用 C# 编写自己区块链的挖矿算法 文章原文来自:Code your own blockchain mining algorithm in Go! ,原始文章通过 Go 语言来实现的,这里 ...

  6. Failed to create the Java Virtual Machine(zt)

    http://lixueli26.iteye.com/blog/711152 在以下版本也发生类似情况,采用同样方法得以解决. 版本:eclipse-jee-indigo-win32 自己电脑上装的j ...

  7. Android开发阅读文档资源

    Android Studio:工具:http://developer.android.com/intl/zh-cn/tools/studio/index.html培训教程:http://develop ...

  8. 几个大型网站的Feeds(Timeline)设计简单对比

    https://mp.weixin.qq.com/s?__biz=MjM5NzQ3ODAwMQ==&mid=404465806&idx=1&sn=3a68a786138538f ...

  9. Ocelot中文文档-流量控制

    感谢@catcherwong 的文章激励我最终写出了这个文档 Ocelot支持上游的请求限制,以便您的下游服务不会过载. 此功能是由GitHub上的@geffzhang添加! 非常感谢. 好了,为了让 ...

  10. Android 开发TCP协议时,报错NetworkOnMainThreadException

    设想是通过Android应用连接PC的TCP服务器,通过点击按钮连接服务器, 最终在点击按钮后报错:networkonmainthreadexception 解决办法: 在MainActivity文件 ...