医疗管理系统-图形报表、POI报表

2023-11-06

1. 套餐预约占比饼形图

1.1 需求分析

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

1.2 完善页面

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

1.2.1 导入ECharts库
<script src="../plugins/echarts/echarts.js"></script>
1.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/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":"获取套餐统计数据成功"
}

1.3 后台代码

1.3.1 Controller

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

@Reference
private SetmealService setmealService;
/**
 * 套餐占比统计
 * @return
 */
@RequestMapping("/getSetmealReport")
public Result getSetmealReport(){
  List<Map<String, Object>> list = setmealService.findSetmealCount();

  Map<String,Object> map = new HashMap<>();
  map.put("setmealCount",list);

  List<String> setmealNames = new ArrayList<>();
  for(Map<String,Object> m : list){
    String name = (String) m.get("name");
    setmealNames.add(name);
  }
  map.put("setmealNames",setmealNames);
  
  return new Result(true, MessageConstant.GET_SETMEAL_COUNT_REPORT_SUCCESS,map);
}
1.3.2 服务接口

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

public List<Map<String,Object>> findSetmealCount();
1.3.3 服务实现类

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

public List<Map<String, Object>> findSetmealCount() {
  return setmealDao.findSetmealCount();
}
1.3.4 Dao接口

在SetmealDao接口中扩展方法findSetmealCount

public List<Map<String,Object>> findSetmealCount();
1.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>

小结

  1. 官方实例,copy Option的配置
  2. 构造数据模型,测试
  3. 后台代码,返回经过测试的数据模型

2. 运营数据统计

—1---

2.1 需求分析

通过运营数据统计可以展示出体检机构的运营情况,包括会员数据、预约到诊数据、热门套餐等信息。本章节就是要通过一个表格的形式来展示这些运营数据。效果如下图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UBtH2axt-1609428362625)(img/2.png)]


-----1----

2.2 完善页面

运营数据统计对应的页面为/pages/report_business.html。

2.2.1 定义模型数据

定义数据模型,通过VUE的数据绑定展示数据

<script>
  var vue = new Vue({
    el: '#app',
    data:{
      reportData:{
        reportDate:null,
        todayNewMember :0,
        totalMember :0,
        thisWeekNewMember :0,
        thisMonthNewMember :0,
        todayOrderNumber :0,
        todayVisitsNumber :0,
        thisWeekOrderNumber :0,
        thisWeekVisitsNumber :0,
        thisMonthOrderNumber :0,
        thisMonthVisitsNumber :0,
        hotSetmeal :[]
      }
    }
  })
</script>
<div class="box" style="height: 900px">
  <div class="excelTitle" >
    <el-button @click="exportExcel">导出Excel</el-button>运营数据统计
  </div>
  <div class="excelTime">日期:{{reportData.reportDate}}</div>
  <table class="exceTable" cellspacing="0" cellpadding="0">
    <tr>
      <td colspan="4" class="headBody">会员数据统计</td>
    </tr>
    <tr>
      <td width='20%' class="tabletrBg">新增会员数</td>
      <td width='30%'>{{reportData.todayNewMember}}</td>
      <td width='20%' class="tabletrBg">总会员数</td>
      <td width='30%'>{{reportData.totalMember}}</td>
    </tr>
    <tr>
      <td class="tabletrBg">本周新增会员数</td>
      <td>{{reportData.thisWeekNewMember}}</td>
      <td class="tabletrBg">本月新增会员数</td>
      <td>{{reportData.thisMonthNewMember}}</td>
    </tr>
    <tr>
      <td colspan="4" class="headBody">预约到诊数据统计</td>
    </tr>
    <tr>
      <td class="tabletrBg">今日预约数</td>
      <td>{{reportData.todayOrderNumber}}</td>
      <td class="tabletrBg">今日到诊数</td>
      <td>{{reportData.todayVisitsNumber}}</td>
    </tr>
    <tr>
      <td class="tabletrBg">本周预约数</td>
      <td>{{reportData.thisWeekOrderNumber}}</td>
      <td class="tabletrBg">本周到诊数</td>
      <td>{{reportData.thisWeekVisitsNumber}}</td>
    </tr>
    <tr>
      <td class="tabletrBg">本月预约数</td>
      <td>{{reportData.thisMonthOrderNumber}}</td>
      <td class="tabletrBg">本月到诊数</td>
      <td>{{reportData.thisMonthVisitsNumber}}</td>
    </tr>
    <tr>
      <td colspan="4" class="headBody">热门套餐</td>
    </tr>
    <tr class="tabletrBg textCenter">
      <td>套餐名称</td>
      <td>预约数量</td>
      <td>占比</td>
      <td>备注</td>
    </tr>
    <tr v-for="s in reportData.hotSetmeal">
      <td>{{s.name}}</td>
      <td>{{s.setmeal_count}}</td>
      <td>{{s.proportion}}</td>
      <td></td>
    </tr>
  </table>
