船志健康项目-会员数量、套餐预约占比-图形报表10

一、会员数量折线图

1. 需求分析

 会员信息是体检机构的核心数据,其会员数量和增长数量可以反映出机构的部分运营情况。通过折线图可以直观的反映出会员数量的增长趋势。本章节我们需要展示过去一年时间内每个月的会员总数据量。展示效果如下图:

  image

2. 完善页面

 会员数量折线图对应的页面为/pages/report_member.html。

 2.1 导入ECharts库

  第一步:将echarts.js文件复制到health_backend工程的webapp/js目录下

  第二步:在report_member.html页面引入echarts.js文件

<script src="../js/echarts.js"></script>

 2.2 参照官方实例导入折线图

<div class="box">
  <!-- 为 ECharts 准备一个具备大小(宽高)的 DOM -->
  <div id="chart1" style="height:600px;"></div>
</div>
    <script type="text/javascript">
        // 基于准备好的dom,初始化echarts实例
        var myChart1 = echarts.init(document.getElementById('chart1'));

        //发送ajax请求获取动态数据
        axios.get("/report/getMemberReport.do").then((res)=>{
            myChart1.setOption(
                                {
                                    title: {
                                        text: '会员数量'
                                    },
                                    tooltip: {},
                                    legend: {
                                        data:['会员数量']
                                    },
                                    xAxis: {
                                        data: res.data.data.months  //动态数据
                                    },
                                    yAxis: {
                                        type:'value'
                                    },
                                    series: [{
                                        name: '会员数量',
                                        type: 'line',
                                        data: res.data.data.memberCount
                                    }]
                                });
        });
    </script>

  根据折线图对数据格式的要求,我们发送ajax请求,服务端需要返回如下格式的数据:

{
 "data":{
 "months":["2019.01","2019.02","2019.03","2019.04"],
 "memberCount":[3,4,8,10]
   },
 "flag":true,
 "message":"获取会员统计数据成功"
}

3. 后台代码

 3.1 Controller

  在health_backend工程中创建ReportController并提供getMemberReport方法

package com.itheima.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.itheima.constant.MessageConstant;
import com.itheima.entity.Result;
import com.itheima.service.MemberService;
import com.itheima.service.ReportService;
import com.itheima.service.SetmealService;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
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.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 报表操作
 */
@RestController
@RequestMapping("/report")
public class ReportController {

    @Reference
    private MemberService memberService;

    @RequestMapping("/getMemberReport")
    public Result getMemberReport(){
        //使用模拟数据测试对象格式是否能够转为echarts所需的数据格式
        Map<String,Object> map = new HashMap<>();
        List<String> months = new ArrayList<>();
        //计算过去一年的12个月
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH,-12);//获得当前日期之前12个月的日期
        for(int i=0;i<12;i++){
            calendar.add(Calendar.MONTH,1); //获得calendar当前时间往后推1个月日期
            Date date = calendar.getTime();
            months.add(new SimpleDateFormat("yyyy.MM").format(date));
        }
        map.put("months",months);

        List<Integer> memberCount = memberService.findMemberCountByMonth(months);
        map.put("memberCount",memberCount);
        return new Result(true, MessageConstant.GET_MEMBER_NUMBER_REPORT_SUCCESS,map);
    }
}

 3.2 服务接口

  在MemberService服务接口中扩展方法findMemberCountByMonth

public List<Integer> findMemberCountByMonth(List<String> months);

 3.3 服务实现类

  在MemberServiceImpl服务实现类中实现findMemberCountByMonth方法

    //统计指定日期之前的会员数(根据月份统计会员数量)
    @Override
    public List<Integer> findMemberCountByMonth(List<String> months) {
        List<Integer> memberCount = new ArrayList<>();
        for (String month : months) {
            String date = month+".31";
            Integer count = memberDao.findMemberCountBeforeDate(date);
            memberCount.add(count);
        }
        return memberCount;
    }

 3.4 Dao接口

  在MemberDao接口中扩展方法findMemberCountBeforeDate

public Integer findMemberCountBeforeDate(String date);

 3.5 Mapper映射文件

  在MemberDao.xml映射文件中提供SQL语句

    <!--根据日期统计会员数,统计指定日期之前的会员数-->
    <select id="findMemberCountBeforeDate" parameterType="string" resultType="int">
        select count(id) from t_member where regTime &lt;= #{value}
    </select>

