# 第10章 后台管理系统

今日内容介绍

63607329175

学习目标

  • 后台系统简介
  • 搭建前端系统
  • 实现登录功能
  • 实现后台管理基本功能

1. 后台系统简介

【目标】

了解后台系统简介

【路径】

1:了解后台系统功能

2:掌握前端系统搭建

3:了解后台API文档

【讲解】

探花交友APP建立的后台管理系统,目的是完成探花交友项目的业务闭环,主要功能包括:用户管理、动态管理、审核管理已经系统管理。

1.1. 功能说明

image-20200921180145987

课程中实现的功能有:登录、首页、用户管理、动态审核。

后台管理系统:****登录、用户管理、动态管理、审核管理等

1.2. 搭建前端系统

后台系统也是采用前后端分离的方式,前端采用Vue.js实现,关于前端系统我们不进行实现,拿来直接使用。

image-20200921182328856

1.2.1. nginx安装

将资料中提供的nginx解压到没有中文没有空格的目录下(右击以管理员身份运行

image-20201111071005581

其中html目录中为,vue编译后的所有页面。

1.2.2. 配置

修改Nginx的/conf/nginx.conf配置文件:

    server {
        listen       8088;  #请求端口
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;
		

		location / {
            root   html;
            index  index.html index.htm;
        }
		
		location  /management {
			proxy_pass http://127.0.0.1:18083/;  #转发后台tanhua-manager地址
		}
		#....略
	}

1.2.3. 测试

双击nginx.exe,待启动完成后访问:http://127.0.0.1:8088即可访问后台项目

1.3. 后台的API文档

登陆:http://192.168.137.160:3000/

(1) 在yapi中创建新项目

image-20201111090709639

(2) 导入API文档数据

image-20201111090805263

【小结】

了解后台系统简介

2. 环境搭建

【目标】

了解后台系统环境搭建

【路径】

1:后台系统环境搭建

【讲解】

63607483889

2.1. 创建tanhua-manage

1、pom.xml添加依赖

    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--SpringDataRedis依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <!--lombok依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <!--工具包-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
        </dependency>
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
        </dependency>

        <!--jwt依赖-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>

        <!--fastdfs文件存储-->
        <dependency>
            <groupId>com.github.tobato</groupId>
            <artifactId>fastdfs-client</artifactId>
            <version>1.26.7</version>
            <exclusions>
                <exclusion>
                    <groupId>ch.qos.logback</groupId>
                    <artifactId>logback-classic</artifactId>
                </exclusion>
            </exclusions>
        </dependency>


        <!--dubbo的起步依赖-->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>2.7.5</version>
        </dependency>

        <!-- zookeeper的api管理依赖 -->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>4.2.0</version>
        </dependency>

        <!-- zookeeper依赖 -->
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.12</version>
        </dependency>

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.4.3</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatis.mybatis-plus}</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        
        <dependency>
            <groupId>cn.itcast</groupId>
            <artifactId>tanhua-dubbo-interface</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>cn.itcast</groupId>
            <artifactId>tanhua-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

2.2. application.yml

server:
  port: 18083

#配置redis
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/tanhua-manager?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true&useSSL=false
    username: root
    password: root
  redis:
    host: 192.168.136.160
    port: 6379
dubbo:
  application:
    name: tanhua-manage
  registry:
    address: zookeeper://192.168.136.160:2181
  consumer:
    check: false
#配置短信平台信息
tanhua:
  secret: 76bd425b6f29f7fcc2e0bfc286043df1
  #替换成自己的 oss存储信息
  sms:
    validateCodeTemplateCode: SMS_204661533
    signName: 传智
    parameterName: code
    accessKeyId: LTAI4FynsGS7V2bPJqQqrzhH
    accessKeySecret: c9fMcE7W8njMFNLJNJQT2vn5A0J1ey
  oss:
    endpoint: http://oss-cn-shenzhen.aliyuncs.com
    bucketName: tanhua
    url: https://tanhua.oss-cn-shenzhen.aliyuncs.com
    accessKeyId: LTVI4FynsGS7V2bPJqQqrzhH
    accessKeySecret: c9fDE7W8njMFNLJNJQT2vn5A0J1ey
  face:
    appId: 22837663
    apiKey: nA43galrxfUZTGtYRVK8F8tb
    secretKey: MQp567q4nGnIKfniURa2XAw8bT1SlPE3
  huanxin:
    url: http://a1.easemob.com/
    orgName: 1112190901181842
    appName: tanhua
    clientId: YXA6VggstiTmSSi_dWvqeoCg
    clientSecret: YXAvRviM513TuJLAeFTtef9Th4wo
