✨Feat: 增加编码时长统计
This commit is contained in:
@@ -2,7 +2,8 @@ package cn.hezhaohui.common;
|
|||||||
|
|
||||||
public enum CardEnum {
|
public enum CardEnum {
|
||||||
CARD_WEATHER("AAqxas5etOJDx", "1.0.5"),
|
CARD_WEATHER("AAqxas5etOJDx", "1.0.5"),
|
||||||
CARD_MOVIE("AAqhYDej6RK7O", "1.0.1");
|
CARD_MOVIE("AAqhYDej6RK7O", "1.0.1"),
|
||||||
|
CARD_WAKATIME("AAqhg9UY0e2Ir", "1.0.1");
|
||||||
|
|
||||||
private final String id;
|
private final String id;
|
||||||
private final String versionName;
|
private final String versionName;
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package cn.hezhaohui.common;
|
||||||
|
|
||||||
|
public class WakaTimeConstant {
|
||||||
|
|
||||||
|
public static final String WAKATIME_API_URL_PREFIX = "https://api.wakatime.com/api/v1/";
|
||||||
|
public static final String WAKATIME_API_URL_LAST_7_DAYS = WAKATIME_API_URL_PREFIX + "users/current/summaries?range=last_7_days";
|
||||||
|
public static final String WAKATIME_API_SECRET_KEY_BASE64 = "d2FrYV80MzYyZjQzMC1kY2Y4LTQ2YzktYjdkYy0yMjMwMjUxOTkwNWQ=";
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package cn.hezhaohui.lark.client;
|
||||||
|
|
||||||
|
public interface WakaTimeClient {
|
||||||
|
|
||||||
|
String getLast7DaysData();
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package cn.hezhaohui.lark.client.impl;
|
||||||
|
|
||||||
|
|
||||||
|
import cn.hezhaohui.common.WakaTimeConstant;
|
||||||
|
import cn.hezhaohui.lark.client.WakaTimeClient;
|
||||||
|
import cn.hutool.http.HttpRequest;
|
||||||
|
import cn.hutool.http.HttpUtil;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class WakaTimeClientImpl implements WakaTimeClient {
|
||||||
|
@Override
|
||||||
|
public String getLast7DaysData() {
|
||||||
|
HttpRequest request = HttpUtil.createGet(WakaTimeConstant.WAKATIME_API_URL_LAST_7_DAYS);
|
||||||
|
request.auth("Basic " + WakaTimeConstant.WAKATIME_API_SECRET_KEY_BASE64);
|
||||||
|
return request.execute().body();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ package cn.hezhaohui.lark.handler;
|
|||||||
import cn.hezhaohui.common.AppConstant;
|
import cn.hezhaohui.common.AppConstant;
|
||||||
import cn.hezhaohui.common.CardEnum;
|
import cn.hezhaohui.common.CardEnum;
|
||||||
import cn.hezhaohui.lark.service.MovieService;
|
import cn.hezhaohui.lark.service.MovieService;
|
||||||
|
import cn.hezhaohui.lark.service.WakaTimeService;
|
||||||
import cn.hezhaohui.pojo.entity.Weather;
|
import cn.hezhaohui.pojo.entity.Weather;
|
||||||
import cn.hezhaohui.lark.client.WeatherClient;
|
import cn.hezhaohui.lark.client.WeatherClient;
|
||||||
import cn.hezhaohui.lark.util.BeanUtil;
|
import cn.hezhaohui.lark.util.BeanUtil;
|
||||||
@@ -48,6 +49,10 @@ public class EventListener {
|
|||||||
MovieService movieService = BeanUtil.getBean(MovieService.class);
|
MovieService movieService = BeanUtil.getBean(MovieService.class);
|
||||||
Map<String, Object> data = movieService.getMovies();
|
Map<String, Object> data = movieService.getMovies();
|
||||||
LarkUtil.sendCard(CardEnum.CARD_MOVIE, data);
|
LarkUtil.sendCard(CardEnum.CARD_MOVIE, data);
|
||||||
|
} else if (eventKey.equals("code")) {
|
||||||
|
WakaTimeService wakaTimeService = BeanUtil.getBean(WakaTimeService.class);
|
||||||
|
HashMap<String, Object> last7DaysCardData = wakaTimeService.getLast7DaysCardData();
|
||||||
|
LarkUtil.sendCard(CardEnum.CARD_WAKATIME, last7DaysCardData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -0,0 +1,126 @@
|
|||||||
|
package cn.hezhaohui.lark.service;
|
||||||
|
|
||||||
|
import cn.hezhaohui.lark.client.WakaTimeClient;
|
||||||
|
import cn.hutool.json.JSONArray;
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class WakaTimeService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private WakaTimeClient wakaTimeClient;
|
||||||
|
|
||||||
|
public List<Map<String, Object>> getLast7DaysData() {
|
||||||
|
String last7DaysData = wakaTimeClient.getLast7DaysData();
|
||||||
|
JSONObject jsonObject = JSONUtil.parseObj(last7DaysData);
|
||||||
|
JSONArray dataArray = jsonObject.getJSONArray("data");
|
||||||
|
// Init
|
||||||
|
List<Map<String, Object>> dailyActivities = new ArrayList<>();
|
||||||
|
// Traverse
|
||||||
|
for (int i = 0; i < dataArray.size(); i++) {
|
||||||
|
JSONObject day = dataArray.getJSONObject(i);
|
||||||
|
|
||||||
|
// 获取日期
|
||||||
|
String date = day.getJSONObject("range").getStr("date");
|
||||||
|
|
||||||
|
// 获取当天编码时间
|
||||||
|
JSONObject grandTotal = day.getJSONObject("grand_total");
|
||||||
|
double total_seconds = grandTotal.getDouble("total_seconds");
|
||||||
|
int total_minutes = (int) (total_seconds / 60);
|
||||||
|
|
||||||
|
// Map 存储
|
||||||
|
Map<String, Object> activity = new HashMap<>();
|
||||||
|
activity.put("date", date);
|
||||||
|
activity.put("total_minutes", total_minutes);
|
||||||
|
|
||||||
|
dailyActivities.add(activity);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return dailyActivities;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HashMap<String, Object> getLast7DaysCardData() {
|
||||||
|
List<Map<String, Object>> daysData = this.getLast7DaysData();
|
||||||
|
int totalMinutes = 0;
|
||||||
|
for (Map<String, Object> dayData : daysData) {
|
||||||
|
totalMinutes += (int) dayData.get("total_minutes");
|
||||||
|
}
|
||||||
|
|
||||||
|
HashMap<String, Object> cardData = new HashMap<>();
|
||||||
|
cardData.put("total_time", totalMinutes);
|
||||||
|
cardData.put("average_time", totalMinutes / 7);
|
||||||
|
|
||||||
|
// 图表
|
||||||
|
// 日期格式化器
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("M/d");
|
||||||
|
// 构造 values 数组
|
||||||
|
List<Map<String, Object>> valuesList = new ArrayList<>();
|
||||||
|
for (int i = 0; i < daysData.size(); i++) {
|
||||||
|
Map<String, Object> entry = daysData.get(i);
|
||||||
|
String originalDate = (String) entry.get("date");
|
||||||
|
Integer singleMinutes = (Integer) entry.get("total_minutes");
|
||||||
|
// 将 "2025-10-26" 转换为 "10/26"
|
||||||
|
LocalDate date = LocalDate.parse(originalDate);
|
||||||
|
String formattedDate = date.format(formatter);
|
||||||
|
// 构造数据项
|
||||||
|
Map<String, Object> item = new HashMap<>();
|
||||||
|
item.put("date", formattedDate);
|
||||||
|
item.put("day", "Day" + (i + 1)); // Day1, Day2, ...
|
||||||
|
item.put("minutes", singleMinutes);
|
||||||
|
valuesList.add(item);
|
||||||
|
}
|
||||||
|
// 构造 axes 数组
|
||||||
|
List<Map<String, Object>> axesList = new ArrayList<>();
|
||||||
|
// 构造第一个轴(y轴)
|
||||||
|
Map<String, Object> axisY = new HashMap<>();
|
||||||
|
axisY.put("orient", "left");
|
||||||
|
Map<String, Object> titleY = new HashMap<>();
|
||||||
|
titleY.put("text", "编码时长(分钟)");
|
||||||
|
axisY.put("title", titleY);
|
||||||
|
axesList.add(axisY);
|
||||||
|
// 构造第二个轴(x轴)
|
||||||
|
Map<String, Object> axisX = new HashMap<>();
|
||||||
|
axisX.put("orient", "bottom");
|
||||||
|
Map<String, Object> titleX = new HashMap<>();
|
||||||
|
titleX.put("text", "日期");
|
||||||
|
axisX.put("title", titleX);
|
||||||
|
axesList.add(axisX);
|
||||||
|
// 构造 data 对象
|
||||||
|
Map<String, Object> dataMap = new HashMap<>();
|
||||||
|
dataMap.put("values", valuesList);
|
||||||
|
// 构造 label
|
||||||
|
Map<String, Object> labelMap = new HashMap<>();
|
||||||
|
labelMap.put("visible", true);
|
||||||
|
// 构造 legends
|
||||||
|
Map<String, Object> legendsMap = new HashMap<>();
|
||||||
|
legendsMap.put("orient", "top");
|
||||||
|
legendsMap.put("visible", true);
|
||||||
|
// 构造 chartConfig 对象
|
||||||
|
Map<String, Object> chartConfig = new HashMap<>();
|
||||||
|
chartConfig.put("axes", axesList);
|
||||||
|
chartConfig.put("data", dataMap);
|
||||||
|
chartConfig.put("label", labelMap);
|
||||||
|
chartConfig.put("legends", legendsMap);
|
||||||
|
chartConfig.put("seriesField", "day");
|
||||||
|
chartConfig.put("title", new HashMap<>(Map.of("text", "每日编码时长(分钟)")));
|
||||||
|
chartConfig.put("type", "bar");
|
||||||
|
chartConfig.put("xField", "date");
|
||||||
|
chartConfig.put("yField", "minutes");
|
||||||
|
|
||||||
|
cardData.put("chart", chartConfig);
|
||||||
|
|
||||||
|
return cardData;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package cn.hezhaohui.lark.client.impl;
|
||||||
|
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class WakaTimeClientImplTest {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private WakaTimeClientImpl wakaTimeClient;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getLast7DaysData() {
|
||||||
|
String last7DaysData = wakaTimeClient.getLast7DaysData();
|
||||||
|
System.out.println(last7DaysData);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package cn.hezhaohui.lark.service;
|
||||||
|
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class WakaTimeServiceTest {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private WakaTimeService wakaTimeService;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getLast7DaysData() {
|
||||||
|
List<Map<String, Object>> last7DaysData = wakaTimeService.getLast7DaysData();
|
||||||
|
// System.out.println(last7DaysData);
|
||||||
|
for (Map<String, Object> data : last7DaysData) {
|
||||||
|
System.out.println(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getLast7DaysCardData() {
|
||||||
|
Map<String, Object> last7DaysCardData = wakaTimeService.getLast7DaysCardData();
|
||||||
|
System.out.println(last7DaysCardData);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user