Compare commits
15
Commits
27cb78112d
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e6111188c1 | ||
|
|
ea8c18b18b | ||
|
|
5ddf362834 | ||
|
|
dbee3a5b12 | ||
|
|
2372b7ebae | ||
|
|
d4afe0e923 | ||
|
|
d76deecb3d | ||
|
|
c4b5927d9d | ||
|
|
db41860804 | ||
|
|
de0d0060c6 | ||
|
|
df4a138159 | ||
|
|
c50c876a53 | ||
|
|
b900377f4f | ||
|
|
2c51bc59e7 | ||
|
|
eb1bbe78a1 |
@@ -0,0 +1,77 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 设置变量
|
||||||
|
REPO_URL="http://47.121.181.112:3000/wonder/stardew-valley.git"
|
||||||
|
PROJECT_DIR="/opt/stardew-valley"
|
||||||
|
MAVEN_CMD="mvn clean package -Dmaven.test.skip=true" # 跳过测试(编译 & 执行都跳过)
|
||||||
|
APP_NAME="stardew-valley" # PM2 中的应用名称
|
||||||
|
JAR_FILE=""
|
||||||
|
DEPLOY_DIR="/opt/stardew-valley/target" # 你可以指定部署目录,也可以直接使用 target 目录
|
||||||
|
|
||||||
|
# 检查依赖是否安装
|
||||||
|
if ! command -v git &> /dev/null; then
|
||||||
|
echo "错误:Git 未安装,请先安装 Git。"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! command -v mvn &> /dev/null; then
|
||||||
|
echo "错误:Maven 未安装,请先安装 Maven。"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! command -v pm2 &> /dev/null; then
|
||||||
|
echo "错误:PM2 未安装,请先安装 PM2。"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 克隆或拉取代码
|
||||||
|
echo "正在克隆或拉取仓库 $REPO_URL 到 $PROJECT_DIR ..."
|
||||||
|
if [ -d "$PROJECT_DIR" ]; then
|
||||||
|
echo "目录 $PROJECT_DIR 已存在,正在拉取最新代码..."
|
||||||
|
cd "$PROJECT_DIR" || { echo "无法进入目录 $PROJECT_DIR"; exit 1; }
|
||||||
|
git pull origin main
|
||||||
|
else
|
||||||
|
git clone "$REPO_URL" "$PROJECT_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 进入项目目录
|
||||||
|
cd "$PROJECT_DIR" || { echo "无法进入目录 $PROJECT_DIR"; exit 1; }
|
||||||
|
|
||||||
|
# 执行 Maven 构建(跳过测试)
|
||||||
|
echo "正在执行 Maven 构建(跳过测试)..."
|
||||||
|
$MAVEN_CMD
|
||||||
|
|
||||||
|
# 检查构建是否成功
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Maven 构建失败,退出脚本。"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 查找生成的 JAR 文件
|
||||||
|
JAR_FILE=$(find "$PROJECT_DIR/target" -type f -name "*.jar" | head -n 1)
|
||||||
|
|
||||||
|
if [ -z "$JAR_FILE" ]; then
|
||||||
|
echo "未找到 JAR 文件,构建可能失败或项目类型不识别。"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "找到 JAR 文件: $JAR_FILE"
|
||||||
|
|
||||||
|
# 部署文件(可选,也可直接在 target 目录下启动)
|
||||||
|
# 可以选择是否拷贝到其他目录(比如 /opt/stardew-valley/app/)
|
||||||
|
# 如果你不需要部署到其他目录,可以直接使用 target 目录
|
||||||
|
|
||||||
|
echo "部署 JAR 文件到 $DEPLOY_DIR ..."
|
||||||
|
# 如果你不需要复制,可以去掉这一行
|
||||||
|
# cp "$JAR_FILE" "$DEPLOY_DIR/"
|
||||||
|
|
||||||
|
# 删除旧的 PM2 进程
|
||||||
|
echo "删除 PM2 中的旧进程 $APP_NAME..."
|
||||||
|
pm2 delete "$APP_NAME" > /dev/null 2>&1
|
||||||
|
|
||||||
|
# 启动 Java 应用
|
||||||
|
echo "正在启动 Java 应用..."
|
||||||
|
pm2 start "java -jar $JAR_FILE" --no-daemon --name "$APP_NAME"
|
||||||
|
|
||||||
|
# 提示信息
|
||||||
|
echo "部署和启动完成!"
|
||||||
@@ -41,6 +41,12 @@
|
|||||||
<artifactId>spring-ai-starter-model-openai</artifactId>
|
<artifactId>spring-ai-starter-model-openai</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.larksuite.oapi</groupId>
|
||||||
|
<artifactId>oapi-sdk</artifactId>
|
||||||
|
<version>2.4.24</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.xiaoymin</groupId>
|
<groupId>com.github.xiaoymin</groupId>
|
||||||
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
|
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
|
||||||
@@ -52,10 +58,32 @@
|
|||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hutool</groupId>
|
||||||
|
<artifactId>hutool-all</artifactId>
|
||||||
|
<version>5.8.9</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>repackage</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.wonderland.stardewvalley;
|
package com.wonderland.stardewvalley;
|
||||||
|
|
||||||
|
import com.wonderland.stardewvalley.util.lark.EventListener;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
@@ -7,5 +8,6 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|||||||
public class Application {
|
public class Application {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
SpringApplication.run(Application.class, args);
|
SpringApplication.run(Application.class, args);
|
||||||
|
EventListener.listen();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package com.wonderland.stardewvalley.common.constant;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class BackGroundConstant {
|
||||||
|
|
||||||
|
public static final String BACKGROUND_SPRING = "春天";
|
||||||
|
public static final String BACKGROUND_SUMMER = "夏天";
|
||||||
|
public static final String BACKGROUND_AUTUMN = "秋天";
|
||||||
|
public static final String BACKGROUND_WINTER = "冬天";
|
||||||
|
|
||||||
|
public static final String BACKGROUND_SPRING_DESCRIPTION = "“春种一粒粟,秋收万颗子”\n" +
|
||||||
|
"耕种 收获提升,户外活动(节日)比例增加";
|
||||||
|
public static final String BACKGROUND_SUMMER_DESCRIPTION = "“日复一日的劳作,是生活的底色”\n" +
|
||||||
|
"钓鱼 收获提升,室内活动(节日)比例增加";
|
||||||
|
public static final String BACKGROUND_AUTUMN_DESCRIPTION = "“收获的喜悦,也伴随着失去的阵痛”\n" +
|
||||||
|
"耕种 收获提升,户外活动(节日)比例增加,随机事件大幅增加";
|
||||||
|
public static final String BACKGROUND_WINTER_DESCRIPTION = "“寒冷的季节,也是心灵的沉淀”\n" +
|
||||||
|
"作息 影响健康值幅度增加,室内活动(节日)比例增加";
|
||||||
|
|
||||||
|
public static final String BACKGROUND_WEATHER = "【要求】请根据传入的今日数据,采用符合的语气,emjoy和符号,带一点想象,用简洁的语句,描述一下想象中的风景,体感,并附带一点小Tips。\n" +
|
||||||
|
"【输出格式】今天的星露谷....(控制在30字)\\nTips。\n" +
|
||||||
|
"【输出示例】\n" +
|
||||||
|
"今天的星露谷天气阴沉,气温舒适,北风轻轻吹拂,风力微弱,湿度较高,仿佛连空气都带着一丝凉意。这种天气最适合在家中泡一杯热茶,或者在庭院里摆上几张藤椅,享受难得的宁静。\n" +
|
||||||
|
"Tips:可以尝试在这样的天气里种植一些耐阴植物,比如蕨类或苔藓,为你的农场增添一抹绿意哦!\uD83D\uDE09\uD83C\uDF31";
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.wonderland.stardewvalley.common.constant;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public enum CityCode {
|
||||||
|
|
||||||
|
WuHan("420100");
|
||||||
|
|
||||||
|
private final String code;
|
||||||
|
|
||||||
|
CityCode(String code){
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.wonderland.stardewvalley.common.constant;
|
||||||
|
|
||||||
|
public class GuideConstant {
|
||||||
|
|
||||||
|
final public static String GUIDE = "\uD83C\uDF31 在这个名为“如果人生是星露谷”的世界中,玩家扮演的是一位现实世界中的普通人 ,在某种“精神投射”或“虚拟现实”中,进入了一个与《星露谷物语》相似的模拟世界。这个世界并非简单的幻想乡,而是对现实生活的重构与映射 ,玩家通过在现实世界中“工作、探索、运动”等行为,影响游戏中的生活节奏与心理状态。\n" +
|
||||||
|
"\n" +
|
||||||
|
"\uD83C\uDFAE 游戏说明:\n" +
|
||||||
|
"\uD83C\uDF06 车水马龙的街道,拥挤的人潮,在这充满快节奏的水泥森林里,人们被巨大的压力裹挟着,疲惫不堪,宛若行尸走肉。改不完的稿子,数不完的ddl,望不到头的前路,许久没体会过的放松....生活什么时变得这么累了\n" +
|
||||||
|
"\n" +
|
||||||
|
"\uD83C\uDFD9 你被困在水泥森林里多久了?你又有多久没给自己好好地放个假了?你童年的星星依然在天上等着你,但你还能找到回家的路吗?\u200B \n" +
|
||||||
|
"\n" +
|
||||||
|
"\uD83C\uDF3E 放下城市的喧嚣,放下心里的压力,拿起一杆锄头,和我们一起,去往一个叫“星露谷”的地方吧。";
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package com.wonderland.stardewvalley.common.constant;
|
||||||
|
|
||||||
|
public class LarkConstant {
|
||||||
|
|
||||||
|
final public static String APP_ID = "cli_a876d25014e9100e";
|
||||||
|
final public static String APP_SECRET = "8rSGfa6nLgB8vQmQRFSzodK4AozlFP3U";
|
||||||
|
final public static String USER_OPEN_ID = "ou_857c58ee28b89f44c4ecc939a83b2476";
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package com.wonderland.stardewvalley.common.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 运行时异常封装为业务异常
|
||||||
|
*/
|
||||||
|
public class BusinessException extends RuntimeException{
|
||||||
|
|
||||||
|
private final int code;
|
||||||
|
|
||||||
|
public BusinessException(int code, String message) {
|
||||||
|
super(message);
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BusinessException(ErrorCode errorCode) {
|
||||||
|
super(errorCode.getMessage());
|
||||||
|
this.code = errorCode.getCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BusinessException(ErrorCode errorCode, String message) {
|
||||||
|
super(message);
|
||||||
|
this.code = errorCode.getCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package com.wonderland.stardewvalley.common.exception;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误码
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public enum ErrorCode {
|
||||||
|
|
||||||
|
SUCCESS(0, "ok"),
|
||||||
|
PARAMS_ERROR(40000, "请求参数错误"),
|
||||||
|
NOT_FOUND_ERROR(40400, "请求数据不存在"),
|
||||||
|
SYSTEM_ERROR(50000, "系统内部异常"),
|
||||||
|
OPERATION_ERROR(50001, "操作失败");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态码
|
||||||
|
*/
|
||||||
|
private final int code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 信息
|
||||||
|
*/
|
||||||
|
private final String message;
|
||||||
|
|
||||||
|
ErrorCode(int code, String message) {
|
||||||
|
this.code = code;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.wonderland.stardewvalley.common.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据条件抛出异常
|
||||||
|
*/
|
||||||
|
public class ThrowUtils {
|
||||||
|
|
||||||
|
public static void throwIf(boolean condition, RuntimeException runtimeException) {
|
||||||
|
if (condition) {
|
||||||
|
throw runtimeException;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void throwIf(boolean condition, ErrorCode errorCode) {
|
||||||
|
throwIf(condition, new BusinessException(errorCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void throwIf(boolean condition, ErrorCode errorCode, String message) {
|
||||||
|
throwIf(condition, new BusinessException(errorCode, message));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
package com.wonderland.stardewvalley.constant;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
public class BackGroundConstant {
|
|
||||||
|
|
||||||
private static final String BACKGROUND_SPRING = "春天";
|
|
||||||
private static final String BACKGROUND_SUMMER = "夏天";
|
|
||||||
private static final String BACKGROUND_AUTUMN = "秋天";
|
|
||||||
private static final String BACKGROUND_WINTER = "冬天";
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
package com.wonderland.stardewvalley.controller;
|
package com.wonderland.stardewvalley.controller;
|
||||||
|
|
||||||
import com.wonderland.stardewvalley.ai.ChatUtil;
|
import com.wonderland.stardewvalley.service.ai.ChatUtil;
|
||||||
import com.wonderland.stardewvalley.entity.AIChatRequest;
|
import com.wonderland.stardewvalley.entity.AIChatRequest;
|
||||||
|
import com.wonderland.stardewvalley.entity.BaseResponse;
|
||||||
|
import com.wonderland.stardewvalley.util.response.ResultUtil;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
@@ -16,7 +18,7 @@ public class ChatController {
|
|||||||
private ChatUtil chatUtil;
|
private ChatUtil chatUtil;
|
||||||
|
|
||||||
@PostMapping
|
@PostMapping
|
||||||
public String chat(@RequestBody AIChatRequest aiChatRequest) {
|
public BaseResponse<String> chat(@RequestBody AIChatRequest aiChatRequest) {
|
||||||
return chatUtil.doChat(aiChatRequest.getBackGround(), aiChatRequest.getContent());
|
return ResultUtil.success(chatUtil.doChat(aiChatRequest.getBackGround(), aiChatRequest.getContent()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.wonderland.stardewvalley.controller;
|
package com.wonderland.stardewvalley.controller;
|
||||||
|
|
||||||
|
import com.wonderland.stardewvalley.entity.BaseResponse;
|
||||||
|
import com.wonderland.stardewvalley.util.response.ResultUtil;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
@@ -9,7 +11,7 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
public class HealthController {
|
public class HealthController {
|
||||||
|
|
||||||
@GetMapping("/ping")
|
@GetMapping("/ping")
|
||||||
public String healthTest() {
|
public BaseResponse<String> healthTest() {
|
||||||
return "Welcome to Stardew Valley!";
|
return ResultUtil.success("Welcome to Stardew Valley!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.wonderland.stardewvalley.controller;
|
||||||
|
|
||||||
|
import com.wonderland.stardewvalley.common.constant.GuideConstant;
|
||||||
|
import com.wonderland.stardewvalley.entity.BaseResponse;
|
||||||
|
import com.wonderland.stardewvalley.util.lark.LarkUtil;
|
||||||
|
import com.wonderland.stardewvalley.util.response.ResultUtil;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("lark")
|
||||||
|
public class LarkController {
|
||||||
|
|
||||||
|
@GetMapping("welcome")
|
||||||
|
public BaseResponse<String> welcome() throws Exception {
|
||||||
|
LarkUtil.sendText(GuideConstant.GUIDE);
|
||||||
|
return ResultUtil.success("发送成功");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,9 @@ package com.wonderland.stardewvalley.entity;
|
|||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 封装 AI 请求:背景信息 + 内容
|
||||||
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class AIChatRequest {
|
public class AIChatRequest {
|
||||||
private String backGround;
|
private String backGround;
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.wonderland.stardewvalley.entity;
|
||||||
|
|
||||||
|
|
||||||
|
import com.wonderland.stardewvalley.common.exception.ErrorCode;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class BaseResponse<T> implements Serializable {
|
||||||
|
|
||||||
|
private int code;
|
||||||
|
|
||||||
|
private T data;
|
||||||
|
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
|
||||||
|
public BaseResponse(int code, T data, String message) {
|
||||||
|
this.code = code;
|
||||||
|
this.data = data;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public BaseResponse(int code, T data) {
|
||||||
|
this(code, data, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public BaseResponse(ErrorCode errorCode) {
|
||||||
|
this(errorCode.getCode(), null, errorCode.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.wonderland.stardewvalley.entity.game;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
public class Weather {
|
||||||
|
private String weather;
|
||||||
|
private String temperature;
|
||||||
|
private String windPower;
|
||||||
|
private String windDirection;
|
||||||
|
private String reportTime;
|
||||||
|
private String humidity;
|
||||||
|
private String content;
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.wonderland.stardewvalley.handle;
|
||||||
|
|
||||||
|
|
||||||
|
import com.wonderland.stardewvalley.entity.game.Weather;
|
||||||
|
import com.wonderland.stardewvalley.util.lark.LarkUtil;
|
||||||
|
import com.wonderland.stardewvalley.util.weather.WeatherUtil;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class WeatherHandle {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private LarkUtil larkUtil;
|
||||||
|
|
||||||
|
public void sendCard() throws Exception {
|
||||||
|
Weather weather = WeatherUtil.getWeather();
|
||||||
|
larkUtil.sendWeatherCard(weather);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.wonderland.stardewvalley.lark.card;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public enum CardTemplate {
|
||||||
|
CARD_TEMPLATE_WEATHER("AAqxas5etOJDx", "1.0.5"),
|
||||||
|
CARD_TEMPLATE_FARM("AAqxaYo9rbXPa", "1.0.8"),
|
||||||
|
CARD_TEMPLATE_FISH("AAqxauQ2FQuSF", "1.0.4"),
|
||||||
|
CARD_TEMPLATE_MINE("AAqxarffytU2e", "1.0.4"),
|
||||||
|
CARD_TEMPLATE_HELP("AAqxaCRidel6g", "1.0.5"),
|
||||||
|
CARD_TEMPLATE_LUCK("AAqxaScwjaUB3", "1.0.2");
|
||||||
|
|
||||||
|
private String cardId;
|
||||||
|
private String version;
|
||||||
|
|
||||||
|
CardTemplate(String cardId, String version) {
|
||||||
|
this.cardId = cardId;
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-2
@@ -1,6 +1,5 @@
|
|||||||
package com.wonderland.stardewvalley.ai;
|
package com.wonderland.stardewvalley.service.ai;
|
||||||
|
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
import org.springframework.ai.chat.client.ChatClient;
|
import org.springframework.ai.chat.client.ChatClient;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.wonderland.stardewvalley.util.bean;
|
||||||
|
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.ApplicationContextAware;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class SpringContextUtil implements ApplicationContextAware {
|
||||||
|
|
||||||
|
private static ApplicationContext context;
|
||||||
|
public static <T> T getBean(Class<T> beanClass) {
|
||||||
|
return context.getBean(beanClass);
|
||||||
|
}
|
||||||
|
public static <T> T getBean(String name, Class<T> beanClass) {
|
||||||
|
return context.getBean(name, beanClass);
|
||||||
|
}
|
||||||
|
public static Object getBean(String name) {
|
||||||
|
return context.getBean(name);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void setApplicationContext(ApplicationContext appContext) throws BeansException {
|
||||||
|
context = appContext;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
package com.wonderland.stardewvalley.util.lark;
|
||||||
|
|
||||||
|
import com.lark.oapi.core.utils.Jsons;
|
||||||
|
import com.lark.oapi.event.EventDispatcher;
|
||||||
|
import com.lark.oapi.service.application.ApplicationService;
|
||||||
|
import com.lark.oapi.service.application.v6.model.P2BotMenuV6;
|
||||||
|
import com.lark.oapi.service.im.ImService;
|
||||||
|
import com.lark.oapi.service.im.v1.model.P2MessageReceiveV1;
|
||||||
|
import com.lark.oapi.ws.Client;
|
||||||
|
import com.wonderland.stardewvalley.common.constant.LarkConstant;
|
||||||
|
import com.wonderland.stardewvalley.handle.WeatherHandle;
|
||||||
|
import com.wonderland.stardewvalley.util.bean.SpringContextUtil;
|
||||||
|
|
||||||
|
public class EventListener {
|
||||||
|
|
||||||
|
// onP2MessageReceiveV1 为接收消息 v2.0;onCustomizedEvent 内的 message 为接收消息 v1.0。
|
||||||
|
private static final EventDispatcher EVENT_HANDLER = EventDispatcher.newBuilder("", "")
|
||||||
|
.onP2MessageReceiveV1(new ImService.P2MessageReceiveV1Handler() {
|
||||||
|
@Override
|
||||||
|
public void handle(P2MessageReceiveV1 event) throws Exception {
|
||||||
|
System.out.printf("[ onP2MessageReceiveV1 access ], data: %s\n", Jsons.DEFAULT.toJson(event.getEvent()));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 首次使用应用
|
||||||
|
// .onCustomizedEvent("p2p_chat_create", new CustomEventHandler() {
|
||||||
|
// @Override
|
||||||
|
// public void handle(EventReq event) throws Exception {
|
||||||
|
// System.out.printf("[ onCustomizedEvent access ], type: message, data: %s\n", new String(event.getBody(), StandardCharsets.UTF_8));
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// 监听点击菜单事件
|
||||||
|
.onP2BotMenuV6(new ApplicationService.P2BotMenuV6Handler() {
|
||||||
|
@Override
|
||||||
|
public void handle(P2BotMenuV6 event) throws Exception {
|
||||||
|
String eventKey = event.getEvent().getEventKey();
|
||||||
|
if (eventKey.equals("weather")) {
|
||||||
|
WeatherHandle weatherHandle = SpringContextUtil.getBean(WeatherHandle.class);
|
||||||
|
weatherHandle.sendCard();
|
||||||
|
} else if (eventKey.equals("farm")) {
|
||||||
|
LarkUtil.sendFarmCard();
|
||||||
|
} else if (eventKey.equals("fish")) {
|
||||||
|
LarkUtil.sendFishCard();
|
||||||
|
} else if (eventKey.equals("mine")) {
|
||||||
|
LarkUtil.sendMineCard();
|
||||||
|
} else if (eventKey.equals("help")) {
|
||||||
|
LarkUtil.sendHelpCard();
|
||||||
|
} else if (eventKey.equals("luck")) {
|
||||||
|
LarkUtil.sendLuckCard();
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.printf("[ onP2BotMenuV6 access ], data: %s\n", Jsons.DEFAULT.toJson(event.getEvent()));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
public static void listen() {
|
||||||
|
Client cli = new Client.Builder(LarkConstant.APP_ID, LarkConstant.APP_SECRET)
|
||||||
|
.eventHandler(EVENT_HANDLER)
|
||||||
|
.build();
|
||||||
|
cli.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,402 @@
|
|||||||
|
package com.wonderland.stardewvalley.util.lark;
|
||||||
|
|
||||||
|
|
||||||
|
import cn.hutool.core.util.IdUtil;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
import com.lark.oapi.Client;
|
||||||
|
import com.lark.oapi.core.utils.Jsons;
|
||||||
|
import com.lark.oapi.service.im.v1.model.CreateMessageReq;
|
||||||
|
import com.lark.oapi.service.im.v1.model.CreateMessageReqBody;
|
||||||
|
import com.lark.oapi.service.im.v1.model.CreateMessageResp;
|
||||||
|
import com.wonderland.stardewvalley.common.constant.BackGroundConstant;
|
||||||
|
import com.wonderland.stardewvalley.common.constant.LarkConstant;
|
||||||
|
import com.wonderland.stardewvalley.entity.game.Weather;
|
||||||
|
import com.wonderland.stardewvalley.lark.card.CardTemplate;
|
||||||
|
import com.wonderland.stardewvalley.service.ai.ChatUtil;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class LarkUtil {
|
||||||
|
// SDK 使用文档:https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/server-side-sdk/java-sdk-guide/preparations
|
||||||
|
// 复制该 Demo 后, 需要将 "YOUR_APP_ID", "YOUR_APP_SECRET" 替换为自己应用的 APP_ID, APP_SECRET.
|
||||||
|
// 以下示例代码默认根据文档示例值填充,如果存在代码问题,请在 API 调试台填上相关必要参数后再复制代码使用
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ChatUtil chatUtil;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送简单的文本消息
|
||||||
|
* @param content 发送的内容
|
||||||
|
* @throws Exception 异常
|
||||||
|
*/
|
||||||
|
public static void sendText(String content) throws Exception {
|
||||||
|
// 构建client
|
||||||
|
Client client = Client.newBuilder(LarkConstant.APP_ID, LarkConstant.APP_SECRET).build();
|
||||||
|
|
||||||
|
// 组装文本 JSON
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
ObjectNode node = mapper.createObjectNode();
|
||||||
|
node.put("text", content);
|
||||||
|
log.info("[Lark] 发送消息:{}", node.toString());
|
||||||
|
|
||||||
|
// 创建请求对象
|
||||||
|
CreateMessageReq req = CreateMessageReq.newBuilder()
|
||||||
|
.receiveIdType("open_id")
|
||||||
|
.createMessageReqBody(CreateMessageReqBody.newBuilder()
|
||||||
|
.receiveId(LarkConstant.USER_OPEN_ID)
|
||||||
|
.msgType("text")
|
||||||
|
.content(node.toString())
|
||||||
|
.uuid(IdUtil.randomUUID())
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// 发起请求
|
||||||
|
CreateMessageResp resp = client.im().v1().message().create(req);
|
||||||
|
|
||||||
|
// 处理服务端错误
|
||||||
|
if(!resp.success()) {
|
||||||
|
System.out.println(String.format("code:%s,msg:%s,reqId:%s, resp:%s",
|
||||||
|
resp.getCode(), resp.getMsg(), resp.getRequestId(), Jsons.createGSON(true, false).toJson(JsonParser.parseString(new String(resp.getRawResponse().getBody(), StandardCharsets.UTF_8)))));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 业务数据处理
|
||||||
|
System.out.println(Jsons.DEFAULT.toJson(resp.getData()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendWeatherCard(Weather weather) throws Exception {
|
||||||
|
// 构建client
|
||||||
|
Client client = Client.newBuilder(LarkConstant.APP_ID, LarkConstant.APP_SECRET).build();
|
||||||
|
|
||||||
|
// 生成uuid
|
||||||
|
String uuid = IdUtil.randomUUID().toString();
|
||||||
|
|
||||||
|
// 卡片参数
|
||||||
|
// String textParam = JSONUtil.toJsonStr(weather);
|
||||||
|
// log.info(textParam);
|
||||||
|
|
||||||
|
|
||||||
|
// 构建卡片:对于不同的卡片,只需要给出不同的 模板id 版本号 变量字段
|
||||||
|
|
||||||
|
String content = chatUtil.doChat(BackGroundConstant.BACKGROUND_WEATHER, weather.toString());
|
||||||
|
weather.setContent(content);
|
||||||
|
log.info("[LarkUtil] Set Content via LLM: {}", content);
|
||||||
|
|
||||||
|
Map<String, Object> templateData = new HashMap<>();
|
||||||
|
templateData.put("template_id", CardTemplate.CARD_TEMPLATE_WEATHER.getCardId());
|
||||||
|
templateData.put("template_version_name", CardTemplate.CARD_TEMPLATE_WEATHER.getVersion());
|
||||||
|
templateData.put("template_variable", weather);
|
||||||
|
// String jsonCardContent = Jsons.DEFAULT.toJson(templateData);
|
||||||
|
|
||||||
|
Map<String, Object> jsonContent = new HashMap<>();
|
||||||
|
jsonContent.put("data", templateData);
|
||||||
|
jsonContent.put("type", "template");
|
||||||
|
String json = Jsons.DEFAULT.toJson(jsonContent);
|
||||||
|
|
||||||
|
log.info(json);
|
||||||
|
|
||||||
|
// 创建请求对象
|
||||||
|
CreateMessageReq req = CreateMessageReq.newBuilder()
|
||||||
|
.receiveIdType("open_id")
|
||||||
|
.createMessageReqBody(CreateMessageReqBody.newBuilder()
|
||||||
|
.receiveId(LarkConstant.USER_OPEN_ID)
|
||||||
|
.msgType("interactive")
|
||||||
|
.content(json)
|
||||||
|
.uuid(uuid)
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// 发起请求
|
||||||
|
CreateMessageResp resp = client.im().v1().message().create(req);
|
||||||
|
|
||||||
|
// 处理服务端错误
|
||||||
|
if(!resp.success()) {
|
||||||
|
System.out.println(String.format("code:%s,msg:%s,reqId:%s, resp:%s",
|
||||||
|
resp.getCode(), resp.getMsg(), resp.getRequestId(), Jsons.createGSON(true, false).toJson(JsonParser.parseString(new String(resp.getRawResponse().getBody(), StandardCharsets.UTF_8)))));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 业务数据处理
|
||||||
|
System.out.println(Jsons.DEFAULT.toJson(resp.getData()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendFarmCard() throws Exception {
|
||||||
|
// 构建client
|
||||||
|
Client client = Client.newBuilder(LarkConstant.APP_ID, LarkConstant.APP_SECRET).build();
|
||||||
|
|
||||||
|
// 生成uuid
|
||||||
|
String uuid = IdUtil.randomUUID().toString();
|
||||||
|
|
||||||
|
// 卡片参数
|
||||||
|
// String textParam = JSONUtil.toJsonStr(weather);
|
||||||
|
// log.info(textParam);
|
||||||
|
|
||||||
|
|
||||||
|
// 构建卡片:对于不同的卡片,只需要给出不同的 模板id 版本号 变量字段
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Map<String, Object> templateData = new HashMap<>();
|
||||||
|
templateData.put("template_id", CardTemplate.CARD_TEMPLATE_FARM.getCardId());
|
||||||
|
templateData.put("template_version_name", CardTemplate.CARD_TEMPLATE_FARM.getVersion());
|
||||||
|
// templateData.put("template_variable", "");
|
||||||
|
// String jsonCardContent = Jsons.DEFAULT.toJson(templateData);
|
||||||
|
|
||||||
|
Map<String, Object> jsonContent = new HashMap<>();
|
||||||
|
jsonContent.put("data", templateData);
|
||||||
|
jsonContent.put("type", "template");
|
||||||
|
String json = Jsons.DEFAULT.toJson(jsonContent);
|
||||||
|
|
||||||
|
log.info(json);
|
||||||
|
|
||||||
|
// 创建请求对象
|
||||||
|
CreateMessageReq req = CreateMessageReq.newBuilder()
|
||||||
|
.receiveIdType("open_id")
|
||||||
|
.createMessageReqBody(CreateMessageReqBody.newBuilder()
|
||||||
|
.receiveId(LarkConstant.USER_OPEN_ID)
|
||||||
|
.msgType("interactive")
|
||||||
|
.content(json)
|
||||||
|
.uuid(uuid)
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// 发起请求
|
||||||
|
CreateMessageResp resp = client.im().v1().message().create(req);
|
||||||
|
|
||||||
|
// 处理服务端错误
|
||||||
|
if(!resp.success()) {
|
||||||
|
System.out.println(String.format("code:%s,msg:%s,reqId:%s, resp:%s",
|
||||||
|
resp.getCode(), resp.getMsg(), resp.getRequestId(), Jsons.createGSON(true, false).toJson(JsonParser.parseString(new String(resp.getRawResponse().getBody(), StandardCharsets.UTF_8)))));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 业务数据处理
|
||||||
|
System.out.println(Jsons.DEFAULT.toJson(resp.getData()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendFishCard() throws Exception {
|
||||||
|
// 构建client
|
||||||
|
Client client = Client.newBuilder(LarkConstant.APP_ID, LarkConstant.APP_SECRET).build();
|
||||||
|
|
||||||
|
// 生成uuid
|
||||||
|
String uuid = IdUtil.randomUUID().toString();
|
||||||
|
|
||||||
|
// 卡片参数
|
||||||
|
// String textParam = JSONUtil.toJsonStr(weather);
|
||||||
|
// log.info(textParam);
|
||||||
|
|
||||||
|
|
||||||
|
// 构建卡片:对于不同的卡片,只需要给出不同的 模板id 版本号 变量字段
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Map<String, Object> templateData = new HashMap<>();
|
||||||
|
templateData.put("template_id", CardTemplate.CARD_TEMPLATE_FISH.getCardId());
|
||||||
|
templateData.put("template_version_name", CardTemplate.CARD_TEMPLATE_FISH.getVersion());
|
||||||
|
// templateData.put("template_variable", "");
|
||||||
|
// String jsonCardContent = Jsons.DEFAULT.toJson(templateData);
|
||||||
|
|
||||||
|
Map<String, Object> jsonContent = new HashMap<>();
|
||||||
|
jsonContent.put("data", templateData);
|
||||||
|
jsonContent.put("type", "template");
|
||||||
|
String json = Jsons.DEFAULT.toJson(jsonContent);
|
||||||
|
|
||||||
|
log.info(json);
|
||||||
|
|
||||||
|
// 创建请求对象
|
||||||
|
CreateMessageReq req = CreateMessageReq.newBuilder()
|
||||||
|
.receiveIdType("open_id")
|
||||||
|
.createMessageReqBody(CreateMessageReqBody.newBuilder()
|
||||||
|
.receiveId(LarkConstant.USER_OPEN_ID)
|
||||||
|
.msgType("interactive")
|
||||||
|
.content(json)
|
||||||
|
.uuid(uuid)
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// 发起请求
|
||||||
|
CreateMessageResp resp = client.im().v1().message().create(req);
|
||||||
|
|
||||||
|
// 处理服务端错误
|
||||||
|
if(!resp.success()) {
|
||||||
|
System.out.println(String.format("code:%s,msg:%s,reqId:%s, resp:%s",
|
||||||
|
resp.getCode(), resp.getMsg(), resp.getRequestId(), Jsons.createGSON(true, false).toJson(JsonParser.parseString(new String(resp.getRawResponse().getBody(), StandardCharsets.UTF_8)))));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 业务数据处理
|
||||||
|
System.out.println(Jsons.DEFAULT.toJson(resp.getData()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendMineCard() throws Exception {
|
||||||
|
// 构建client
|
||||||
|
Client client = Client.newBuilder(LarkConstant.APP_ID, LarkConstant.APP_SECRET).build();
|
||||||
|
|
||||||
|
// 生成uuid
|
||||||
|
String uuid = IdUtil.randomUUID().toString();
|
||||||
|
|
||||||
|
// 卡片参数
|
||||||
|
// String textParam = JSONUtil.toJsonStr(weather);
|
||||||
|
// log.info(textParam);
|
||||||
|
|
||||||
|
|
||||||
|
// 构建卡片:对于不同的卡片,只需要给出不同的 模板id 版本号 变量字段
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Map<String, Object> templateData = new HashMap<>();
|
||||||
|
templateData.put("template_id", CardTemplate.CARD_TEMPLATE_MINE.getCardId());
|
||||||
|
templateData.put("template_version_name", CardTemplate.CARD_TEMPLATE_MINE.getVersion());
|
||||||
|
// templateData.put("template_variable", "");
|
||||||
|
// String jsonCardContent = Jsons.DEFAULT.toJson(templateData);
|
||||||
|
|
||||||
|
Map<String, Object> jsonContent = new HashMap<>();
|
||||||
|
jsonContent.put("data", templateData);
|
||||||
|
jsonContent.put("type", "template");
|
||||||
|
String json = Jsons.DEFAULT.toJson(jsonContent);
|
||||||
|
|
||||||
|
log.info(json);
|
||||||
|
|
||||||
|
// 创建请求对象
|
||||||
|
CreateMessageReq req = CreateMessageReq.newBuilder()
|
||||||
|
.receiveIdType("open_id")
|
||||||
|
.createMessageReqBody(CreateMessageReqBody.newBuilder()
|
||||||
|
.receiveId(LarkConstant.USER_OPEN_ID)
|
||||||
|
.msgType("interactive")
|
||||||
|
.content(json)
|
||||||
|
.uuid(uuid)
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// 发起请求
|
||||||
|
CreateMessageResp resp = client.im().v1().message().create(req);
|
||||||
|
|
||||||
|
// 处理服务端错误
|
||||||
|
if(!resp.success()) {
|
||||||
|
System.out.println(String.format("code:%s,msg:%s,reqId:%s, resp:%s",
|
||||||
|
resp.getCode(), resp.getMsg(), resp.getRequestId(), Jsons.createGSON(true, false).toJson(JsonParser.parseString(new String(resp.getRawResponse().getBody(), StandardCharsets.UTF_8)))));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 业务数据处理
|
||||||
|
System.out.println(Jsons.DEFAULT.toJson(resp.getData()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendHelpCard() throws Exception {
|
||||||
|
// 构建client
|
||||||
|
Client client = Client.newBuilder(LarkConstant.APP_ID, LarkConstant.APP_SECRET).build();
|
||||||
|
|
||||||
|
// 生成uuid
|
||||||
|
String uuid = IdUtil.randomUUID().toString();
|
||||||
|
|
||||||
|
// 卡片参数
|
||||||
|
// String textParam = JSONUtil.toJsonStr(weather);
|
||||||
|
// log.info(textParam);
|
||||||
|
|
||||||
|
|
||||||
|
// 构建卡片:对于不同的卡片,只需要给出不同的 模板id 版本号 变量字段
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Map<String, Object> templateData = new HashMap<>();
|
||||||
|
templateData.put("template_id", CardTemplate.CARD_TEMPLATE_HELP.getCardId());
|
||||||
|
templateData.put("template_version_name", CardTemplate.CARD_TEMPLATE_HELP.getVersion());
|
||||||
|
// templateData.put("template_variable", "");
|
||||||
|
// String jsonCardContent = Jsons.DEFAULT.toJson(templateData);
|
||||||
|
|
||||||
|
Map<String, Object> jsonContent = new HashMap<>();
|
||||||
|
jsonContent.put("data", templateData);
|
||||||
|
jsonContent.put("type", "template");
|
||||||
|
String json = Jsons.DEFAULT.toJson(jsonContent);
|
||||||
|
|
||||||
|
log.info(json);
|
||||||
|
|
||||||
|
// 创建请求对象
|
||||||
|
CreateMessageReq req = CreateMessageReq.newBuilder()
|
||||||
|
.receiveIdType("open_id")
|
||||||
|
.createMessageReqBody(CreateMessageReqBody.newBuilder()
|
||||||
|
.receiveId(LarkConstant.USER_OPEN_ID)
|
||||||
|
.msgType("interactive")
|
||||||
|
.content(json)
|
||||||
|
.uuid(uuid)
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// 发起请求
|
||||||
|
CreateMessageResp resp = client.im().v1().message().create(req);
|
||||||
|
|
||||||
|
// 处理服务端错误
|
||||||
|
if(!resp.success()) {
|
||||||
|
System.out.println(String.format("code:%s,msg:%s,reqId:%s, resp:%s",
|
||||||
|
resp.getCode(), resp.getMsg(), resp.getRequestId(), Jsons.createGSON(true, false).toJson(JsonParser.parseString(new String(resp.getRawResponse().getBody(), StandardCharsets.UTF_8)))));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 业务数据处理
|
||||||
|
System.out.println(Jsons.DEFAULT.toJson(resp.getData()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendLuckCard() throws Exception {
|
||||||
|
// 构建client
|
||||||
|
Client client = Client.newBuilder(LarkConstant.APP_ID, LarkConstant.APP_SECRET).build();
|
||||||
|
|
||||||
|
// 生成uuid
|
||||||
|
String uuid = IdUtil.randomUUID().toString();
|
||||||
|
|
||||||
|
// 卡片参数
|
||||||
|
// String textParam = JSONUtil.toJsonStr(weather);
|
||||||
|
// log.info(textParam);
|
||||||
|
|
||||||
|
|
||||||
|
// 构建卡片:对于不同的卡片,只需要给出不同的 模板id 版本号 变量字段
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Map<String, Object> templateData = new HashMap<>();
|
||||||
|
templateData.put("template_id", CardTemplate.CARD_TEMPLATE_LUCK.getCardId());
|
||||||
|
templateData.put("template_version_name", CardTemplate.CARD_TEMPLATE_LUCK.getVersion());
|
||||||
|
// templateData.put("template_variable", "");
|
||||||
|
// String jsonCardContent = Jsons.DEFAULT.toJson(templateData);
|
||||||
|
|
||||||
|
Map<String, Object> jsonContent = new HashMap<>();
|
||||||
|
jsonContent.put("data", templateData);
|
||||||
|
jsonContent.put("type", "template");
|
||||||
|
String json = Jsons.DEFAULT.toJson(jsonContent);
|
||||||
|
|
||||||
|
log.info(json);
|
||||||
|
|
||||||
|
// 创建请求对象
|
||||||
|
CreateMessageReq req = CreateMessageReq.newBuilder()
|
||||||
|
.receiveIdType("open_id")
|
||||||
|
.createMessageReqBody(CreateMessageReqBody.newBuilder()
|
||||||
|
.receiveId(LarkConstant.USER_OPEN_ID)
|
||||||
|
.msgType("interactive")
|
||||||
|
.content(json)
|
||||||
|
.uuid(uuid)
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// 发起请求
|
||||||
|
CreateMessageResp resp = client.im().v1().message().create(req);
|
||||||
|
|
||||||
|
// 处理服务端错误
|
||||||
|
if(!resp.success()) {
|
||||||
|
System.out.println(String.format("code:%s,msg:%s,reqId:%s, resp:%s",
|
||||||
|
resp.getCode(), resp.getMsg(), resp.getRequestId(), Jsons.createGSON(true, false).toJson(JsonParser.parseString(new String(resp.getRawResponse().getBody(), StandardCharsets.UTF_8)))));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 业务数据处理
|
||||||
|
System.out.println(Jsons.DEFAULT.toJson(resp.getData()));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package com.wonderland.stardewvalley.util.response;
|
||||||
|
|
||||||
|
|
||||||
|
import com.wonderland.stardewvalley.entity.BaseResponse;
|
||||||
|
import com.wonderland.stardewvalley.common.exception.ErrorCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回统一的格式
|
||||||
|
*/
|
||||||
|
public class ResultUtil {
|
||||||
|
|
||||||
|
public static <T> BaseResponse<T> success(T data) {
|
||||||
|
return new BaseResponse<>(ErrorCode.SUCCESS.getCode(), data, ErrorCode.SUCCESS.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BaseResponse<?> error(ErrorCode errorCode) {
|
||||||
|
return new BaseResponse<>(errorCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BaseResponse<?> error(int code, String message) {
|
||||||
|
return new BaseResponse<>(code, null, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BaseResponse<?> error(ErrorCode errorCode, String message) {
|
||||||
|
return new BaseResponse<>(errorCode.getCode(), null, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
package com.wonderland.stardewvalley.util.weather;
|
||||||
|
|
||||||
|
import cn.hutool.http.HttpUtil;
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import com.wonderland.stardewvalley.common.constant.CityCode;
|
||||||
|
import com.wonderland.stardewvalley.entity.game.Weather;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
public class WeatherUtil {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 参考文档: https://lbs.amap.com/api/webservice/guide/api/weatherinfo
|
||||||
|
* URL 格式: https://restapi.amap.com/v3/weather/weatherInfo?parameters
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
private static final String API_BASE_URL = "https://restapi.amap.com/v3/weather/weatherInfo";
|
||||||
|
private static final String API_SECRET = "d0f5599ac19a5e4553ba68cd1781d2df";
|
||||||
|
|
||||||
|
private static String createUrl() {
|
||||||
|
StringBuffer stringBuffer = new StringBuffer();
|
||||||
|
String url = stringBuffer
|
||||||
|
.append(API_BASE_URL)
|
||||||
|
.append("?key=")
|
||||||
|
.append(API_SECRET)
|
||||||
|
.append("&city=")
|
||||||
|
.append(CityCode.WuHan.getCode())
|
||||||
|
.append("&extensions=base")
|
||||||
|
.toString();
|
||||||
|
log.info("[Weather] URL: {}", url);
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Weather getWeather() {
|
||||||
|
String url = createUrl();
|
||||||
|
String ans = HttpUtil.get(url);
|
||||||
|
log.info("[Weather] Response: {}", ans);
|
||||||
|
// TODO 封装为需要的对象
|
||||||
|
JSONObject obj = JSONUtil.parseObj(ans);
|
||||||
|
log.info("[Weather] Obj: {}", obj);
|
||||||
|
// 检查返回状态码
|
||||||
|
String status = obj.getStr("status");
|
||||||
|
if (!"1".equals(status)) {
|
||||||
|
String info = obj.getStr("info", "Unknown Error");
|
||||||
|
String errorCode = obj.getStr("infocode", "N/A");
|
||||||
|
log.error("[Weather] Request failed with code: {}, error: {}", errorCode, info);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// 获取天气信息数组
|
||||||
|
JSONObject weatherData = obj.getJSONArray("lives").getJSONObject(0);
|
||||||
|
Weather weather = Weather.builder()
|
||||||
|
.weather(weatherData.getStr("weather"))
|
||||||
|
.temperature(weatherData.getStr("temperature"))
|
||||||
|
.windDirection(weatherData.getStr("winddirection"))
|
||||||
|
.windPower(weatherData.getStr("windpower"))
|
||||||
|
.reportTime(weatherData.getStr("reporttime"))
|
||||||
|
.humidity(weatherData.getStr("humidity"))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
log.info("[Weather] Prepared: {}", weather);
|
||||||
|
return weather;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.wonderland.stardewvalley.ai;
|
||||||
|
|
||||||
|
import com.wonderland.stardewvalley.common.constant.BackGroundConstant;
|
||||||
|
import com.wonderland.stardewvalley.service.ai.ChatUtil;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class ChatUtilTest {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ChatUtil chatUtil;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void doChat() {
|
||||||
|
System.out.println(chatUtil.doChat(BackGroundConstant.BACKGROUND_SPRING + BackGroundConstant.BACKGROUND_SPRING_DESCRIPTION, "根据背景给出春天的特点,不需要输出背景以外的信息"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.wonderland.stardewvalley.lark;
|
||||||
|
|
||||||
|
import com.wonderland.stardewvalley.entity.game.Weather;
|
||||||
|
import com.wonderland.stardewvalley.util.weather.WeatherUtil;
|
||||||
|
import com.wonderland.stardewvalley.util.lark.LarkUtil;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class LarkUtilTest {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private LarkUtil larkUtil;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void sendText() throws Exception {
|
||||||
|
LarkUtil.sendText("\uD83C\uDF31 在这个名为“如果人生是星露谷”的世界中,玩家扮演的是一位现实世界中的普通人 ,在某种“精神投射”或“虚拟现实”中,进入了一个与《星露谷物语》相似的模拟世界。这个世界并非简单的幻想乡,而是对现实生活的重构与映射 ,玩家通过在现实世界中“种田、打工、探索、运动”等行为,影响游戏中的生活节奏与心理状态。\n" +
|
||||||
|
"\n" +
|
||||||
|
"\uD83C\uDFAE 游戏说明:\n" +
|
||||||
|
"\uD83C\uDF06 车水马龙的街道,拥挤的人潮,在这充满快节奏的水泥森林里,人们被巨大的压力裹挟着,疲惫不堪,宛若行尸走肉。改不完的稿子,数不完的ddl,望不到头的前路,许久没体会过的放松....生活什么时变得这么累了\n" +
|
||||||
|
"\n" +
|
||||||
|
"\uD83C\uDFD9 你被困在水泥森林里多久了?你又有多久没给自己好好地放个假了?你童年的星星依然在天上等着你,但你还能找到回家的路吗?\u200B \n" +
|
||||||
|
"\n" +
|
||||||
|
"\uD83C\uDF3E 放下城市的喧嚣,放下心里的压力,拿起一杆锄头,和我们一起,去往一个叫“星露谷”的地方吧。");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void sendWeatherCard() throws Exception {
|
||||||
|
Weather weather = WeatherUtil.getWeather();
|
||||||
|
larkUtil.sendWeatherCard(weather);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.wonderland.stardewvalley.util;
|
||||||
|
|
||||||
|
import com.wonderland.stardewvalley.entity.game.Weather;
|
||||||
|
import com.wonderland.stardewvalley.util.weather.WeatherUtil;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class WeatherUtilTest {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private WeatherUtil weatherUtil;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getWeather() {
|
||||||
|
Weather weather = weatherUtil.getWeather();
|
||||||
|
System.out.println(weather);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user