1、概要

生日跨年提醒,在EHR系统中,用户选择某个时间段都那些人过生日,并发送邮件提醒;本文只描述如何去跨年查询。
前端使用Vue.js/Element UI;
后端使用Java/Spring Cloud/微服务架构模式
本文修改于:2019年03月15日

2、思路

1、前端获取的是时间段,用户输入的时间段发送给后端的时候,判断一下用户选择的时间;
2、如果没有跨年,则调用函数a;
3、如果跨年了,则调用函数b;

3、实现过程

3.1、前端实现

3.1.1、界面效果

Element UI时间组件:点击这里

3.1.2、前端代码
1
2
3
4
5
6
7
8
9
10
11
handleFilter() {
this.searchkpi();
this.listQuery.startDataBirthdayPoint = this.employeeBirthday[0].toString().substring(5, 10).replace('-', '')
this.listQuery.endDataBirthdayPoint = this.employeeBirthday[1].toString().substring(5, 10).replace('-', '')
if (this.employeeBirthday[0].toString().substring(0, 4) === this.employeeBirthday[1].toString().substring(0, 4)) {
this.getListNotAcrossYear();
} else {
this.getList();
}
}
// 代码片段1

第5行代码,判断了年份是否相同,如果年份是否相同,如果相同,则调用this.getListNotAcrossYear, 调用接口:pageBirthdayNotAcrossYear(), 参数为this.listQuery;

1
2
3
4
5
6
7
8
9
10
11
12
13
getListNotAcrossYear() {
this.loading = true;
pageBirthdayNotAcrossYear(this.listQuery)
.then(response => {
this.list = response.data.rows;
this.total = response.data.total;
this.loading = false;
}).catch(error => {
console.error(error)
this.loading = false
})
}
// 代码片段2

this.listQuery包含两个字段:

1
2
3
startDataBirthdayPoint: undefined,
endDataBirthdayPoint: undefined
// 代码片段3

这两个字段,作为listQuery的一部分,作为参数,通过前端的API请求接口,传递给后端:

1
2
3
4
5
6
7
8
9
// 生日提醒
export function pageBirthdayNotAcrossYear(query) {
return request({
url: '/api/admin/mEmployeeInfo/pageBirthdayNotAcrossYear',
method: 'get',
params: query
})
}
// 代码片段4

从接口中可以看到:传入的参数是query,使用GET的方式传递给后端。
相同的,在代码片段1中的第8行,则是请求跨年的,在前端的代码部分都是一样的,这里我是在前端就对其进行了分开,后来想了想,如果日期传递到后端,在后端进行处理,代码量要少很多。

3.2、后端实现

先看下不跨年的,包含Java代码和MyBatis的.xml映射文件;

3.2.1、Java代码

首先是Controller类:

1
2
@RequestMapping("mEmployeeInfo")
// 代码片段5

应和了在代码片段4中的请求接口;
这是Java代码Controller的函数:

1
2
3
4
5
6
7
@RequestMapping(value = "/pageBirthdayNotAcrossYear", method = RequestMethod.GET)
@ResponseBody
public TableResultResponse<MEmployeeInfo> selectBirthdayNotAcrossYear(@RequestParam Map<String, Object> params) {
PageQuery query = new PageQuery(params, params);
return mEmployeeInfoBiz.selectBirthdayNotAcrossYear(query);
}
//代码片段6

函数的类型是TableResultResponse,返回的是一个结果集;

这是Java代码Service类的函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 生日到期提醒(不跨年)
public TableResultResponse<MEmployeeInfo> selectBirthdayNotAcrossYear(PageQuery<MEmployeeInfo> query) {
PageExample example = new PageExample(MEmployeeInfo.class, query.getData());
Page<MEmployeeInfo> result = PageHelper.startPage(query.getPage(), query.getLimit());
List<MEmployeeInfo> list = mEmployeeInfoMapper.selectBirthdayNotAcrossYear(example);
if (list.size() > 0){
try {
mergeCore.mergeResult(MEmployeeInfo.class, list);
} catch (Exception e) {
e.printStackTrace();
}
}
return new TableResultResponse<MEmployeeInfo>(result.getTotal(), list);
}
// 代码片段7

DAO类

1
2
List<MEmployeeInfo> selectBirthdayNotAcrossYear(Object example);
// 代码片段8

3.2.2、MyBatis的映射文件

接下来是MyBatis的映射文件代码

1
2
3
4
5
6
7
8
9
10
11
12
13
<select id="selectBirthdayNotAcrossYear" parameterType="com.savor.security.common.entity.PageExample" resultMap="BaseResultMap">
SELECT
t.*, y.position_name
FROM
m_employee_info t
LEFT JOIN m_position y ON t.position_id = y.position_id
WHERE
t.employee_id IS NOT NULL
<if test="data.startDataBirthdayPoint != null and data.startDataBirthdayPoint != '' and data.endDataBirthdayPoint != null and data.endDataBirthdayPoint !=''">
AND DATE_FORMAT(t.employee_birthday , '%m%d') BETWEEN #{data.startDataBirthdayPoint} AND #{data.endDataBirthdayPoint}
</if>
</select>
-- 代码片段9

跨年的请求处理,跟上面的代码没有区别,不同之处体现在最后的映射文件这里:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<select id="selectByBirthday" parameterType="com.savor.security.common.entity.PageExample" resultMap="BaseResultMap">
select a.* from (
SELECT
t.*, y.position_name
FROM
m_employee_info t
LEFT JOIN m_position y ON t.position_id = y.position_id
WHERE
t.employee_id IS NOT NULL
<if test="data.startDataBirthdayPoint != null and data.startDataBirthdayPoint != '' and data.endDataBirthdayPoint != null and data.endDataBirthdayPoint !=''">
AND DATE_FORMAT(t.employee_birthday , '%m%d') BETWEEN #{data.startDataBirthdayPoint} AND #{data.endDataBirthdayPoint}
</if>
UNION ALL
SELECT
t.*, y.position_name
FROM
m_employee_info t
LEFT JOIN m_position y ON t.position_id = y.position_id
WHERE
t.employee_id IS NOT NULL
<if test="data.startDataBirthdayPoint != null and data.startDataBirthdayPoint != '' and data.endDataBirthdayPoint != null and data.endDataBirthdayPoint !=''">
AND DATE_FORMAT(t.employee_birthday , '%m%d') BETWEEN #{data.startDataBirthdayPoint} AND '1231'
</if>
UNION ALL
SELECT
t.*, y.position_name
FROM
m_employee_info t
LEFT JOIN m_position y ON t.position_id = y.position_id
WHERE
t.employee_id IS NOT NULL
<if test="data.startDataBirthdayPoint != null and data.startDataBirthdayPoint != '' and data.endDataBirthdayPoint != null and data.endDataBirthdayPoint !=''">
AND DATE_FORMAT(t.employee_birthday , '%m%d') BETWEEN '0101' AND #{data.endDataBirthdayPoint}
</if>
) as a
</select>

其中也分成了三段,第一段就是正常的输入日期,但是不会去调用了。
后两段是:
如果跨年的时候,比如选择这个时间段2018-12-05~2019-03-15进行查询,那么数据流到映射文件这里的时候,会被分成两段(因为生日是考虑月日的,不考虑年):就是12-05~12-31一部分人;01-01~03-15第二部分人;最后加起来,就是要的人数;