尚医通 (三十七) --------- 定时任务与统计

news2024/9/22 15:41:30

目录

  • 一、就医提醒
    • 1. 搭建定时任务模块 service-task
    • 2. 添加就医提醒处理
  • 二、预约统计
    • 1. ECharts
    • 2. 获取医院每天平台预约数据接口
    • 3. 添加 feign 方法
    • 4. 搭建 service-statistics
    • 5. 前端展示


一、就医提醒

我们通过定时任务,每天 8 点执行,提醒就诊。

1. 搭建定时任务模块 service-task

A、搭建 service-task 服务

搭建方式如 service-user

B、修改配置 pom.xml

<dependencies>
    <dependency>
        <groupId>com.fancy.yygh</groupId>
        <artifactId>rabbit-util</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>
</dependencies>

说明:引入依赖

C、添加配置文件

application.properties

# 服务端口
server.port=8207
# 服务名
spring.application.name=service-task
# 环境设置:dev、test、prod
spring.profiles.active=dev

# nacos服务地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848

#rabbitmq地址
spring.rabbitmq.host=192.168.44.165
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest

D、添加启动类

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)//取消数据源自动配置
@EnableDiscoveryClient
public class ServiceTaskApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceTaskApplication.class, args);
    }
}

E、添加常量配置

在 rabbit-util 模块 com.fancy.yygh.common.constant.MqConst 类添加

public static final String EXCHANGE_DIRECT_TASK = "exchange.direct.task";
public static final String ROUTING_TASK_8 = "task.8";
//队列
public static final String QUEUE_TASK_8 = "queue.task.8";

F、添加定时任务

Cron 表达式

在这里插入图片描述

@Component
@EnableScheduling
public class ScheduledTask {

    @Autowired
    private RabbitService rabbitService;

    /**
     * 每天8点执行 提醒就诊
     */
    //@Scheduled(cron = "0 0 1 * * ?")
    @Scheduled(cron = "0/30 * * * * ?")
    public void task1() {
        rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_TASK, MqConst.ROUTING_TASK_8, "");
    }
}

2. 添加就医提醒处理

操作模块 service-order

A、添加 service 接口

在 OrderService 类添加接口

/**
 * 就诊提醒
 */
void patientTips();

B、添加 service 接口实现类

在 OrderServiceImpl 类添加接口实现

@Override
public void patientTips() {
    QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("reserve_date",new DateTime().toString("yyyy-MM-dd"));
    List<OrderInfo> orderInfoList = baseMapper.selectList(queryWrapper);
    for(OrderInfo orderInfo : orderInfoList) {
        //短信提示
        MsmVo msmVo = new MsmVo();
        msmVo.setPhone(orderInfo.getPatientPhone());
        String reserveDate = new DateTime(orderInfo.getReserveDate()).toString("yyyy-MM-dd") + (orderInfo.getReserveTime()==0 ? "上午": "下午");
        Map<String,Object> param = new HashMap<String,Object>(){{
            put("title", orderInfo.getHosname()+"|"+orderInfo.getDepname()+"|"+orderInfo.getTitle());
            put("reserveDate", reserveDate);
            put("name", orderInfo.getPatientName());
        }};
        msmVo.setParam(param);
        rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_MSM, MqConst.ROUTING_MSM_ITEM, msmVo);
    }
}

C、添加 mq 监听

添加OrderReceiver 类

@Component
public class OrderReceiver {

    @Autowired
    private OrderService orderService;

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = MqConst.QUEUE_TASK_8, durable = "true"),
            exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_TASK),
            key = {MqConst.ROUTING_TASK_8}
    ))
    public void patientTips(Message message, Channel channel) throws IOException {
        orderService.patientTips();
    }
}

二、预约统计

我们统计医院每天的预约情况,通过图表的形式展示,统计的数据都来自订单模块,因此我们在该模块封装好数据,在统计模块通过 feign 的形式获取数据。

我们为什么需要一个统计模块呢,因为在实际的生成环境中,有很多种各式统计,数据来源于各个服务模块,我们得有一个统计模块来专门管理

1. ECharts

A、简介

