mirror of
https://gitcode.com/ageerle/ruoyi-ai.git
synced 2026-04-05 15:57:32 +00:00
feat(知识库): 增加知识库模块
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
package org.ruoyi.system.builder;
|
||||
|
||||
import me.chanjar.weixin.cp.api.WxCpService;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||
*/
|
||||
public abstract class AbstractBuilder {
|
||||
protected final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
public abstract WxCpXmlOutMessage build(String content, WxCpXmlMessage wxMessage, WxCpService service);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.ruoyi.system.builder;
|
||||
|
||||
import me.chanjar.weixin.cp.api.WxCpService;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutImageMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
|
||||
|
||||
|
||||
/**
|
||||
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||
*/
|
||||
public class ImageBuilder extends AbstractBuilder {
|
||||
|
||||
@Override
|
||||
public WxCpXmlOutMessage build(String content, WxCpXmlMessage wxMessage,
|
||||
WxCpService service) {
|
||||
|
||||
WxCpXmlOutImageMessage m = WxCpXmlOutMessage.IMAGE().mediaId(content)
|
||||
.fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName())
|
||||
.build();
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.ruoyi.system.builder;
|
||||
|
||||
import me.chanjar.weixin.cp.api.WxCpService;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutTextMessage;
|
||||
|
||||
/**
|
||||
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||
*/
|
||||
public class TextBuilder extends AbstractBuilder {
|
||||
|
||||
@Override
|
||||
public WxCpXmlOutMessage build(String content, WxCpXmlMessage wxMessage,
|
||||
WxCpService service) {
|
||||
WxCpXmlOutTextMessage m = WxCpXmlOutMessage.TEXT().content(content)
|
||||
.fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName())
|
||||
.build();
|
||||
return m;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,6 +26,7 @@ public class OkHttpConfig {
|
||||
public void init() {
|
||||
initializeOkHttpUtil("suno");
|
||||
initializeOkHttpUtil("luma");
|
||||
initializeOkHttpUtil("ppt");
|
||||
}
|
||||
|
||||
private void initializeOkHttpUtil(String modelName) {
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
package org.ruoyi.system.cofing;
|
||||
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import lombok.val;
|
||||
import me.chanjar.weixin.common.api.WxConsts;
|
||||
import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl;
|
||||
import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl;
|
||||
import me.chanjar.weixin.cp.constant.WxCpConsts;
|
||||
import me.chanjar.weixin.cp.message.WxCpMessageRouter;
|
||||
import org.ruoyi.system.handler.wxcp.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import me.chanjar.weixin.cp.api.WxCpService;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 单实例配置
|
||||
*
|
||||
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||
*/
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(WxCpProperties.class)
|
||||
public class WxCpConfiguration {
|
||||
private LogHandler logHandler;
|
||||
private NullHandler nullHandler;
|
||||
private LocationHandler locationHandler;
|
||||
private MenuHandler menuHandler;
|
||||
private MsgHandler msgHandler;
|
||||
private UnsubscribeHandler unsubscribeHandler;
|
||||
private SubscribeHandler subscribeHandler;
|
||||
|
||||
private WxCpProperties properties;
|
||||
|
||||
private static Map<Integer, WxCpMessageRouter> routers = Maps.newHashMap();
|
||||
private static Map<Integer, WxCpService> cpServices = Maps.newHashMap();
|
||||
|
||||
@Autowired
|
||||
public WxCpConfiguration(LogHandler logHandler, NullHandler nullHandler, LocationHandler locationHandler,
|
||||
MenuHandler menuHandler, MsgHandler msgHandler, UnsubscribeHandler unsubscribeHandler,
|
||||
SubscribeHandler subscribeHandler, WxCpProperties properties) {
|
||||
this.logHandler = logHandler;
|
||||
this.nullHandler = nullHandler;
|
||||
this.locationHandler = locationHandler;
|
||||
this.menuHandler = menuHandler;
|
||||
this.msgHandler = msgHandler;
|
||||
this.unsubscribeHandler = unsubscribeHandler;
|
||||
this.subscribeHandler = subscribeHandler;
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
|
||||
public static Map<Integer, WxCpMessageRouter> getRouters() {
|
||||
return routers;
|
||||
}
|
||||
|
||||
public static WxCpService getCpService(Integer agentId) {
|
||||
return cpServices.get(agentId);
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void initServices() {
|
||||
cpServices = this.properties.getAppConfigs().stream().map(a -> {
|
||||
val configStorage = new WxCpDefaultConfigImpl();
|
||||
configStorage.setCorpId(this.properties.getCorpId());
|
||||
configStorage.setAgentId(a.getAgentId());
|
||||
configStorage.setCorpSecret(a.getSecret());
|
||||
configStorage.setToken(a.getToken());
|
||||
configStorage.setAesKey(a.getAesKey());
|
||||
val service = new WxCpServiceImpl();
|
||||
service.setWxCpConfigStorage(configStorage);
|
||||
routers.put(a.getAgentId(), this.newRouter(service));
|
||||
return service;
|
||||
}).collect(Collectors.toMap(service -> service.getWxCpConfigStorage().getAgentId(), a -> a));
|
||||
}
|
||||
|
||||
private WxCpMessageRouter newRouter(WxCpService wxCpService) {
|
||||
final val newRouter = new WxCpMessageRouter(wxCpService);
|
||||
|
||||
// 记录所有事件的日志 (异步执行)
|
||||
newRouter.rule().handler(this.logHandler).next();
|
||||
|
||||
// 自定义菜单事件
|
||||
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
|
||||
.event(WxConsts.MenuButtonType.CLICK).handler(this.menuHandler).end();
|
||||
|
||||
// 点击菜单链接事件(这里使用了一个空的处理器,可以根据自己需要进行扩展)
|
||||
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
|
||||
.event(WxConsts.MenuButtonType.VIEW).handler(this.nullHandler).end();
|
||||
|
||||
// 关注事件
|
||||
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
|
||||
.event(WxConsts.EventType.SUBSCRIBE).handler(this.subscribeHandler)
|
||||
.end();
|
||||
|
||||
// 取消关注事件
|
||||
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
|
||||
.event(WxConsts.EventType.UNSUBSCRIBE)
|
||||
.handler(this.unsubscribeHandler).end();
|
||||
|
||||
// 上报地理位置事件
|
||||
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
|
||||
.event(WxConsts.EventType.LOCATION).handler(this.locationHandler)
|
||||
.end();
|
||||
|
||||
// 接收地理位置消息
|
||||
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.LOCATION)
|
||||
.handler(this.locationHandler).end();
|
||||
|
||||
// 扫码事件(这里使用了一个空的处理器,可以根据自己需要进行扩展)
|
||||
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
|
||||
.event(WxConsts.EventType.SCAN).handler(this.nullHandler).end();
|
||||
|
||||
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
|
||||
.event(WxCpConsts.EventType.CHANGE_CONTACT).handler(new ContactChangeHandler()).end();
|
||||
|
||||
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
|
||||
.event(WxCpConsts.EventType.ENTER_AGENT).handler(new EnterAgentHandler()).end();
|
||||
|
||||
// 默认
|
||||
newRouter.rule().async(false).handler(this.msgHandler).end();
|
||||
|
||||
return newRouter;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package org.ruoyi.system.cofing;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||
*/
|
||||
@Data
|
||||
@ConfigurationProperties(prefix = "wechat.cp")
|
||||
public class WxCpProperties {
|
||||
/**
|
||||
* 设置企业微信的corpId
|
||||
*/
|
||||
private String corpId;
|
||||
|
||||
private List<AppConfig> appConfigs;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public static class AppConfig {
|
||||
/**
|
||||
* 设置企业微信应用的AgentId
|
||||
*/
|
||||
private Integer agentId;
|
||||
|
||||
/**
|
||||
* 设置企业微信应用的Secret
|
||||
*/
|
||||
private String secret;
|
||||
|
||||
/**
|
||||
* 设置企业微信应用的token
|
||||
*/
|
||||
private String token;
|
||||
|
||||
/**
|
||||
* 设置企业微信应用的EncodingAESKey
|
||||
*/
|
||||
private String aesKey;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -36,8 +36,8 @@ public class ChatConfigController extends BaseController {
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
@SaCheckPermission("system:config:list")
|
||||
public R<List<ChatConfigVo>> list(ChatConfigBo bo) {
|
||||
return R.ok(chatConfigService.queryList(bo));
|
||||
public List<ChatConfigVo> list(ChatConfigBo bo) {
|
||||
return chatConfigService.queryList(bo);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,7 +46,8 @@ public class ChatConfigController extends BaseController {
|
||||
* @param id 主键
|
||||
*/
|
||||
@GetMapping("/{id}")
|
||||
public R<ChatConfigVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) {
|
||||
public R<ChatConfigVo> getInfo(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
return R.ok(chatConfigService.queryById(id));
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package org.ruoyi.system.controller.system;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.ruoyi.common.core.domain.R;
|
||||
import org.ruoyi.common.web.core.BaseController;
|
||||
import org.ruoyi.system.domain.bo.ChatAppStoreBo;
|
||||
import org.ruoyi.system.domain.bo.ChatMessageBo;
|
||||
import org.ruoyi.system.domain.vo.ChatAppStoreVo;
|
||||
import org.ruoyi.system.service.IChatAppStoreService;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 应用商店
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2024-03-19
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/system/store")
|
||||
public class ChatStoreController extends BaseController {
|
||||
|
||||
private final IChatAppStoreService appStoreService;
|
||||
|
||||
/**
|
||||
* 应用商店
|
||||
*/
|
||||
@GetMapping("/appList")
|
||||
public R<List<ChatAppStoreVo>> appList(ChatAppStoreBo bo) {
|
||||
return R.ok(appStoreService.queryList(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 收藏应用
|
||||
*/
|
||||
@PostMapping("/copyApp")
|
||||
public R<String> copyApp() {
|
||||
return R.ok();
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import org.ruoyi.common.log.enums.BusinessType;
|
||||
import org.ruoyi.common.mybatis.core.page.PageQuery;
|
||||
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
|
||||
import org.ruoyi.common.web.core.BaseController;
|
||||
import org.ruoyi.common.wechat.web.utils.UUIDShortUtil;
|
||||
import org.ruoyi.system.domain.bo.ChatVoucherBo;
|
||||
import org.ruoyi.system.domain.vo.ChatVoucherVo;
|
||||
import org.ruoyi.system.service.IChatVoucherService;
|
||||
@@ -22,7 +23,6 @@ import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* 用户兑换记录
|
||||
@@ -78,7 +78,7 @@ public class ChatVoucherController extends BaseController {
|
||||
@RepeatSubmit()
|
||||
@PostMapping()
|
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody ChatVoucherBo bo) {
|
||||
bo.setCode(UUID.randomUUID().toString().replace("-", ""));
|
||||
bo.setCode(UUIDShortUtil.generateShortUuid());
|
||||
return toAjax(chatVoucherService.insertByBo(bo));
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
package org.ruoyi.system.controller.system;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaIgnore;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.ruoyi.common.core.exception.ServiceException;
|
||||
import org.ruoyi.common.wechat.itchat4j.api.WechatTools;
|
||||
import org.ruoyi.common.wechat.itchat4j.controller.LoginController;
|
||||
import org.ruoyi.common.wechat.itchat4j.core.MsgCenter;
|
||||
import org.ruoyi.common.wechat.itchat4j.face.IMsgHandlerFace;
|
||||
import org.ruoyi.common.wechat.web.base.BaseException;
|
||||
import org.ruoyi.system.domain.bo.WxRobConfigBo;
|
||||
import org.ruoyi.system.domain.vo.WxRobConfigVo;
|
||||
import org.ruoyi.system.handler.MyMsgHandler;
|
||||
import org.ruoyi.system.service.ISseService;
|
||||
import org.ruoyi.system.service.IWxRobConfigService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 个人微信扩展控制器
|
||||
*
|
||||
* @author WangLe
|
||||
*/
|
||||
@SaIgnore
|
||||
@Slf4j
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
public class WeChatController {
|
||||
|
||||
private final ISseService sseService;
|
||||
|
||||
private final IWxRobConfigService wxRobConfigService;
|
||||
|
||||
/**
|
||||
* 登录第一步,获取二维码链接
|
||||
* @throws BaseException
|
||||
*/
|
||||
@PostMapping("/getQr")
|
||||
public String getQr(@RequestParam String uniqueKey) {
|
||||
LoginController login = new LoginController(uniqueKey);
|
||||
try {
|
||||
return login.login_1();
|
||||
} catch (BaseException e) {
|
||||
throw new ServiceException("获取二维码失败:"+ e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/wxLogin")
|
||||
public Boolean wxLogin(@RequestParam String uniqueKey) {
|
||||
LoginController login = new LoginController(uniqueKey);
|
||||
return login.login_2();
|
||||
}
|
||||
|
||||
@PostMapping("/wxInit")
|
||||
public Boolean wxInit(@RequestParam String uniqueKey) {
|
||||
LoginController login = new LoginController(uniqueKey);
|
||||
// 开启消息处理线程
|
||||
WxRobConfigBo wxRobConfigBo = new WxRobConfigBo();
|
||||
wxRobConfigBo.setUniqueKey(uniqueKey);
|
||||
List<WxRobConfigVo> wxRobConfigVos = wxRobConfigService.queryList(wxRobConfigBo);
|
||||
//查询机器人对应的用户
|
||||
start(uniqueKey,new MyMsgHandler(uniqueKey,sseService,wxRobConfigVos.get(0)));
|
||||
return login.login_3();
|
||||
}
|
||||
|
||||
@PostMapping("/wxLogout")
|
||||
public void wxLogout(@RequestParam String uniqueKey) {
|
||||
WechatTools.logout(uniqueKey);
|
||||
}
|
||||
|
||||
public void start(String uniqueKey,IMsgHandlerFace msgHandler) {
|
||||
log.info("7.+++开启消息处理线程["+uniqueKey+"]+++");
|
||||
new Thread(() -> MsgCenter.handleMsg(uniqueKey,msgHandler)).start();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
package org.ruoyi.system.controller.system;
|
||||
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.ruoyi.common.core.domain.R;
|
||||
import org.ruoyi.common.core.validate.AddGroup;
|
||||
import org.ruoyi.common.core.validate.EditGroup;
|
||||
import org.ruoyi.common.excel.utils.ExcelUtil;
|
||||
import org.ruoyi.common.idempotent.annotation.RepeatSubmit;
|
||||
import org.ruoyi.common.log.annotation.Log;
|
||||
import org.ruoyi.common.log.enums.BusinessType;
|
||||
import org.ruoyi.common.mybatis.core.page.PageQuery;
|
||||
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
|
||||
import org.ruoyi.common.satoken.utils.LoginHelper;
|
||||
import org.ruoyi.common.web.core.BaseController;
|
||||
import org.ruoyi.common.wechat.web.utils.UUIDShortUtil;
|
||||
import org.ruoyi.system.domain.bo.WxRobConfigBo;
|
||||
import org.ruoyi.system.domain.vo.WxRobConfigVo;
|
||||
import org.ruoyi.system.service.IWxRobConfigService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 机器人
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2024-05-01
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/system/robConfig")
|
||||
public class WxRobConfigController extends BaseController {
|
||||
|
||||
private final IWxRobConfigService wxRobConfigService;
|
||||
|
||||
/**
|
||||
* 查询机器人列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<WxRobConfigVo> list(WxRobConfigBo bo, PageQuery pageQuery) {
|
||||
return wxRobConfigService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询当前用户绑定的机器人信息
|
||||
* @param bo 查询参数
|
||||
* @return 机器人信息
|
||||
*/
|
||||
@GetMapping("/getRobConfig")
|
||||
public R<List<WxRobConfigVo>> botList(WxRobConfigBo bo) {
|
||||
bo.setUserId(LoginHelper.getUserId());
|
||||
return R.ok(wxRobConfigService.queryList(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出机器人列表
|
||||
*/
|
||||
@Log(title = "机器人", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(WxRobConfigBo bo, HttpServletResponse response) {
|
||||
List<WxRobConfigVo> list = wxRobConfigService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "机器人", WxRobConfigVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取机器人详细信息
|
||||
*
|
||||
* @param id 主键
|
||||
*/
|
||||
@GetMapping("/{id}")
|
||||
public R<WxRobConfigVo> getInfo(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
return R.ok(wxRobConfigService.queryById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增机器人
|
||||
*/
|
||||
@Log(title = "机器人", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping()
|
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody WxRobConfigBo bo) {
|
||||
String uniKey = UUIDShortUtil.generateShortUuid();
|
||||
bo.setUniqueKey(uniKey);
|
||||
return toAjax(wxRobConfigService.insertByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改机器人
|
||||
*/
|
||||
@Log(title = "机器人", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping()
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody WxRobConfigBo bo) {
|
||||
return toAjax(wxRobConfigService.updateByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除机器人
|
||||
*
|
||||
* @param ids 主键串
|
||||
*/
|
||||
@Log(title = "删除机器人", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||
@PathVariable Long[] ids) {
|
||||
return toAjax(wxRobConfigService.deleteWithValidByIds(List.of(ids), true));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package org.ruoyi.system.controller.wxsingle;
|
||||
|
||||
|
||||
import me.chanjar.weixin.common.bean.WxJsapiSignature;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.cp.api.WxCpService;
|
||||
import org.ruoyi.system.cofing.WxCpConfiguration;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Formatter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="https://github.com/0katekate0">Wang_Wong</a>
|
||||
*/
|
||||
//@RestController
|
||||
//@RequiredArgsConstructor
|
||||
//@RequestMapping("/wx/cp/js/{corpId}/{agentId}/getJsConf")
|
||||
public class WxJsController {
|
||||
@PostMapping("/getJsConf")
|
||||
public Map getJsConf(
|
||||
@PathVariable String corpId,
|
||||
@PathVariable Integer agentId,
|
||||
String uri) throws WxErrorException {
|
||||
|
||||
final WxCpService wxCpService = WxCpConfiguration.getCpService(agentId);
|
||||
if (wxCpService == null) {
|
||||
throw new IllegalArgumentException(String.format("未找到对应agentId=[%d]的配置,请核实!", agentId));
|
||||
}
|
||||
|
||||
WxJsapiSignature wxJsapiSignature = wxCpService.createJsapiSignature(uri);
|
||||
String signature = wxJsapiSignature.getSignature();
|
||||
String nonceStr = wxJsapiSignature.getNonceStr();
|
||||
long timestamp = wxJsapiSignature.getTimestamp();
|
||||
|
||||
Map res = new HashMap<String, String>();
|
||||
res.put("appId", corpId); // 必填,企业微信的corpID
|
||||
res.put("timestamp", timestamp); // 必填,生成签名的时间戳
|
||||
res.put("nonceStr", nonceStr); // 必填,生成签名的随机串
|
||||
res.put("signature", signature); // 必填,签名,见 附录-JS-SDK使用权限签名算法
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
public static String genNonce() {
|
||||
return bytesToHex(Long.toString(System.nanoTime()).getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
public static String bytesToHex(final byte[] hash) {
|
||||
Formatter formatter = new Formatter();
|
||||
for (byte b : hash) {
|
||||
formatter.format("%02x", b);
|
||||
}
|
||||
String result = formatter.toString();
|
||||
formatter.close();
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package org.ruoyi.system.controller.wxsingle;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.chanjar.weixin.cp.api.WxCpService;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
|
||||
import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.ruoyi.common.core.utils.JsonUtils;
|
||||
import org.ruoyi.system.cofing.WxCpConfiguration;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/wx/cp")
|
||||
@Slf4j
|
||||
public class WxPortalController {
|
||||
|
||||
@Value("${wechat.cp.appConfigs[0].agentId}")
|
||||
private Integer agentId;
|
||||
|
||||
|
||||
@GetMapping(produces = "text/plain;charset=utf-8")
|
||||
public String authGet(
|
||||
@RequestParam(name = "msg_signature", required = false) String signature,
|
||||
@RequestParam(name = "timestamp", required = false) String timestamp,
|
||||
@RequestParam(name = "nonce", required = false) String nonce,
|
||||
@RequestParam(name = "echostr", required = false) String echostr) {
|
||||
log.info("\n接收到来自微信服务器的认证消息:signature = [{}], timestamp = [{}], nonce = [{}], echostr = [{}]",
|
||||
signature, timestamp, nonce, echostr);
|
||||
|
||||
if (StringUtils.isAnyBlank(signature, timestamp, nonce, echostr)) {
|
||||
throw new IllegalArgumentException("请求参数非法,请核实!");
|
||||
}
|
||||
|
||||
final WxCpService wxCpService = WxCpConfiguration.getCpService(agentId);
|
||||
if (wxCpService == null) {
|
||||
throw new IllegalArgumentException(String.format("未找到对应agentId=[%d]的配置,请核实!", agentId));
|
||||
}
|
||||
|
||||
if (wxCpService.checkSignature(signature, timestamp, nonce, echostr)) {
|
||||
return new WxCpCryptUtil(wxCpService.getWxCpConfigStorage()).decrypt(echostr);
|
||||
}
|
||||
|
||||
return "非法请求";
|
||||
}
|
||||
|
||||
@PostMapping(produces = "application/xml; charset=UTF-8")
|
||||
public String post(
|
||||
@RequestBody String requestBody,
|
||||
@RequestParam("msg_signature") String signature,
|
||||
@RequestParam("timestamp") String timestamp,
|
||||
@RequestParam("nonce") String nonce) {
|
||||
log.info("\n接收微信请求:[signature=[{}], timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ",
|
||||
signature, timestamp, nonce, requestBody);
|
||||
|
||||
final WxCpService wxCpService = WxCpConfiguration.getCpService(1000002);
|
||||
WxCpXmlMessage inMessage = WxCpXmlMessage.fromEncryptedXml(requestBody, wxCpService.getWxCpConfigStorage(),
|
||||
timestamp, nonce, signature);
|
||||
log.debug("\n消息解密后内容为:\n{} ", JsonUtils.toJson(inMessage));
|
||||
WxCpXmlOutMessage outMessage = this.route(1000002, inMessage);
|
||||
if (outMessage == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
String out = outMessage.toEncryptedXml(wxCpService.getWxCpConfigStorage());
|
||||
log.debug("\n组装回复信息:{}", out);
|
||||
return out;
|
||||
}
|
||||
|
||||
private WxCpXmlOutMessage route(Integer agentId, WxCpXmlMessage message) {
|
||||
try {
|
||||
return WxCpConfiguration.getRouters().get(agentId).route(message);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -9,32 +9,32 @@ import lombok.EqualsAndHashCode;
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* 配音角色对象 voice_role
|
||||
* 应用市场
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2024-03-19
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("chat_audio_role")
|
||||
public class VoiceRole extends BaseEntity {
|
||||
@TableName("chat_app_store")
|
||||
public class ChatAppStore extends BaseEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* id
|
||||
* 主键
|
||||
*/
|
||||
@TableId(value = "id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 角色名称
|
||||
* 名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 角色描述
|
||||
* 描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
@@ -44,14 +44,9 @@ public class VoiceRole extends BaseEntity {
|
||||
private String avatar;
|
||||
|
||||
/**
|
||||
* 角色id
|
||||
* 应用地址
|
||||
*/
|
||||
private String voiceId;
|
||||
|
||||
/**
|
||||
* 音频地址
|
||||
*/
|
||||
private String fileUrl;
|
||||
private String appUrl;
|
||||
|
||||
|
||||
/**
|
||||
@@ -10,8 +10,7 @@ import org.ruoyi.common.tenant.core.TenantEntity;
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* 对话配置信息
|
||||
对象 chat_config
|
||||
* 对话配置信息对象 chat_config
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2024-04-13
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package org.ruoyi.system.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* 翻唱对象
|
||||
*
|
||||
* @author NSL
|
||||
* @date 2024-12-25
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("chat_cover")
|
||||
public class Cover extends BaseEntity {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(value = "id")
|
||||
private Long id;
|
||||
/**
|
||||
* 歌曲名称
|
||||
*/
|
||||
private String coverMusicName;
|
||||
/**
|
||||
* 歌曲地址
|
||||
*/
|
||||
private String coverMusicUrl;
|
||||
/**
|
||||
* 歌手性别 枚举 FEMALE 女性 MALE 男性
|
||||
*/
|
||||
private String coverSingerGender;
|
||||
/**
|
||||
* 歌手姓名
|
||||
*/
|
||||
private String coverSingerName;
|
||||
/**
|
||||
* 用户性别 FEMALE MALE
|
||||
*/
|
||||
private String userGender;
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
private Long userId;
|
||||
/**
|
||||
* 本次消费金额
|
||||
*/
|
||||
private String cost;
|
||||
/**
|
||||
* 翻唱后的URL
|
||||
*/
|
||||
private String coverUrl;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package org.ruoyi.system.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* 翻唱用户参考音频对象
|
||||
*
|
||||
* @author NSL
|
||||
* @since 2024-12-25
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("chat_cover_prompt_audio")
|
||||
public class CoverPromptAudio extends BaseEntity {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(value = "id")
|
||||
private Long id;
|
||||
/**
|
||||
* 翻唱主表id
|
||||
*/
|
||||
private Long coverId;
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
private Long userId;
|
||||
/**
|
||||
* 参考音频
|
||||
*/
|
||||
private String promptAudioUrl;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.ruoyi.system.domain.bo;
|
||||
|
||||
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
|
||||
import org.ruoyi.system.domain.VoiceRole;
|
||||
import org.ruoyi.system.domain.ChatAppStore;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
@@ -9,15 +9,15 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 配音角色业务对象 voice_role
|
||||
* 应用市场业务对象 voice_role
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2024-03-19
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@AutoMapper(target = VoiceRole.class, reverseConvertGenerate = false)
|
||||
public class VoiceRoleBo extends BaseEntity {
|
||||
@AutoMapper(target = ChatAppStore.class, reverseConvertGenerate = false)
|
||||
public class ChatAppStoreBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* id
|
||||
@@ -28,13 +28,13 @@ public class VoiceRoleBo extends BaseEntity {
|
||||
/**
|
||||
* 角色名称
|
||||
*/
|
||||
@NotBlank(message = "角色名称不能为空")
|
||||
@NotBlank(message = "名称不能为空")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 角色描述
|
||||
*/
|
||||
@NotBlank(message = "角色描述不能为空")
|
||||
@NotBlank(message = "描述不能为空")
|
||||
private String description;
|
||||
|
||||
/**
|
||||
@@ -43,18 +43,11 @@ public class VoiceRoleBo extends BaseEntity {
|
||||
@NotBlank(message = "头像不能为空")
|
||||
private String avatar;
|
||||
|
||||
/**
|
||||
* 角色id
|
||||
*/
|
||||
@NotBlank(message = "角色id不能为空")
|
||||
private String voiceId;
|
||||
|
||||
/**
|
||||
* 音频地址
|
||||
*/
|
||||
@NotBlank(message = "音频地址不能为空")
|
||||
private String fileUrl;
|
||||
|
||||
@NotBlank(message = "应用地址不能为空")
|
||||
private String appUrl;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
@@ -0,0 +1,34 @@
|
||||
package org.ruoyi.system.domain.request.translation;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 描述:翻译请求对象
|
||||
*
|
||||
* @author ageerle@163.com
|
||||
* date 2025/1/13
|
||||
*/
|
||||
|
||||
@Data
|
||||
public class TranslationRequest {
|
||||
/**
|
||||
* 提示词
|
||||
*/
|
||||
private String prompt;
|
||||
|
||||
/**
|
||||
* 模型名称
|
||||
*/
|
||||
private String model;
|
||||
|
||||
/**
|
||||
* 源语言
|
||||
*/
|
||||
private String sourceLanguage;
|
||||
|
||||
/**
|
||||
* 目标语言
|
||||
*/
|
||||
private String targetLanguage;
|
||||
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
import org.ruoyi.system.domain.VoiceRole;
|
||||
import org.ruoyi.system.domain.ChatAppStore;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
@@ -12,15 +12,15 @@ import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* 配音角色视图对象 voice_role
|
||||
* 应用市场视图对象
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2024-03-19
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
@AutoMapper(target = VoiceRole.class)
|
||||
public class VoiceRoleVo implements Serializable {
|
||||
@AutoMapper(target = ChatAppStore.class)
|
||||
public class ChatAppStoreVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
@@ -34,13 +34,13 @@ public class VoiceRoleVo implements Serializable {
|
||||
/**
|
||||
* 角色名称
|
||||
*/
|
||||
@ExcelProperty(value = "角色名称")
|
||||
@ExcelProperty(value = "名称")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 角色描述
|
||||
*/
|
||||
@ExcelProperty(value = "角色描述")
|
||||
@ExcelProperty(value = "描述")
|
||||
private String description;
|
||||
|
||||
/**
|
||||
@@ -49,23 +49,11 @@ public class VoiceRoleVo implements Serializable {
|
||||
@ExcelProperty(value = "头像")
|
||||
private String avatar;
|
||||
|
||||
/**
|
||||
* 角色id
|
||||
*/
|
||||
@ExcelProperty(value = "角色id")
|
||||
private String voiceId;
|
||||
|
||||
/**
|
||||
* 音频地址
|
||||
*/
|
||||
@ExcelProperty(value = "音频地址")
|
||||
private String fileUrl;
|
||||
|
||||
/**
|
||||
* 音频预处理(实验性)
|
||||
*/
|
||||
@ExcelProperty(value = "音频预处理")
|
||||
private String preProcess;
|
||||
@ExcelProperty(value = "应用地址")
|
||||
private String appUrl;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
@@ -0,0 +1,24 @@
|
||||
package org.ruoyi.system.domain.vo.cover;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 翻唱回调VO
|
||||
*
|
||||
* @author NSL
|
||||
* @since 2024-12-26
|
||||
*/
|
||||
@Data
|
||||
public class CoverCallbackVo {
|
||||
/** 本次请求的订单号 */
|
||||
private String orderId;
|
||||
|
||||
/** 用户ID */
|
||||
private String userId;
|
||||
|
||||
/** 本次消费金额 */
|
||||
private String cost;
|
||||
|
||||
/** 翻唱后的URL */
|
||||
private String coverUrl;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package org.ruoyi.system.domain.vo.cover;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 翻唱歌曲入参
|
||||
*
|
||||
* @author NSL
|
||||
* @since 2024-12-25
|
||||
*/
|
||||
@Data
|
||||
public class CoverParamVo implements Serializable {
|
||||
|
||||
/**
|
||||
* 歌曲名称
|
||||
*/
|
||||
@ExcelProperty(value = "歌曲名称")
|
||||
private String coverMusicName;
|
||||
/**
|
||||
* 歌曲地址
|
||||
*/
|
||||
@ExcelProperty(value = "歌曲地址")
|
||||
private String coverMusicUrl;
|
||||
/**
|
||||
* 歌手性别 枚举 FEMALE 女性 MALE 男性
|
||||
*/
|
||||
@ExcelProperty(value = "歌手性别")
|
||||
private String coverSingerGender;
|
||||
/**
|
||||
* 歌手姓名
|
||||
*/
|
||||
@ExcelProperty(value = "歌手姓名")
|
||||
private String coverSingerName;
|
||||
/**
|
||||
* 参考音频:用户首次翻唱,必填;第二次及之后翻唱:若为空则沿用最近一次参考音频训练模型,若不为空则使用该参考音频训练模型。
|
||||
* 可多传
|
||||
*/
|
||||
@ExcelProperty(value = "参考音频")
|
||||
private List<String> promptAudioUrl;
|
||||
/**
|
||||
* 用户性别 FEMALE MALE
|
||||
*/
|
||||
@ExcelProperty(value = "用户性别")
|
||||
private String userGender;
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
@ExcelProperty(value = "用户id")
|
||||
private String userId;
|
||||
|
||||
/**
|
||||
* 业务主键id
|
||||
*/
|
||||
@ExcelProperty(value = "业务主键id")
|
||||
private String orderId;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package org.ruoyi.system.domain.vo.cover;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
import org.ruoyi.system.domain.Cover;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 翻唱用户参考音频视图对象
|
||||
*
|
||||
* @author NSL
|
||||
* @since 2024-12-25
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
@AutoMapper(target = Cover.class)
|
||||
public class CoverPromptAudioVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ExcelProperty(value = "id")
|
||||
private Long id;
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
@ExcelProperty(value = "用户id")
|
||||
private Long userId;
|
||||
/**
|
||||
* 翻唱主表id
|
||||
*/
|
||||
@ExcelProperty(value = "翻唱主表id")
|
||||
private Long coverId;
|
||||
/**
|
||||
* 翻唱后的URL
|
||||
*/
|
||||
@ExcelProperty(value = "参考音频")
|
||||
private String promptAudioUrl;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package org.ruoyi.system.domain.vo.cover;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
import org.ruoyi.system.domain.Cover;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 翻唱视图对象
|
||||
*
|
||||
* @author NSL
|
||||
* @date 2024-12-25
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
@AutoMapper(target = Cover.class)
|
||||
public class CoverVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ExcelProperty(value = "id")
|
||||
private Long id;
|
||||
/**
|
||||
* 歌曲名称
|
||||
*/
|
||||
@ExcelProperty(value = "歌曲名称")
|
||||
private String coverMusicName;
|
||||
/**
|
||||
* 歌曲地址
|
||||
*/
|
||||
@ExcelProperty(value = "歌曲地址")
|
||||
private String coverMusicUrl;
|
||||
/**
|
||||
* 歌手性别 枚举 FEMALE 女性 MALE 男性
|
||||
*/
|
||||
@ExcelProperty(value = "歌手性别")
|
||||
private String coverSingerGender;
|
||||
/**
|
||||
* 歌手姓名
|
||||
*/
|
||||
@ExcelProperty(value = "歌手姓名")
|
||||
private String coverSingerName;
|
||||
/**
|
||||
* 用户性别 FEMALE MALE
|
||||
*/
|
||||
@ExcelProperty(value = "用户性别")
|
||||
private String userGender;
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
@ExcelProperty(value = "用户id")
|
||||
private Long userId;
|
||||
/**
|
||||
* 本次消费金额
|
||||
*/
|
||||
@ExcelProperty(value = "本次消费金额")
|
||||
private String cost;
|
||||
/**
|
||||
* 翻唱后的URL
|
||||
*/
|
||||
@ExcelProperty(value = "翻唱后的URL")
|
||||
private String coverUrl;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.ruoyi.system.domain.vo.cover;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author NSL
|
||||
* @since 2024-12-25
|
||||
*/
|
||||
@Data
|
||||
public class MusicVo {
|
||||
/**
|
||||
* 歌曲名称
|
||||
*/
|
||||
private String musicName;
|
||||
|
||||
/**
|
||||
* 音乐地址
|
||||
*/
|
||||
private String mp3Url;
|
||||
|
||||
/**
|
||||
* 歌曲图片
|
||||
*/
|
||||
private String pic;
|
||||
|
||||
/**
|
||||
* 歌手或乐队名
|
||||
*/
|
||||
private String singerName;
|
||||
|
||||
/**
|
||||
* 歌手性别
|
||||
*/
|
||||
private String singerGender;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.ruoyi.system.domain.vo.ppt;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 查询所有PPT列表查询参数
|
||||
*
|
||||
* @author NSL
|
||||
* @since 2024/12/31
|
||||
*/
|
||||
@Data
|
||||
public class PptAllQueryDto {
|
||||
// 分页
|
||||
private Integer page;
|
||||
// 每页大小(最大不超过100)
|
||||
private Integer size;
|
||||
// ppt id(非必填)
|
||||
private String id;
|
||||
// 第三方用户ID(非必填)
|
||||
private String uid;
|
||||
// 模板ID(非必填)
|
||||
private String templateId;
|
||||
// 创建开始时间(非必填)
|
||||
private String startDate;
|
||||
// 创建结束时间(非必填)
|
||||
private String endDate;
|
||||
// 按时间倒序返回(非必填)
|
||||
private boolean desc;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package org.ruoyi.system.domain.vo.ppt;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 生成大纲内容参数
|
||||
*
|
||||
* @author NSL
|
||||
* @since 2024/12/31
|
||||
*/
|
||||
@Data
|
||||
public class PptGenerateContentDto {
|
||||
// 模板ID(非必填)
|
||||
private String templateId;
|
||||
|
||||
// 大纲 markdown 文本
|
||||
private String outlineMarkdown;
|
||||
|
||||
// 异步生成PPT(这里必须为 true 才会流式生成)
|
||||
private boolean asyncGenPptx = false;
|
||||
|
||||
// 用户要求
|
||||
private String prompt;
|
||||
|
||||
// 文件数据url,调用解析文件内容接口返回
|
||||
private String dataUrl;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.ruoyi.system.domain.vo.ppt;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 生成PPT大纲参数
|
||||
*
|
||||
* @author NSL
|
||||
* @since 2024/12/31
|
||||
*/
|
||||
@Data
|
||||
public class PptGenerateOutlineDto {
|
||||
// 是否流式生成(默认流式)
|
||||
private boolean stream = true;
|
||||
// 篇幅长度:short/medium/long, 默认 medium, 分别对应: 10-15页/20-30页/25-35页
|
||||
private String length = "medium";
|
||||
// 语言: zh/zh-Hant/en/ja/ko/ar/de/fr/it/pt/es/ru
|
||||
private String lang;
|
||||
// 用户要求(小于50字)
|
||||
private String prompt;
|
||||
// 方式一:通过主题创建 主题(与dataUrl可同时存在)
|
||||
private String subject;
|
||||
// 方式二:通过文件内容创建 文件数据url,通过解析文件内容接口返回(与subject可同时存在)
|
||||
private String dataUrl;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package org.ruoyi.system.domain.vo.ppt;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 生成PPT参数
|
||||
*
|
||||
* @author NSL
|
||||
* @since 2024/12/31
|
||||
*/
|
||||
@Data
|
||||
public class PptGeneratePptxDto {
|
||||
// 模板ID(非必填)
|
||||
private String templateId;
|
||||
|
||||
// 是否返回PPT数据结构
|
||||
private boolean pptxProperty;
|
||||
|
||||
// 大纲内容markdown
|
||||
private String outlineContentMarkdown;
|
||||
|
||||
// 备注(PPT页面备注,非必填,数组 ["内容页面一备注", "内容页面二备注"])
|
||||
private String notes;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package org.ruoyi.system.domain.vo.ppt;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* PPT模板筛选查询参数
|
||||
*
|
||||
* @author NSL
|
||||
* @since 2024/12/31
|
||||
*/
|
||||
@Data
|
||||
public class PptTemplateFilterDto {
|
||||
// 模板类型(必传):1系统模板、4用户自定义模板
|
||||
private Integer type;
|
||||
|
||||
// 类目筛选 ['年终总结', '教育培训', '医学医疗', '商业计划书', '企业介绍', '毕业答辩', '营销推广', '晚会表彰', '个人简历']
|
||||
private String category;
|
||||
|
||||
// 风格筛选 ['扁平简约', '商务科技', '文艺清新', '卡通手绘', '中国风', '创意时尚', '创意趣味']
|
||||
private String style;
|
||||
|
||||
// 主题颜色筛选 ['#FA920A', '#589AFD', '#7664FA', '#65E5EC', '#61D328', '#F5FD59', '#E05757', '#8F5A0B', '#FFFFFF', '#000000']
|
||||
private String themeColor;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.ruoyi.system.domain.vo.ppt;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 分页查询 PPT 模板查询参数
|
||||
*
|
||||
* @author NSL
|
||||
* @since 2024/12/31
|
||||
*/
|
||||
@Data
|
||||
public class PptTemplateQueryDto {
|
||||
// 分页
|
||||
private Integer page;
|
||||
// 每页大小(最大不超过100)
|
||||
private Integer size;
|
||||
// 模型筛选参数
|
||||
private PptTemplateFilterDto filters;
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
package org.ruoyi.system.handler;
|
||||
|
||||
import com.jfinal.kit.PropKit;
|
||||
import org.ruoyi.common.chat.domain.request.ChatRequest;
|
||||
import org.ruoyi.common.chat.entity.chat.ChatCompletion;
|
||||
import org.ruoyi.common.chat.entity.images.Item;
|
||||
import org.ruoyi.common.wechat.itchat4j.beans.BaseMsg;
|
||||
import org.ruoyi.common.wechat.itchat4j.core.CoreManage;
|
||||
import org.ruoyi.common.wechat.itchat4j.face.IMsgHandlerFace;
|
||||
import org.ruoyi.common.wechat.itchat4j.utils.LogInterface;
|
||||
import org.ruoyi.common.wechat.itchat4j.utils.enums.SendMsgType;
|
||||
import org.ruoyi.common.wechat.itchat4j.utils.tools.CommonTools;
|
||||
import org.ruoyi.common.wechat.web.constant.ConfigKeys;
|
||||
import org.ruoyi.common.wechat.web.model.WxRobConfig;
|
||||
import org.ruoyi.common.wechat.web.model.WxRobKeyword;
|
||||
import org.ruoyi.system.domain.vo.WxRobConfigVo;
|
||||
import org.ruoyi.system.service.ISseService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
* 消息处理实现 默认方案
|
||||
* @author WesleyOne
|
||||
* @create 2018/12/11
|
||||
*/
|
||||
public class MyMsgHandler implements IMsgHandlerFace,LogInterface {
|
||||
private String uniqueKey;
|
||||
private final ISseService sseService;
|
||||
private WxRobConfigVo robConfigVo;
|
||||
|
||||
public MyMsgHandler(String uniqueKey,ISseService sseService,WxRobConfigVo robConfigVo){
|
||||
this.uniqueKey = uniqueKey;
|
||||
this.sseService = sseService;
|
||||
this.robConfigVo = robConfigVo;
|
||||
}
|
||||
|
||||
private String getDownloadPath(String fileName) {
|
||||
String download_path = PropKit.get("download_path");
|
||||
return download_path+ File.separator + uniqueKey +File.separator + fileName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void textMsgHandle(BaseMsg msg) {
|
||||
String fromNickName = msg.getFromNickName();
|
||||
String fromUserName = msg.getFromUserName();
|
||||
boolean groupMsg = msg.isGroupMsg();
|
||||
String text = msg.getText().trim();
|
||||
|
||||
if (groupMsg && text.contains("@" + fromNickName)) {
|
||||
handleGroupMessage(fromNickName, fromUserName, text);
|
||||
} else {
|
||||
respondWithChatGPT(fromUserName, text);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleGroupMessage(String fromNickName, String fromUserName, String text) {
|
||||
String prompt = text.replace("@" + fromNickName + " ", "");
|
||||
if (prompt.startsWith("画")) {
|
||||
generateAndSendImage(fromUserName, prompt.replaceFirst("画 ", ""));
|
||||
} else {
|
||||
respondWithChatGPT(fromUserName, prompt);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateAndSendImage(String fromUserName, String prompt) {
|
||||
List<Item> items = sseService.wxDall(prompt,robConfigVo.getUserId().toString());
|
||||
WxRobKeyword robKeyword = new WxRobKeyword();
|
||||
robKeyword.setTypeData(SendMsgType.IMG.toValue());
|
||||
robKeyword.setValueData(items.get(0).getUrl());
|
||||
sendDataByType(fromUserName, robKeyword);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void respondWithChatGPT(String fromUserName, String prompt) {
|
||||
ChatRequest chatBO = new ChatRequest();
|
||||
//chatBO.setPrompt(prompt);
|
||||
chatBO.setModel(ChatCompletion.Model.GPT_3_5_TURBO.getName());
|
||||
String chat = sseService.chat(chatBO,robConfigVo.getUserId().toString());
|
||||
WxRobKeyword robKeyword = new WxRobKeyword();
|
||||
robKeyword.setTypeData(SendMsgType.TEXT.toValue());
|
||||
robKeyword.setValueData(chat);
|
||||
sendDataByType(fromUserName, robKeyword);
|
||||
}
|
||||
|
||||
private boolean sendDataByType(String fromUserName, WxRobKeyword robKeyword) {
|
||||
String data;
|
||||
String type;
|
||||
if (robKeyword != null){
|
||||
data = robKeyword.getValueData();
|
||||
type = robKeyword.getTypeData();
|
||||
CoreManage.addSendMsg4UserName(uniqueKey,fromUserName,data,SendMsgType.fromValue(type));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void sysMsgHandle(BaseMsg msg) {
|
||||
String fromNickName = msg.getFromNickName();
|
||||
String fromUserName = msg.getFromUserName();
|
||||
boolean groupMsg = msg.isGroupMsg();
|
||||
|
||||
/**
|
||||
* 群里的新人进群消息处理
|
||||
* 优先发专门这个群的欢迎词
|
||||
* 没有发通用的
|
||||
* 欢迎词内容实质就是在最前面加上@昵称\n
|
||||
*
|
||||
* 欢迎词的关键字
|
||||
* @see ConfigKeys#DEAFAULT_WELCOME
|
||||
*/
|
||||
|
||||
// 解析新人名字
|
||||
String text = msg.getContent();
|
||||
String newNickName = "";
|
||||
Matcher matcher = CommonTools.getMatcher("邀请\"(.+?)\"加入了群聊", text);
|
||||
if (matcher.find()){
|
||||
newNickName = matcher.group(1);
|
||||
}else{
|
||||
matcher = CommonTools.getMatcher("\"(.+?)\"通过扫描(.+?)分享的二维码加入群聊", text);
|
||||
if (matcher.find()){
|
||||
newNickName = matcher.group(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (StringUtils.isNotEmpty(newNickName)){
|
||||
|
||||
WxRobConfig robConfig = WxRobConfig.dao.findFirst("SELECT * FROM wx_rob_config WHERE unique_key = ? LIMIT 1", uniqueKey);
|
||||
if(robConfig != null && robConfig.getEnable()){
|
||||
// 判断是否要回复
|
||||
boolean isOpen = false;
|
||||
// 判断是群聊的话是否允许回复 昵称关键字
|
||||
if (robConfig.getToGroup() && groupMsg){
|
||||
isOpen = true;
|
||||
}
|
||||
if (isOpen){
|
||||
WxRobKeyword robKeyword = WxRobKeyword.dao.findFirst("SELECT * FROM wx_rob_keyword WHERE unique_key = ? AND key_data = ? AND nick_name = ? AND enable = 1 AND to_group = ? ORDER BY id DESC LIMIT 1", uniqueKey, ConfigKeys.DEAFAULT_WELCOME,fromNickName,msg.isGroupMsg()?1:0);
|
||||
if (sendSysWelcomeMsg(fromUserName, newNickName, robKeyword)){ return;}
|
||||
}
|
||||
|
||||
// 没有专门的关键字,则使用默认关键字
|
||||
isOpen = false;
|
||||
// 判断是群聊的话是否允许回复 昵称关键字
|
||||
if (robConfig.getDefaultGroup() && groupMsg){
|
||||
isOpen = true;
|
||||
}
|
||||
if (isOpen){
|
||||
WxRobKeyword defaultRobKeyword = WxRobKeyword.dao.findFirst("SELECT * FROM wx_rob_keyword WHERE unique_key = ? AND key_data = ? AND nick_name = ? AND enable = 1 AND to_group = ? ORDER BY id DESC LIMIT 1", uniqueKey, ConfigKeys.DEAFAULT_WELCOME, ConfigKeys.DEAFAULT_KEYWORD,msg.isGroupMsg()?1:0);
|
||||
if (sendSysWelcomeMsg(fromUserName, newNickName, defaultRobKeyword)){ return;}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送欢迎内容
|
||||
* @param fromUserName
|
||||
* @param newNickName
|
||||
* @param robKeyword
|
||||
* @return
|
||||
*/
|
||||
private boolean sendSysWelcomeMsg(String fromUserName, String newNickName, WxRobKeyword robKeyword) {
|
||||
if (robKeyword != null){
|
||||
if (robKeyword.getTypeData().equals(SendMsgType.TEXT.toValue())){
|
||||
robKeyword.setValueData(String.format("@%s\n%s",newNickName,robKeyword.getValueData()));
|
||||
}
|
||||
if (sendDataByType(fromUserName, robKeyword)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void picMsgHandle(BaseMsg msg) {
|
||||
// // 这里使用收到图片的时间作为文件名
|
||||
// String fileName = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date()) + ".jpg";
|
||||
// // 保存图片的路径
|
||||
// String picPath = getDownloadPath(fileName);
|
||||
// // 调用此方法来保存图片
|
||||
// DownloadTools.getDownloadFn(msg, MsgTypeEnum.PIC.getType(), picPath, this.uniqueKey);
|
||||
// CoreManage.addSendMsg4UserName(uniqueKey,msg.getFromUserName(),"图片保存成功",SendMsgType.TEXT);
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void voiceMsgHandle(BaseMsg msg) {
|
||||
// // 这里使用收到语音的时间作为文件名
|
||||
// String fileName = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date()) + ".mp3";
|
||||
// // 保存语音的路径
|
||||
// String voicePath = getDownloadPath(fileName);
|
||||
// // 调用此方法来保存语音
|
||||
// DownloadTools.getDownloadFn(msg, MsgTypeEnum.VOICE.getType(), voicePath, this.uniqueKey);
|
||||
// CoreManage.addSendMsg4UserName(uniqueKey,msg.getFromUserName(),"声音保存成功",SendMsgType.TEXT);
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void videoMsgHandle(BaseMsg msg) {
|
||||
// // 这里使用收到小视频的时间作为文件名
|
||||
// String fileName = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date()) + ".mp4";
|
||||
// // 保存小视频的路径
|
||||
// String viedoPath = getDownloadPath(fileName);
|
||||
// // 调用此方法来保存小视频
|
||||
// DownloadTools.getDownloadFn(msg, MsgTypeEnum.VIEDO.getType(), viedoPath,this.uniqueKey);
|
||||
// CoreManage.addSendMsg4UserName(uniqueKey,msg.getFromUserName(),"视频保存成功",SendMsgType.TEXT);
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nameCardMsgHandle(BaseMsg msg) {
|
||||
return ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void verifyAddFriendMsgHandle(BaseMsg msg) {
|
||||
return ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mediaMsgHandle(BaseMsg msg) {
|
||||
return ;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package org.ruoyi.system.handler.wxcp;
|
||||
|
||||
import me.chanjar.weixin.cp.message.WxCpMessageHandler;
|
||||
|
||||
/**
|
||||
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||
*/
|
||||
public abstract class AbstractHandler implements WxCpMessageHandler {
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package org.ruoyi.system.handler.wxcp;
|
||||
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.cp.api.WxCpService;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
|
||||
import org.ruoyi.common.core.utils.JsonUtils;
|
||||
import org.ruoyi.system.builder.TextBuilder;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 通讯录变更事件处理器.
|
||||
*
|
||||
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class ContactChangeHandler extends AbstractHandler {
|
||||
|
||||
@Override
|
||||
public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService cpService,
|
||||
WxSessionManager sessionManager) {
|
||||
String content = "收到通讯录变更事件,内容:" + JsonUtils.toJson(wxMessage);
|
||||
log.info(content);
|
||||
|
||||
return new TextBuilder().build(content, wxMessage, cpService);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.ruoyi.system.handler.wxcp;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.cp.api.WxCpService;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
*
|
||||
* Created by Binary Wang on 2018/8/27.
|
||||
* </pre>
|
||||
*
|
||||
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||
*/
|
||||
@Slf4j
|
||||
public class EnterAgentHandler extends AbstractHandler {
|
||||
private static final int TEST_AGENT = 1000002;
|
||||
|
||||
@Override
|
||||
public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService wxCpService, WxSessionManager sessionManager) throws WxErrorException {
|
||||
// do something
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package org.ruoyi.system.handler.wxcp;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.chanjar.weixin.common.api.WxConsts;
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.cp.api.WxCpService;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
|
||||
import org.ruoyi.system.builder.TextBuilder;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class LocationHandler extends AbstractHandler {
|
||||
|
||||
@Override
|
||||
public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService cpService,
|
||||
WxSessionManager sessionManager) {
|
||||
if (wxMessage.getMsgType().equals(WxConsts.XmlMsgType.LOCATION)) {
|
||||
//TODO 接收处理用户发送的地理位置消息
|
||||
try {
|
||||
String content = "感谢反馈,您的的地理位置已收到!";
|
||||
return new TextBuilder().build(content, wxMessage, null);
|
||||
} catch (Exception e) {
|
||||
log.error("位置消息接收处理失败", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//上报地理位置事件
|
||||
log.info("\n上报地理位置,纬度 : {}\n经度 : {}\n精度 : {}",
|
||||
wxMessage.getLatitude(), wxMessage.getLongitude(), String.valueOf(wxMessage.getPrecision()));
|
||||
|
||||
//TODO 可以将用户地理位置信息保存到本地数据库,以便以后使用
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package org.ruoyi.system.handler.wxcp;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.cp.api.WxCpService;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
|
||||
import org.ruoyi.common.core.utils.JsonUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class LogHandler extends AbstractHandler {
|
||||
@Override
|
||||
public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService cpService,
|
||||
WxSessionManager sessionManager) {
|
||||
log.info("\n接收到请求消息,内容:{}", JsonUtils.toJson(wxMessage));
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package org.ruoyi.system.handler.wxcp;
|
||||
|
||||
import me.chanjar.weixin.common.api.WxConsts.MenuButtonType;
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.cp.api.WxCpService;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||
*/
|
||||
@Component
|
||||
public class MenuHandler extends AbstractHandler {
|
||||
|
||||
@Override
|
||||
public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService cpService,
|
||||
WxSessionManager sessionManager) {
|
||||
|
||||
String msg = String.format("type:%s, event:%s, key:%s",
|
||||
wxMessage.getMsgType(), wxMessage.getEvent(),
|
||||
wxMessage.getEventKey());
|
||||
if (MenuButtonType.VIEW.equals(wxMessage.getEvent())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return WxCpXmlOutMessage.TEXT().content(msg)
|
||||
.fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName())
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package org.ruoyi.system.handler.wxcp;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import me.chanjar.weixin.common.api.WxConsts;
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.cp.api.WxCpService;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
|
||||
import org.ruoyi.system.builder.TextBuilder;
|
||||
import org.ruoyi.system.service.ISseService;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class MsgHandler extends AbstractHandler {
|
||||
|
||||
private final ISseService sseService;
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService cpService,
|
||||
WxSessionManager sessionManager) {
|
||||
final String msgType = wxMessage.getMsgType();
|
||||
if (msgType == null) {
|
||||
// 如果msgType没有,就自己根据具体报文内容做处理
|
||||
}
|
||||
|
||||
if (!msgType.equals(WxConsts.XmlMsgType.EVENT)) {
|
||||
//TODO 可以选择将消息保存到本地
|
||||
}
|
||||
//TODO 组装回复消息
|
||||
String content = sseService.wxCpChat(wxMessage.getContent());
|
||||
|
||||
return new TextBuilder().build(content, wxMessage, cpService);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.ruoyi.system.handler.wxcp;
|
||||
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.cp.api.WxCpService;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||
*/
|
||||
@Component
|
||||
public class NullHandler extends AbstractHandler {
|
||||
|
||||
@Override
|
||||
public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService cpService,
|
||||
WxSessionManager sessionManager) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package org.ruoyi.system.handler.wxcp;
|
||||
|
||||
/**
|
||||
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||
*/
|
||||
public abstract class ScanHandler extends AbstractHandler {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package org.ruoyi.system.handler.wxcp;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.cp.api.WxCpService;
|
||||
import me.chanjar.weixin.cp.bean.WxCpUser;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
|
||||
import org.ruoyi.system.builder.TextBuilder;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class SubscribeHandler extends AbstractHandler {
|
||||
|
||||
@Override
|
||||
public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService cpService,
|
||||
WxSessionManager sessionManager) throws WxErrorException {
|
||||
|
||||
log.info("新关注用户 OPENID: " + wxMessage.getFromUserName());
|
||||
|
||||
// 获取微信用户基本信息
|
||||
WxCpUser userWxInfo = cpService.getUserService().getById(wxMessage.getFromUserName());
|
||||
|
||||
if (userWxInfo != null) {
|
||||
// TODO 可以添加关注用户到本地
|
||||
}
|
||||
|
||||
WxCpXmlOutMessage responseResult = null;
|
||||
try {
|
||||
responseResult = handleSpecial(wxMessage);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
|
||||
if (responseResult != null) {
|
||||
return responseResult;
|
||||
}
|
||||
|
||||
try {
|
||||
return new TextBuilder().build("感谢关注", wxMessage, cpService);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理特殊请求,比如如果是扫码进来的,可以做相应处理
|
||||
*/
|
||||
private WxCpXmlOutMessage handleSpecial(WxCpXmlMessage wxMessage) {
|
||||
//TODO
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.ruoyi.system.handler.wxcp;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.cp.api.WxCpService;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
|
||||
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class UnsubscribeHandler extends AbstractHandler {
|
||||
|
||||
@Override
|
||||
public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService cpService,
|
||||
WxSessionManager sessionManager) {
|
||||
String openId = wxMessage.getFromUserName();
|
||||
log.info("取消关注用户 OPENID: " + openId);
|
||||
// TODO 可以更新本地数据库为取消关注状态
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -104,8 +104,8 @@ public class SSEEventSourceListener extends EventSourceListener {
|
||||
if(completionResponse == null || CollectionUtil.isEmpty(completionResponse.getChoices())){
|
||||
return;
|
||||
}
|
||||
String content = "completionResponse.getChoices().get(0).getDelta().getContent()";
|
||||
if(StringUtils.isEmpty(content)){
|
||||
Object content = completionResponse.getChoices().get(0).getDelta().getContent();
|
||||
if(content == null){
|
||||
return;
|
||||
}
|
||||
if(StringUtils.isEmpty(modelName)){
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package org.ruoyi.system.mapper;
|
||||
|
||||
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
import org.ruoyi.system.domain.ChatAppStore;
|
||||
import org.ruoyi.system.domain.vo.ChatAppStoreVo;
|
||||
|
||||
/**
|
||||
* 应用市场Mapper接口
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2024-03-19
|
||||
*/
|
||||
public interface ChatAppStoreMapper extends BaseMapperPlus<ChatAppStore, ChatAppStoreVo> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package org.ruoyi.system.mapper;
|
||||
|
||||
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
import org.ruoyi.system.domain.Cover;
|
||||
import org.ruoyi.system.domain.vo.cover.CoverVo;
|
||||
|
||||
/**
|
||||
* 翻唱Mapper接口
|
||||
*
|
||||
* @author NSL
|
||||
* @since 2024-12-25
|
||||
*/
|
||||
public interface CoverMapper extends BaseMapperPlus<Cover, CoverVo> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.ruoyi.system.mapper;
|
||||
|
||||
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
import org.ruoyi.system.domain.CoverPromptAudio;
|
||||
import org.ruoyi.system.domain.vo.cover.CoverPromptAudioVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 翻唱用户参考音频Mapper接口
|
||||
*
|
||||
* @author NSL
|
||||
* @since 2024-12-25
|
||||
*/
|
||||
public interface CoverPromptAudioMapper extends BaseMapperPlus<CoverPromptAudio, CoverPromptAudioVo> {
|
||||
|
||||
/**
|
||||
* 获取最近一次翻唱记录
|
||||
* @param userId 用户id
|
||||
* @return 翻唱记录
|
||||
*/
|
||||
List<CoverPromptAudioVo> selectLatestVoByUserId(Long userId);
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package org.ruoyi.system.mapper;
|
||||
|
||||
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
import org.ruoyi.system.domain.VoiceRole;
|
||||
import org.ruoyi.system.domain.vo.VoiceRoleVo;
|
||||
|
||||
/**
|
||||
* 配音角色Mapper接口
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2024-03-19
|
||||
*/
|
||||
public interface VoiceRoleMapper extends BaseMapperPlus<VoiceRole, VoiceRoleVo> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.ruoyi.system.response.rolelist;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ChatAppStoreVO {
|
||||
|
||||
|
||||
private String name;
|
||||
|
||||
private String description;
|
||||
|
||||
private String voicesId;
|
||||
|
||||
private String avatar;
|
||||
|
||||
private String appUrl;
|
||||
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package org.ruoyi.system.response.rolelist;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 描述:
|
||||
*
|
||||
* @author ageerle@163.com
|
||||
* date 2024/4/27
|
||||
*/
|
||||
@Data
|
||||
public class RoleListVO {
|
||||
|
||||
|
||||
private String name;
|
||||
|
||||
private String description;
|
||||
|
||||
private String voicesId;
|
||||
|
||||
private String avatar;
|
||||
|
||||
private String previewAudio;
|
||||
|
||||
public RoleListVO(String name, String description, String voicesId, String previewAudio,String avatar) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.voicesId = voicesId;
|
||||
this.previewAudio = previewAudio;
|
||||
this.avatar = avatar;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user