</div>
2.2.2 发送请求获取动态数据

在VUE的钩子函数中发送ajax请求获取动态数据,通过VUE的数据绑定将数据展示到页面

<script>
  var vue = new Vue({
    el: '#app',
    data:{
      reportData:{
        reportDate:null,
        todayNewMember :0,
        totalMember :0,
        thisWeekNewMember :0,
        thisMonthNewMember :0,
        todayOrderNumber :0,
        todayVisitsNumber :0,
        thisWeekOrderNumber :0,
        thisWeekVisitsNumber :0,
        thisMonthOrderNumber :0,
        thisMonthVisitsNumber :0,
        hotSetmeal :[]
      }
    },
    created() {
      //发送ajax请求获取动态数据
      axios.get("/report/getBusinessReportData.do").then((res)=>{
        this.reportData = res.data.data;
      });
    }
  })
</script>

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

{
  "data":{
    "todayVisitsNumber":0,
    "reportDate":"2019-04-25",
    "todayNewMember":0,
    "thisWeekVisitsNumber":0,
    "thisMonthNewMember":2,
    "thisWeekNewMember":0,
    "totalMember":10,
    "thisMonthOrderNumber":2,
    "thisMonthVisitsNumber":0,
    "todayOrderNumber":0,
    "thisWeekOrderNumber":0,
    "hotSetmeal":[
      {"proportion":0.4545,"name":"粉红珍爱(女)升级TM12项筛查体检套餐","setmeal_count":5},
      {"proportion":0.1818,"name":"阳光爸妈升级肿瘤12项筛查体检套餐","setmeal_count":2},
      {"proportion":0.1818,"name":"珍爱高端升级肿瘤12项筛查","setmeal_count":2},
      {"proportion":0.0909,"name":"孕前检查套餐","setmeal_count":1}
    ],
  },
  "flag":true,
  "message":"获取运营统计数据成功"
}

----2—

2.3 后台代码

2.3.1 Controller

在ReportController中提供getBusinessReportData方法

@Reference
private ReportService reportService;

/**
 * 获取运营统计数据
 * @return
*/
@RequestMapping("/getBusinessReportData")
public Result getBusinessReportData(){
  try {
    Map<String, Object> result = reportService.getBusinessReport();
    return new Result(true,MessageConstant.GET_BUSINESS_REPORT_SUCCESS,result);
  } catch (Exception e) {
    e.printStackTrace();
    return new Result(true,MessageConstant.GET_BUSINESS_REPORT_FAIL);
  }
}

–1—

2.3.2 服务接口

在health_interface工程中创建ReportService服务接口并声明getBusinessReport方法

package com.itheima.service;

import java.util.Map;

public interface ReportService {
    /**
     * 获得运营统计数据
     * Map数据格式:
     *      todayNewMember -> number
     *      totalMember -> number
     *      thisWeekNewMember -> number
     *      thisMonthNewMember -> number
     *      todayOrderNumber -> number
     *      todayVisitsNumber -> number
     *      thisWeekOrderNumber -> number
     *      thisWeekVisitsNumber -> number
     *      thisMonthOrderNumber -> number
     *      thisMonthVisitsNumber -> number
     *      hotSetmeals -> List<Setmeal>
     */
    public Map<String,Object> getBusinessReport() throws Exception;
}
2.3.3 服务实现类

在health_service_provider工程中创建服务实现类ReportServiceImpl并实现ReportService接口

package com.itheima.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.itheima.dao.MemberDao;
import com.itheima.dao.OrderDao;
import com.itheima.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 统计报表服务
 */
@Service(interfaceClass = ReportService.class)
@Transactional
public class ReportServiceImpl implements ReportService {
    @Autowired
    private MemberDao memberDao;
    @Autowired
    private OrderDao orderDao;