ECharts 是百度的一个项目,后来百度把 Echart 捐给 apache,用于图表展示,提供了常规的折线图、柱状图、散点图、饼图、K 线图,用于统计的盒形图,用于地理数据可视化的地图、热力图、线图,用于关系数据可视化的关系图、treemap、旭日图,多维数据可视化的平行坐标,还有用于 BI 的漏斗图,仪表盘,并且支持图与图之间的混搭。

官方网站:https://echarts.apache.org/zh/index.html

B、基本使用

引入 ECharts

<!-- 引入 ECharts 文件 -->
<script src="echarts.min.js"></script>

定义图表区域

<!-- 为ECharts准备一个具备大小(宽高)的Dom -->
<div id="main" style="width: 600px;height:400px;"></div>

渲染图表 (折线图)

<script>
    var myChart = echarts.init(document.getElementById('main'));
    var option = {
        //x轴是类目轴(离散数据),必须通过data设置类目数据
        xAxis: {
            type: 'category',
            data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
        },
        //y轴是数据轴(连续数据)
        yAxis: {
            type: 'value'
        },
        //系列列表。每个系列通过 type 决定自己的图表类型
        series: [{
            //系列中的数据内容数组
            data: [820, 932, 901, 934, 1290, 1330, 1320],
            //折线图
            type: 'line'
        }]
    };
    myChart.setOption(option);
</script>

D、渲染图表(柱状图)

<script type="text/javascript">
    // 基于准备好的dom,初始化echarts实例
    var myChart = echarts.init(document.getElementById('main'));
    // 指定图表的配置项和数据
    var option = {
        title: {
            text: 'ECharts 入门示例'
        },
        tooltip: {},
        legend: {
            data:['销量']
        },
        xAxis: {
            data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"]
        },
        yAxis: {},
        series: [{
            name: '销量',
            type: 'bar',
            data: [5, 20, 36, 10, 10, 20]
        }]
    };
    // 使用刚指定的配置项和数据显示图表。
    myChart.setOption(option);
</script>

E、项目中集成 ECharts

npm install --save echarts@4.1.0

2. 获取医院每天平台预约数据接口

操作模块:service-order

A、添加Mapper接口

在 OrderInfoMapper 类添加接口

public interface OrderMapper extends BaseMapper<OrderInfo> {
    List<OrderCountVo> selectOrderCount(@Param("vo") OrderCountQueryVo orderCountQueryVo);
}

在OrderInfoMapper.xml文件添加方法

<?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="com.fancy.yygh.order.mapper.OrderMapper">

    <select id="selectOrderCount" resultType="com.atguigu.yygh.vo.order.OrderCountVo">
        select reserve_date as reserveDate, count(reserve_date) as count
        from order_info
        <where>
            <if test="vo.hosname != null and vo.hosname != ''">
                and hosname like CONCAT('%',#{vo.hosname},'%')
            </if>
            <if test="vo.reserveDateBegin != null and vo.reserveDateBegin != ''">
                and reserve_date >= #{vo.reserveDateBegin}
            </if>
            <if test="vo.reserveDateEnd != null and vo.reserveDateEnd != ''">
                and reserve_date &lt;= #{vo.reserveDateEnd}
            </if>
            and is_deleted = 0
        </where>
        group by reserve_date
        order by reserve_date
    </select>
</mapper>

添加 application.properties 配置

mybatis-plus.mapper-locations=classpath:com/fancy/yygh/order/mapper/xml/*.xml

B、添加 service 接口

在 OrderService 类添加接口

/**
 * 订单统计
 */
Map<String, Object> getCountMap(OrderCountQueryVo orderCountQueryVo);

C、添加 service 接口实现

在 OrderServiceImpl 类添加实现

@Override
public Map<String, Object> getCountMap(OrderCountQueryVo orderCountQueryVo) {
    Map<String, Object> map = new HashMap<>();

    List<OrderCountVo> orderCountVoList = baseMapper.selectOrderCount(orderCountQueryVo);
    //日期列表
    List<String> dateList = orderCountVoList.stream().map(OrderCountVo::getReserveDate).collect(Collectors.toList());
    //统计列表
    List<Integer> countList = orderCountVoList.stream().map(OrderCountVo::getCount).collect(Collectors.toList());
    map.put("dateList", dateList);
    map.put("countList", countList);
    return map;
}

D、添加 controller 方法

在 OrderApiController 类添加方法

@ApiOperation(value = "获取订单统计数据")
@PostMapping("inner/getCountMap")
public Map<String, Object> getCountMap(@RequestBody OrderCountQueryVo orderCountQueryVo) {
    return orderService.getCountMap(orderCountQueryVo);
}

3. 添加 feign 方法

创建模块:service-order-client

A、添加 feign 接口

添加接口和方法

@FeignClient(value = "service-order")
@Repository
public interface OrderFeignClient {
    /**
     * 获取订单统计数据
     */
    @PostMapping("/api/order/orderInfo/inner/getCountMap")
    Map<String, Object> getCountMap(@RequestBody OrderCountQueryVo orderCountQueryVo);

}

4. 搭建 service-statistics

A、搭建service-statistics服务

搭建方式如 service-user

B、修改配置 pom.xml

<dependencies>
    <dependency>
        <groupId>com.fancy.yygh</groupId>
        <artifactId>service-order-client</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>
</dependencies>

C、添加配置文件

application.properties

# 服务端口
server.port=8208
# 服务名
spring.application.name=service-statistics
# 环境设置:dev、test、prod
spring.profiles.active=dev

# nacos服务地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848

D、添加启动类

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)//取消数据源自动配置
@EnableDiscoveryClient
@EnableFeignClients
public class ServiceStatisticsApplication {

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

}

E、添加 controller 方法

@Api(tags = "统计管理接口")
@RestController
@RequestMapping("/admin/statistics")
public class StatisticsController {

    @Autowired
    private OrderFeignClient orderFeignClient;

    @ApiOperation(value = "获取订单统计数据")
    @GetMapping("getCountMap")
    public Result getCountMap(@ApiParam(name = "orderCountQueryVo", value = "查询对象", required = false) OrderCountQueryVo orderCountQueryVo) {
        return Result.ok(orderFeignClient.getCountMap(orderCountQueryVo));
    }
}

5. 前端展示

A、添加路由

在 src/router/index.js 文件添加路由

{
	path: '/statistics',
	 component: Layout,
	 redirect: '/statistics/order/index',
	 name: 'BasesInfo',
	 meta: { title: '统计管理', icon: 'table' },
	 alwaysShow: true,
	 children: [
	     {
			  path: 'order/index',
			  name: '预约统计',
			  component: () =>import('@/views/statistics/order/index'),
			  meta: { title: '预约统计' }
	     }
	]
},

B、封装 api 请求

创建 /api/statistics/orderStatistics.js

import request from '@/utils/request'

const api_name = '/admin/statistics'

export default {

    getCountMap(searchObj) {
        return request({
            url: `${api_name}/getCountMap`,
            method: 'get',
            params: searchObj
        })
    }
}

C、添加组件

创建 /views/statistics/order/index.vue 组件

<template>
    <div class="app-container">
    <!--表单-->
    <el-form :inline="true" class="demo-form-inline">
        <el-form-item>
            <el-input v-model="searchObj.hosname" placeholder="点击输入医院名称"/>
        </el-form-item>

        <el-form-item>
            <el-date-picker
                v-model="searchObj.reserveDateBegin"
                type="date"
                placeholder="选择开始日期"
                value-format="yyyy-MM-dd"/>
        </el-form-item>
        <el-form-item>
            <el-date-picker
                v-model="searchObj.reserveDateEnd"
                type="date"
                placeholder="选择截止日期"
                value-format="yyyy-MM-dd"/>
        </el-form-item>
        <el-button
            :disabled="btnDisabled"
            type="primary"
            icon="el-icon-search"
            @click="showChart()">查询</el-button>
    </el-form>

    <div class="chart-container">
        <div id="chart" ref="chart" 
            class="chart" style="height:500px;width:100%"/>
   		</div>
    </div>
</template>

<script>
import echarts from 'echarts'
import statisticsApi from '@/api/orderStatistics'

