Commit 098fefc9 authored by Junling Bu's avatar Junling Bu
Browse files

feature[litemall-admin, litemall-admin-api]:实现几个统计页面和效果。

parent d55d5d3f
package org.linlinjava.litemall.admin.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class StatVo {
private String[] columns = new String[0];
private List<Map> rows = new ArrayList<>();
public String[] getColumns() {
return columns;
}
public void setColumns(String[] columns) {
this.columns = columns;
}
public List<Map> getRows() {
return rows;
}
public void setRows(List<Map> rows) {
this.rows = rows;
}
public void add(Map ... r) {
rows.addAll(Arrays.asList(r));
}
}
package org.linlinjava.litemall.admin.web;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.linlinjava.litemall.admin.annotation.LoginAdmin;
import org.linlinjava.litemall.admin.util.StatVo;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.dao.StatMapper;
import org.linlinjava.litemall.db.service.LitemallOrderService;
import org.linlinjava.litemall.db.service.StatService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/admin/stat")
public class AdminStatController {
private final Log logger = LogFactory.getLog(AdminStatController.class);
@Autowired
private StatService statService;
@GetMapping("/user")
public Object statUser(@LoginAdmin Integer adminId){
if(adminId == null){
return ResponseUtil.unlogin();
}
List<Map> rows = statService.statUser();
String[] columns = new String[]{"day", "users"};
StatVo statVo = new StatVo();
statVo.setColumns(columns);
statVo.setRows(rows);
return ResponseUtil.ok(statVo);
}
@GetMapping("/order")
public Object statOrder(@LoginAdmin Integer adminId){
if(adminId == null){
return ResponseUtil.unlogin();
}
List<Map> rows = statService.statOrder();
String[] columns = new String[]{"day", "orders", "customers", "amount", "pcr"};
StatVo statVo = new StatVo();
statVo.setColumns(columns);
statVo.setRows(rows);
return ResponseUtil.ok(statVo);
}
@GetMapping("/goods")
public Object statGoods(@LoginAdmin Integer adminId){
if(adminId == null){
return ResponseUtil.unlogin();
}
List<Map> rows = statService.statGoods();
String[] columns = new String[]{"day", "orders", "products", "amount"};
StatVo statVo = new StatVo();
statVo.setColumns(columns);
statVo.setRows(rows);
return ResponseUtil.ok(statVo);
}
}
......@@ -13,9 +13,10 @@
"test": "npm run lint"
},
"dependencies": {
"@tinymce/tinymce-vue": "^1.0.8",
"axios": "0.17.1",
"clipboard": "1.7.1",
"echarts": "3.8.5",
"echarts": "^4.1.0",
"element-ui": "2.0.8",
"file-saver": "1.3.3",
"font-awesome": "4.7.0",
......@@ -24,13 +25,13 @@
"normalize.css": "7.0.0",
"nprogress": "0.2.0",
"screenfull": "3.3.2",
"v-charts": "^1.16.19",
"vue": "2.5.10",
"vue-count-to": "1.0.13",
"vue-router": "3.0.1",
"vue-splitpane": "1.0.2",
"vuex": "3.0.1",
"xlsx": "^0.11.16",
"@tinymce/tinymce-vue": "1.0.8"
"xlsx": "^0.11.16"
},
"devDependencies": {
"autoprefixer": "7.2.3",
......
import request from '@/utils/request'
export function statUser(query) {
return request({
url: '/stat/user',
method: 'get',
params: query
})
}
export function statOrder(query) {
return request({
url: '/stat/order',
method: 'get',
params: query
})
}
export function statGoods(query) {
return request({
url: '/stat/goods',
method: 'get',
params: query
})
}
......@@ -106,6 +106,7 @@ export const asyncRouterMap = [
{ path: 'comment', component: _import('goods/comment'), name: 'comment', meta: { title: '用户评论', noCache: true }}
]
},
{
path: '/promotion',
component: Layout,
......@@ -120,6 +121,7 @@ export const asyncRouterMap = [
{ path: 'topic', component: _import('promotion/topic'), name: 'topic', meta: { title: '专题管理', noCache: true }}
]
},
{
path: '/sys',
component: Layout,
......@@ -135,5 +137,21 @@ export const asyncRouterMap = [
]
},
{
path: '/stat',
component: Layout,
redirect: 'noredirect',
name: 'statManage',
meta: {
title: '统计',
icon: 'chart'
},
children: [
{ path: 'user', component: _import('stat/user'), name: 'statUser', meta: { title: '用户统计', noCache: true }},
{ path: 'order', component: _import('stat/order'), name: 'statOrder', meta: { title: '订单统计', noCache: true }},
{ path: 'goods', component: _import('stat/goods'), name: 'statGoods', meta: { title: '商品统计', noCache: true }}
]
},
{ path: '*', redirect: '/404', hidden: true }
]
<template>
<div class="app-container calendar-list-container">
<ve-line :extend="chartExtend" :data="chartData" :settings="chartSettings"></ve-line>
</div>
</template>
<script>
import { statGoods } from '@/api/stat'
import VeLine from 'v-charts/lib/line'
export default {
components: { VeLine },
data() {
return {
chartData: {},
chartSettings: {},
chartExtend: {}
}
},
created() {
statGoods().then(response => {
this.chartData = response.data.data
this.chartSettings = {
labelMap: {
'orders': '订单量',
'products': '下单货品数量',
'amount': '下单货品总额'
}
}
this.chartExtend = {
xAxis: { boundaryGap: true }
}
})
}
}
</script>
\ No newline at end of file
<template>
<div class="app-container calendar-list-container">
<ve-line :extend="chartExtend" :data="chartData" :settings="chartSettings"></ve-line>
</div>
</template>
<script>
import { statOrder } from '@/api/stat'
import VeLine from 'v-charts/lib/line'
export default {
components: { VeLine },
data() {
return {
chartData: {},
chartSettings: {},
chartExtend: {}
}
},
created() {
statOrder().then(response => {
this.chartData = response.data.data
this.chartSettings = {
labelMap: {
'orders': '订单量',
'customers': '下单用户',
'amount': '订单总额',
'pcr': '客单价'
}
}
this.chartExtend = {
xAxis: { boundaryGap: true }
}
})
}
}
</script>
\ No newline at end of file
<template>
<div class="app-container calendar-list-container">
<ve-histogram :extend="chartExtend" :data="chartData" :settings="chartSettings"></ve-histogram>
</div>
</template>
<script>
import { statUser } from '@/api/stat'
import VeHistogram from 'v-charts/lib/histogram'
export default {
components: { VeHistogram },
data() {
return {
chartData: {},
chartSettings: {},
chartExtend: {}
}
},
created() {
statUser().then(response => {
this.chartData = response.data.data
this.chartSettings = {
labelMap: {
'users': '用户增长数'
}
}
this.chartExtend = {
xAxis: { boundaryGap: true },
series: {
label: { show: true, position: 'top' }
}
}
})
}
}
</script>
\ No newline at end of file
package org.linlinjava.litemall.db.dao;
import org.apache.ibatis.annotations.Param;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public interface StatMapper {
List<Map> statUser();
List<Map> statOrder();
List<Map> statGoods();
}
\ No newline at end of file
package org.linlinjava.litemall.db.service;
import com.github.pagehelper.PageHelper;
import org.linlinjava.litemall.db.dao.LitemallUserMapper;
import org.linlinjava.litemall.db.dao.StatMapper;
import org.linlinjava.litemall.db.domain.LitemallUser;
import org.linlinjava.litemall.db.domain.LitemallUserExample;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
@Service
public class StatService {
@Resource
private StatMapper statMapper;
public List<Map> statUser() {
return statMapper.statUser();
}
public List<Map> statOrder(){
return statMapper.statOrder();
}
public List<Map> statGoods(){
return statMapper.statGoods();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.linlinjava.litemall.db.dao.StatMapper">
<select id="statUser" resultType="map">
select
substr(add_time,1,10) as day,
count(distinct id) as users
from litemall_user
group by substr(add_time,1,10)
</select>
<select id="statOrder" resultType="map">
select
substr(add_time,1,10) as day,
count(id) as orders,
count(distinct user_id) as customers,
sum(actual_price) as amount,
round(sum(actual_price)/count(distinct user_id),2) as pcr
from litemall_order
where order_status in(103)
group by substr(add_time,1,10)
</select>
<select id="statGoods" resultType="map">
select
substr(add_time,1, 10) as day,
count(distinct order_id) as orders,
sum(number) as products,
sum(number*retail_price) as amount
from litemall_order_goods
group by substr(add_time,1, 10)
</select>
</mapper>
\ No newline at end of file
package org.linlinjava.litemall.db;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.linlinjava.litemall.db.dao.StatMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import java.util.List;
import java.util.Map;
@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class StatMapperTest {
@Autowired
private StatMapper statMapper;
@Test
public void testUser() {
List<Map> result = statMapper.statUser();
for(Map m : result) {
m.forEach((k, v) -> System.out.println("key:value = " + k + ":" + v));
}
}
@Test
public void testOrder() {
List<Map> result = statMapper.statOrder();
for(Map m : result) {
m.forEach((k, v) -> System.out.println("key:value = " + k + ":" + v));
}
}
@Test
public void testGoods() {
List<Map> result = statMapper.statGoods();
for(Map m : result) {
m.forEach((k, v) -> System.out.println("key:value = " + k + ":" + v));
}
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment