commit acdbe48502de516f366d99a20b351f10a3f77144
Author: humf <231006755@qq.com>
Date: Sat Jan 31 01:30:29 2026 +0800
初始化
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..51f3478
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,274 @@
+
+
+ 4.0.0
+
+ com.yunying
+ yunying
+ 3.8.8
+
+ yunying
+ http://www.fjyy.com.cn
+ 云赢智能综合管理平台
+
+
+ 3.8.8
+ UTF-8
+ UTF-8
+ 1.8
+ 3.1.1
+ 5.3.39
+ 5.7.12
+ 2.5.15
+ 1.2.23
+ 1.21
+ 3.0.0
+ 2.3.3
+ 1.4.7
+ 2.0.53
+ 6.6.5
+ 2.13.0
+ 4.1.2
+ 2.3
+ 0.9.1
+ 1.2.13
+ 6.8.0
+
+
+
+
+
+
+
+
+ org.springframework
+ spring-framework-bom
+ ${spring-framework.version}
+ pom
+ import
+
+
+
+
+ org.springframework.security
+ spring-security-bom
+ ${spring-security.version}
+ pom
+ import
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ ${spring-boot.version}
+ pom
+ import
+
+
+
+
+ ch.qos.logback
+ logback-core
+ ${logback.version}
+
+
+
+ ch.qos.logback
+ logback-classic
+ ${logback.version}
+
+
+
+
+ com.alibaba
+ druid-spring-boot-starter
+ ${druid.version}
+
+
+
+
+ eu.bitwalker
+ UserAgentUtils
+ ${bitwalker.version}
+
+
+
+
+ com.github.pagehelper
+ pagehelper-spring-boot-starter
+ ${pagehelper.boot.version}
+
+
+
+
+ com.github.oshi
+ oshi-core
+ ${oshi.version}
+
+
+
+
+ io.springfox
+ springfox-boot-starter
+ ${swagger.version}
+
+
+ io.swagger
+ swagger-models
+
+
+
+
+
+
+ commons-io
+ commons-io
+ ${commons.io.version}
+
+
+
+
+ org.apache.poi
+ poi-ooxml
+ ${poi.version}
+
+
+
+
+ org.apache.velocity
+ velocity-engine-core
+ ${velocity.version}
+
+
+
+
+ com.alibaba.fastjson2
+ fastjson2
+ ${fastjson.version}
+
+
+
+
+ io.jsonwebtoken
+ jjwt
+ ${jwt.version}
+
+
+
+
+ pro.fessional
+ kaptcha
+ ${kaptcha.version}
+
+
+
+
+ com.yunying
+ yunying-quartz
+ ${yunying.version}
+
+
+
+
+ com.yunying
+ yunying-generator
+ ${yunying.version}
+
+
+
+
+ com.yunying
+ yunying-framework
+ ${yunying.version}
+
+
+
+
+ com.yunying
+ yunying-common
+ ${yunying.version}
+
+
+
+
+ com.yunying
+ yunying-flowable
+ ${yunying.version}
+
+
+
+
+ org.flowable
+ flowable-spring-boot-starter
+ ${flowable.version}
+
+
+
+ io.swagger
+ swagger-annotations
+ 1.5.21
+ compile
+
+
+
+ com.baomidou
+ mybatis-plus-boot-starter
+ 3.4.0
+
+
+
+
+
+
+ yunying-admin
+ yunying-quartz
+ yunying-generator
+ yunying-flowable
+ yunying-framework
+ yunying-common
+
+ pom
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.1
+
+ ${java.version}
+ ${java.version}
+ ${project.build.sourceEncoding}
+
+
+
+
+
+
+
+ public
+ aliyun nexus
+ https://maven.aliyun.com/repository/public
+
+ true
+
+
+
+
+
+
+ public
+ aliyun nexus
+ https://maven.aliyun.com/repository/public
+
+ true
+
+
+ false
+
+
+
+
+
diff --git a/yunying-admin/pom.xml b/yunying-admin/pom.xml
new file mode 100644
index 0000000..44fa5d4
--- /dev/null
+++ b/yunying-admin/pom.xml
@@ -0,0 +1,96 @@
+
+
+
+ yunying
+ com.yunying
+ 3.8.8
+
+ 4.0.0
+ jar
+ yunying-admin
+
+ web服务入口
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+
+
+
+
+ mysql
+ mysql-connector-java
+
+
+
+
+ com.yunying
+ yunying-framework
+
+
+
+
+ com.yunying
+ yunying-quartz
+
+
+
+
+ com.yunying
+ yunying-generator
+
+
+
+
+ com.yunying
+ yunying-flowable
+
+
+
+ com.google.code.gson
+ gson
+
+
+ org.java-websocket
+ Java-WebSocket
+ 1.5.6
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ 2.5.15
+
+ true
+
+
+
+
+ repackage
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+ 3.1.0
+
+ false
+ ${project.artifactId}
+
+
+
+ ${project.artifactId}
+
+
+
\ No newline at end of file
diff --git a/yunying-admin/src/main/java/com/yunying/YYApplication.java b/yunying-admin/src/main/java/com/yunying/YYApplication.java
new file mode 100644
index 0000000..d84d0e3
--- /dev/null
+++ b/yunying-admin/src/main/java/com/yunying/YYApplication.java
@@ -0,0 +1,19 @@
+package com.yunying;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+
+/**
+ * 启动程序
+ *
+ * @author humf
+ */
+@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
+public class YYApplication {
+ public static void main(String[] args) {
+ // System.setProperty("spring.devtools.restart.enabled", "false");
+ SpringApplication.run(YYApplication.class, args);
+ System.out.println("YUNYING云赢智能综合管理平台启动成功......\n");
+ }
+}
diff --git a/yunying-admin/src/main/java/com/yunying/YYServletInitializer.java b/yunying-admin/src/main/java/com/yunying/YYServletInitializer.java
new file mode 100644
index 0000000..fd9a159
--- /dev/null
+++ b/yunying-admin/src/main/java/com/yunying/YYServletInitializer.java
@@ -0,0 +1,16 @@
+package com.yunying;
+
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+
+/**
+ * web容器中进行部署
+ *
+ * @author humf
+ */
+public class YYServletInitializer extends SpringBootServletInitializer {
+ @Override
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+ return application.sources(YYApplication.class);
+ }
+}
diff --git a/yunying-admin/src/main/java/com/yunying/recharge/controller/TestController.java b/yunying-admin/src/main/java/com/yunying/recharge/controller/TestController.java
new file mode 100644
index 0000000..78cee30
--- /dev/null
+++ b/yunying-admin/src/main/java/com/yunying/recharge/controller/TestController.java
@@ -0,0 +1,155 @@
+package com.yunying.recharge.controller;
+
+import com.yunying.common.annotation.Anonymous;
+import com.yunying.common.core.controller.BaseController;
+import com.yunying.common.core.domain.R;
+import com.yunying.common.utils.StringUtils;
+import io.swagger.annotations.*;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * swagger 用户测试方法
+ *
+ * @author humf
+ */
+@Api(tags = "用户信息管理")
+@RestController
+@RequestMapping("/api/user")
+public class TestController extends BaseController {
+ private final static Map users = new LinkedHashMap();
+
+ {
+ users.put(1, new UserEntity(1, "admin", "admin123", "15888888888"));
+ users.put(2, new UserEntity(2, "ry", "admin123", "15666666666"));
+ }
+
+ /**
+ * 忽略Token验证测试
+ *
+ * @author humf
+ * @last_update 2025年2月14日 23:22:33
+ */
+ @ApiOperation("获取用户列表")
+ @Anonymous
+ @GetMapping("/list")
+ public R> userList() {
+ List userList = new ArrayList(users.values());
+ return R.ok(userList);
+ }
+
+ @ApiOperation("获取用户详细")
+ @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class)
+ @GetMapping("/{userId}")
+ public R getUser(@PathVariable Integer userId) {
+ if (!users.isEmpty() && users.containsKey(userId)) {
+ return R.ok(users.get(userId));
+ } else {
+ return R.fail("用户不存在");
+ }
+ }
+
+ @ApiOperation("新增用户")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "userId", value = "用户id", dataType = "Integer", dataTypeClass = Integer.class),
+ @ApiImplicitParam(name = "username", value = "用户名称", dataType = "String", dataTypeClass = String.class),
+ @ApiImplicitParam(name = "password", value = "用户密码", dataType = "String", dataTypeClass = String.class),
+ @ApiImplicitParam(name = "mobile", value = "用户手机", dataType = "String", dataTypeClass = String.class)
+ })
+ @PostMapping("/save")
+ public R save(UserEntity user) {
+ if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId())) {
+ return R.fail("用户ID不能为空");
+ }
+ users.put(user.getUserId(), user);
+ return R.ok();
+ }
+
+ @ApiOperation("更新用户")
+ @PutMapping("/update")
+ public R update(@RequestBody UserEntity user) {
+ if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId())) {
+ return R.fail("用户ID不能为空");
+ }
+ if (users.isEmpty() || !users.containsKey(user.getUserId())) {
+ return R.fail("用户不存在");
+ }
+ users.remove(user.getUserId());
+ users.put(user.getUserId(), user);
+ return R.ok();
+ }
+
+ @ApiOperation("删除用户信息")
+ @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class)
+ @DeleteMapping("/{userId}")
+ public R delete(@PathVariable Integer userId) {
+ if (!users.isEmpty() && users.containsKey(userId)) {
+ users.remove(userId);
+ return R.ok();
+ } else {
+ return R.fail("用户不存在");
+ }
+ }
+}
+
+@ApiModel(value = "UserEntity", description = "用户实体")
+class UserEntity {
+ @ApiModelProperty("用户ID")
+ private Integer userId;
+
+ @ApiModelProperty("用户名称")
+ private String username;
+
+ @ApiModelProperty("用户密码")
+ private String password;
+
+ @ApiModelProperty("用户手机")
+ private String mobile;
+
+ public UserEntity() {
+
+ }
+
+ public UserEntity(Integer userId, String username, String password, String mobile) {
+ this.userId = userId;
+ this.username = username;
+ this.password = password;
+ this.mobile = mobile;
+ }
+
+ public Integer getUserId() {
+ return userId;
+ }
+
+ public void setUserId(Integer userId) {
+ this.userId = userId;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getMobile() {
+ return mobile;
+ }
+
+ public void setMobile(String mobile) {
+ this.mobile = mobile;
+ }
+}
diff --git a/yunying-admin/src/main/java/com/yunying/recharge/dto/AccountAllotDTO.java b/yunying-admin/src/main/java/com/yunying/recharge/dto/AccountAllotDTO.java
new file mode 100644
index 0000000..227b812
--- /dev/null
+++ b/yunying-admin/src/main/java/com/yunying/recharge/dto/AccountAllotDTO.java
@@ -0,0 +1,155 @@
+package com.yunying.recharge.dto;
+
+import com.google.gson.Gson;
+
+import java.math.BigDecimal;
+import java.util.Objects;
+
+/**
+ * 调拨参数接口对象
+ *
+ * @author humf
+ * @email 231006755@qq.com
+ * @date 2024-08-23 15:47
+ */
+public class AccountAllotDTO {
+ private String accountId;
+
+ private String allotAccountId;
+
+ private String contractNum;
+
+ private String execCustomerName;
+
+ private String allotTenFundType;
+
+ private String tenFundType;
+
+ private BigDecimal money;
+
+ private Integer fundType;
+
+ private Integer isPermit;
+
+ private Integer isSameRebate;
+
+ private String sign;
+
+ public void setAccountId(String accountId) {
+ this.accountId = accountId;
+ }
+
+ public void setAllotAccountId(String allotAccountId) {
+ this.allotAccountId = allotAccountId;
+ }
+
+ public void setContractNum(String contractNum) {
+ this.contractNum = contractNum;
+ }
+
+ public void setExecCustomerName(String execCustomerName) {
+ this.execCustomerName = execCustomerName;
+ }
+
+ public void setAllotTenFundType(String allotTenFundType) {
+ this.allotTenFundType = allotTenFundType;
+ }
+
+ public void setTenFundType(String tenFundType) {
+ this.tenFundType = tenFundType;
+ }
+
+ public void setMoney(BigDecimal money) {
+ this.money = money;
+ }
+
+ public void setFundType(Integer fundType) {
+ this.fundType = fundType;
+ }
+
+ public void setIsPermit(Integer isPermit) {
+ this.isPermit = isPermit;
+ }
+
+ public void setIsSameRebate(Integer isSameRebate) {
+ this.isSameRebate = isSameRebate;
+ }
+
+ public void setSign(String sign) {
+ this.sign = sign;
+ }
+
+ public String getAccountId() {
+ return this.accountId;
+ }
+
+ public String getAllotAccountId() {
+ return this.allotAccountId;
+ }
+
+ public String getContractNum() {
+ return this.contractNum;
+ }
+
+ public String getExecCustomerName() {
+ return this.execCustomerName;
+ }
+
+ public String getAllotTenFundType() {
+ return this.allotTenFundType;
+ }
+
+ public String getTenFundType() {
+ return this.tenFundType;
+ }
+
+ public BigDecimal getMoney() {
+ return this.money;
+ }
+
+ public Integer getFundType() {
+ return this.fundType;
+ }
+
+ public Integer getIsPermit() {
+ return isPermit;
+ }
+
+ public Integer getIsSameRebate() {
+ return isSameRebate;
+ }
+
+ public String getSign() {
+ return this.sign;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(accountId, allotAccountId, allotTenFundType, contractNum, execCustomerName, fundType,
+ isPermit, isSameRebate, money, sign, tenFundType);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ AccountAllotDTO other = (AccountAllotDTO) obj;
+ return Objects.equals(accountId, other.accountId) && Objects.equals(allotAccountId, other.allotAccountId)
+ && Objects.equals(allotTenFundType, other.allotTenFundType)
+ && Objects.equals(contractNum, other.contractNum)
+ && Objects.equals(execCustomerName, other.execCustomerName) && Objects.equals(fundType, other.fundType)
+ && Objects.equals(isPermit, other.isPermit) && Objects.equals(isSameRebate, other.isSameRebate)
+ && Objects.equals(money, other.money) && Objects.equals(sign, other.sign)
+ && Objects.equals(tenFundType, other.tenFundType);
+ }
+
+ @Override
+ public String toString() {
+ Gson gson = new Gson();
+ return gson.toJson(this);
+ }
+}
diff --git a/yunying-admin/src/main/java/com/yunying/recharge/dto/AccountRechargeDTO.java b/yunying-admin/src/main/java/com/yunying/recharge/dto/AccountRechargeDTO.java
new file mode 100644
index 0000000..f0166fc
--- /dev/null
+++ b/yunying-admin/src/main/java/com/yunying/recharge/dto/AccountRechargeDTO.java
@@ -0,0 +1,133 @@
+package com.yunying.recharge.dto;
+
+import com.google.gson.Gson;
+
+import java.math.BigDecimal;
+import java.util.Objects;
+
+/**
+ * 充值参数接口对象
+ *
+ * @author humf
+ * @email 231006755@qq.com
+ * @date 2024-08-23 15:47
+ */
+public class AccountRechargeDTO {
+ private String accountId;
+
+ private String accountId2;
+
+ private String contractNum;
+
+ private Integer dataType;
+
+ private String execCustomerName;
+
+ private String tenFundType;
+
+ private BigDecimal money;
+
+ private Integer fundType;
+
+ private String sign;
+
+ public void setAccountId(String accountId) {
+ this.accountId = accountId;
+ }
+
+ public void setAccountId2(String accountId2) {
+ this.accountId2 = accountId2;
+ }
+
+ public void setContractNum(String contractNum) {
+ this.contractNum = contractNum;
+ }
+
+ public void setDataType(Integer dataType) {
+ this.dataType = dataType;
+ }
+
+ public void setExecCustomerName(String execCustomerName) {
+ this.execCustomerName = execCustomerName;
+ }
+
+ public void setTenFundType(String tenFundType) {
+ this.tenFundType = tenFundType;
+ }
+
+ public void setMoney(BigDecimal money) {
+ this.money = money;
+ }
+
+ public void setFundType(Integer fundType) {
+ this.fundType = fundType;
+ }
+
+ public void setSign(String sign) {
+ this.sign = sign;
+ }
+
+ public String getAccountId() {
+ return this.accountId;
+ }
+
+ public String getAccountId2() {
+ return this.accountId2;
+ }
+
+ public String getContractNum() {
+ return this.contractNum;
+ }
+
+ public Integer getDataType() {
+ return this.dataType;
+ }
+
+ public String getExecCustomerName() {
+ return this.execCustomerName;
+ }
+
+ public String getTenFundType() {
+ return this.tenFundType;
+ }
+
+ public BigDecimal getMoney() {
+ return this.money;
+ }
+
+ public Integer getFundType() {
+ return this.fundType;
+ }
+
+ public String getSign() {
+ return this.sign;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(accountId, accountId2, contractNum, dataType, execCustomerName, fundType, money, sign,
+ tenFundType);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ AccountRechargeDTO other = (AccountRechargeDTO) obj;
+ return Objects.equals(accountId, other.accountId) && Objects.equals(accountId2, other.accountId2)
+ && Objects.equals(contractNum, other.contractNum) && Objects.equals(dataType, other.dataType)
+ && Objects.equals(execCustomerName, other.execCustomerName) && Objects.equals(fundType, other.fundType)
+ && Objects.equals(money, other.money) && Objects.equals(sign, other.sign)
+ && Objects.equals(tenFundType, other.tenFundType);
+ }
+
+ @Override
+ public String toString() {
+ Gson gson = new Gson();
+ return gson.toJson(this);
+ }
+}
diff --git a/yunying-admin/src/main/java/com/yunying/recharge/dto/AiTokenDTO.java b/yunying-admin/src/main/java/com/yunying/recharge/dto/AiTokenDTO.java
new file mode 100644
index 0000000..fc87acd
--- /dev/null
+++ b/yunying-admin/src/main/java/com/yunying/recharge/dto/AiTokenDTO.java
@@ -0,0 +1,47 @@
+package com.yunying.recharge.dto;
+
+import com.google.gson.Gson;
+
+import java.util.Objects;
+
+/**
+ * 获取Token参数接口对象
+ *
+ * @author humf
+ * @email 231006755@qq.com
+ * @date 2024-08-23 15:47
+ */
+public class AiTokenDTO {
+ private String sign;
+
+ public void setSign(String sign) {
+ this.sign = sign;
+ }
+
+ public String getSign() {
+ return this.sign;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(sign);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ AiTokenDTO other = (AiTokenDTO) obj;
+ return Objects.equals(sign, other.sign);
+ }
+
+ @Override
+ public String toString() {
+ Gson gson = new Gson();
+ return gson.toJson(this);
+ }
+}
diff --git a/yunying-admin/src/main/java/com/yunying/recharge/dto/CallbackData.java b/yunying-admin/src/main/java/com/yunying/recharge/dto/CallbackData.java
new file mode 100644
index 0000000..53d17c9
--- /dev/null
+++ b/yunying-admin/src/main/java/com/yunying/recharge/dto/CallbackData.java
@@ -0,0 +1,118 @@
+package com.yunying.recharge.dto;
+
+import com.google.gson.Gson;
+
+/**
+ * 机器人回调信息接口对象
+ *
+ * @author humf
+ * @email 231006755@qq.com
+ * @date 2024-08-23 15:47
+ */
+public class CallbackData {
+ private String robotId;
+
+ private String spoken;
+
+ private String rawSpoken;
+
+ private String receivedName;
+
+ private String groupName;
+
+ private String groupRemark;
+
+ private Integer roomType;
+
+ private Boolean atMe;
+
+ private Integer textType;
+
+ private String bizBatchNo;
+
+ public void setRobotId(String robotId) {
+ this.robotId = robotId;
+ }
+
+ public void setSpoken(String spoken) {
+ this.spoken = spoken;
+ }
+
+ public void setRawSpoken(String rawSpoken) {
+ this.rawSpoken = rawSpoken;
+ }
+
+ public void setReceivedName(String receivedName) {
+ this.receivedName = receivedName;
+ }
+
+ public void setGroupName(String groupName) {
+ this.groupName = groupName;
+ }
+
+ public void setGroupRemark(String groupRemark) {
+ this.groupRemark = groupRemark;
+ }
+
+ public void setRoomType(Integer roomType) {
+ this.roomType = roomType;
+ }
+
+ public void setAtMe(Boolean atMe) {
+ this.atMe = atMe;
+ }
+
+ public void setTextType(Integer textType) {
+ this.textType = textType;
+ }
+
+ public String getRobotId() {
+ return this.robotId;
+ }
+
+ public String getSpoken() {
+ return this.spoken;
+ }
+
+ public String getRawSpoken() {
+ return this.rawSpoken;
+ }
+
+ public String getReceivedName() {
+ return this.receivedName;
+ }
+
+ public String getGroupName() {
+ return this.groupName;
+ }
+
+ public String getGroupRemark() {
+ return this.groupRemark;
+ }
+
+ public Integer getRoomType() {
+ return this.roomType;
+ }
+
+ public Boolean getAtMe() {
+ return this.atMe;
+ }
+
+ public Integer getTextType() {
+ return this.textType;
+ }
+
+ public String getBizBatchNo() {
+ return bizBatchNo;
+ }
+
+ public void setBizBatchNo(String bizBatchNo) {
+ this.bizBatchNo = bizBatchNo;
+ }
+
+ @Override
+ public String toString() {
+ Gson gson = new Gson();
+ return gson.toJson(this);
+ }
+}
diff --git a/yunying-admin/src/main/java/com/yunying/recharge/dto/MsgData.java b/yunying-admin/src/main/java/com/yunying/recharge/dto/MsgData.java
new file mode 100644
index 0000000..6fea0fe
--- /dev/null
+++ b/yunying-admin/src/main/java/com/yunying/recharge/dto/MsgData.java
@@ -0,0 +1,52 @@
+package com.yunying.recharge.dto;
+
+import com.google.gson.Gson;
+
+/**
+ * 请填写类注释
+ *
+ * @author humf
+ * @email 231006755@qq.com
+ * @date 2024年12月26日 17:19:04
+ */
+public class MsgData {
+ private String message;
+ private String atName;
+ private String groupName;
+
+ public MsgData(String groupName, String atName, String message) {
+ this.message = message;
+ this.atName = atName;
+ this.groupName = groupName;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String getAtName() {
+ return atName;
+ }
+
+ public void setAtName(String atName) {
+ this.atName = atName;
+ }
+
+ public String getGroupName() {
+ return groupName;
+ }
+
+ public void setGroupName(String groupName) {
+ this.groupName = groupName;
+ }
+
+ @Override
+ public String toString() {
+ Gson gson = new Gson();
+ return gson.toJson(this);
+ }
+}
\ No newline at end of file
diff --git a/yunying-admin/src/main/java/com/yunying/recharge/dto/ReceiveData.java b/yunying-admin/src/main/java/com/yunying/recharge/dto/ReceiveData.java
new file mode 100644
index 0000000..71811c5
--- /dev/null
+++ b/yunying-admin/src/main/java/com/yunying/recharge/dto/ReceiveData.java
@@ -0,0 +1,59 @@
+package com.yunying.recharge.dto;
+
+import com.google.gson.Gson;
+
+/**
+ * 请填写类注释
+ *
+ * @author humf
+ * @email 231006755@qq.com
+ * @date 2024年12月26日 13:15:12
+ */
+public class ReceiveData {
+ // 指令类型
+ private Integer cmdCode;
+ // 消息json数据
+ private CallbackData data;
+ // 消息ID
+ private String msgID;
+ // 消息类型
+ private String msgType;
+
+ public Integer getCmdCode() {
+ return cmdCode;
+ }
+
+ public void setCmdCode(Integer cmdCode) {
+ this.cmdCode = cmdCode;
+ }
+
+ public CallbackData getData() {
+ return data;
+ }
+
+ public void setData(CallbackData data) {
+ this.data = data;
+ }
+
+ public String getMsgID() {
+ return msgID;
+ }
+
+ public void setMsgID(String msgID) {
+ this.msgID = msgID;
+ }
+
+ public String getMsgType() {
+ return msgType;
+ }
+
+ public void setMsgType(String msgType) {
+ this.msgType = msgType;
+ }
+
+ @Override
+ public String toString() {
+ Gson gson = new Gson();
+ return gson.toJson(this);
+ }
+}
diff --git a/yunying-admin/src/main/java/com/yunying/recharge/dto/SendData.java b/yunying-admin/src/main/java/com/yunying/recharge/dto/SendData.java
new file mode 100644
index 0000000..99387b7
--- /dev/null
+++ b/yunying-admin/src/main/java/com/yunying/recharge/dto/SendData.java
@@ -0,0 +1,79 @@
+package com.yunying.recharge.dto;
+
+import com.google.gson.Gson;
+
+/**
+ * 请填写类注释
+ *
+ * @author humf
+ * @email 231006755@qq.com
+ * @date 2024年12月26日 15:50:16
+ */
+public class SendData {
+ // 指令类型
+ private Integer cmdCode;
+ // 消息json数据
+ private MsgData data;
+ // 消息ID
+ private String msgID;
+ // 消息类型
+ private String msgType;
+ // 错误码-暂时不用
+ private Integer exeCode;
+
+ private Integer show;
+
+ public Integer getCmdCode() {
+ return cmdCode;
+ }
+
+ public void setCmdCode(Integer cmdCode) {
+ this.cmdCode = cmdCode;
+ }
+
+ public MsgData getData() {
+ return data;
+ }
+
+ public void setData(MsgData data) {
+ this.data = data;
+ }
+
+ public String getMsgID() {
+ return msgID;
+ }
+
+ public void setMsgID(String msgID) {
+ this.msgID = msgID;
+ }
+
+ public String getMsgType() {
+ return msgType;
+ }
+
+ public void setMsgType(String msgType) {
+ this.msgType = msgType;
+ }
+
+ public Integer getExeCode() {
+ return exeCode;
+ }
+
+ public void setExeCode(Integer exeCode) {
+ this.exeCode = exeCode;
+ }
+
+ public Integer getShow() {
+ return show;
+ }
+
+ public void setShow(Integer show) {
+ this.show = show;
+ }
+
+ @Override
+ public String toString() {
+ Gson gson = new Gson();
+ return gson.toJson(this);
+ }
+}
diff --git a/yunying-admin/src/main/java/com/yunying/recharge/service/IRobotService.java b/yunying-admin/src/main/java/com/yunying/recharge/service/IRobotService.java
new file mode 100644
index 0000000..51dff33
--- /dev/null
+++ b/yunying-admin/src/main/java/com/yunying/recharge/service/IRobotService.java
@@ -0,0 +1,17 @@
+package com.yunying.recharge.service;
+
+import com.yunying.recharge.dto.CallbackData;
+import com.yunying.recharge.websocket.MessageQueue;
+
+/**
+ * 企微机器人消息回调处理接口
+ *
+ * @author humf
+ * @email 231006755@qq.com
+ * @date 2024-08-23 15:47
+ */
+public interface IRobotService {
+ void callback(CallbackData callData, MessageQueue msgQueue) throws Exception;
+
+ void asyncCallback(CallbackData callData, MessageQueue msgQueue) throws Exception;
+}
diff --git a/yunying-admin/src/main/java/com/yunying/recharge/service/impl/RobotServiceImpl.java b/yunying-admin/src/main/java/com/yunying/recharge/service/impl/RobotServiceImpl.java
new file mode 100644
index 0000000..21e7090
--- /dev/null
+++ b/yunying-admin/src/main/java/com/yunying/recharge/service/impl/RobotServiceImpl.java
@@ -0,0 +1,28 @@
+package com.yunying.recharge.service.impl;
+
+import com.yunying.recharge.dto.CallbackData;
+import com.yunying.recharge.service.IRobotService;
+import com.yunying.recharge.websocket.MessageQueue;
+import org.springframework.stereotype.Service;
+
+/**
+ * 企微机器人消息回调处理实现
+ *
+ * @author humf
+ * @email 231006755@qq.com
+ * @date 2024-08-23 15:47
+ */
+@Service("robotService")
+public class RobotServiceImpl implements IRobotService {
+
+ @Override
+ public void callback(CallbackData callData, MessageQueue msgQueue) throws Exception {
+ System.out.println("callback同步处理");
+ }
+
+ @Override
+ public void asyncCallback(CallbackData callData, MessageQueue msgQueue) throws Exception {
+ System.out.println("callback异步处理");
+ }
+
+}
diff --git a/yunying-admin/src/main/java/com/yunying/recharge/test/WsTestClient.java b/yunying-admin/src/main/java/com/yunying/recharge/test/WsTestClient.java
new file mode 100644
index 0000000..56460a7
--- /dev/null
+++ b/yunying-admin/src/main/java/com/yunying/recharge/test/WsTestClient.java
@@ -0,0 +1,63 @@
+package com.yunying.recharge.test;
+
+import org.java_websocket.client.WebSocketClient;
+import org.java_websocket.handshake.ServerHandshake;
+
+import java.net.URI;
+import java.util.Scanner;
+
+/**
+ * 请填写类注释
+ *
+ * @author humf
+ * @email 231006755@qq.com
+ * @date 2025年2月21日 00:08:49
+ */
+public class WsTestClient extends WebSocketClient {
+ public WsTestClient(URI serverUri) {
+ super(serverUri);
+ }
+
+ @Override
+ public void onOpen(ServerHandshake handshake) {
+ System.out.println("🔗 Connected to: " + getURI());
+ System.out.println("🔄 Protocol Version: " + handshake.getHttpStatusMessage());
+ }
+
+ @Override
+ public void onMessage(String message) {
+ System.out.println("📩 Received: " + message);
+ }
+
+ @Override
+ public void onClose(int code, String reason, boolean remote) {
+ System.out.println("🚫 Connection closed: " + reason);
+ }
+
+ @Override
+ public void onError(Exception ex) {
+ System.err.println("❗ Error: " + ex.getMessage());
+ ex.printStackTrace();
+ }
+
+ public static void main(String[] args) throws Exception {
+ URI uri = new URI("ws://127.0.0.1:8080/webserver/wework/1001/1111111"); // 免费测试服务器
+ WsTestClient client = new WsTestClient(uri);
+
+ // 设置超时和重连
+ client.setConnectionLostTimeout(30);
+ client.connectBlocking(); // 阻塞直到连接成功
+
+ // 交互式消息发送
+ try (Scanner scanner = new Scanner(System.in)) {
+ while (true) {
+ System.out.print("💬 Enter message (输入 'exit' 退出): ");
+ String input = scanner.nextLine();
+ if ("exit".equalsIgnoreCase(input)) break;
+ client.send(input);
+ }
+ } finally {
+ client.closeBlocking();
+ }
+ }
+}
diff --git a/yunying-admin/src/main/java/com/yunying/recharge/websocket/MessageQueue.java b/yunying-admin/src/main/java/com/yunying/recharge/websocket/MessageQueue.java
new file mode 100644
index 0000000..543f3c3
--- /dev/null
+++ b/yunying-admin/src/main/java/com/yunying/recharge/websocket/MessageQueue.java
@@ -0,0 +1,101 @@
+package com.yunying.recharge.websocket;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.LinkedList;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * 消息发送队列
+ *
+ * @author humf
+ * @email 231006755@qq.com
+ * @date 2025年1月12日 22:09:41
+ */
+public class MessageQueue {
+ private static Logger log = LoggerFactory.getLogger(MessageQueue.class);
+
+ // 初始化一个普通队列
+ private final LinkedList