    /**
     * 获得运营统计数据
     * Map数据格式:
     *      todayNewMember -> number
     *      totalMember -> number
     *      thisWeekNewMember -> number
     *      thisMonthNewMember -> number
     *      todayOrderNumber -> number
     *      todayVisitsNumber -> number
     *      thisWeekOrderNumber -> number
     *      thisWeekVisitsNumber -> number
     *      thisMonthOrderNumber -> number
     *      thisMonthVisitsNumber -> number
     *      hotSetmeal -> List<Setmeal>
     */
    public Map<String, Object> getBusinessReport() throws Exception{
        //获得当前日期
        String today = DateUtils.parseDate2String(DateUtils.getToday());
        //获得本周一的日期
        String thisWeekMonday = DateUtils.parseDate2String(DateUtils.getThisWeekMonday());
        //获得本月第一天的日期  
        String firstDay4ThisMonth = 
                            DateUtils.parseDate2String(DateUtils.getFirstDay4ThisMonth());

        //今日新增会员数
        Integer todayNewMember = memberDao.findMemberCountByDate(today);

        //总会员数
        Integer totalMember = memberDao.findMemberTotalCount();

        //本周新增会员数
        Integer thisWeekNewMember = memberDao.findMemberCountAfterDate(thisWeekMonday);

        //本月新增会员数
        Integer thisMonthNewMember = memberDao.findMemberCountAfterDate(firstDay4ThisMonth);

        //今日预约数
        Integer todayOrderNumber = orderDao.findOrderCountByDate(today);

        //本周预约数
        Integer thisWeekOrderNumber = orderDao.findOrderCountAfterDate(thisWeekMonday);

        //本月预约数
        Integer thisMonthOrderNumber = orderDao.findOrderCountAfterDate(firstDay4ThisMonth);

        //今日到诊数
        Integer todayVisitsNumber = orderDao.findVisitsCountByDate(today);

        //本周到诊数
        Integer thisWeekVisitsNumber = orderDao.findVisitsCountAfterDate(thisWeekMonday);

        //本月到诊数
        Integer thisMonthVisitsNumber = orderDao.findVisitsCountAfterDate(firstDay4ThisMonth);

        //热门套餐(取前4)
        List<Map> hotSetmeal = orderDao.findHotSetmeal();

        Map<String,Object> result = new HashMap<>();
        result.put("reportDate",today);
        result.put("todayNewMember",todayNewMember);
        result.put("totalMember",totalMember);
        result.put("thisWeekNewMember",thisWeekNewMember);
        result.put("thisMonthNewMember",thisMonthNewMember);
        result.put("todayOrderNumber",todayOrderNumber);
        result.put("thisWeekOrderNumber",thisWeekOrderNumber);
        result.put("thisMonthOrderNumber",thisMonthOrderNumber);
        result.put("todayVisitsNumber",todayVisitsNumber);
        result.put("thisWeekVisitsNumber",thisWeekVisitsNumber);
        result.put("thisMonthVisitsNumber",thisMonthVisitsNumber);
        result.put("hotSetmeal",hotSetmeal);

        return result;
    }
}
2.3.4 Dao接口

在OrderDao和MemberDao中声明相关统计查询方法

package com.itheima.dao;

import com.itheima.pojo.Order;
import java.util.List;
import java.util.Map;

public interface OrderDao {
    public void add(Order order);
    public List<Order> findByCondition(Order order);
    public Map findById4Detail(Integer id);
    public Integer findOrderCountByDate(String date);
    public Integer findOrderCountAfterDate(String date);
    public Integer findVisitsCountByDate(String date);
    public Integer findVisitsCountAfterDate(String date);
    public List<Map> findHotSetmeal();
}
package com.itheima.dao;

import com.github.pagehelper.Page;
import com.itheima.pojo.Member;
import java.util.List;

public interface MemberDao {
    public List<Member> findAll();
    public Page<Member> selectByCondition(String queryString);
    public void add(Member member);
    public void deleteById(Integer id);
    public Member findById(Integer id);
    public Member findByTelephone(String telephone);
    public void edit(Member member);
    public Integer findMemberCountBeforeDate(String date);
    public Integer findMemberCountByDate(String date);
    public Integer findMemberCountAfterDate(String date);
    public Integer findMemberTotalCount();
}
  1. count(1)比count(*) 效率高
2.3.5 Mapper映射文件

在OrderDao.xml和MemberDao.xml中定义SQL语句

OrderDao.xml:

<!--根据日期统计预约数-->
<select id="findOrderCountByDate" parameterType="string" resultType="int">
  select count(id) from t_order where orderDate = #{value}
</select>

