Java生鲜电商平台-财务系统模块的设计与架构

前言:任何一个平台也好,系统也好,挣钱养活团队这个是无可厚非的,那么对于一个生鲜B2B平台盈利模式( 查看:http://www.cnblogs.com/jurendage/p/9016411.html)而言,

其中财务模块无论是对于买家而言还是卖家而言都至关重要,老百姓对钱的看重是没有经历的人想不到的,一句话说清楚了:一分钱也不能少。

买家或者卖家对财务模块的要求很简单:

1. 账清楚明白。

2. 消费清清楚楚。

3. 计算准确无误。

对平台而言:财务的要求是每笔资金的输入与输出,有理有据,真真实实。

我们分两个模块来讨论,买家与卖家我们称为客户财务模块,平台我们称为公司财务模块

1. 客户财务模块

1.1 买家需要查看任何一天的消费记录。数据按照时间的倒叙排列,根据时间进入某天的消费记录,需要查看当天的历史订单数据。

业务中按照时间来分组,数据是来源于订单表:

相关业务核心代码如下:

    /**
* 订单列表
*
* @description 1.用户的所有订单列表。 2.支付状态 3.交易状态.
* @param request
* @param response
* @param orderStatus
* 0 待支付 1待送达 2已完成
* @return
*/
@RequestMapping(value = "/order/list", method = { RequestMethod.GET, RequestMethod.POST })
public JsonResult buyerOrderList(HttpServletRequest request, HttpServletResponse response, Long buyerId,
int orderStatus) { List<OrderListVo> listVo = new ArrayList<OrderListVo>(); // 需要顺序
Map<String, List<OrderInfoVo>> resultMap = new TreeMap<String, List<OrderInfoVo>>(new Comparator<String>() {
public int compare(String obj1, String obj2) {
// 降序排序
return obj2.compareTo(obj1);
}
}); try {
List<OrderInfo> orderList = orderInfoService.getAllOrderInfo(buyerId, orderStatus); // 判断是否有订单
if (CollectionUtils.isEmpty(orderList)) {
return new JsonResult(JsonResultCode.SUCCESS, "订单查询成功", listVo);
} // 组装Map对象
for (OrderInfo order : orderList) {
List<OrderInfoVo> resultList = new ArrayList<OrderInfoVo>(); OrderInfoVo orderInfoVo = transform(order); String time = DateUtil.dateToString(order.getCreateTime(), "yyyy-MM-dd"); if (resultMap.get(time) == null) {
resultList.add(orderInfoVo);
resultMap.put(time, resultList);
} else {
List<OrderInfoVo> mapList = resultMap.get(time);
mapList.add(orderInfoVo);
resultMap.put(time, mapList);
}
} // 组装VO
Set<String> keys = resultMap.keySet();
for (String data : keys) {
OrderListVo vo = new OrderListVo();
vo.setDate(data);
vo.setList(resultMap.get(data));
listVo.add(vo);
}
return new JsonResult(JsonResultCode.SUCCESS, "订单查询成功", listVo);
} catch (Exception ex) {
logger.error("[OrderController][buyerOrderList] exception :", ex);
return new JsonResult(JsonResultCode.FAILURE, "系统错误,请稍后重试", "");
}
}

说明:买家而言其实就是待支付,已经支付等订单的明细查询,根据时间进行分组,根据时间(按照天来计算,查看自己的明细。),然后查询出整个订单明细即可。

相关运营截图如下:

1.2  对于卖家而言,他肯定想知道每天具体卖了多少东西,多少钱,但是不是针对某一个买家而言,是针对整个统计而言。

比如:他想知道我今天卖了土豆多少共多少斤,白菜多少斤,萝卜多少斤,花菜多少斤等等,同时他自己会算出今天的利润多少。

补充说明:其实系统是可以算出来今天他挣钱多少的,但是客户很讨厌输入进货价,相当于把自己的“秘密”出卖了一样,整个系统架构中

先前是有的,但是实际运营发现,不是我们的那个样子,最终是去掉了。

相关的业务核心代码如下:(数据也是来源于订单明细表中)

订单主表的列表:

 
/**
* 查询买家需要确认的订单列表
*/
@RequestMapping(value = "/order/list", method = { RequestMethod.GET, RequestMethod.POST })
public JsonResult orderList(HttpServletRequest request, HttpServletResponse response,Integer type,Long saleId) {
try {
List<OrderVo> orderList = orderService.getOrderList(type, saleId);
return new JsonResult(JsonResultCode.SUCCESS, "查询信息成功", orderList);
} catch (Exception ex) {
logger.error("[OrderController][orderList] exception :", ex);
return new JsonResult(JsonResultCode.FAILURE, "系统错误,请稍后重试", "");
}
}

根据订单号获取订单明细:

/**
* 查询买家需要确认的订单列表
*/
@RequestMapping(value = "/order/detail", method = { RequestMethod.GET, RequestMethod.POST })
public JsonResult getOrderDetail(HttpServletRequest request, HttpServletResponse response,Long orderId) {
try {
OrderDetailVo odv = orderService.getOrderDetail(orderId);
return new JsonResult(JsonResultCode.SUCCESS, "查询信息成功", odv);
} catch (Exception ex) {
logger.error("[OrderController][getOrderDetail] exception :", ex);
return new JsonResult(JsonResultCode.FAILURE, "系统错误,请稍后重试", "");
}
}

订单明细VO:对象:

/**
* 订单详情VO
*/
public class OrderDetailVo implements java.io.Serializable { private static final long serialVersionUID = 1L;
/**
* 订单主表id,order_info表的order_id
*/
private Long orderId;
/**
* 唯一订单号
*/
private String orderNumber;
/**
* 买家ID
*/
private Long buyerId;
/**
* 买家店铺名称
*/
private String buyerName;
/**
* 买家店铺图片
*/
private String buyerLogo;
/**
* 买家地址
*/
private String buyerAddress;
/**
* 买家姓名
*/
private String bossName;
/**
* 买家手机
*/
private String bossTel;
/**
* 收货人的最佳送货时间
*/
private String bestTime;
/**
* 订单创建时间
*/
private String createTime;
/**
* 商品列表
*/
private List<OrderGoodsVo> goodsList; public Long getOrderId() {
return orderId;
}
public void setOrderId(Long orderId) {
this.orderId = orderId;
}
public String getOrderNumber() {
return orderNumber;
}
public void setOrderNumber(String orderNumber) {
this.orderNumber = orderNumber;
}
public Long getBuyerId() {
return buyerId;
}
public void setBuyerId(Long buyerId) {
this.buyerId = buyerId;
}
public String getBuyerName() {
return buyerName;
}
public void setBuyerName(String buyerName) {
this.buyerName = buyerName;
}
public String getBuyerLogo() {
return buyerLogo;
}
public void setBuyerLogo(String buyerLogo) {
this.buyerLogo = buyerLogo;
}
public String getBuyerAddress() {
return buyerAddress;
}
public void setBuyerAddress(String buyerAddress) {
this.buyerAddress = buyerAddress;
}
public String getBossName() {
return bossName;
}
public void setBossName(String bossName) {
this.bossName = bossName;
}
public String getBossTel() {
return bossTel;
}
public void setBossTel(String bossTel) {
this.bossTel = bossTel;
}
public String getBestTime() {
return bestTime;
}
public void setBestTime(String bestTime) {
this.bestTime = bestTime;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
public List<OrderGoodsVo> getGoodsList() {
return goodsList;
}
public void setGoodsList(List<OrderGoodsVo> goodsList) {
this.goodsList = goodsList;
}
}

相关SQL核心:

  <!-- 订单详情 -->
<select id="getOrderDetail" resultMap="orderDetailMap">
select
o.order_id,o.order_number,o.buyer_id,b.buyer_name,b.buyer_logo,b.buyer_address,b.boss_name,b.boss_tel,
date_format(o.best_time,'%Y-%m-%d %H:%i') as best_time,date_format(o.create_time,'%Y-%m-%d %H:%i') as create_time,
oi.item_id,oi.remark,g.goods_id,g.goods_name,g.goods_brand,g.goods_label,
gf.format_id,gf.format_name,u.unit_id,u.unit_name,gf.format_num,
pm.method_id,pm.method_name,oi.goods_price,oi.goods_number,oi.goods_amount,
gp.pic_id,gp.pic_url,gp.is_main,gp.pic_seq
from order_item oi
inner join order_info o on o.order_id=oi.order_id
inner join buyer b on b.buyer_id=o.buyer_id
inner join goods_format gf on gf.format_id=oi.format_id
inner join goods g on gf.goods_id=g.goods_id
inner join unit u on gf.unit_id=u.unit_id
left join process_method pm on pm.method_id=oi.method_id
left join goods_picture gp on g.goods_id=gp.goods_id
where oi.order_id=#{orderId}
order by gp.is_main desc
</select>

疑问一:为什么会贴出如此多的代码吗?尤其是SQL? 

理由只有一点:的确这块比较复杂,很多都是基于SQL语句的查询,需要SQL功底。

相关的业务运营截图如下:

下面的核心的历史收益这块,卖家可以扔掉自己的手抄本了。根据这个平台就可以方便的明细的账单记录

补充说明:数据报表有金额,有数据,有统计,有分析,包括以后的折线图,柱状图等等报表分析,让用户明确的知道今天挣钱多少,明天预警备货多少,一切清楚明了。

总结:我的经验是所有的人心与人性都是相同的,你需要功能的客户其实也想看到,对于这种模式的采用,我们是经历了很多都经验后才总结出来的,

          看起来很简单,其实背后的努力不简单。一起努力做好生鲜电商。

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

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

    Java开源生鲜电商平台-团购模块设计与架构(源码可下载) 说明:任何一个电商系统中,对于促销这块是必不可少的,毕竟这块是最吸引用户的,用户也是最爱的模块之一,理由很简单,便宜. 我的经验是无论是大的 ...

  2. Java生鲜电商平台-RBAC系统权限的设计与架构

    Java生鲜电商平台-RBAC系统权限的设计与架构 说明:根据上面的需求描述以及对需求的分析,我们得知通常的一个中小型系统对于权限系统所需实现的功能以及非功能性的需求,在下面我们将根据需求从技术角度上 ...

  3. 26、生鲜电商平台-RBAC系统权限的设计与架构

    说明:根据上面的需求描述以及对需求的分析,我们得知通常的一个中小型系统对于权限系统所需实现的功能以及非功能性的需求,在下面我们将根据需求从技术角度上分析实现的策略以及基于目前两种比较流行的权限设计思想 ...

  4. Java开源生鲜电商平台-系统简介

    Java开源生鲜电商平台-系统简介 1.生鲜电商平台的价值与定位. 生鲜电商平台是一家致力于打造全国餐饮行业智能化.便利化.平台化与透明化服务的创新型移动互联网平台,连接买家与卖家之间的一个平台 看以 ...

  5. Java开源生鲜电商平台-系统架构与技术选型(源码可下载)

    Java开源生鲜电商平台-系统架构与技术选型(源码可下载) 1.  硬件环境 公司服务器 2.   软件环境 2.1  操作系统 Linux CentOS 6.8系列 2.2 反向代理/web服务器 ...

  6. 点菜网---Java开源生鲜电商平台-系统架构图(源码可下载)

    点菜网---Java开源生鲜电商平台-系统架构图(源码可下载) 1.点菜网-生鲜电商平台的价值与定位. 生鲜电商平台是一家致力于打造全国餐饮行业智能化.便利化.平台化与透明化服务的创新型移动互联网平台 ...

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

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

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

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

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

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

随机推荐

  1. 【翻译】在Ext JS 5应用程序中如何使用路由

    原文:How to Use Routing in Your Ext JS 5 Apps 简介 Ext JS 5是一个重要的发布版本,它提供了许多新特性来创建丰富的.企业级的Web应用程序.MVVM和双 ...

  2. zookeeper+kafka集群安装之二

    zookeeper+kafka集群安装之二 此为上一篇文章的续篇, kafka安装需要依赖zookeeper, 本文与上一篇文章都是真正分布式安装配置, 可以直接用于生产环境. zookeeper安装 ...

  3. UTF-8是现在流行的编码方式,根据规定回答问题

    UTF-8是现在流行的编码方式,下面是RFC2279对UTF-8编码规则的规定 UCS-4 range (hex.) UTF-8 octet sequence (binary) 0000 0000-0 ...

  4. Android特效专辑(十一)——仿水波纹流量球进度条控制器,实现高端大气的主流特效

    Android特效专辑(十一)--仿水波纹流球进度条控制器,实现高端大气的主流特效 今天看到一个效果挺不错的,就模仿了下来,加上了一些自己想要的效果,感觉还不错的样子,所以就分享出来了,话不多说,上图 ...

  5. C语言之linux内核--BCD码转二进制与二进制转BCD码(笔试经典)

    在分析代码之前,我们先来了解一下,BCD码和二进制到底区别在哪? 学习过计算机原理的和数字电子技术这两门课的都会知道这两个到底是什么含义,也有的同学学过了,考过了,过了一段时间又忘记了,今天,我们通过 ...

  6. myBatis源码学习之SqlSessionFactoryBuilder

    SqlSessionFactoryBuilder通过类名就可以看出这个类的主要作用就是创建一个SqlSessionFactory,通过输入mybatis配置文件的字节流或者字符流,生成XMLConfi ...

  7. obj-c编程10:Foundation库中类的使用(6)[线程和操作队列]

    任何语言都不能避而不谈线程这个东东,虽然他是和平台相关的鸟,虽说unix哲学比较讨厌线程的说...线程不是万能灵药,但有些场合还是需要的.谈到线程就不得不考虑同步和死锁问题,见如下代码: #impor ...

  8. iOS 字体权重weight

    UIFontWeightUltraLight  - 超细字体 UIFontWeightThin  - 纤细字体 UIFontWeightLight  - 亮字体 UIFontWeightRegular ...

  9. Access Treeview树节点代码一

    Private Sub TreeView0_Updated(Code As Integer)Dim ndeindex As NodeSet ndeindex = TreeView0.Nodes.Add ...

  10. JAVA设计模式--学习总结(序)

    设计模式(Design pattern)是一套被反复使用的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 常见的设计模式有23种.分为三大类:创建型模式, ...