export default {

    data() {
        return {
            searchObj: {
                hosname: '',
                reserveDateBegin: '',
                reserveDateEnd: ''
            },
            btnDisabled: false,
            chart: null,
            title: '',
            xData: [], // x轴数据
            yData: [] // y轴数据
        }
    },

    methods: {
        // 初始化图表数据
        showChart() {
            statisticsApi.getCountMap(this.searchObj).then(response => {
                this.yData = response.data.countList
                this.xData = response.data.dateList
                this.setChartData()
            })
        },

        setChartData() {
            // 基于准备好的dom,初始化echarts实例
            var myChart = echarts.init(document.getElementById('chart'))
            // 指定图表的配置项和数据
            var option = {
                title: {
                    text: this.title + '挂号量统计'
                },
                tooltip: {},
                legend: {
                    data: [this.title]
                },
                xAxis: {
                    data: this.xData
                },
                yAxis: {
                    minInterval: 1
                },
                series: [{
                    name: this.title,
                    type: 'line',
                    data: this.yData
                }]
            }

            // 使用刚指定的配置项和数据显示图表。
            myChart.setOption(option)
        },
    }
}
</script>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/98962.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[附源码]Python计算机毕业设计Django校园招聘系统设计

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

Android Accessibility知识分享

工具 工欲善其事&#xff0c;必先利其器。下面我们介绍一下工具来发现我们的accessibility问题。感谢这篇文章的分享&#xff1a;https://www.kodeco.com/240-android-accessibility-tutorial-getting-started Lint&#xff1a;这个工具是google提供的&#xff0c;在android …

python--面向对象以及其三大特性(封装、继承、多态)

文章目录前言一、面向过程二、 面向对象三、面向对象的三大特性一、封装二、继承私有属性和私有方法三、多态四、高级特性单例模式前言 这一节主要学习面向对象以及面向对象的三大特性&#xff1a;封装、继承、多态&#xff1b;还有高级特性&#xff1a;类方法、静态方法、pro…

【OpenFeign】【源码+图解】【二】注册OpenFeign接口的实例

【OpenFeign】【源码图解】【一】HelloWorld及其工作原理 目录3. 注册OpenFeign接口的实例3. 注册OpenFeign接口的实例 从HelloWorld中我们看到需要显示加入**EnableFeignClients注解才能开启openFeign的功能&#xff0c;因此它就成为我们分析openFeign**的入口&#xff0c;先…

Chrony时间同步服务

目录 一、时间同步 1.概念 2.时间同步在运维工作中的作用 3.时间同步完成方法 &#xff08;1&#xff09;NTP时间服务&#xff08;centos 6 &#xff09; &#xff08;2&#xff09;Chrony时间服务 二、Chrony时间服务 1.Chrony介绍 2.Chrony的优点 三、Chrony安装 …

逻辑回归(Logistic Regression)原理及过程

目录 一&#xff1a;逻辑回归简介 二&#xff1a;逻辑回归原理 三&#xff1a;逻辑回归 损失函数 四&#xff1a;逻辑回归 梯度下降算法 五&#xff1a;逻辑回归 过程 一&#xff1a;逻辑回归简介 Logistic模型是1938年Verhulst-Pearl在修正非密度方程时提出来的&#xf…

算法刷题打卡第49天:排序数组---计数排序

排序数组 难度&#xff1a;中等 给你一个整数数组 nums&#xff0c;请你将该数组升序排列。 示例 1&#xff1a; 输入&#xff1a;nums [5,2,3,1] 输出&#xff1a;[1,2,3,5]示例 2&#xff1a; 输入&#xff1a;nums [5,1,1,2,0,0] 输出&#xff1a;[0,0,1,1,2,5]计数排…

我与世界杯的故事——达利奇:铜牌闪耀着金光

目录 克罗地亚球队的历史 奇迹出现 心得总结 克罗地亚球队的历史 克罗地亚球队拥有悠久的历史&#xff1a; 1998年首次亮相法国世界杯&#xff0c;克罗地亚就以季军的战绩惊艳众人。 2018年的俄罗斯世界杯&#xff0c;虽然格子军团在决赛中不敌强大的法国&#xff0c;遗憾地…

<Linux进程通信之共享内存>——《Linux》

目录 一、system V共享机制 1.共享内存示意图 2.共享内存数据结构 3.共享内存函数 3.1shmget函数 3.2 shmat函数 3.3 shmdt函数 3.4 shmctl函数 3.5 实例代码&#xff1a; 3.6 结果演示&#xff1a; 4. 创建共享内存 5. 基于共享内存与管道进行访问控制的共享内存读…

(P4)Python plt显示图像