<!--根据日期统计预约数,统计指定日期之后的预约数-->
<select id="findOrderCountAfterDate" parameterType="string" resultType="int">
  select count(id) from t_order where orderDate &gt;= #{value}
</select>

<!--根据日期统计到诊数-->
<select id="findVisitsCountByDate" parameterType="string" resultType="int">
  select count(id) from t_order where orderDate = #{value} and orderStatus = '已到诊'
</select>

<!--根据日期统计到诊数,统计指定日期之后的到诊数-->
<select id="findVisitsCountAfterDate" parameterType="string" resultType="int">
  select count(id) from t_order where orderDate &gt;= #{value} and orderStatus = '已到诊'
</select>

<!--热门套餐,查询前4条-->
<select id="findHotSetmeal" resultType="map">
  select 
      s.name, 
      count(o.id) setmeal_count ,
      count(o.id)/(select count(id) from t_order) proportion
    from t_order o inner join t_setmeal s on s.id = o.setmeal_id
    group by o.setmeal_id
    order by setmeal_count desc 
    limit 0,4
</select>

MemberDao.xml:

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

<!--根据日期统计会员数-->
<select id="findMemberCountByDate" parameterType="string" resultType="int">
  select count(id) from t_member where regTime = #{value}
</select>

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

<!--总会员数-->
<select id="findMemberTotalCount" resultType="int">
  select count(id) from t_member
</select>
 SELECT a.name,count(b.id) as setmeal_count, (count(b.id)/(select count(1) from t_order)) as proportion,a.remark FROM
        t_setmeal a ,t_order b where a.id = b.setmeal_id 
				group by a.id
				order by setmeal_count DESC
				limit 2

 SELECT a.name,count(b.id) as setmeal_count, (count(b.id)/(select count(1) from t_order)) as proportion,a.remark FROM
        t_order b right join t_setmeal a on a.id = b.setmeal_id 
				group by a.id
				order by setmeal_count DESC
			

				
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

医疗管理系统-图形报表、POI报表 的相关文章

