单个短链访问监控详情
# 指定时间内监控数据
# 接口层
接口:
@RestController
@RequiredArgsConstructor
public class ShortLinkStatsController {
private final ShortLinkStatsService shortLinkStatsService;
/**
* 访问单个短链接指定时间内监控数据
*/
@GetMapping("/api/short-link/v1/stats")
public Result<ShortLinkStatsRespDTO> shortLinkStats(ShortLinkStatsReqDTO requestParam) {
return Results.success(shortLinkStatsService.oneShortLinkStats(requestParam));
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
@Service
@RequiredArgsConstructor
public class ShortLinkStatsServiceImpl implements ShortLinkStatsService {
private final LinkAccessStatsMapper linkAccessStatsMapper;
private final LinkLocaleStatsMapper linkLocaleStatsMapper;
private final LinkAccessLogsMapper linkAccessLogsMapper;
private final LinkBrowserStatsMapper linkBrowserStatsMapper;
private final LinkOsStatsMapper linkOsStatsMapper;
private final LinkDeviceStatsMapper linkDeviceStatsMapper;
private final LinkNetworkStatsMapper linkNetworkStatsMapper;
@Override
public ShortLinkStatsRespDTO oneShortLinkStats(ShortLinkStatsReqDTO requestParam) {
List<LinkAccessStatsDO> listStatsByShortLink = linkAccessStatsMapper.listStatsByShortLink(requestParam);
// 没有访问记录
if (CollUtil.isEmpty(listStatsByShortLink)) {
return null;
}
// 基础访问详情
List<ShortLinkStatsAccessDailyRespDTO> daily = new ArrayList<>();
List<String> rangeDates = DateUtil.rangeToList(DateUtil.parse(requestParam.getStartDate()), DateUtil.parse(requestParam.getEndDate()), DateField.DAY_OF_MONTH).stream()
.map(DateUtil::formatDate)
.toList();
rangeDates.forEach(each -> listStatsByShortLink.stream()
.filter(item -> Objects.equals(each, DateUtil.formatDate(item.getDate())))
.findFirst()
.ifPresentOrElse(item -> {
ShortLinkStatsAccessDailyRespDTO accessDailyRespDTO = ShortLinkStatsAccessDailyRespDTO.builder()
.date(each)
.pv(item.getPv())
.uv(item.getUv())
.uip(item.getUip())
.build();
daily.add(accessDailyRespDTO);
}, () -> {
ShortLinkStatsAccessDailyRespDTO accessDailyRespDTO = ShortLinkStatsAccessDailyRespDTO.builder()
.date(each)
.pv(0)
.uv(0)
.uip(0)
.build();
daily.add(accessDailyRespDTO);
}));
// 地区访问详情(仅国内)
List<ShortLinkStatsLocaleCNRespDTO> localeCnStats = new ArrayList<>();
List<LinkLocaleStatsDO> listedLocaleByShortLink = linkLocaleStatsMapper.listLocaleByShortLink(requestParam);
int localeCnSum = listedLocaleByShortLink.stream()
.mapToInt(LinkLocaleStatsDO::getCnt)
.sum();
listedLocaleByShortLink.forEach(each -> {
double ratio = (double) each.getCnt() / localeCnSum;
double actualRatio = Math.round(ratio * 100.0) / 100.0;
ShortLinkStatsLocaleCNRespDTO localeCNRespDTO = ShortLinkStatsLocaleCNRespDTO.builder()
.cnt(each.getCnt())
.locale(each.getProvince())
.ratio(actualRatio)
.build();
localeCnStats.add(localeCNRespDTO);
});
// 小时访问详情
List<Integer> hourStats = new ArrayList<>();
List<LinkAccessStatsDO> listHourStatsByShortLink = linkAccessStatsMapper.listHourStatsByShortLink(requestParam);
for (int i = 0; i < 24; i++) {
AtomicInteger hour = new AtomicInteger(i);
int hourCnt = listHourStatsByShortLink.stream()
.filter(each -> Objects.equals(each.getHour(), hour.get()))
.findFirst()
.map(LinkAccessStatsDO::getPv)
.orElse(0);
hourStats.add(hourCnt);
}
// 高频访问IP详情
List<ShortLinkStatsTopIpRespDTO> topIpStats = new ArrayList<>();
List<HashMap<String, Object>> listTopIpByShortLink = linkAccessLogsMapper.listTopIpByShortLink(requestParam);
listTopIpByShortLink.forEach(each -> {
ShortLinkStatsTopIpRespDTO statsTopIpRespDTO = ShortLinkStatsTopIpRespDTO.builder()
.ip(each.get("ip").toString())
.cnt(Integer.parseInt(each.get("count").toString()))
.build();
topIpStats.add(statsTopIpRespDTO);
});
// 一周访问详情
List<Integer> weekdayStats = new ArrayList<>();
List<LinkAccessStatsDO> listWeekdayStatsByShortLink = linkAccessStatsMapper.listWeekdayStatsByShortLink(requestParam);
for (int i = 1; i < 8; i++) {
AtomicInteger weekday = new AtomicInteger(i);
int weekdayCnt = listWeekdayStatsByShortLink.stream()
.filter(each -> Objects.equals(each.getWeekday(), weekday.get()))
.findFirst()
.map(LinkAccessStatsDO::getPv)
.orElse(0);
weekdayStats.add(weekdayCnt);
}
// 浏览器访问详情
List<ShortLinkStatsBrowserRespDTO> browserStats = new ArrayList<>();
List<HashMap<String, Object>> listBrowserStatsByShortLink = linkBrowserStatsMapper.listBrowserStatsByShortLink(requestParam);
int browserSum = listBrowserStatsByShortLink.stream()
.mapToInt(each -> Integer.parseInt(each.get("count").toString()))
.sum();
listBrowserStatsByShortLink.forEach(each -> {
double ratio = (double) Integer.parseInt(each.get("count").toString()) / browserSum;
double actualRatio = Math.round(ratio * 100.0) / 100.0;
ShortLinkStatsBrowserRespDTO browserRespDTO = ShortLinkStatsBrowserRespDTO.builder()
.cnt(Integer.parseInt(each.get("count").toString()))
.browser(each.get("browser").toString())
.ratio(actualRatio)
.build();
browserStats.add(browserRespDTO);
});
// 操作系统访问详情
List<ShortLinkStatsOsRespDTO> osStats = new ArrayList<>();
List<HashMap<String, Object>> listOsStatsByShortLink = linkOsStatsMapper.listOsStatsByShortLink(requestParam);
int osSum = listOsStatsByShortLink.stream()
.mapToInt(each -> Integer.parseInt(each.get("count").toString()))
.sum();
listOsStatsByShortLink.forEach(each -> {
double ratio = (double) Integer.parseInt(each.get("count").toString()) / osSum;
double actualRatio = Math.round(ratio * 100.0) / 100.0;
ShortLinkStatsOsRespDTO osRespDTO = ShortLinkStatsOsRespDTO.builder()
.cnt(Integer.parseInt(each.get("count").toString()))
.os(each.get("os").toString())
.ratio(actualRatio)
.build();
osStats.add(osRespDTO);
});
// 访客访问类型详情
List<ShortLinkStatsUvRespDTO> uvTypeStats = new ArrayList<>();
HashMap<String, Object> findUvTypeByShortLink = linkAccessLogsMapper.findUvTypeCntByShortLink(requestParam);
int oldUserCnt = Integer.parseInt(
Optional.ofNullable(findUvTypeByShortLink)
.map(each -> each.get("oldUserCnt"))
.map(Object::toString)
.orElse("0")
);
int newUserCnt = Integer.parseInt(
Optional.ofNullable(findUvTypeByShortLink)
.map(each -> each.get("newUserCnt"))
.map(Object::toString)
.orElse("0")
);
int uvSum = oldUserCnt + newUserCnt;
double oldRatio = (double) oldUserCnt / uvSum;
double actualOldRatio = Math.round(oldRatio * 100.0) / 100.0;
double newRatio = (double) newUserCnt / uvSum;
double actualNewRatio = Math.round(newRatio * 100.0) / 100.0;
ShortLinkStatsUvRespDTO newUvRespDTO = ShortLinkStatsUvRespDTO.builder()
.uvType("newUser")
.cnt(newUserCnt)
.ratio(actualNewRatio)
.build();
uvTypeStats.add(newUvRespDTO);
ShortLinkStatsUvRespDTO oldUvRespDTO = ShortLinkStatsUvRespDTO.builder()
.uvType("oldUser")
.cnt(oldUserCnt)
.ratio(actualOldRatio)
.build();
uvTypeStats.add(oldUvRespDTO);
// 访问设备类型详情
List<ShortLinkStatsDeviceRespDTO> deviceStats = new ArrayList<>();
List<LinkDeviceStatsDO> listDeviceStatsByShortLink = linkDeviceStatsMapper.listDeviceStatsByShortLink(requestParam);
int deviceSum = listDeviceStatsByShortLink.stream()
.mapToInt(LinkDeviceStatsDO::getCnt)
.sum();
listDeviceStatsByShortLink.forEach(each -> {
double ratio = (double) each.getCnt() / deviceSum;
double actualRatio = Math.round(ratio * 100.0) / 100.0;
ShortLinkStatsDeviceRespDTO deviceRespDTO = ShortLinkStatsDeviceRespDTO.builder()
.cnt(each.getCnt())
.device(each.getDevice())
.ratio(actualRatio)
.build();
deviceStats.add(deviceRespDTO);
});
// 访问网络类型详情
List<ShortLinkStatsNetworkRespDTO> networkStats = new ArrayList<>();
List<LinkNetworkStatsDO> listNetworkStatsByShortLink = linkNetworkStatsMapper.listNetworkStatsByShortLink(requestParam);
int networkSum = listNetworkStatsByShortLink.stream()
.mapToInt(LinkNetworkStatsDO::getCnt)
.sum();
listNetworkStatsByShortLink.forEach(each -> {
double ratio = (double) each.getCnt() / networkSum;
double actualRatio = Math.round(ratio * 100.0) / 100.0;
ShortLinkStatsNetworkRespDTO networkRespDTO = ShortLinkStatsNetworkRespDTO.builder()
.cnt(each.getCnt())
.network(each.getNetwork())
.ratio(actualRatio)
.build();
networkStats.add(networkRespDTO);
});
return ShortLinkStatsRespDTO.builder()
.daily(daily)
.localeCnStats(localeCnStats)
.hourStats(hourStats)
.topIpStats(topIpStats)
.weekdayStats(weekdayStats)
.browserStats(browserStats)
.osStats(osStats)
.uvTypeStats(uvTypeStats)
.deviceStats(deviceStats)
.networkStats(networkStats)
.build();
}
}
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# 持久层
# 基础访问监控
public interface LinkAccessStatsMapper extends BaseMapper<LinkAccessStatsDO> {
/**
* 记录基础访问监控数据
*/
@Insert("INSERT INTO t_link_access_stats (full_short_url, gid, date, pv, uv, uip, hour, weekday, create_time, update_time, del_flag) " +
"VALUES( #{linkAccessStats.fullShortUrl}, #{linkAccessStats.gid}, #{linkAccessStats.date}, #{linkAccessStats.pv}, #{linkAccessStats.uv}, #{linkAccessStats.uip}, #{linkAccessStats.hour}, #{linkAccessStats.weekday}, NOW(), NOW(), 0) ON DUPLICATE KEY UPDATE pv = pv + #{linkAccessStats.pv}, " +
"uv = uv + #{linkAccessStats.uv}, " +
"uip = uip + #{linkAccessStats.uip};")
void shortLinkStats(@Param("linkAccessStats") LinkAccessStatsDO linkAccessStatsDO);
/**
* 根据短链接获取指定日期内基础监控数据
*/
@Select("SELECT " +
" date, " +
" SUM(pv) AS pv, " +
" SUM(uv) AS uv, " +
" SUM(uip) AS uip " +
"FROM " +
" t_link_access_stats " +
"WHERE " +
" full_short_url = #{param.fullShortUrl} " +
" AND gid = #{param.gid} " +
" AND date BETWEEN #{param.startDate} and #{param.endDate} " +
"GROUP BY " +
" full_short_url, gid, date;")
List<LinkAccessStatsDO> listStatsByShortLink(@Param("param") ShortLinkStatsReqDTO requestParam);
/**
* 根据短链接获取指定日期内小时基础监控数据
*/
@Select("SELECT " +
" hour, " +
" SUM(pv) AS pv " +
"FROM " +
" t_link_access_stats " +
"WHERE " +
" full_short_url = #{param.fullShortUrl} " +
" AND gid = #{param.gid} " +
" AND date BETWEEN #{param.startDate} and #{param.endDate} " +
"GROUP BY " +
" full_short_url, gid, hour;")
List<LinkAccessStatsDO> listHourStatsByShortLink(@Param("param") ShortLinkStatsReqDTO requestParam);
/**
* 根据短链接获取指定日期内周日基础监控数据
*/
@Select("SELECT " +
" weekday, " +
" SUM(pv) AS pv " +
"FROM " +
" t_link_access_stats " +
"WHERE " +
" full_short_url = #{param.fullShortUrl} " +
" AND gid = #{param.gid} " +
" AND date BETWEEN #{param.startDate} and #{param.endDate} " +
"GROUP BY " +
" full_short_url, gid, weekday;")
List<LinkAccessStatsDO> listWeekdayStatsByShortLink(@Param("param") ShortLinkStatsReqDTO requestParam);
}
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# 地区访问监控
public interface LinkLocaleStatsMapper extends BaseMapper<LinkLocaleStatsDO> {
@Insert("INSERT INTO t_link_locale_stats (full_short_url, gid, date, cnt, country, province, city, adcode, create_time, update_time, del_flag) " +
"VALUES( #{linkLocaleStats.fullShortUrl}, #{linkLocaleStats.gid}, #{linkLocaleStats.date}, #{linkLocaleStats.cnt}, #{linkLocaleStats.country}, #{linkLocaleStats.province}, #{linkLocaleStats.city}, #{linkLocaleStats.adcode}, NOW(), NOW(), 0) " +
"ON DUPLICATE KEY UPDATE cnt = cnt + #{linkLocaleStats.cnt};")
void shortLinkLocaleState(@Param("linkLocaleStats") LinkLocaleStatsDO linkLocaleStatsDO);
/**
* 根据短链接获取指定日期内地区监控数据
*/
@Select("SELECT " +
" province, " +
" SUM(cnt) AS cnt " +
"FROM " +
" t_link_locale_stats " +
"WHERE " +
" full_short_url = #{param.fullShortUrl} " +
" AND gid = #{param.gid} " +
" AND date BETWEEN #{param.startDate} and #{param.endDate} " +
"GROUP BY " +
" full_short_url, gid, province;")
List<LinkLocaleStatsDO> listLocaleByShortLink(@Param("param") ShortLinkStatsReqDTO requestParam);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# OS访问监控
public interface LinkOsStatsMapper extends BaseMapper<LinkOsStatsDO> {
@Insert("INSERT INTO t_link_os_stats (full_short_url, gid, date, cnt, os, create_time, update_time, del_flag) " +
"VALUES( #{linkOsStats.fullShortUrl}, #{linkOsStats.gid}, #{linkOsStats.date}, #{linkOsStats.cnt}, #{linkOsStats.os}, NOW(), NOW(), 0) " +
"ON DUPLICATE KEY UPDATE cnt = cnt + #{linkOsStats.cnt};")
void shortLinkOsState(@Param("linkOsStats") LinkOsStatsDO linkOsStatsDO);
/**
* 根据短链接获取指定日期内操作系统监控数据
*/
@Select("SELECT " +
" os, " +
" SUM(cnt) AS count " +
"FROM " +
" t_link_os_stats " +
"WHERE " +
" full_short_url = #{param.fullShortUrl} " +
" AND gid = #{param.gid} " +
" AND date BETWEEN #{param.startDate} and #{param.endDate} " +
"GROUP BY " +
" full_short_url, gid, os;")
List<HashMap<String, Object>> listOsStatsByShortLink(@Param("param") ShortLinkStatsReqDTO requestParam);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 浏览器访问监控
public interface LinkBrowserStatsMapper extends BaseMapper<LinkBrowserStatsDO> {
@Insert("INSERT INTO t_link_browser_stats (full_short_url, gid, date, cnt, browser, create_time, update_time, del_flag) " +
"VALUES( #{linkBrowserStats.fullShortUrl}, #{linkBrowserStats.gid}, #{linkBrowserStats.date}, #{linkBrowserStats.cnt}, #{linkBrowserStats.browser}, NOW(), NOW(), 0) " +
"ON DUPLICATE KEY UPDATE cnt = cnt + #{linkBrowserStats.cnt};")
void shortLinkBrowserState(@Param("linkBrowserStats") LinkBrowserStatsDO linkBrowserStatsDO);
/**
* 根据短链接获取指定日期内浏览器监控数据
*/
@Select("SELECT " +
" browser, " +
" SUM(cnt) AS count " +
"FROM " +
" t_link_browser_stats " +
"WHERE " +
" full_short_url = #{param.fullShortUrl} " +
" AND gid = #{param.gid} " +
" AND date BETWEEN #{param.startDate} and #{param.endDate} " +
"GROUP BY " +
" full_short_url, gid, date, browser;")
List<HashMap<String, Object>> listBrowserStatsByShortLink(@Param("param") ShortLinkStatsReqDTO requestParam);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 设备访问监控
/**
* 根据短链接获取指定日期内访问设备监控数据
*/
@Select("SELECT " +
" device, " +
" SUM(cnt) AS cnt " +
"FROM " +
" t_link_device_stats " +
"WHERE " +
" full_short_url = #{param.fullShortUrl} " +
" AND gid = #{param.gid} " +
" AND date BETWEEN #{param.startDate} and #{param.endDate} " +
"GROUP BY " +
" full_short_url, gid, device;")
List<LinkDeviceStatsDO> listDeviceStatsByShortLink(@Param("param") ShortLinkStatsReqDTO requestParam);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 网络访问监控
/**
* 根据短链接获取指定日期内访问网络监控数据
*/
@Select("SELECT " +
" network, " +
" SUM(cnt) AS cnt " +
"FROM " +
" t_link_network_stats " +
"WHERE " +
" full_short_url = #{param.fullShortUrl} " +
" AND gid = #{param.gid} " +
" AND date BETWEEN #{param.startDate} and #{param.endDate} " +
"GROUP BY " +
" full_short_url, gid, network;")
List<LinkNetworkStatsDO> listNetworkStatsByShortLink(@Param("param") ShortLinkStatsReqDTO requestParam);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 访问日志监控
/**
* 访问日志监控持久层
*/
public interface LinkAccessLogsMapper extends BaseMapper<LinkAccessLogsDO> {
/**
* 根据短链接获取指定日期内高频访问IP数据
*/
@Select("SELECT " +
" ip, " +
" COUNT(ip) AS count " +
"FROM " +
" t_link_access_logs " +
"WHERE " +
" full_short_url = #{param.fullShortUrl} " +
" AND gid = #{param.gid} " +
" AND create_time BETWEEN #{param.startDate} and #{param.endDate} " +
"GROUP BY " +
" full_short_url, gid, ip " +
"ORDER BY " +
" count DESC " +
"LIMIT 5;")
List<HashMap<String, Object>> listTopIpByShortLink(@Param("param") ShortLinkStatsReqDTO requestParam);
/**
* 根据短链接获取指定日期内新旧访客数据
*/
@Select("SELECT " +
" SUM(old_user) AS oldUserCnt, " +
" SUM(new_user) AS newUserCnt " +
"FROM ( " +
" SELECT " +
" CASE WHEN COUNT(DISTINCT DATE(create_time)) > 1 THEN 1 ELSE 0 END AS old_user, " +
" CASE WHEN COUNT(DISTINCT DATE(create_time)) = 1 AND MAX(create_time) >= #{param.startDate} AND MAX(create_time) <= #{param.endDate} THEN 1 ELSE 0 END AS new_user " +
" FROM " +
" t_link_access_logs " +
" WHERE " +
" full_short_url = #{param.fullShortUrl} " +
" AND gid = #{param.gid} " +
" GROUP BY " +
" user " +
") AS user_counts;")
HashMap<String, Object> findUvTypeCntByShortLink(@Param("param") ShortLinkStatsReqDTO requestParam);
}
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
37
38
39
40
41
42
43
44
45
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
37
38
39
40
41
42
43
44
45
# 指定日期的统计
LinkAccessLogsMapper:
/**
* 根据短链接获取指定日期内PV、UV、UIP数据
*/
@Select("SELECT " +
" COUNT(user) AS pv, " +
" COUNT(DISTINCT user) AS uv, " +
" COUNT(DISTINCT ip) AS uip " +
"FROM " +
" t_link_access_logs " +
"WHERE " +
" full_short_url = #{param.fullShortUrl} " +
" AND gid = #{param.gid} " +
" AND create_time BETWEEN #{param.startDate} and #{param.endDate} " +
"GROUP BY " +
" full_short_url, gid;")
LinkAccessStatsDO findPvUvUidStatsByShortLink(@Param("param") ShortLinkStatsReqDTO requestParam);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ShortLinkStatsServiceImpl#oneShortLinkStats