Java生鮮電商平台-系統報表設計與架構
說明:任何一個運行的平台都需要一個很清楚的報表來顯示,那么作為Java開源生鮮電商平台而言,我們應該如何設計報表呢?或者說我們希望報表來看到什么數據呢?
通過報表我們可以分析出目前整個公司的運營情況,以及下一步的調整方向,這樣更加有理有據的掌握整個市場與決策。
設計基礎維度:
1. 今日訂單,今日營業額,總訂單數,總營業額
2. 今日的注冊買家,總的注冊買家。
3. 實時的營收,實時的下單買家。
4. 今日下單買家,空降A(空降A指的是今天注冊同時下單的客戶)
數據的力量在於清楚的明白的告訴整個系統運營人員,昨天我們的銷售團隊創造了多少的業績,以及整個趨勢是怎么樣的,今天的努力方向是怎么樣的,昨天的所獲是怎么樣的
如何進行一起努力與學習。
業務分析: 今日訂單,今日營業額,總訂單數,總營業額等來源於訂單表以及訂單匯總表。鑒於數據量並不是很大,所以可以實時的進行查詢。
如果存在數據量過大,比如訂單表我們有100w的數量,那么可以采用定時器在規定的時間內進行執行,然后把統計結果放在統計表中
統計表的系統設計如下:
CREATE TABLE `report_days` ( `id` bigint(20) DEFAULT NULL, `order_number_count` int(11) DEFAULT NULL COMMENT '今日訂單數', `order_rmb_count` decimal(12,2) DEFAULT NULL COMMENT '今日營業額', `order_number_amount` int(11) DEFAULT NULL COMMENT '總訂單數', `order_rmb_amount` decimal(12,2) DEFAULT NULL COMMENT '總營業額', `create_time` datetime DEFAULT NULL COMMENT '創建時間' ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='每日報表';
說明:其實就是向這里面進行數據的更新與增加操作即可,每天進行報表的讀取與顯示
不過有些網友提出采用緩存來處理,我個人的意見是不需要。數據也沒那么多,而且都是定時器來執行,緩存的價值與意義很小。
相關的執行代碼如下:
@Component
public class TaskReport {
private static final Logger logger=LoggerFactory.getLogger(TaskReport.class);
@Autowired
private BuyerOrderReportService buyerOrderReportService;
@Autowired
private ReportDayService reportDayService;
@Autowired
private BillService billService;
/**
* 計算每天報表;
* 每日上午6:00觸發
*/
@Scheduled(cron="0 0 6 * * ?")
protected void day(){
try{
logger.info("TaskReport.day.start");
//統計每天訂單報表;
Integer today = 0;//0表示今天 1表示昨天;
reportDayService.insertBatch(today);
//統計買家每日訂單金額;
buyerOrderReportService.insertBatch(today);
}catch(Exception e){
logger.error("TaskReport.day.exception",e);
}finally {
logger.info("TaskReport.day.end");
}
}
2. 相關的報表的形狀顯示,目前折線圖,柱狀圖是比較理想的一種方式,采用百度的echarts進行顯示
相關的運行實例如下:



補充說明:相關的echarts的用法,這邊就不列舉了,的確蠻簡單的,返回json給echarts所需要的數據格式即可。
代碼這里只貼出相對核心的代碼:
public class IndexController extends BaseController {
private static final Logger logger = LoggerFactory.getLogger(IndexController.class);
@Autowired
private OrderInfoService orderInfoService;
@Autowired
private OrderItemService orderItemService;
@Autowired
private SalesService salesService;
@Autowired
private BuyerService buyerService;
@Autowired
private SellerService sellerService;
@Autowired
private ReportedService reportedService;
@RequestMapping(value = "/index", method = { RequestMethod.GET, RequestMethod.POST })
public String index(HttpServletRequest request, HttpServletResponse response, Model model, Long areaId) {
logger.info("[IndexController][index] :查詢訂單統計數據");
try {
// 查詢訂單總數量和金額
Map<String, Object> totalMap = orderInfoService.getCountAndAmount();
int totalCount = (int) totalMap.get("count");
BigDecimal totalAmount = (BigDecimal) totalMap.get("amount");
if (totalAmount == null) {
totalAmount = BigDecimal.ZERO;
}
// 查詢今日的訂單總數量和金額
Map<String, Object> todayMap = orderInfoService.getOrderCountAndAmountByToday();
int todayOrderCount = (int) todayMap.get("count");
BigDecimal todayOrderAmount = (BigDecimal) todayMap.get("amount");
if (todayOrderAmount == null) {
todayOrderAmount = BigDecimal.ZERO;
}
// 查詢實時的訂單總數量和金額
Map<String, Object> realTimeRevenueMap = orderInfoService.getRealTimeRevenueCount();
int realTimeOrderCount = (int) realTimeRevenueMap.get("count");
BigDecimal realTimeOrderAmount = (BigDecimal) realTimeRevenueMap.get("amount");
if (realTimeOrderAmount == null) {
realTimeOrderAmount = BigDecimal.ZERO;
}
// 入駐買家數量
int totalBuyerCount = buyerService.getBuyerCount(null);
// 當日注冊買家數量
int todayBuyercount = buyerService.getDailyBuyerCount();
// 當日入駐賣家數量
int todaySellerCount = sellerService.getDailySellerCount();
model.addAttribute("totalCount", totalCount);
model.addAttribute("totalAmount", totalAmount);
model.addAttribute("todayOrderCount", todayOrderCount);
model.addAttribute("todayOrderAmount", todayOrderAmount);
model.addAttribute("totalBuyerCount", totalBuyerCount);
model.addAttribute("todayBuyercount", todayBuyercount);
model.addAttribute("todaySellerCount", todaySellerCount);
model.addAttribute("realTimeOrderAmount", realTimeOrderAmount);
model.addAttribute("realTimeOrderCount", realTimeOrderCount);
// 查詢今兒下單買家數量和空降A;
int order_buyerCount = orderInfoService.getBuyerCountByTodayOrder();
int newBuyerNum = orderInfoService.getBuyerNumByThatDay();
model.addAttribute("order_buyerCount", order_buyerCount);
model.addAttribute("newBuyerNum", newBuyerNum);
Reported reported = new Reported();
reported.setrSolveStatus(1);
int count = reportedService.getCount(reported);
model.addAttribute("count", count);
} catch (Exception ex) {
logger.error("[IndexController][index] :exception", ex);
}
return "index";
}
3.對於賣家而言,我們的報表需要有以下幾個維度來統計(統計最新的TOP的賣家)
3.1 買家消費。
3. 2 賣家收入
3.3 熱賣的菜品
3.4 銷售業績
3. 5 訂單項最多的買家。

這里面也是些統計的數據,相對而言跟上面的買家維度差不多,代碼方面也類似,無外乎需要的是多點數據庫的查詢與統計即可。
總結:其實整個報表的設計與實現過程並不難,難的是你為什么要這樣設計,你通過這個運營的后台給整個項目的運營能夠帶來怎么樣的用戶體驗與指導,
你需要通過數據來診斷這個銷售團隊過程中是否存在什么問題。有沒什么刷單以及其他的作弊嫌疑在里面。
最后:很多人說系統功能很強大很好,但是我的一種思維方式是不一定,強大固然好,但是你需要通過這么多的系統數據中來分析出問題的關鍵,而不是所謂的代碼堆積。
你所需要的是思考,再思考,最終思考。

