電商平臺-系統報表設計與架構
說明:任何一個執行的平臺都需要一個很清楚的報表來顯示,那麼作為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 訂單項最多的買家。
這裡面也是些統計的資料,相對而言跟上面的買家維度差不多,程式碼方面也類似,無外乎需要的是多點資料庫的查詢與統計即可。
總結:其實整個報表的設計與實現過程並不難,難的是你為什麼要這樣設計,你通過這個運營的後臺給整個專案的運營能夠帶來怎麼樣的使用者體驗與指導,
你需要通過資料來診斷這個銷售團隊過程中是否存在什麼問題。有沒什麼刷單以及其他的作弊嫌疑在裡面。