#mybaits-plus
mybatis-plus:
  global-config:
    db-config:
      table-prefix: tb_    #数据库表前缀
      id-type: auto        #数据库表主键的策略

2.3. 启动类

package com.tanhua.manage;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration;
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
import org.springframework.cache.annotation.EnableCaching;


@SpringBootApplication(exclude = {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class})
public class ManagerServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ManagerServerApplication.class,args);
    }
}

2.4. 创建数据库

image-20201111091951573

2.5. 基础代码

将今日资料中的基础代码,拷贝到工程中

image-20201111181038446

将资料中exception统一异常处理代码和Interceptor拦截器代码copy到工程合适位置

【小结】

了解后台系统环境搭建

3. 登录

【目标】

掌握登录退出功能实现

【路径】

1:验证码功能实现

2:登录功能实现

3:用户基础信息实现

4:退出功能实现

【讲解】

后台系统的登录模块独立于APP端的登录。

表结构:

CREATE TABLE `tb_admin` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `username` varchar(255) NOT NULL COMMENT '账号',
  `password` varchar(255) NOT NULL COMMENT '密码',
  `avatar` varchar(255) DEFAULT NULL COMMENT '头像',
  `created` datetime NOT NULL COMMENT '创建时间',
  `updated` datetime NOT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `username` (`username`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='后台管理员表';

INSERT INTO `tb_admin` (`id`, `username`, `password`, `avatar`, `created`, `updated`) VALUES ('1', 'admin', 'e10adc3949ba59abbe56e057f20f883e', NULL, '2020-09-07 17:55:28', '2020-09-07 17:55:28');

3.1. 验证码

3.1.1. 接口说明

image-20200922110555409

3.1.2. AdminController

package com.tanhua.manage.controller;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import com.tanhua.manage.service.AdminService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@RestController
@RequestMapping("/system/users")
@Slf4j
public class AdminController {

    @Autowired
    private AdminService adminService;

    /**
     * 后台登陆时 图片验证码 生成
     */
    @GetMapping("/verification")
    public void showValidateCodePic(String uuid,HttpServletRequest req, HttpServletResponse res){
        res.setDateHeader("Expires",0);
        res.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
        res.addHeader("Cache-Control", "post-check=0, pre-check=0");
        // Set standard HTTP/1.0 no-cache header.
        res.setHeader("Pragma", "no-cache");
        res.setContentType("image/jpeg");
        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(299, 97);
        String code = lineCaptcha.getCode();
        log.debug("uuid={},code={}",uuid,code);
        adminService.saveCode(uuid,code);
        try {
            lineCaptcha.write(res.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3.1.3. AdminService

package com.tanhua.manage.service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tanhua.manage.domain.Admin;
import com.tanhua.manage.mapper.AdminMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Duration;

@Service
@Slf4j
public class AdminService extends ServiceImpl<AdminMapper, Admin> {

    private static final String CACHE_KEY_CAP_PREFIX = "MANAGE_CAP_";

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 保存生成的验证码
     * @param uuid
     * @param code
     */
    public void saveCode(String uuid, String code) {
        String key = CACHE_KEY_CAP_PREFIX + uuid;
        // 缓存验证码,10分钟后失效
        redisTemplate.opsForValue().set(key,code, Duration.ofMinutes(10));
    }
}

3.1.4. 测试

地址:http://localhost:8088/management/system/users/verification

61354416340

地址:http://localhost:8088/

61354422332

3.2. 登录

61461624924

3.2.1. 接口说明

image-20200922152139545

3.2.3. AdminController

    /**
     * 登录功能
     */
    @RequestMapping(value = "/login",method = RequestMethod.POST)
    public ResponseEntity login(@RequestBody Map<String,String> params){
        String username = params.get("username");
        String password = params.get("password");
        String verificationCode = params.get("verificationCode");
        String uuid = params.get("uuid");
        Map map = adminService.login(username,password,verificationCode,uuid);
        return ResponseEntity.ok(map);
    }

3.2.3. AdminService

    /**
     * 登录
     * @param username
     * @param password
     * @param verificationCode
     * @param uuid
     * @return
     */
    public Map login(String username, String password, String verificationCode, String uuid) {
        Map map = new HashMap();
        //1 校验验证码
        String key = CACHE_KEY_CAP_PREFIX + uuid;
        String redisCode = (String)redisTemplate.opsForValue().get(key);
        if(StringUtils.isEmpty(redisCode)){
            throw new BusinessException("验证码失效");
        }
        if(!redisCode.equals(verificationCode)){
            throw new BusinessException("验证码不正确");
        }
        //2 校验用户名(通用service)
        Admin admin = query().eq("username", username).one();
        if(admin == null){
            throw new BusinessException("用户名不存在");
        }
        //3 校验密码
        if(!admin.getPassword().equals(SecureUtil.md5(password))){
            throw new BusinessException("密码错误");
        }
        //4 生成token
        String token = jwtUtils.createJWT(username, admin.getId());
        map.put("token",token);
        //5 存入redis
        String tokenKey = CACHE_KEY_TOKEN_PREFIX + token;
        String adminStr = JSON.toJSONString(admin);
        redisTemplate.opsForValue().set(tokenKey,adminStr,30,TimeUnit.MINUTES);
        return map;
    }

3.3. 用户基本信息

3.3.1. 接口说明

image-20200922162833847

3.3.2. AdminController

    /**
     * 用户基本信息
     */
    @RequestMapping(value = "/profile",method = RequestMethod.POST)
    public ResponseEntity profile(){
        Admin admin = AdminHolder.getAdmin();
        AdminVo adminVo = new AdminVo();
        BeanUtils.copyProperties(admin,adminVo);
        return ResponseEntity.ok(adminVo);
    }

3.4. 退出

3.4.1. 接口说明

image-20200922215207553

3.4.2. AdminController

    /**
     * 退出
     */
    @RequestMapping(value = "/logout",method = RequestMethod.POST)
    public ResponseEntity logout(@RequestHeader("Authorization") String token){
        String headToken = token.replace("Bearer ", "");
        adminService.logout(headToken);
        return ResponseEntity.ok(null);
    }

3.4.3. AdminService


    /**
     * 登出
     * @param headToken
     */
    public void logout(String headToken) {
        String tokenKey = CACHE_KEY_TOKEN_PREFIX + headToken;
        redisTemplate.delete(tokenKey);
    }

【小结】

掌握登录退出功能实现

4. 首页

【目标】

掌握概要统计信息功能实现

【路径】

1:概要统计信息功能分析

2:概要统计信息功能实现

【讲解】

63608217966

image-20200923153755527

在首页中,显示各种的数据,比如:累计用户数、新增用户数、登录次数等内容。这些数据是需要基于用户的操作来进行统计的,所以需要建立tb_log表来记录用户的操作。

基于log表的数据进行计算,将计算的结果保存到tb_analysis_by_day表中。

4.1. 表结构

CREATE TABLE `tb_log` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `user_id` bigint(20) NOT NULL COMMENT '用户id',
  `type` varchar(255) NOT NULL COMMENT '操作类型,\r\n01为登录,0201为发动态,0202为浏览动态,0203为动态点赞,0204为动态喜欢,0205为评论,0206为动态取消点赞,0207为动态取消喜欢,0301为发小视频,0302为小视频点赞,0303为小视频取消点赞,0304为小视频评论',
  `log_time` varchar(10) DEFAULT NULL COMMENT '操作日期',
  `place` varchar(255) DEFAULT NULL COMMENT '操作地点',
  `equipment` varchar(255) DEFAULT NULL COMMENT '操作设备',
  `created` datetime DEFAULT NULL COMMENT '创建时间',
  `updated` datetime DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `time_type_user` (`log_time`,`type`,`user_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=152668 DEFAULT CHARSET=utf8 COMMENT='用户日志表';


CREATE TABLE `tb_analysis_by_day` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `record_date` date NOT NULL COMMENT '日期',
  `num_registered` int(8) NOT NULL DEFAULT '0' COMMENT '新注册用户数',
  `num_active` int(8) NOT NULL DEFAULT '0' COMMENT '活跃用户数',
  `num_login` int(8) NOT NULL DEFAULT '0' COMMENT '登陆次数',
  `num_retention1d` int(8) NOT NULL DEFAULT '0' COMMENT '次日留存用户数',
  `created` datetime NOT NULL COMMENT '创建时间',
  `updated` datetime NOT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `record_date` (`record_date`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1001 DEFAULT CHARSET=utf8;

4.2. 概要统计信息

4.2.1. 接口说明

image-20200925114000280

返回数据:

名称 类型 是否必须 默认值 备注 其他信息
cumulativeUsers integer 必须 累计用户 最大值: 500最小值: 0
activePassMonth integer 必须 过去30天活跃用户 最大值: 500最小值: 0
activePassWeek integer 必须 过去7天活跃用户 最大值: 500最小值: 0
newUsersToday integer 必须 今日新增用户 最大值: 500最小值: 0
newUsersTodayRate integer 必须 今日新增用户涨跌率,单位百分数,正数为涨,负数为跌
loginTimesToday integer 必须 今日登录次数 最大值: 500最小值: 0
loginTimesTodayRate integer 必须 今日登录次数涨跌率,单位百分数,正数为涨,负数为跌
activeUsersToday integer 必须 今日活跃用户 最大值: 500最小值: 0
activeUsersTodayRate integer 必须 今日活跃用户涨跌率,单位百分数,正数为涨,负数为跌
useTimePassWeek integer 必须 过去7天平均日使用时长,单位秒
activeUsersYesterday integer 必须 昨日活跃用户
activeUsersYesterdayRate integer 必须 昨日活跃用户涨跌率,单位百分数,正数为涨,负数为跌

4.2.2. AnalysisController

package com.tanhua.manage.controller;

import com.tanhua.manage.service.AnalysisService;
import com.tanhua.manage.vo.AnalysisSummaryVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

/**
 * 概要统计分析控制层
 */
@RestController
@RequestMapping("/dashboard")
@Slf4j
public class AnalysisController {

    @Autowired
    private AnalysisService analysisService;

    /**
     * 概要统计分析数据展示
     */
    @RequestMapping(value = "/summary",method = RequestMethod.GET)
    public ResponseEntity summary(){
        AnalysisSummaryVo analysisSummaryVo =analysisService.summary();
        return ResponseEntity.ok(analysisSummaryVo);
    }
}

4.2.3. AnalysisService

package com.tanhua.manage.service;

import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tanhua.manage.domain.AnalysisByDay;
import com.tanhua.manage.mapper.AnalysisByDayMapper;
import com.tanhua.manage.utils.ComputeUtil;
import com.tanhua.manage.vo.AnalysisSummaryVo;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTimeUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

/**
 * 概要统计业务逻辑处理类
 */
@Service
@Slf4j
public class AnalysisService extends ServiceImpl<AnalysisByDayMapper, AnalysisByDay> {

    /**
     * 概要统计分析数据展示
     */
    public AnalysisSummaryVo summary() {
        AnalysisSummaryVo vo = new AnalysisSummaryVo();
        //SELECT SUM(num_registered) as numRegistered FROM tb_analysis_by_day;
        vo.setCumulativeUsers(findCumulativeUsers());//累计用户数

        DateTime today = DateTime.now();//今天时间
        String endDate = today.toDateStr();//今天时间字符串
        String yesterday = ComputeUtil.offsetDay(today, -1);
        //计算得到30天之前时间 ComputeUtil.offsetDay(today,-30)
        //计算得到7天之前时间 ComputeUtil.offsetDay(today,-7)
        //计算得到昨天时间 ComputeUtil.offsetDay(today,-1)
        vo.setActivePassMonth(findCount("num_active", ComputeUtil.offsetDay(today,-30),endDate));//过去30天活跃用户数
        vo.setActivePassWeek(findCount("num_active", ComputeUtil.offsetDay(today,-7),endDate));//过去7天活跃用户

        Long todayNumRegistered = findCount("num_registered", endDate, endDate);//今天新增用户数量
        Long yesterdayNumRegistered = findCount("num_registered", yesterday, yesterday);//昨天新增用户数量
        vo.setNewUsersToday(todayNumRegistered);//今日新增用户数量
        vo.setNewUsersTodayRate(ComputeUtil.computeRate(todayNumRegistered,yesterdayNumRegistered));//今日新增用户涨跌率


        Long todayNumLogin = findCount("num_login", endDate, endDate);
        Long yesterdayNumLogin = findCount("num_login", yesterday, yesterday);
        vo.setLoginTimesToday(todayNumLogin);//今日登录次数
        vo.setLoginTimesTodayRate(ComputeUtil.computeRate(todayNumLogin,yesterdayNumLogin));//今日登录次数涨跌率

        Long todayNumActive = findCount("num_active", endDate, endDate);
        Long yesterdayNumActive = findCount("num_active", yesterday, yesterday);
        vo.setActiveUsersToday(todayNumActive);//今日活跃用户数量
        vo.setActiveUsersTodayRate(ComputeUtil.computeRate(todayNumActive,yesterdayNumActive));//今日活跃用户涨跌率
        return vo;
    }


    /**
     * 查询累计用户
     */
    private Long findCumulativeUsers(){
        AnalysisByDay analysisByDay = query().select("SUM(num_registered) as numRegistered").one();
        return analysisByDay.getNumRegistered().longValue();
    }


    /**
     * 过去30天活跃用户数
     * 过去7天活跃用户
     * 今日新增用户数量
     * 今日登录次数
     * 今日活跃用户数量
     *
     * 公共方法
     * 例如:SELECT SUM(num_login) AS num_active
     *    FROM tb_analysis_by_day
     *    WHERE record_date <= '2021-11-05' AND record_date >= '2021-11-05'
     */
    private Long findCount(String column,String startDate,String endDate){
        AnalysisByDay analysisByDay = query()
                .select("SUM("+column+") as numRegistered")
                .ge("record_date",startDate)
                .le("record_date",endDate)
                .one();
        return analysisByDay.getNumRegistered().longValue();
    }
}

4.2.5. 测试

postman测试

61354902367

页面效果

61354905337

4.4. 新增、活跃用户、次日留存率-作业

4.4.1. 接口说明

image-20200927114033032

返回数据:

名称 类型 是否必须 默认值 备注 其他信息
thisYear object [] 必须 本年 最小数量: 12元素是否都不同: true最大数量: 12item 类型: object
title string 必须 日期 枚举: 1,2,3,4,5,6,7,8,9,10,11,12
amount integer 必须 数量 最大值: 9999最小值: 50
lastYear object [] 必须 去年 最小数量: 12元素是否都不同: true最大数量: 12item 类型: object
title string 必须 日期 枚举: 1,2,3,4,5,6,7,8,9,10,11,12
amount integer 必须 数量 最大值: 9999最小值: 50

4.4.2. AnalysisController

    @GetMapping("/users")
    public AnalysisUsersVo getUsers(@RequestParam(name = "sd") Long sd
            , @RequestParam("ed") Long ed
            , @RequestParam("type") Integer type) {
        return this.analysisService.queryAnalysisUsersVo(sd, ed, type);
    }

4.4.3. AnalysisService

 /**
     * 新增、活跃用户、次日留存率
     */
    public AnalysisUsersVo queryAnalysisUsersVo(Long sd, Long ed, Integer type) {

        DateTime startDate = DateUtil.date(sd);

        DateTime endDate = DateUtil.date(ed);

        AnalysisUsersVo analysisUsersVo = new AnalysisUsersVo();

        //今年数据
        analysisUsersVo.setThisYear(this.queryDataPointVos(startDate, endDate, type));
        //去年数据
        analysisUsersVo.setLastYear(this.queryDataPointVos(
                DateUtil.offset(startDate, DateField.YEAR, -1),
                DateUtil.offset(endDate, DateField.YEAR, -1), type)
        );

        return analysisUsersVo;
    }

    private List<DataPointVo> queryDataPointVos(DateTime sd, DateTime ed, Integer type) {

        String startDate = sd.toDateStr();

        String endDate = ed.toDateStr();

        String column = null;
        switch (type) { //101 新增 102 活跃用户 103 次日留存率
            case 101:
                column = "num_registered";
                break;
            case 102:
                column = "num_active";
                break;
            case 103:
                column = "num_retention1d";
                break;
            default:
                column = "num_active";
                break;
        }

        List<AnalysisByDay> analysisByDayList = super.list(Wrappers.<AnalysisByDay>query()
                .select("record_date , " + column + " as num_active")
                .ge("record_date", startDate)
                .le("record_date", endDate));

        return analysisByDayList.stream()
                .map(analysisByDay -> new DataPointVo(DateUtil.date(analysisByDay.getRecordDate()).toDateStr(), analysisByDay.getNumActive().longValue()))
                .collect(Collectors.toList());
    }

4.4.4. 测试

postman测试

61355025844

页面效果

61355012645

【小结】

掌握概要统计信息功能实现

作业

1.新增、活跃用户、次日留存率

总结

1.会搭建前端环境

2.会搭建后端工程环境(掌握能够看懂工程结构 在对应包下编码 调试

3.登录功能-重点掌握

4.首页-概要统计信息-重点掌握(讲清楚整个业务流程)


5.新增、活跃用户、次日留存率-作业

posted on 2022-04-23 15:35  ofanimon  阅读(512)  评论(0编辑  收藏  举报
// 侧边栏目录 // https://blog-static.cnblogs.com/files/douzujun/marvin.nav.my1502.css