随机推荐

  • 顺序表的基本操作(C语言实现)

    顺序表 前言 本文主要讲线性表的其中一种 那就是顺序表 顺序表就是采用顺序储存方式来存储数据 所谓顺序存储 就是数据在内存上的地址同样为连续储存 中间不允许有空 有间隔 顺序表的优点在于支持随机访问 就是通过下标来访问元素 缺点是插入 删除
  • iBatis resultMap报错 nullValue完美解决

    错误信息 SQLErrorCodesFactory Database product name cached for DataSource org apache commons dbcp BasicDataSource 19c5048 na
  • OSWatcher.sh脚本说明

    OSWatcher sh脚本位于oswbb目录下 Oracle 19c数据库中脚本的路径是 u01 app oracle product 19 0 0 dbhome 1 suptools tfa release tfa home ext o
  • Maven中dependencyManagement作用说明

    备注 今天有好些实习的同事问到Maven中关于dependencyManagement和普通dependencies的区别 说多了 麻烦 记录一下 在Maven多模块的时候 管理依赖关系是非常重要的 各种依赖包冲突 查询问题起来非常复杂 于
  • python网络爬虫有那些实例_python爬虫经典例子有哪些

    python爬虫例子 首先导入爬虫的库 生成一个response对象 然后设置编码格式 并打印状态码 最后输出爬取的信息 代码为 print response text python爬虫例子 1 爬取强大的BD页面 打印页面信息 第一个爬虫
  • 毕业设计-基于机器视觉的焊缝图像处理研究- OpenCV

    目录 前言 课题背景和意义 实现技术思路 一 焊缝识别系统设计 二 焊缝图像预处理 实现效果图样例 最后 前言 大四是整个大学期间最忙碌的时光 一边要忙着备考或实习为毕业后面临的就业升学做准备 一边要为毕业设计耗费大量精力 近几年各个学校要
  • 设置读取plc时间_Visual Studio 2010-C#跟西门子1200(Sharp7)窗体控制④-循环读取

    Visual Studio 2010 C 跟西门子1200 Sharp7 窗体控制 循环读取 上期回顾 上期主要是对单个按钮 按下后能够同时置位PLC的多个位 本期做一个读取PLC的OK NOK的统计数据的C 标签 先创建一个标签 在设定一
  • SpringBoot:@Schedule定时任务

    一 Schedule SpringBoot内置了Sping Schedule定时框架 通过注解驱动方式添加所注解方法到定时任务 根据配置定时信息定时执行 二 定时任务实现 1 开启定时任务 package com gupao springb
  • 使用VBA在工作表中快速插入行

    在工作表中插入行 有需要用到代码吗 是不是杀鸡用牛刀的感觉 其实不是这样的 在很多复杂的应用场景中 插入行不再是简单的单击鼠标右键就可以即刻完成的 比如需要隔行插入空行 如果有一万行数据 是不是搞到手抽筋了 再比如插入空行的数量不是固定的
  • 自动记录数据录入时间不懂得VBA的朋友可以看看

    在日常工作中 经常会遇到需要实时记录数据录入的时间问题 有朋友会说了 用快捷键啊 按Ctrl 分号 可以返回当前的系统日期 按Ctrl Shift 分号 可以返回当前的系统时间 但是如果需要同时返回日期和时间又该怎么处理呢 对于懂得VBA的
  • 关于对Vue中slot插槽理解

    关于slot插槽理解 1 何时需要使用插槽 在开发中 我们需要将共性内容抽取到组件中 将不同的暴露为插槽 插槽的益处便是 一旦预留了插槽 使用者便可以根据自己的需求来决定插槽中插入的的内容 2 slot的基本使用 div div
  • 软件测试之网络协议基础

    软件测试之网络协议基础 前言 我会在此账号上持续更新 软件测试的文章 包括网络部分 前端代码部分 数据库部分 软件测试部分 互联网协议 osi 7层协议 tcp ip 5层协议 网络协议的存在是为了两者中间根据一定的协议沟通交流 每层运行常
  • 光线跟踪(RayTracing)原理及c++实现

    Chapt1 Why to write a RayTracing Render 提到Computer Graphics 众所周知的是如OpenGL Direct3D这样非常流行的光栅化渲染器 事实上 这些大部分应用于游戏制作的API主要为实
  • Flutter控件——布局控件:层叠

    Stack 层叠布局 Android 中的 Frame 布局是相似的 子组件可以根据距父容器四个角的位置来确定自身的位置 层叠布局允许子组件按照代码中声明的顺序堆叠起来 Flutter中使用Stack和Positioned这两个组件来配合实
  • 怎么关闭win10虚拟机服务器,win10系统彻底关闭退出vmware虚拟机的步骤

    有关win10系统彻底关闭退出vmware虚拟机的操作方法想必大家有所耳闻 但是能够对win10系统彻底关闭退出vmware虚拟机进行实际操作的人却不多 其实解决win10系统彻底关闭退出vmware虚拟机的问题也不是难事 小编这里提示两点
  • 数十万条以上的大量数据如何快速插入数据库中

    引言 这几天工作这边同事遇到了一个问题 对十五万条数据进行计算 插入数据库的时候耗时很严重 使用了批量插入对十五万条数据插入仍然耗费了30秒 前面计算也耗费了二十多秒 系统流畅度因此很难堪 经过我的排查发现主要是两个点需要优化 1 计算的算
  • 关于STM32在线升级文件大或者跳转后中断有问题的解决方法(IAR环境)

    首先 大家都知道是跳转到每个程序的复位中断地址 一开始我的IAR环境的启动文件是没有复位中断地址的 可以去IAR官网随便下载一个重新覆盖掉启动文件 当然还得看你的外设中断有没有包含 或者有多的要去掉 DCD Handler类型的 如果遇到I
  • 怎样在 Markdown 中使程序代码带上行号

    在图灵社区使用 Markdown 写文章时 如果在一段文字的每行开头加上四个空格 或者一个制表符 Tab 这段文字就会被视为程序代码 这样 就会自动识别所用的编程语言 进行代码染色 语法高亮显示 但是 如果这段程序很长的话 就有两个小问题
  • 假设检验,显著性,置信水平,p值,点估计

    1 为什么需要假设检验 以下图激光器项目为例子 抽样30个 改善前720mw 改善后723mw 有一点提升 提升小 可能是正常的波动 所以不一定真的提升了 所以到底是正常波动还是真的改善了 需要结合功率标准差进行分析 标准差决定了波动的情况
  • 医疗管理系统-图形报表、POI报表

    目录 1 套餐预约占比饼形图 1 1 需求分析 1 2 完善页面 1 2 1 导入ECharts库 1 2 2 参照官方实例导入饼形图 1 3 后台代码 1 3 1 Controller 1 3 2 服务接口 1 3 3 服务实现类 1 3