二、套餐预约占比饼形图

1. 需求分析

 会员可以通过移动端自助进行体检预约,在预约时需要选择预约的体检套餐。本章节我们需要通过饼形图直观的展示出会员预约的各个套餐占比情况。展示效果如下图:

  image

2. 完善页面

 套餐预约占比饼形图对应的页面为/pages/report_setmeal.html。

 2.1 导入ECharts库

<script src="../js/echarts.js"></script>

 2.2 参照官方实例导入饼形图

<div class="box">
  <!-- 为 ECharts 准备一个具备大小(宽高)的 DOM -->
  <div id="chart1" style="height:600px;"></div>
</div>
    <script type="text/javascript">
        // 基于准备好的dom,初始化echarts实例
        var myChart1 = echarts.init(document.getElementById('chart1'));

        axios.get("/report/getSetmealReport.do").then((res)=>{
            myChart1.setOption({
                                    title : {
                                        text: '套餐预约占比',
                                        subtext: '',
                                        x:'center'
                                    },
                                    tooltip : {//提示框组件
                                        trigger: 'item',//触发类型,在饼形图中为item
                                        formatter: "{a} <br/>{b} : {c} ({d}%)"//提示内容格式
                                    },
                                    legend: {//图例
                                        orient: 'vertical',
                                        left: 'left',
                                        data: res.data.data.setmealNames
                                    },
                                    series : [//数据系列
                                        {
                                            name: '套餐预约占比',
                                            type: 'pie',//饼形图
                                            radius : '55%',
                                            center: ['50%', '60%'],
                                            data:res.data.data.setmealCount,
                                            itemStyle: {
                                                emphasis: {
                                                    shadowBlur: 10,
                                                    shadowOffsetX: 0,
                                                    shadowColor: 'rgba(0, 0, 0, 0.5)'
                                                }
                                            }
                                        }
                                    ]
                                });
        });
    </script>

  根据饼形图对数据格式的要求,我们发送ajax请求,服务端需要返回如下格式的数据:

{
 "data":{
 "setmealNames":["套餐1","套餐2","套餐3"],
 "setmealCount":[
 {"name":"套餐1","value":10},
 {"name":"套餐2","value":30},
 {"name":"套餐3","value":25}
   ]
   },
 "flag":true,
 "message":"获取套餐统计数据成功"
}

3. 后台代码

 3.1 Controller

  在health_backend工程的ReportController中提供getSetmealReport方法

    @Reference
    private SetmealService setmealService;

    @RequestMapping("/getSetmealReport")
    public Result getSetmealReport(){

        Map<String,Object> map = new HashMap<>();

        try{
            List<Map<String,Object>> setmealCount = setmealService.findSetmealCount();
            System.out.println("setmealCount:"+setmealCount);
            map.put("setmealCount",setmealCount);

            List<String> setmealNames = new ArrayList<>();
            for (Map<String, Object> m : setmealCount) {
                String name = (String) m.get("name");
                setmealNames.add(name);
            }
            map.put("setmealNames",setmealNames);
            return new Result(true, MessageConstant.GET_SETMEAL_COUNT_REPORT_SUCCESS,map);
        }catch (Exception e){
            return new Result(false,MessageConstant.GET_SETMEAL_COUNT_REPORT_FAIL);
        }
    }

 3.2 服务接口

  在SetmealService服务接口中扩展方法findSetmealCount

public List<Map<String, Object>> findSetmealCount();

 3.3 服务实现类

  在SetmealServiceImpl服务实现类中实现findSetmealCount方法

    //查询套餐预约占比数据
    @Override
    public List<Map<String, Object>> findSetmealCount() {
        return setmealDao.findSetmealCount();
    }

 3.4 Dao接口

  在SetmealDao接口中扩展方法findSetmealCount

public List<Map<String, Object>> findSetmealCount();

 3.5 Mapper映射文件

  在SetmealDao.xml映射文件中提供SQL语句

    <select id="findSetmealCount" resultType="map">
        select s.name,count(o.id) as value from t_order o,t_setmeal s where o.setmeal_id = s.id group by s.name;
    </select>

 

posted on 2025-11-29 04:18  花溪月影  阅读(1)  评论(0)    收藏  举报