Python plt显示图片 本地可以显示&#xff0c;服务器操作不太行。 plt.plot(x,y) plt.imshow(image) plt.show() # 显示图像&#xff08;曲线/图片都需要这一行&#xff09; plt.savefig(xx.png) # 保存图片 fig.savefig(xx.png) 功能相同 # 保存图片在本地执行失败&#xff…

Elasticsearch学习笔记

Elasticsearch学习笔记 ----第1章 Elasticsearch概述-01-开篇02-技术选型03-教学大纲-第2章 Elasticsearch入门-04-入门-环境准备05-入门-RESTful & JSON06-入门-Postman客户端工具07-入门-倒排索引08-入门-HTTP-索引-创建09-入门-HTTP-索引-查询 & 删除10-入门-HTTP-…

Linux 调试之 TRACE_EVENT(一)

文章目录前言一、TRACE_EVENT简介二、TRACE_EVENT() 结构2.1 TRACE_EVENT简介2.2 trace_sched_switch示例2.2.1 Name2.2.2 Prototype2.2.3 Arguments2.2.4 Structure2.2.5 Assignment2.2.6 Print2.3 Format file2.3.1 tracing/events/2.3.2 perf2.3.3 bpftrace2.3.4 bcc2.3.5 S…

逻辑回归 鸢尾花分类预测

目录 一&#xff1a;加载数据 二&#xff1a;数据集划分 三&#xff1a;选择算法 四&#xff1a;网格模型 超参数最优解 五&#xff1a;鸢尾花分类预测 六&#xff1a;预测与实际比对 七&#xff1a;完整源码分享 一&#xff1a;加载数据 from sklearn.datasets import…

Jenkins启动项目时报错问题

问题 在工作中使用jenkins进行项目部署启动时遇到问题&#xff0c;项目构建成功但是发布时一直显示时间增加&#xff0c;但是项目本身并没有问题&#xff0c;使用传统方法部署项目也能正常启动。报错如下图所示&#xff1a; 解决方法 是由于jenkins文件中打印日志的问题&am…

PayPal,Stripe,Square轮询支付系统

轮询展示 展示我们轮询的页面 轮询套餐 根据不同的用户和需求&#xff0c;可以选择不同的套餐 普通版 1500元 1年 1个用户 支持Paypal/Stripe 不限制A站个数 不限制B站个数 不限制提交模式 订单管理 物流管理 风控管理 必要的网站数据处理 24小时远程协助 开始…

springcloud服务消费与熔断

今天与大家分享服务消费与熔断&#xff0c;就是说当我们服务消费者转发到服务生产者时&#xff0c;如果有那一步出现了问题或者error&#xff0c;可以进行服务熔断&#xff08;服务降级&#xff09;&#xff0c;为了补救系统问题&#xff0c;不让用户使用时看见error报错信息&a…

《Java》String、StringBuffer、StringBuilder有什么区别?

目录 String StringBuffer StringBuilder 总结 ps&#xff1a;昨天在讨论完String的不可变性之后突然想要做一份总结笔记&#xff0c;总结一下String、StringBuffer、StringBuilder的区别 String String是Java中的基础类&#xff0c;提供了各种构造和对字符串的基本操作&am…

Cocos Creater(3.6.1)开发笔记——Typscript

文章目录项目入门关于cocos creator 3.x关于TypeScript新建项目VS setting json配置屏蔽项事件节点添加脚本&#xff08;事件&#xff09;案例代码素材使用技巧素材组合固定布局&#xff08;类似css&#xff09;项目入门 关于cocos creator 3.x 相当于cocos所有版本的功能的综…

初探MapReduce

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录MapReduce核心思想MapReduce编程模型MapReduce编程实例——词频统计思路1、Map阶段&#xff08;映射阶段&#xff09;2、Reduce阶段&#xff08;归并阶段&#xff09…

VS2019下C#调用C++ DLL详解+数据转换

VS2019下C#调用C DLL详解数据转换 -C#调用OpenCV&#xff08;c的.dll主要有两种常见的方式&#xff1a;托管和非托管两种形式&#xff01; 非托管的形式即是采用[DllImport]的形式&#xff0c;这种形式只能调用的C的函数&#xff0c;适合用于简单的图形处理调用&#xff0c;这也…