mirror of
https://gitcode.com/ageerle/ruoyi-ai.git
synced 2026-04-07 08:47:32 +00:00
feat: 重构模块
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
package org.ruoyi.system.domain;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.annotation.Version;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* 配置信息对象 chat_config
|
||||
*
|
||||
* @author ageerle
|
||||
* @date 2025-04-08
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("chat_config")
|
||||
public class ChatConfig extends BaseEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId(value = "id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 配置类型
|
||||
*/
|
||||
private String category;
|
||||
|
||||
/**
|
||||
* 配置名称
|
||||
*/
|
||||
private String configName;
|
||||
|
||||
/**
|
||||
* 配置值
|
||||
*/
|
||||
private String configValue;
|
||||
|
||||
/**
|
||||
* 说明
|
||||
*/
|
||||
private String configDict;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 版本
|
||||
*/
|
||||
@Version
|
||||
private Long version;
|
||||
|
||||
/**
|
||||
* 删除标志(0代表存在 1代表删除)
|
||||
*/
|
||||
@TableLogic
|
||||
private String delFlag;
|
||||
|
||||
/**
|
||||
* 更新IP
|
||||
*/
|
||||
private String updateIp;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package org.ruoyi.system.domain.bo;
|
||||
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.ruoyi.common.core.validate.AddGroup;
|
||||
import org.ruoyi.common.core.validate.EditGroup;
|
||||
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
|
||||
import org.ruoyi.system.domain.ChatConfig;
|
||||
|
||||
/**
|
||||
* 配置信息业务对象 chat_config
|
||||
*
|
||||
* @author ageerle
|
||||
* @date 2025-04-08
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@AutoMapper(target = ChatConfig.class, reverseConvertGenerate = false)
|
||||
public class ChatConfigBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@NotNull(message = "主键不能为空", groups = { EditGroup.class })
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 配置类型
|
||||
*/
|
||||
@NotBlank(message = "配置类型不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private String category;
|
||||
|
||||
/**
|
||||
* 配置名称
|
||||
*/
|
||||
@NotBlank(message = "配置名称不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private String configName;
|
||||
|
||||
/**
|
||||
* 配置值
|
||||
*/
|
||||
@NotBlank(message = "配置值不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private String configValue;
|
||||
|
||||
/**
|
||||
* 说明
|
||||
*/
|
||||
@NotBlank(message = "说明不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private String configDict;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@NotBlank(message = "备注不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 更新IP
|
||||
*/
|
||||
@NotBlank(message = "更新IP不能为空", groups = { AddGroup.class, EditGroup.class })
|
||||
private String updateIp;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package org.ruoyi.system.domain.vo;
|
||||
|
||||
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.ChatConfig;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* 配置信息视图对象 chat_config
|
||||
*
|
||||
* @author ageerle
|
||||
* @date 2025-04-08
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
@AutoMapper(target = ChatConfig.class)
|
||||
public class ChatConfigVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@ExcelProperty(value = "主键")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 配置类型
|
||||
*/
|
||||
@ExcelProperty(value = "配置类型")
|
||||
private String category;
|
||||
|
||||
/**
|
||||
* 配置名称
|
||||
*/
|
||||
@ExcelProperty(value = "配置名称")
|
||||
private String configName;
|
||||
|
||||
/**
|
||||
* 配置值
|
||||
*/
|
||||
@ExcelProperty(value = "配置值")
|
||||
private String configValue;
|
||||
|
||||
/**
|
||||
* 说明
|
||||
*/
|
||||
@ExcelProperty(value = "说明")
|
||||
private String configDict;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@ExcelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 更新IP
|
||||
*/
|
||||
@ExcelProperty(value = "更新IP")
|
||||
private String updateIp;
|
||||
|
||||
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package org.ruoyi.system.domain.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* 【请填写功能名称】视图对象 sys_user_model
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2024-08-03
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
@AutoMapper(target = SysUserModel.class)
|
||||
public class SysUserModelVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@ExcelProperty(value = "id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 模型id
|
||||
*/
|
||||
@ExcelProperty(value = "模型id")
|
||||
private Long mid;
|
||||
|
||||
/**
|
||||
* 用户组id
|
||||
*/
|
||||
@ExcelProperty(value = "用户组id")
|
||||
private Long gid;
|
||||
|
||||
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package org.ruoyi.system.mapper;
|
||||
|
||||
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
/**
|
||||
* 应用市场Mapper接口
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2024-03-19
|
||||
*/
|
||||
public interface ChatAppStoreMapper extends BaseMapperPlus<ChatAppStore, ChatAppStoreVo> {
|
||||
|
||||
}
|
||||
@@ -1,15 +1,16 @@
|
||||
package org.ruoyi.system.mapper;
|
||||
|
||||
|
||||
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
import org.ruoyi.system.domain.ChatConfig;
|
||||
import org.ruoyi.system.domain.vo.ChatConfigVo;
|
||||
|
||||
/**
|
||||
* 对话配置信息
|
||||
Mapper接口
|
||||
* 配置信息Mapper接口
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2024-04-13
|
||||
* @author ageerle
|
||||
* @date 2025-04-08
|
||||
*/
|
||||
public interface ChatConfigMapper extends BaseMapperPlus<ChatConfig, ChatConfigVo> {
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
package org.ruoyi.system.mapper;
|
||||
|
||||
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
/**
|
||||
* gpts管理Mapper接口
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2024-07-09
|
||||
*/
|
||||
public interface ChatGptsMapper extends BaseMapperPlus<ChatGpts, ChatGptsVo> {
|
||||
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package org.ruoyi.system.mapper;
|
||||
|
||||
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
|
||||
/**
|
||||
* 聊天消息Mapper接口
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2023-11-26
|
||||
*/
|
||||
public interface ChatMessageMapper extends BaseMapperPlus<ChatMessage, ChatMessageVo> {
|
||||
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package org.ruoyi.system.mapper;
|
||||
|
||||
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
/**
|
||||
* 插件管理Mapper接口
|
||||
*
|
||||
* @author ageerle
|
||||
* @date 2025-03-30
|
||||
*/
|
||||
public interface ChatPluginMapper extends BaseMapperPlus<ChatPlugin, ChatPluginVo> {
|
||||
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package org.ruoyi.system.mapper;
|
||||
|
||||
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
|
||||
/**
|
||||
* 聊天消息Mapper接口
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2023-11-26
|
||||
*/
|
||||
public interface ChatTokenMapper extends BaseMapperPlus<ChatToken, ChatTokenVo> {
|
||||
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package org.ruoyi.system.mapper;
|
||||
|
||||
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
/**
|
||||
* 访客管理Mapper接口
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2024-07-14
|
||||
*/
|
||||
public interface ChatVisitorUsageMapper extends BaseMapperPlus<ChatVisitorUsage, ChatVisitorUsageVo> {
|
||||
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package org.ruoyi.system.mapper;
|
||||
|
||||
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
/**
|
||||
* 用户兑换记录Mapper接口
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2024-05-03
|
||||
*/
|
||||
public interface ChatVoucherMapper extends BaseMapperPlus<ChatVoucher, ChatVoucherVo> {
|
||||
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package org.ruoyi.system.mapper;
|
||||
|
||||
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
import org.ruoyi.system.domain.vo.cover.CoverVo;
|
||||
|
||||
/**
|
||||
* 翻唱Mapper接口
|
||||
*
|
||||
* @author NSL
|
||||
* @since 2024-12-25
|
||||
*/
|
||||
public interface CoverMapper extends BaseMapperPlus<Cover, CoverVo> {
|
||||
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package org.ruoyi.system.mapper;
|
||||
|
||||
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
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,13 +0,0 @@
|
||||
package org.ruoyi.system.mapper;
|
||||
|
||||
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
/**
|
||||
* 支付订单Mapper接口
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2024-04-16
|
||||
*/
|
||||
public interface PaymentOrdersMapper extends BaseMapperPlus<PaymentOrder, PaymentOrdersVo> {
|
||||
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package org.ruoyi.system.mapper;
|
||||
|
||||
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
/**
|
||||
* 系统模型Mapper接口
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2024-04-04
|
||||
*/
|
||||
public interface SysModelMapper extends BaseMapperPlus<SysModel, SysModelVo> {
|
||||
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package org.ruoyi.system.mapper;
|
||||
|
||||
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
/**
|
||||
* 套餐管理Mapper接口
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2024-05-05
|
||||
*/
|
||||
public interface SysPackagePlanMapper extends BaseMapperPlus<SysPackagePlan, SysPackagePlanVo> {
|
||||
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package org.ruoyi.system.mapper;
|
||||
|
||||
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
/**
|
||||
* 【请填写功能名称】Mapper接口
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2024-08-03
|
||||
*/
|
||||
public interface SysUserGroupMapper extends BaseMapperPlus<SysUserGroup, SysUserGroupVo> {
|
||||
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package org.ruoyi.system.mapper;
|
||||
|
||||
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
import org.ruoyi.system.domain.vo.SysUserModelVo;
|
||||
|
||||
/**
|
||||
* 【请填写功能名称】Mapper接口
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2024-08-03
|
||||
*/
|
||||
public interface SysUserModelMapper extends BaseMapperPlus<SysUserModel, SysUserModelVo> {
|
||||
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package org.ruoyi.system.mapper;
|
||||
|
||||
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
/**
|
||||
* 【请填写功能名称】Mapper接口
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2024-05-01
|
||||
*/
|
||||
public interface WxRobConfigMapper extends BaseMapperPlus<WxRobConfig, WxRobConfigVo> {
|
||||
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package org.ruoyi.system.mapper;
|
||||
|
||||
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
/**
|
||||
* 【请填写功能名称】Mapper接口
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2024-05-01
|
||||
*/
|
||||
public interface WxRobKeywordMapper extends BaseMapperPlus<WxRobKeyword, WxRobKeywordVo> {
|
||||
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package org.ruoyi.system.mapper;
|
||||
|
||||
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
/**
|
||||
* 【请填写功能名称】Mapper接口
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2024-05-01
|
||||
*/
|
||||
public interface WxRobRelationMapper extends BaseMapperPlus<WxRobRelation, WxRobRelationVo> {
|
||||
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package org.ruoyi.system.runner;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.ruoyi.system.service.ISysOssConfigService;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 初始化 system 模块对应业务数据
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Component
|
||||
public class SystemApplicationRunner implements ApplicationRunner {
|
||||
|
||||
private final ISysOssConfigService ossConfigService;
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) {
|
||||
ossConfigService.init();
|
||||
log.info("初始化OSS配置成功");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,433 +0,0 @@
|
||||
package org.ruoyi.system.service;
|
||||
|
||||
import cn.binarywang.wx.miniapp.api.WxMaService;
|
||||
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
|
||||
import cn.binarywang.wx.miniapp.util.WxMaConfigHolder;
|
||||
import cn.dev33.satoken.exception.NotLoginException;
|
||||
import cn.dev33.satoken.secure.BCrypt;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
import org.ruoyi.common.core.constant.Constants;
|
||||
import org.ruoyi.common.core.constant.GlobalConstants;
|
||||
import org.ruoyi.common.core.constant.TenantConstants;
|
||||
import org.ruoyi.common.core.domain.dto.RoleDTO;
|
||||
import org.ruoyi.common.core.domain.model.LoginUser;
|
||||
import org.ruoyi.common.core.domain.model.VisitorLoginBody;
|
||||
import org.ruoyi.common.core.domain.model.VisitorLoginUser;
|
||||
import org.ruoyi.common.core.enums.*;
|
||||
import org.ruoyi.common.core.exception.user.CaptchaException;
|
||||
import org.ruoyi.common.core.exception.user.CaptchaExpireException;
|
||||
import org.ruoyi.common.core.exception.user.UserException;
|
||||
import org.ruoyi.common.core.service.ConfigService;
|
||||
import org.ruoyi.common.core.utils.*;
|
||||
import org.ruoyi.common.log.event.LogininforEvent;
|
||||
import org.ruoyi.common.redis.utils.RedisUtils;
|
||||
import org.ruoyi.common.satoken.utils.LoginHelper;
|
||||
import org.ruoyi.common.tenant.exception.TenantException;
|
||||
import org.ruoyi.common.tenant.helper.TenantHelper;
|
||||
import org.ruoyi.system.domain.SysUser;
|
||||
import org.ruoyi.system.domain.bo.SysUserBo;
|
||||
import org.ruoyi.system.domain.vo.LoginVo;
|
||||
import org.ruoyi.system.domain.vo.SysTenantVo;
|
||||
import org.ruoyi.system.domain.vo.SysUserVo;
|
||||
import org.ruoyi.system.mapper.SysUserMapper;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* 登录校验方法
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
@Service
|
||||
public class SysLoginService {
|
||||
|
||||
private final SysUserMapper userMapper;
|
||||
private final ISysPermissionService permissionService;
|
||||
private final ISysTenantService tenantService;
|
||||
private final WxMaService wxMaService;
|
||||
private final ISysUserService userService;
|
||||
private final ConfigService configService;
|
||||
@Value("${user.password.maxRetryCount}")
|
||||
private Integer maxRetryCount;
|
||||
|
||||
@Value("${user.password.lockTime}")
|
||||
private Integer lockTime;
|
||||
|
||||
/**
|
||||
* 获取微信
|
||||
* @param xcxCode 获取xcxCode
|
||||
*/
|
||||
public String getOpenidFromCode(String xcxCode) {
|
||||
try {
|
||||
WxMaJscode2SessionResult sessionInfo = wxMaService.getUserService().getSessionInfo(xcxCode);
|
||||
return sessionInfo.getOpenid();
|
||||
} catch (WxErrorException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 登录验证
|
||||
*
|
||||
* @param username 用户名
|
||||
* @param password 密码
|
||||
* @param code 验证码
|
||||
* @param uuid 唯一标识
|
||||
* @return 结果
|
||||
*/
|
||||
public String login(String tenantId, String username, String password, String code, String uuid) {
|
||||
SysUserVo user = loadUserByUsername(tenantId, username);
|
||||
checkLogin(LoginType.PASSWORD, tenantId, username, () -> !BCrypt.checkpw(password, user.getPassword()));
|
||||
// 此处可根据登录用户的数据不同 自行创建 loginUser
|
||||
LoginUser loginUser = buildLoginUser(user);
|
||||
// 生成token
|
||||
LoginHelper.loginByDevice(loginUser, DeviceType.PC);
|
||||
|
||||
recordLogininfor(loginUser.getTenantId(), username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
|
||||
recordLoginInfo(user.getUserId());
|
||||
return StpUtil.getTokenValue();
|
||||
}
|
||||
|
||||
public String smsLogin(String tenantId, String phonenumber, String smsCode) {
|
||||
// 校验租户
|
||||
checkTenant(tenantId);
|
||||
// 通过手机号查找用户
|
||||
SysUserVo user = loadUserByPhonenumber(tenantId, phonenumber);
|
||||
|
||||
checkLogin(LoginType.SMS, tenantId, user.getUserName(), () -> !validateSmsCode(tenantId, phonenumber, smsCode));
|
||||
// 此处可根据登录用户的数据不同 自行创建 loginUser
|
||||
LoginUser loginUser = buildLoginUser(user);
|
||||
// 生成token
|
||||
LoginHelper.loginByDevice(loginUser, DeviceType.APP);
|
||||
|
||||
recordLogininfor(loginUser.getTenantId(), user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
|
||||
recordLoginInfo(user.getUserId());
|
||||
return StpUtil.getTokenValue();
|
||||
}
|
||||
|
||||
public String emailLogin(String tenantId, String email, String emailCode) {
|
||||
// 校验租户
|
||||
checkTenant(tenantId);
|
||||
// 通过手机号查找用户
|
||||
SysUserVo user = loadUserByEmail(tenantId, email);
|
||||
|
||||
checkLogin(LoginType.EMAIL, tenantId, user.getUserName(), () -> !validateEmailCode(tenantId, email, emailCode));
|
||||
// 此处可根据登录用户的数据不同 自行创建 loginUser
|
||||
LoginUser loginUser = buildLoginUser(user);
|
||||
// 生成token
|
||||
LoginHelper.loginByDevice(loginUser, DeviceType.APP);
|
||||
|
||||
recordLogininfor(loginUser.getTenantId(), user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
|
||||
recordLoginInfo(user.getUserId());
|
||||
return StpUtil.getTokenValue();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 游客登录
|
||||
*
|
||||
* @param loginBody
|
||||
* @return String
|
||||
* @Date 2023/5/18
|
||||
**/
|
||||
public void visitorLogin(VisitorLoginBody loginBody) {
|
||||
String openid = "";
|
||||
// PC端游客登录
|
||||
if (LoginUserType.PC.getCode().equals(loginBody.getType())) {
|
||||
openid = loginBody.getCode();
|
||||
} else {
|
||||
// 小程序匿名登录
|
||||
try {
|
||||
WxMaJscode2SessionResult session = wxMaService.getUserService().getSessionInfo(loginBody.getCode());
|
||||
openid = session.getOpenid();
|
||||
} catch (WxErrorException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
} finally {
|
||||
// 清理ThreadLocal
|
||||
WxMaConfigHolder.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public LoginVo mpLogin(String openid) {
|
||||
// 使用 openid 查询绑定用户 如未绑定用户 则根据业务自行处理 例如 创建默认用户
|
||||
SysUserVo user = userService.selectUserByOpenId(openid);
|
||||
VisitorLoginUser loginUser = new VisitorLoginUser();
|
||||
if (ObjectUtil.isNull(user)) {
|
||||
SysUserBo sysUser = new SysUserBo();
|
||||
// 改为自增
|
||||
String name = "用户" + UUID.randomUUID().toString().replace("-", "");
|
||||
// 设置默认用户名
|
||||
sysUser.setUserName(name);
|
||||
// 设置默认昵称
|
||||
sysUser.setNickName(name);
|
||||
// 设置默认密码
|
||||
sysUser.setPassword(BCrypt.hashpw("123456"));
|
||||
// 设置微信openId
|
||||
sysUser.setOpenId(openid);
|
||||
String configValue = configService.getConfigValue("mail", "amount");
|
||||
// 设置默认余额
|
||||
sysUser.setUserBalance(NumberUtils.toDouble(configValue, 1));
|
||||
// 注册用户,设置默认租户为0
|
||||
SysUser registerUser = userService.registerUser(sysUser, "0");
|
||||
|
||||
// 构建登录用户信息
|
||||
loginUser.setTenantId("0");
|
||||
loginUser.setUserId(registerUser.getUserId());
|
||||
loginUser.setUsername(registerUser.getUserName());
|
||||
loginUser.setUserType(UserType.APP_USER.getUserType());
|
||||
loginUser.setOpenid(openid);
|
||||
loginUser.setNickName(registerUser.getNickName());
|
||||
|
||||
} else {
|
||||
// 此处可根据登录用户的数据不同 自行创建 loginUser
|
||||
loginUser.setTenantId(user.getTenantId());
|
||||
loginUser.setUserId(user.getUserId());
|
||||
loginUser.setUsername(user.getUserName());
|
||||
loginUser.setUserType(user.getUserType());
|
||||
loginUser.setNickName(user.getNickName());
|
||||
loginUser.setAvatar(user.getWxAvatar());
|
||||
loginUser.setOpenid(openid);
|
||||
}
|
||||
// 生成token
|
||||
LoginHelper.loginByDevice(loginUser, DeviceType.XCX);
|
||||
recordLogininfor(loginUser.getTenantId(), loginUser.getUsername(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
|
||||
LoginVo loginVo = new LoginVo();
|
||||
// 生成令牌
|
||||
loginVo.setToken(StpUtil.getTokenValue());
|
||||
loginVo.setUserInfo(loginUser);
|
||||
return loginVo;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 退出登录
|
||||
*/
|
||||
public void logout() {
|
||||
try {
|
||||
LoginUser loginUser = LoginHelper.getLoginUser();
|
||||
if (TenantHelper.isEnable() && LoginHelper.isSuperAdmin()) {
|
||||
// 超级管理员 登出清除动态租户
|
||||
TenantHelper.clearDynamic();
|
||||
}
|
||||
StpUtil.logout();
|
||||
if (loginUser !=null) {
|
||||
recordLogininfor(loginUser.getTenantId(), loginUser.getUsername(), Constants.LOGOUT, MessageUtils.message("user.logout.success"));
|
||||
}
|
||||
} catch (NotLoginException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录登录信息
|
||||
*
|
||||
* @param tenantId 租户ID
|
||||
* @param username 用户名
|
||||
* @param status 状态
|
||||
* @param message 消息内容
|
||||
*/
|
||||
private void recordLogininfor(String tenantId, String username, String status, String message) {
|
||||
LogininforEvent logininforEvent = new LogininforEvent();
|
||||
logininforEvent.setTenantId(tenantId);
|
||||
logininforEvent.setUsername(username);
|
||||
logininforEvent.setStatus(status);
|
||||
logininforEvent.setMessage(message);
|
||||
logininforEvent.setRequest(ServletUtils.getRequest());
|
||||
SpringUtils.context().publishEvent(logininforEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验短信验证码
|
||||
*/
|
||||
private boolean validateSmsCode(String tenantId, String phonenumber, String smsCode) {
|
||||
String code = RedisUtils.getCacheObject(GlobalConstants.CAPTCHA_CODE_KEY + phonenumber);
|
||||
if (StringUtils.isBlank(code)) {
|
||||
recordLogininfor(tenantId, phonenumber, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"));
|
||||
throw new CaptchaExpireException();
|
||||
}
|
||||
return code.equals(smsCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验邮箱验证码
|
||||
*/
|
||||
private boolean validateEmailCode(String tenantId, String email, String emailCode) {
|
||||
String code = RedisUtils.getCacheObject(GlobalConstants.CAPTCHA_CODE_KEY + email);
|
||||
if (StringUtils.isBlank(code)) {
|
||||
recordLogininfor(tenantId, email, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"));
|
||||
throw new CaptchaExpireException();
|
||||
}
|
||||
return code.equals(emailCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验验证码
|
||||
*
|
||||
* @param username 用户名
|
||||
* @param code 验证码
|
||||
* @param uuid 唯一标识
|
||||
*/
|
||||
public void validateCaptcha(String tenantId, String username, String code, String uuid) {
|
||||
String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + StringUtils.defaultString(uuid, "");
|
||||
String captcha = RedisUtils.getCacheObject(verifyKey);
|
||||
RedisUtils.deleteObject(verifyKey);
|
||||
if (captcha == null) {
|
||||
recordLogininfor(tenantId, username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"));
|
||||
throw new CaptchaExpireException();
|
||||
}
|
||||
if (!code.equalsIgnoreCase(captcha)) {
|
||||
recordLogininfor(tenantId, username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error"));
|
||||
throw new CaptchaException();
|
||||
}
|
||||
}
|
||||
|
||||
private SysUserVo loadUserByUsername(String tenantId, String username) {
|
||||
|
||||
SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>().select(SysUser::getUserName, SysUser::getStatus).eq(TenantHelper.isEnable(), SysUser::getTenantId, tenantId).eq(SysUser::getUserName, username));
|
||||
if (ObjectUtil.isNull(user)) {
|
||||
log.info("登录用户:{} 不存在.", username);
|
||||
throw new UserException("user.not.exists", username);
|
||||
} else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
|
||||
log.info("登录用户:{} 已被停用.", username);
|
||||
throw new UserException("user.blocked", username);
|
||||
}
|
||||
if (TenantHelper.isEnable()) {
|
||||
return userMapper.selectTenantUserByUserName(username, tenantId);
|
||||
}
|
||||
return userMapper.selectUserByUserName(username);
|
||||
}
|
||||
|
||||
private SysUserVo loadUserByPhonenumber(String tenantId, String phonenumber) {
|
||||
SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>().select(SysUser::getPhonenumber, SysUser::getStatus).eq(TenantHelper.isEnable(), SysUser::getTenantId, tenantId).eq(SysUser::getPhonenumber, phonenumber));
|
||||
if (ObjectUtil.isNull(user)) {
|
||||
log.info("登录用户:{} 不存在.", phonenumber);
|
||||
throw new UserException("user.not.exists", phonenumber);
|
||||
} else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
|
||||
log.info("登录用户:{} 已被停用.", phonenumber);
|
||||
throw new UserException("user.blocked", phonenumber);
|
||||
}
|
||||
if (TenantHelper.isEnable()) {
|
||||
return userMapper.selectTenantUserByPhonenumber(phonenumber, tenantId);
|
||||
}
|
||||
return userMapper.selectUserByPhonenumber(phonenumber);
|
||||
}
|
||||
|
||||
private SysUserVo loadUserByEmail(String tenantId, String email) {
|
||||
SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>().select(SysUser::getPhonenumber, SysUser::getStatus).eq(TenantHelper.isEnable(), SysUser::getTenantId, tenantId).eq(SysUser::getEmail, email));
|
||||
if (ObjectUtil.isNull(user)) {
|
||||
log.info("登录用户:{} 不存在.", email);
|
||||
throw new UserException("user.not.exists", email);
|
||||
} else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
|
||||
log.info("登录用户:{} 已被停用.", email);
|
||||
throw new UserException("user.blocked", email);
|
||||
}
|
||||
if (TenantHelper.isEnable()) {
|
||||
return userMapper.selectTenantUserByEmail(email, tenantId);
|
||||
}
|
||||
return userMapper.selectUserByEmail(email);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建登录用户
|
||||
*/
|
||||
private LoginUser buildLoginUser(SysUserVo user) {
|
||||
LoginUser loginUser = new LoginUser();
|
||||
loginUser.setTenantId(user.getTenantId());
|
||||
loginUser.setUserId(user.getUserId());
|
||||
loginUser.setDeptId(user.getDeptId());
|
||||
loginUser.setUsername(user.getUserName());
|
||||
loginUser.setAvatar(user.getAvatar());
|
||||
loginUser.setUserType(user.getUserType());
|
||||
loginUser.setMenuPermission(permissionService.getMenuPermission(user.getUserId()));
|
||||
loginUser.setRolePermission(permissionService.getRolePermission(user.getUserId()));
|
||||
loginUser.setDeptName(ObjectUtil.isNull(user.getDept()) ? "" : user.getDept().getDeptName());
|
||||
List<RoleDTO> roles = BeanUtil.copyToList(user.getRoles(), RoleDTO.class);
|
||||
loginUser.setRoles(roles);
|
||||
return loginUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录登录信息
|
||||
*
|
||||
* @param userId 用户ID
|
||||
*/
|
||||
public void recordLoginInfo(Long userId) {
|
||||
SysUser sysUser = new SysUser();
|
||||
sysUser.setUserId(userId);
|
||||
sysUser.setLoginIp(ServletUtils.getClientIP());
|
||||
sysUser.setLoginDate(DateUtils.getNowDate());
|
||||
sysUser.setUpdateBy(userId);
|
||||
userMapper.updateById(sysUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录校验
|
||||
*/
|
||||
private void checkLogin(LoginType loginType, String tenantId, String username, Supplier<Boolean> supplier) {
|
||||
String errorKey = GlobalConstants.PWD_ERR_CNT_KEY + username;
|
||||
String loginFail = Constants.LOGIN_FAIL;
|
||||
|
||||
// 获取用户登录错误次数(可自定义限制策略 例如: key + username + ip)
|
||||
Integer errorNumber = RedisUtils.getCacheObject(errorKey);
|
||||
// 锁定时间内登录 则踢出
|
||||
if (ObjectUtil.isNotNull(errorNumber) && errorNumber.equals(maxRetryCount)) {
|
||||
recordLogininfor(tenantId, username, loginFail, MessageUtils.message(loginType.getRetryLimitExceed(), maxRetryCount, lockTime));
|
||||
throw new UserException(loginType.getRetryLimitExceed(), maxRetryCount, lockTime);
|
||||
}
|
||||
|
||||
if (supplier.get()) {
|
||||
// 是否第一次
|
||||
errorNumber = ObjectUtil.isNull(errorNumber) ? 1 : errorNumber + 1;
|
||||
// 达到规定错误次数 则锁定登录
|
||||
if (errorNumber.equals(maxRetryCount)) {
|
||||
RedisUtils.setCacheObject(errorKey, errorNumber, Duration.ofMinutes(lockTime));
|
||||
recordLogininfor(tenantId, username, loginFail, MessageUtils.message(loginType.getRetryLimitExceed(), maxRetryCount, lockTime));
|
||||
throw new UserException(loginType.getRetryLimitExceed(), maxRetryCount, lockTime);
|
||||
} else {
|
||||
// 未达到规定错误次数 则递增
|
||||
RedisUtils.setCacheObject(errorKey, errorNumber);
|
||||
recordLogininfor(tenantId, username, loginFail, MessageUtils.message(loginType.getRetryLimitCount(), errorNumber));
|
||||
throw new UserException(loginType.getRetryLimitCount(), errorNumber);
|
||||
}
|
||||
}
|
||||
|
||||
// 登录成功 清空错误次数
|
||||
RedisUtils.deleteObject(errorKey);
|
||||
}
|
||||
|
||||
private void checkTenant(String tenantId) {
|
||||
if (!TenantHelper.isEnable()) {
|
||||
return;
|
||||
}
|
||||
if (TenantConstants.DEFAULT_TENANT_ID.equals(tenantId)) {
|
||||
return;
|
||||
}
|
||||
SysTenantVo tenant = tenantService.queryByTenantId(tenantId);
|
||||
if (ObjectUtil.isNull(tenant)) {
|
||||
log.info("登录租户:{} 不存在.", tenantId);
|
||||
throw new TenantException("tenant.not.exists");
|
||||
} else if (TenantStatus.DISABLE.getCode().equals(tenant.getStatus())) {
|
||||
log.info("登录租户:{} 已被停用.", tenantId);
|
||||
throw new TenantException("tenant.blocked");
|
||||
} else if (ObjectUtil.isNotNull(tenant.getExpireTime()) && new Date().after(tenant.getExpireTime())) {
|
||||
log.info("登录租户:{} 已超过有效期.", tenantId);
|
||||
throw new TenantException("tenant.expired");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,153 +0,0 @@
|
||||
package org.ruoyi.system.service;
|
||||
|
||||
import cn.dev33.satoken.secure.BCrypt;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
import org.ruoyi.common.core.constant.Constants;
|
||||
import org.ruoyi.common.core.constant.GlobalConstants;
|
||||
import org.ruoyi.common.core.domain.model.RegisterBody;
|
||||
import org.ruoyi.common.core.exception.base.BaseException;
|
||||
import org.ruoyi.common.core.exception.user.CaptchaException;
|
||||
import org.ruoyi.common.core.exception.user.CaptchaExpireException;
|
||||
import org.ruoyi.common.core.exception.user.UserException;
|
||||
import org.ruoyi.common.core.service.ConfigService;
|
||||
import org.ruoyi.common.core.utils.MessageUtils;
|
||||
import org.ruoyi.common.core.utils.ServletUtils;
|
||||
import org.ruoyi.common.core.utils.SpringUtils;
|
||||
import org.ruoyi.common.core.utils.StringUtils;
|
||||
import org.ruoyi.common.log.event.LogininforEvent;
|
||||
import org.ruoyi.common.redis.utils.RedisUtils;
|
||||
import org.ruoyi.system.domain.SysUser;
|
||||
import org.ruoyi.system.domain.SysUserRole;
|
||||
import org.ruoyi.system.domain.bo.SysUserBo;
|
||||
import org.ruoyi.system.domain.vo.SysUserVo;
|
||||
import org.ruoyi.system.mapper.SysUserRoleMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 注册校验方法
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class SysRegisterService {
|
||||
|
||||
private final ISysUserService userService;
|
||||
|
||||
private final SysUserRoleMapper userRoleMapper;
|
||||
|
||||
private final ConfigService configService;
|
||||
/**
|
||||
* 注册
|
||||
*/
|
||||
public void register(RegisterBody registerBody) {
|
||||
|
||||
|
||||
String tenantId = Constants.TENANT_ID;
|
||||
if(StringUtils.isNotBlank(registerBody.getTenantId())){
|
||||
tenantId = registerBody.getTenantId();
|
||||
}
|
||||
String username = registerBody.getUsername();
|
||||
String password = registerBody.getPassword();
|
||||
|
||||
// 检查验证码是否正确
|
||||
validateEmail(username,registerBody.getCode());
|
||||
SysUserBo sysUser = new SysUserBo();
|
||||
sysUser.setDomainName(registerBody.getDomainName());
|
||||
sysUser.setUserName(username);
|
||||
sysUser.setNickName(username);
|
||||
sysUser.setPassword(BCrypt.hashpw(password));
|
||||
if (!userService.checkUserNameUnique(sysUser)) {
|
||||
throw new UserException("添加用户失败", username);
|
||||
}
|
||||
String configValue = configService.getConfigValue("mail", "amount");
|
||||
|
||||
|
||||
|
||||
// 设置默认余额
|
||||
sysUser.setUserBalance(NumberUtils.toDouble(configValue,1));
|
||||
SysUser user = userService.registerUser(sysUser, tenantId);
|
||||
if (user == null) {
|
||||
throw new UserException("用户注册失败!");
|
||||
}
|
||||
// 设置默认角色
|
||||
SysUserRole sysRole = new SysUserRole();
|
||||
sysRole.setUserId(user.getUserId());
|
||||
sysRole.setRoleId(1L);
|
||||
userRoleMapper.insert(sysRole);
|
||||
recordLogininfor(tenantId, username, Constants.REGISTER, MessageUtils.message("user.register.success"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置密码
|
||||
*/
|
||||
public void resetPassWord(RegisterBody registerBody) {
|
||||
String username = registerBody.getUsername();
|
||||
String password = registerBody.getPassword();
|
||||
SysUserVo user = userService.selectUserByUserName(username);
|
||||
if(user == null){
|
||||
throw new UserException(String.format("用户【%s】,未注册!",username));
|
||||
}
|
||||
// 检查验证码是否正确
|
||||
validateEmail(username,registerBody.getCode());
|
||||
userService.resetUserPwd(user.getUserId(),BCrypt.hashpw(password));
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验邮箱验证码
|
||||
*
|
||||
* @param username 用户名
|
||||
*/
|
||||
public void validateEmail(String username,String code) {
|
||||
String key = GlobalConstants.CAPTCHA_CODE_KEY + username;
|
||||
String captcha = RedisUtils.getCacheObject(key);
|
||||
if(code.equals(captcha)){
|
||||
RedisUtils.deleteObject(captcha);
|
||||
}else {
|
||||
throw new BaseException("验证码错误,请重试!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 校验验证码
|
||||
*
|
||||
* @param username 用户名
|
||||
* @param code 验证码
|
||||
* @param uuid 唯一标识
|
||||
*/
|
||||
public void validateCaptcha(String tenantId, String username, String code, String uuid) {
|
||||
String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + StringUtils.defaultString(uuid, "");
|
||||
String captcha = RedisUtils.getCacheObject(verifyKey);
|
||||
RedisUtils.deleteObject(verifyKey);
|
||||
if (captcha == null) {
|
||||
recordLogininfor(tenantId, username, Constants.REGISTER, MessageUtils.message("user.jcaptcha.expire"));
|
||||
throw new CaptchaExpireException();
|
||||
}
|
||||
if (!code.equalsIgnoreCase(captcha)) {
|
||||
recordLogininfor(tenantId, username, Constants.REGISTER, MessageUtils.message("user.jcaptcha.error"));
|
||||
throw new CaptchaException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录登录信息
|
||||
*
|
||||
* @param tenantId 租户ID
|
||||
* @param username 用户名
|
||||
* @param status 状态
|
||||
* @param message 消息内容
|
||||
* @return
|
||||
*/
|
||||
private void recordLogininfor(String tenantId, String username, String status, String message) {
|
||||
LogininforEvent logininforEvent = new LogininforEvent();
|
||||
logininforEvent.setTenantId(tenantId);
|
||||
logininforEvent.setUsername(username);
|
||||
logininforEvent.setStatus(status);
|
||||
logininforEvent.setMessage(message);
|
||||
logininforEvent.setRequest(ServletUtils.getRequest());
|
||||
SpringUtils.context().publishEvent(logininforEvent);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package org.ruoyi.system.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.ruoyi.common.core.service.ConfigService;
|
||||
import org.ruoyi.common.core.utils.StringUtils;
|
||||
import org.ruoyi.system.domain.ChatConfig;
|
||||
import org.ruoyi.system.domain.bo.ChatConfigBo;
|
||||
import org.ruoyi.system.domain.vo.ChatConfigVo;
|
||||
import org.ruoyi.system.mapper.ChatConfigMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
|
||||
/**
|
||||
* 配置信息Service业务层处理
|
||||
*
|
||||
* @author ageerle
|
||||
* @date 2025-04-08
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class ChatConfigServiceImpl implements ConfigService {
|
||||
|
||||
private final ChatConfigMapper baseMapper;
|
||||
|
||||
/**
|
||||
* 根据配置类型和配置key获取值
|
||||
*
|
||||
* @param category 分类
|
||||
* @param configKey key名称
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String getConfigValue(String category,String configKey) {
|
||||
ChatConfigBo bo = new ChatConfigBo();
|
||||
bo.setCategory(category);
|
||||
bo.setConfigName(configKey);
|
||||
LambdaQueryWrapper<ChatConfig> lqw = buildQueryWrapper(bo);
|
||||
ChatConfigVo chatConfigVo = baseMapper.selectVoOne(lqw);
|
||||
return chatConfigVo.getConfigValue();
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<ChatConfig> buildQueryWrapper(ChatConfigBo bo) {
|
||||
LambdaQueryWrapper<ChatConfig> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getCategory()), ChatConfig::getCategory, bo.getCategory());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getConfigName()), ChatConfig::getConfigName, bo.getConfigName());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getConfigValue()), ChatConfig::getConfigValue, bo.getConfigValue());
|
||||
return lqw;
|
||||
}
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
package org.ruoyi.system.service.impl;
|
||||
|
||||
import org.ruoyi.common.core.utils.MapstructUtils;
|
||||
import org.ruoyi.common.core.utils.StringUtils;
|
||||
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
|
||||
import org.ruoyi.common.mybatis.core.page.PageQuery;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.ruoyi.system.mapper.SysUserGroupMapper;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* 【请填写功能名称】Service业务层处理
|
||||
*
|
||||
* @author Lion Li
|
||||
* @date 2024-08-03
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class SysUserGroupServiceImpl implements ISysUserGroupService {
|
||||
|
||||
private final SysUserGroupMapper baseMapper;
|
||||
|
||||
/**
|
||||
* 查询【请填写功能名称】
|
||||
*/
|
||||
@Override
|
||||
public SysUserGroupVo queryById(Long id){
|
||||
return baseMapper.selectVoById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询【请填写功能名称】列表
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<SysUserGroupVo> queryPageList(SysUserGroupBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<SysUserGroup> lqw = buildQueryWrapper(bo);
|
||||
Page<SysUserGroupVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询【请填写功能名称】列表
|
||||
*/
|
||||
@Override
|
||||
public List<SysUserGroupVo> queryList(SysUserGroupBo bo) {
|
||||
LambdaQueryWrapper<SysUserGroup> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<SysUserGroup> buildQueryWrapper(SysUserGroupBo bo) {
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<SysUserGroup> lqw = Wrappers.lambdaQuery();
|
||||
lqw.like(StringUtils.isNotBlank(bo.getGroupName()), SysUserGroup::getGroupName, bo.getGroupName());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getUpdateIp()), SysUserGroup::getUpdateIp, bo.getUpdateIp());
|
||||
return lqw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增【请填写功能名称】
|
||||
*/
|
||||
@Override
|
||||
public Boolean insertByBo(SysUserGroupBo bo) {
|
||||
SysUserGroup add = MapstructUtils.convert(bo, SysUserGroup.class);
|
||||
validEntityBeforeSave(add);
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setId(add.getId());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改【请填写功能名称】
|
||||
*/
|
||||
@Override
|
||||
public Boolean updateByBo(SysUserGroupBo bo) {
|
||||
SysUserGroup update = MapstructUtils.convert(bo, SysUserGroup.class);
|
||||
validEntityBeforeSave(update);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(SysUserGroup entity){
|
||||
//TODO 做一些数据校验,如唯一约束
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除【请填写功能名称】
|
||||
*/
|
||||
@Override
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if(isValid){
|
||||
//TODO 做一些业务上的校验,判断是否需要校验
|
||||
}
|
||||
return baseMapper.deleteBatchIds(ids) > 0;
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
package org.ruoyi.system.util;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* Java 使用 AES 加密算法进行加密解密
|
||||
*/
|
||||
@Component
|
||||
public class AesUtils {
|
||||
|
||||
/**
|
||||
* 秘钥(需要使用长度为16、24或32的字节数组作为AES算法的密钥,否则就会遇到java.security.InvalidKeyException异常)
|
||||
*/
|
||||
// @Value("${ase.util.secret}")
|
||||
public String key;
|
||||
|
||||
/**
|
||||
* AES算法加密
|
||||
*
|
||||
* @Param:text原文
|
||||
* @Param:key密钥
|
||||
*/
|
||||
|
||||
@SneakyThrows
|
||||
public String aesEncrypt(String text) {
|
||||
// 创建AES加密算法实例(根据传入指定的秘钥进行加密)
|
||||
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
|
||||
SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "AES");
|
||||
// 初始化为加密模式,并将密钥注入到算法中
|
||||
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
|
||||
// 将传入的文本加密
|
||||
byte[] encrypted = cipher.doFinal(text.getBytes());
|
||||
//生成密文
|
||||
// 将密文进行Base64编码,方便传输
|
||||
return Base64.getEncoder().encodeToString(encrypted);
|
||||
}
|
||||
|
||||
/**
|
||||
* AES算法解密
|
||||
*
|
||||
* @Param:base64Encrypted密文
|
||||
* @Param:key密钥
|
||||
*/
|
||||
public String aesDecrypt(String base64Encrypted) throws Exception {
|
||||
// 创建AES解密算法实例
|
||||
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
|
||||
SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "AES");
|
||||
|
||||
// 初始化为解密模式,并将密钥注入到算法中
|
||||
cipher.init(Cipher.DECRYPT_MODE, keySpec);
|
||||
// 将Base64编码的密文解码
|
||||
byte[] encrypted = Base64.getDecoder().decode(base64Encrypted);
|
||||
// 解密
|
||||
byte[] decrypted = cipher.doFinal(encrypted);
|
||||
return new String(decrypted);
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
package org.ruoyi.system.util;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import okhttp3.*;
|
||||
import org.ruoyi.common.core.service.ConfigService;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author WangLe
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Component
|
||||
@Slf4j
|
||||
public class AudioOkHttpUtil {
|
||||
|
||||
private final ConfigService configService;
|
||||
|
||||
private static final String AUTHORIZATION = "Authorization";
|
||||
|
||||
private final OkHttpClient client = new OkHttpClient.Builder()
|
||||
.connectTimeout(300, TimeUnit.SECONDS)
|
||||
.writeTimeout(300, TimeUnit.SECONDS)
|
||||
.readTimeout(300, TimeUnit.SECONDS)
|
||||
.build();
|
||||
|
||||
public String executeRequest(Request request) {
|
||||
try (Response response = client.newCall(request).execute()) {
|
||||
if (!response.isSuccessful()) {
|
||||
throw new IOException("Unexpected code " + response);
|
||||
}
|
||||
return response.body() != null ? response.body().string() : null;
|
||||
} catch (IOException e) {
|
||||
// 这里应根据实际情况使用适当的日志记录方式
|
||||
log.error("请求失败: {}",e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Request createPostRequest(String url, String json) {
|
||||
MediaType JSON = MediaType.get("application/json; charset=utf-8");
|
||||
RequestBody body = RequestBody.create(json, JSON);
|
||||
return new Request.Builder()
|
||||
.url(getKey("apiHost") + url)
|
||||
.post(body)
|
||||
.header("Content-Type", "application/json")
|
||||
.header(AUTHORIZATION, "Bearer "+getKey("apiKey"))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
public Request createGetRequest(String url) {
|
||||
return new Request.Builder()
|
||||
.url(getKey("apiHost") + url)
|
||||
.header(AUTHORIZATION, "Bearer "+getKey("apiKey"))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
public String getKey(String key) {
|
||||
return configService.getConfigValue("audio", key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
package org.ruoyi.system.util;
|
||||
|
||||
|
||||
public class DesensitizationUtil {
|
||||
public static String maskData(String data) {
|
||||
if (data == null || data.length() <= 4) {
|
||||
return data;
|
||||
}
|
||||
int start = 2;
|
||||
int end = data.length() - 2;
|
||||
StringBuilder masked = new StringBuilder();
|
||||
masked.append(data, 0, start);
|
||||
for (int i = start; i < end; i++) {
|
||||
masked.append('*');
|
||||
}
|
||||
masked.append(data.substring(end));
|
||||
return masked.toString();
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,24 +0,0 @@
|
||||
package org.ruoyi.system.util;
|
||||
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author https://www.wdbyte.com
|
||||
*/
|
||||
public class KeyUtils {
|
||||
|
||||
public synchronized static String key6() {
|
||||
return RandomStringUtils.randomAlphanumeric(6);
|
||||
}
|
||||
|
||||
public synchronized static String key16() {
|
||||
return RandomStringUtils.randomAlphanumeric(16);
|
||||
}
|
||||
|
||||
public static String uuid32() {
|
||||
return UUID.randomUUID().toString().replace("-", "");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package org.ruoyi.system.util;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
public class OrderNumberGenerator {
|
||||
// 订单编号前缀
|
||||
private static final String PREFIX = "NO";
|
||||
|
||||
// 时间格式化
|
||||
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMddHHmm");
|
||||
|
||||
// 生成订单编号
|
||||
public static String generate() {
|
||||
// 获取当前日期时间字符串
|
||||
String dateTimeStr = DATE_FORMAT.format(new Date());
|
||||
|
||||
// 生成随机数 (这里举例生成一个5位随机数)
|
||||
int randomNum = ThreadLocalRandom.current().nextInt(10000, 99999);
|
||||
|
||||
// 拼接订单编号
|
||||
return dateTimeStr + randomNum;
|
||||
}
|
||||
}
|
||||
@@ -1,438 +0,0 @@
|
||||
package org.ruoyi.system.util;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.mime.MultipartEntityBuilder;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 文多多PPT-API
|
||||
*
|
||||
* @author NSL
|
||||
* @since 2024-12-30
|
||||
*/
|
||||
public class WddPptApi {
|
||||
|
||||
public static final String BASE_URL = "https://docmee.cn";
|
||||
private static Long DEFAULT_TIME_OUT = 5 * 60 * 1000L;
|
||||
|
||||
public static String createApiToken(String apiKey, String uid, Integer limit) {
|
||||
String url = BASE_URL + "/api/user/createApiToken";
|
||||
JSONObject body = new JSONObject();
|
||||
body.put("uid", uid);
|
||||
body.put("limit", limit);
|
||||
HttpUtils.HttpRequest httpRequest = HttpUtils.HttpRequest.postJson(url);
|
||||
httpRequest.setBody(body.toJSONString());
|
||||
httpRequest.addHeaders("Api-Key", apiKey);
|
||||
HttpUtils.HttpResponse response = HttpUtils.request(httpRequest);
|
||||
if (response.getStatus() != 200) {
|
||||
throw new RuntimeException("创建apiToken失败,httpStatus=" + response.getStatus());
|
||||
}
|
||||
JSONObject result = response.getResponseToJson();
|
||||
if (result.getIntValue("code") != 0) {
|
||||
throw new RuntimeException("创建apiToken异常," + result.getString("message"));
|
||||
}
|
||||
return result.getJSONObject("data").getString("token");
|
||||
}
|
||||
|
||||
public static String parseFileData(String apiToken, File file, String content, String fileUrl) {
|
||||
String url = BASE_URL + "/api/ppt/parseFileData";
|
||||
HttpUtils.HttpRequest httpRequest = new HttpUtils.HttpRequest();
|
||||
httpRequest.setUrl(url);
|
||||
httpRequest.setMethod("POST");
|
||||
httpRequest.addHeaders("token", apiToken);
|
||||
MultipartEntityBuilder multipartEntity = MultipartEntityBuilder.create();
|
||||
multipartEntity.setCharset(StandardCharsets.UTF_8);
|
||||
if (file != null) {
|
||||
multipartEntity.addBinaryBody("file", file);
|
||||
}
|
||||
if (content != null) {
|
||||
multipartEntity.addTextBody("content", content, ContentType.create("text/plain", StandardCharsets.UTF_8));
|
||||
}
|
||||
if (fileUrl != null) {
|
||||
multipartEntity.addTextBody("fileUrl", fileUrl, ContentType.create("text/plain", StandardCharsets.UTF_8));
|
||||
}
|
||||
httpRequest.setBody(multipartEntity.build());
|
||||
HttpUtils.HttpResponse response = HttpUtils.request(httpRequest);
|
||||
if (response.getStatus() != 200) {
|
||||
throw new RuntimeException("解析文件或内容失败,httpStatus=" + response.getStatus());
|
||||
}
|
||||
JSONObject result = response.getResponseToJson();
|
||||
if (result.getIntValue("code") != 0) {
|
||||
throw new RuntimeException("解析文件或内容异常," + result.getString("message"));
|
||||
}
|
||||
return result.getJSONObject("data").getString("dataUrl");
|
||||
}
|
||||
|
||||
/**
|
||||
* 生产大纲
|
||||
*/
|
||||
public static String generateOutline(String apiToken, String subject, String dataUrl, String prompt) {
|
||||
String url = BASE_URL + "/api/ppt/generateOutline";
|
||||
JSONObject body = new JSONObject();
|
||||
body.put("subject", subject);
|
||||
body.put("dataUrl", dataUrl);
|
||||
body.put("prompt", prompt);
|
||||
HttpUtils.HttpRequest httpRequest = HttpUtils.HttpRequest.postJson(url);
|
||||
httpRequest.setBody(body.toJSONString());
|
||||
httpRequest.addHeaders("token", apiToken);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
HttpUtils.HttpResponse response = HttpUtils.requestWithEventStream(httpRequest, data -> {
|
||||
if (data == null || data.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
JSONObject json = JSONObject.parseObject(data);
|
||||
if (Objects.equals(json.getInteger("status"), -1)) {
|
||||
throw new RuntimeException(json.getString("error"));
|
||||
}
|
||||
String text = json.getString("text");
|
||||
sb.append(text);
|
||||
// 打印输出
|
||||
System.out.print(text);
|
||||
});
|
||||
if (response.getStatus() != 200) {
|
||||
throw new RuntimeException("生成大纲失败,httpStatus=" + response.getStatus());
|
||||
}
|
||||
if (response.getHeaders().getOrDefault("Content-Type", response.getHeaders().get("content-type")).contains("application/json")) {
|
||||
JSONObject result = response.getResponseToJson();
|
||||
throw new RuntimeException("生成大纲失败:" + result.getString("message"));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 生产大纲
|
||||
*/
|
||||
public static SseEmitter sseGenerateOutline(String apiToken, String subject, String dataUrl, String prompt) {
|
||||
String url = BASE_URL + "/api/ppt/generateOutline";
|
||||
JSONObject body = new JSONObject();
|
||||
body.put("subject", subject);
|
||||
body.put("dataUrl", dataUrl);
|
||||
body.put("prompt", prompt);
|
||||
HttpUtils.HttpRequest httpRequest = HttpUtils.HttpRequest.postJson(url);
|
||||
httpRequest.setBody(body.toJSONString());
|
||||
httpRequest.addHeaders("token", apiToken);
|
||||
SseEmitter sseEmitter = new SseEmitter(DEFAULT_TIME_OUT);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
new Thread(() -> {
|
||||
HttpUtils.HttpResponse response = HttpUtils.requestWithEventStream(httpRequest, data -> {
|
||||
if (data == null || data.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
JSONObject json = JSONObject.parseObject(data);
|
||||
Integer status = json.getInteger("status");
|
||||
if (Objects.equals(status, -1)) {
|
||||
throw new RuntimeException(json.getString("error"));
|
||||
}
|
||||
String text = json.getString("text");
|
||||
try {
|
||||
sseEmitter.send(SseEmitter.event().data(text));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
sb.append(text);
|
||||
// status 4 表示生成完成
|
||||
if (status == 4) {
|
||||
// 打印输出
|
||||
System.out.print(sb);
|
||||
sseEmitter.complete();
|
||||
}
|
||||
});
|
||||
if (response.getStatus() != 200) {
|
||||
throw new RuntimeException("生成大纲失败,httpStatus=" + response.getStatus());
|
||||
}
|
||||
if (response.getHeaders().getOrDefault("Content-Type", response.getHeaders().get("content-type")).contains("application/json")) {
|
||||
JSONObject result = response.getResponseToJson();
|
||||
throw new RuntimeException("生成大纲失败:" + result.getString("message"));
|
||||
}
|
||||
}).start();
|
||||
return sseEmitter;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成大纲内容
|
||||
*/
|
||||
public static String generateContent(String apiToken, String outlineMarkdown, String dataUrl, String prompt) {
|
||||
String url = BASE_URL + "/api/ppt/generateContent";
|
||||
JSONObject body = new JSONObject();
|
||||
body.put("outlineMarkdown", outlineMarkdown);
|
||||
body.put("dataUrl", dataUrl);
|
||||
body.put("prompt", prompt);
|
||||
HttpUtils.HttpRequest httpRequest = HttpUtils.HttpRequest.postJson(url);
|
||||
httpRequest.setBody(body.toJSONString());
|
||||
httpRequest.addHeaders("token", apiToken);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
HttpUtils.HttpResponse response = HttpUtils.requestWithEventStream(httpRequest, data -> {
|
||||
if (data == null || data.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
JSONObject json = JSONObject.parseObject(data);
|
||||
if (Objects.equals(json.getInteger("status"), -1)) {
|
||||
throw new RuntimeException(json.getString("error"));
|
||||
}
|
||||
String text = json.getString("text");
|
||||
sb.append(text);
|
||||
// 打印输出
|
||||
System.out.print(text);
|
||||
});
|
||||
if (response.getStatus() != 200) {
|
||||
throw new RuntimeException("生成大纲内容失败,httpStatus=" + response.getStatus());
|
||||
}
|
||||
if (response.getHeaders().getOrDefault("Content-Type", response.getHeaders().get("content-type")).contains("application/json")) {
|
||||
JSONObject result = response.getResponseToJson();
|
||||
throw new RuntimeException("生成大纲内容失败:" + result.getString("message"));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 流式生成大纲内容
|
||||
*/
|
||||
public static SseEmitter sseGenerateContent(String apiToken, String outlineMarkdown, String dataUrl, String prompt) {
|
||||
String url = BASE_URL + "/api/ppt/generateContent";
|
||||
JSONObject body = new JSONObject();
|
||||
body.put("outlineMarkdown", outlineMarkdown);
|
||||
body.put("dataUrl", dataUrl);
|
||||
body.put("prompt", prompt);
|
||||
HttpUtils.HttpRequest httpRequest = HttpUtils.HttpRequest.postJson(url);
|
||||
httpRequest.setBody(body.toJSONString());
|
||||
httpRequest.addHeaders("token", apiToken);
|
||||
SseEmitter sseEmitter = new SseEmitter(DEFAULT_TIME_OUT);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
new Thread(() -> {
|
||||
HttpUtils.HttpResponse response = HttpUtils.requestWithEventStream(httpRequest, data -> {
|
||||
if (data == null || data.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
JSONObject json = JSONObject.parseObject(data);
|
||||
Integer status = json.getInteger("status");
|
||||
if (Objects.equals(status, -1)) {
|
||||
throw new RuntimeException(json.getString("error"));
|
||||
}
|
||||
String text = json.getString("text");
|
||||
try {
|
||||
sseEmitter.send(text);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
sb.append(text);
|
||||
// status 4 表示生成完成
|
||||
if (status == 4) {
|
||||
// 打印输出
|
||||
System.out.print(sb);
|
||||
sseEmitter.complete();
|
||||
}
|
||||
});
|
||||
if (response.getStatus() != 200) {
|
||||
throw new RuntimeException("生成大纲内容失败,httpStatus=" + response.getStatus());
|
||||
}
|
||||
if (response.getHeaders().getOrDefault("Content-Type", response.getHeaders().get("content-type")).contains("application/json")) {
|
||||
JSONObject result = response.getResponseToJson();
|
||||
throw new RuntimeException("生成大纲内容失败:" + result.getString("message"));
|
||||
}
|
||||
}).start();
|
||||
return sseEmitter;
|
||||
}
|
||||
|
||||
public static Map<String, String> asyncGenerateContent(String apiToken, String outlineMarkdown, String dataUrl, String templateId, String prompt) {
|
||||
String url = BASE_URL + "/api/ppt/generateContent";
|
||||
JSONObject body = new JSONObject();
|
||||
body.put("asyncGenPptx", true);
|
||||
body.put("templateId", templateId);
|
||||
body.put("outlineMarkdown", outlineMarkdown);
|
||||
body.put("dataUrl", dataUrl);
|
||||
body.put("prompt", prompt);
|
||||
HttpUtils.HttpRequest httpRequest = HttpUtils.HttpRequest.postJson(url);
|
||||
httpRequest.setBody(body.toJSONString());
|
||||
httpRequest.addHeaders("token", apiToken);
|
||||
Map<String, String> pptInfo = new HashMap<>();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
HttpUtils.HttpResponse response = HttpUtils.requestWithEventStream(httpRequest, data -> {
|
||||
if (data == null || data.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
JSONObject json = JSONObject.parseObject(data);
|
||||
if (Objects.equals(json.getInteger("status"), -1)) {
|
||||
throw new RuntimeException(json.getString("error"));
|
||||
}
|
||||
if (json.getString("pptId") != null) {
|
||||
pptInfo.put("id", json.getString("pptId"));
|
||||
}
|
||||
String text = json.getString("text");
|
||||
sb.append(text);
|
||||
// 打印输出
|
||||
System.out.print(text);
|
||||
});
|
||||
if (response.getStatus() != 200) {
|
||||
throw new RuntimeException("生成大纲内容失败,httpStatus=" + response.getStatus());
|
||||
}
|
||||
if (response.getHeaders().getOrDefault("Content-Type", response.getHeaders().get("content-type")).contains("application/json")) {
|
||||
JSONObject result = response.getResponseToJson();
|
||||
throw new RuntimeException("生成大纲内容失败:" + result.getString("message"));
|
||||
}
|
||||
pptInfo.put("markdown", sb.toString());
|
||||
return pptInfo;
|
||||
}
|
||||
|
||||
public static String randomOneTemplateId(String apiToken) {
|
||||
String url = BASE_URL + "/api/ppt/randomTemplates";
|
||||
JSONObject body = new JSONObject();
|
||||
body.put("size", 1);
|
||||
JSONObject filters = new JSONObject();
|
||||
filters.put("type", 1);
|
||||
body.put("filters", filters);
|
||||
HttpUtils.HttpRequest httpRequest = HttpUtils.HttpRequest.postJson(url);
|
||||
httpRequest.setBody(body.toJSONString());
|
||||
httpRequest.addHeaders("token", apiToken);
|
||||
HttpUtils.HttpResponse response = HttpUtils.request(httpRequest);
|
||||
if (response.getStatus() != 200) {
|
||||
throw new RuntimeException("获取模板失败,httpStatus=" + response.getStatus());
|
||||
}
|
||||
JSONObject result = response.getResponseToJson();
|
||||
if (result.getIntValue("code") != 0) {
|
||||
throw new RuntimeException("获取模板异常," + result.getString("message"));
|
||||
}
|
||||
JSONArray data = result.getJSONArray("data");
|
||||
JSONObject template = data.getJSONObject(0);
|
||||
return template.getString("id");
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成PPT
|
||||
*/
|
||||
public static JSONObject generatePptx(String apiToken, String templateId, String markdown, boolean pptxProperty) {
|
||||
String url = BASE_URL + "/api/ppt/generatePptx";
|
||||
JSONObject body = new JSONObject();
|
||||
body.put("templateId", templateId);
|
||||
body.put("outlineContentMarkdown", markdown);
|
||||
body.put("pptxProperty", pptxProperty);
|
||||
HttpUtils.HttpRequest httpRequest = HttpUtils.HttpRequest.postJson(url);
|
||||
httpRequest.setBody(body.toJSONString());
|
||||
httpRequest.addHeaders("token", apiToken);
|
||||
HttpUtils.HttpResponse response = HttpUtils.request(httpRequest);
|
||||
if (response.getStatus() != 200) {
|
||||
throw new RuntimeException("生成PPT失败,httpStatus=" + response.getStatus());
|
||||
}
|
||||
JSONObject result = response.getResponseToJson();
|
||||
if (result.getIntValue("code") != 0) {
|
||||
throw new RuntimeException("生成PPT异常," + result.getString("message"));
|
||||
}
|
||||
return result.getJSONObject("data").getJSONObject("pptInfo");
|
||||
}
|
||||
|
||||
public static JSONObject downloadPptx(String apiToken, String id) {
|
||||
String url = BASE_URL + "/api/ppt/downloadPptx";
|
||||
JSONObject body = new JSONObject();
|
||||
body.put("id", id);
|
||||
HttpUtils.HttpRequest httpRequest = HttpUtils.HttpRequest.postJson(url);
|
||||
httpRequest.setBody(body.toJSONString());
|
||||
httpRequest.addHeaders("token", apiToken);
|
||||
HttpUtils.HttpResponse response = HttpUtils.request(httpRequest);
|
||||
if (response.getStatus() != 200) {
|
||||
throw new RuntimeException("下载PPT失败,httpStatus=" + response.getStatus());
|
||||
}
|
||||
JSONObject result = response.getResponseToJson();
|
||||
if (result.getIntValue("code") != 0) {
|
||||
throw new RuntimeException("下载PPT异常," + result.getString("message"));
|
||||
}
|
||||
return result.getJSONObject("data");
|
||||
}
|
||||
|
||||
public static JSONObject directGeneratePptx(String apiToken, boolean stream, String templateId, String subject, String dataUrl, String prompt, boolean pptxProperty) {
|
||||
String url = BASE_URL + "/api/ppt/directGeneratePptx";
|
||||
JSONObject body = new JSONObject();
|
||||
body.put("stream", stream);
|
||||
body.put("templateId", templateId);
|
||||
body.put("subject", subject);
|
||||
body.put("dataUrl", dataUrl);
|
||||
body.put("prompt", prompt);
|
||||
body.put("pptxProperty", pptxProperty);
|
||||
HttpUtils.HttpRequest httpRequest = HttpUtils.HttpRequest.postJson(url);
|
||||
httpRequest.setBody(body.toJSONString());
|
||||
httpRequest.addHeaders("token", apiToken);
|
||||
if (stream) {
|
||||
// 流式生成
|
||||
JSONObject[] pptInfo = new JSONObject[1];
|
||||
HttpUtils.HttpResponse response = HttpUtils.requestWithEventStream(httpRequest, data -> {
|
||||
if (data == null || data.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
JSONObject json = JSONObject.parseObject(data);
|
||||
if (Objects.equals(json.getInteger("status"), -1)) {
|
||||
throw new RuntimeException(json.getString("error"));
|
||||
}
|
||||
if (Objects.equals(json.getInteger("status"), 4) && json.containsKey("result")) {
|
||||
pptInfo[0] = json.getJSONObject("result");
|
||||
}
|
||||
String text = json.getString("text");
|
||||
// 打印输出
|
||||
System.out.print(text);
|
||||
});
|
||||
if (response.getStatus() != 200) {
|
||||
throw new RuntimeException("生成PPT失败,httpStatus=" + response.getStatus());
|
||||
}
|
||||
if (response.getHeaders().getOrDefault("Content-Type", response.getHeaders().get("content-type")).contains("application/json")) {
|
||||
JSONObject result = response.getResponseToJson();
|
||||
throw new RuntimeException("生成PPT失败:" + result.getString("message"));
|
||||
}
|
||||
return pptInfo[0];
|
||||
} else {
|
||||
// 非流式生成
|
||||
HttpUtils.HttpResponse response = HttpUtils.request(httpRequest);
|
||||
if (response.getStatus() != 200) {
|
||||
throw new RuntimeException("生成PPT失败,httpStatus=" + response.getStatus());
|
||||
}
|
||||
JSONObject result = response.getResponseToJson();
|
||||
if (result.getIntValue("code") != 0) {
|
||||
throw new RuntimeException("生成PPT异常," + result.getString("message"));
|
||||
}
|
||||
return result.getJSONObject("data").getJSONObject("pptInfo");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有PPT列表
|
||||
*/
|
||||
public static JSONObject listAllPptx(String apiToken, String body) {
|
||||
String url = BASE_URL + "/api/ppt/listAllPptx";
|
||||
HttpUtils.HttpRequest httpRequest = HttpUtils.HttpRequest.postJson(url);
|
||||
httpRequest.setBody(body);
|
||||
httpRequest.addHeaders("token", apiToken);
|
||||
HttpUtils.HttpResponse response = HttpUtils.request(httpRequest);
|
||||
if (response.getStatus() != 200) {
|
||||
throw new RuntimeException("查询所有PPT列表失败,httpStatus=" + response.getStatus());
|
||||
}
|
||||
JSONObject result = response.getResponseToJson();
|
||||
if (result.getIntValue("code") != 0) {
|
||||
throw new RuntimeException("查询所有PPT列表异常," + result.getString("message"));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询 PPT 模板
|
||||
*/
|
||||
public static JSONObject getPptTemplates(String apiToken, String body) {
|
||||
String url = BASE_URL + "/api/ppt/templates";
|
||||
HttpUtils.HttpRequest httpRequest = HttpUtils.HttpRequest.postJson(url);
|
||||
httpRequest.setBody(body);
|
||||
httpRequest.addHeaders("token", apiToken);
|
||||
HttpUtils.HttpResponse response = HttpUtils.request(httpRequest);
|
||||
if (response.getStatus() != 200) {
|
||||
throw new RuntimeException("分页查询 PPT 模板失败,httpStatus=" + response.getStatus());
|
||||
}
|
||||
JSONObject result = response.getResponseToJson();
|
||||
if (result.getIntValue("code") != 0) {
|
||||
throw new RuntimeException("分页查询 PPT 模板异常," + result.getString("message"));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
package org.ruoyi.system.util;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import okhttp3.*;
|
||||
import org.ruoyi.common.core.service.ConfigService;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 绘声美音HTTP请求工具类
|
||||
*
|
||||
* @author NSL
|
||||
* @since 2024-12-25
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Component
|
||||
@Slf4j
|
||||
public class WeChatScanHttpUtil {
|
||||
|
||||
private final ConfigService configService;
|
||||
|
||||
private static final String TOKEN = "token";
|
||||
|
||||
private final OkHttpClient client = new OkHttpClient.Builder()
|
||||
.connectTimeout(300, TimeUnit.SECONDS)
|
||||
.writeTimeout(300, TimeUnit.SECONDS)
|
||||
.readTimeout(300, TimeUnit.SECONDS)
|
||||
.build();
|
||||
|
||||
public String executeRequest(Request request) {
|
||||
try (Response response = client.newCall(request).execute()) {
|
||||
if (!response.isSuccessful()) {
|
||||
throw new IOException("Unexpected code " + response);
|
||||
}
|
||||
return response.body() != null ? response.body().string() : null;
|
||||
} catch (IOException e) {
|
||||
// 这里应根据实际情况使用适当的日志记录方式
|
||||
log.error("请求失败: {}",e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Request createPostRequest(String url, String json) {
|
||||
RequestBody body = RequestBody.create(json, MediaType.get("application/json; charset=utf-8"));
|
||||
return new Request.Builder()
|
||||
.url(url)
|
||||
.post(body)
|
||||
.header("Content-Type", "application/json")
|
||||
.header(TOKEN, getKey(TOKEN))
|
||||
.build();
|
||||
}
|
||||
|
||||
public String getKey(String key) {
|
||||
return configService.getConfigValue("cover", key);
|
||||
}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
package org.ruoyi.system.util;
|
||||
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.ruoyi.common.core.service.ConfigService;
|
||||
import org.ruoyi.system.domain.model.WeixinQrCode;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.net.URI;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* @author https://www.wdbyte.com
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class WeixinApiUtil {
|
||||
|
||||
private final ConfigService configService;
|
||||
|
||||
private static String QR_CODE_URL_PREFIX = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=";
|
||||
|
||||
private static String ACCESS_TOKEN = null;
|
||||
private static LocalDateTime ACCESS_TOKEN_EXPIRE_TIME = null;
|
||||
/**
|
||||
* 二维码 Ticket 过期时间
|
||||
*/
|
||||
private static int QR_CODE_TICKET_TIMEOUT = 10 * 60;
|
||||
|
||||
/**
|
||||
* 获取 access token
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public synchronized String getAccessToken() {
|
||||
if (ACCESS_TOKEN != null && ACCESS_TOKEN_EXPIRE_TIME.isAfter(LocalDateTime.now())) {
|
||||
return ACCESS_TOKEN;
|
||||
}
|
||||
String api = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + getKey("appid") + "&secret="
|
||||
+ getKey("secret");
|
||||
String result = HttpUtil.get(api);
|
||||
JSONObject jsonObject = JSON.parseObject(result);
|
||||
ACCESS_TOKEN = jsonObject.getString("access_token");
|
||||
ACCESS_TOKEN_EXPIRE_TIME = LocalDateTime.now().plusSeconds(jsonObject.getLong("expires_in") - 10);
|
||||
return ACCESS_TOKEN;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取二维码 Ticket
|
||||
*
|
||||
* https://developers.weixin.qq.com/doc/offiaccount/Account_Management/Generating_a_Parametric_QR_Code.html
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public WeixinQrCode getQrCode() {
|
||||
String api = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" + getAccessToken();
|
||||
String jsonBody = String.format("{\n"
|
||||
+ " \"expire_seconds\": %d,\n"
|
||||
+ " \"action_name\": \"QR_STR_SCENE\",\n"
|
||||
+ " \"action_info\": {\n"
|
||||
+ " \"scene\": {\n"
|
||||
+ " \"scene_str\": \"%s\"\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ "}", QR_CODE_TICKET_TIMEOUT, KeyUtils.uuid32());
|
||||
String result = HttpUtil.post(api, jsonBody);
|
||||
log.info("get qr code params:{}", jsonBody);
|
||||
log.info("get qr code result:{}", result);
|
||||
WeixinQrCode weixinQrCode = JSON.parseObject(result, WeixinQrCode.class);
|
||||
weixinQrCode.setQrCodeUrl(QR_CODE_URL_PREFIX + URI.create(weixinQrCode.getTicket()).toASCIIString());
|
||||
return weixinQrCode;
|
||||
}
|
||||
|
||||
public String getKey(String key) {
|
||||
return configService.getConfigValue("weixin", key);
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
package org.ruoyi.system.util;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.ruoyi.system.domain.model.ReceiveMessage;
|
||||
|
||||
/**
|
||||
* @author https://www.wdbyte.com
|
||||
*/
|
||||
public class WeixinMsgUtil {
|
||||
|
||||
// 事件-关注
|
||||
private static String EVENT_SUBSCRIBE = "subscribe";
|
||||
|
||||
/**
|
||||
* 微信消息转对象
|
||||
*
|
||||
* @param xml
|
||||
* @return
|
||||
*/
|
||||
public static ReceiveMessage msgToReceiveMessage(String xml) {
|
||||
JSONObject jsonObject = JSON.parseObject(XmlUtil.xml2json(xml));
|
||||
ReceiveMessage receiveMessage = new ReceiveMessage();
|
||||
receiveMessage.setToUserName(jsonObject.getString("ToUserName"));
|
||||
receiveMessage.setFromUserName(jsonObject.getString("FromUserName"));
|
||||
receiveMessage.setCreateTime(jsonObject.getString("CreateTime"));
|
||||
receiveMessage.setMsgType(jsonObject.getString("MsgType"));
|
||||
receiveMessage.setContent(jsonObject.getString("Content"));
|
||||
receiveMessage.setMsgId(jsonObject.getString("MsgId"));
|
||||
receiveMessage.setEvent(jsonObject.getString("Event"));
|
||||
receiveMessage.setTicket(jsonObject.getString("Ticket"));
|
||||
return receiveMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是订阅事件
|
||||
*
|
||||
* @param receiveMessage
|
||||
* @return
|
||||
*/
|
||||
public static boolean isEventAndSubscribe(ReceiveMessage receiveMessage) {
|
||||
return StringUtils.equals(receiveMessage.getEvent(), EVENT_SUBSCRIBE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是二维码扫描事件
|
||||
*
|
||||
* @param receiveMessage
|
||||
* @return
|
||||
*/
|
||||
public static boolean isScanQrCode(ReceiveMessage receiveMessage) {
|
||||
return StringUtils.isNotEmpty(receiveMessage.getTicket());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取扫描的二维码 Ticket
|
||||
*
|
||||
* @param receiveMessage
|
||||
* @return
|
||||
*/
|
||||
public static String getQrCodeTicket(ReceiveMessage receiveMessage) {
|
||||
return receiveMessage.getTicket();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package org.ruoyi.system.util;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
/**
|
||||
* 微信二维码缓存工具类
|
||||
*
|
||||
* @author https://www.wdbyte.com
|
||||
*/
|
||||
public class WeixinQrCodeCacheUtil {
|
||||
private static long MAX_CACHE_SIZE = 10000;
|
||||
private static LinkedHashMap<String, String> QR_CODE_TICKET_MAP = new LinkedHashMap<>();
|
||||
|
||||
/**
|
||||
* 增加一个 Ticket
|
||||
* 首次 put:value 为 ""
|
||||
* 再次 put: value 有 openId,若openId已经存在,则已被扫码
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public synchronized static void put(String key, String value) {
|
||||
QR_CODE_TICKET_MAP.put(key, value);
|
||||
if (QR_CODE_TICKET_MAP.size() > MAX_CACHE_SIZE) {
|
||||
String first = QR_CODE_TICKET_MAP.keySet().stream().findFirst().get();
|
||||
QR_CODE_TICKET_MAP.remove(first);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized static String get(String key) {
|
||||
return QR_CODE_TICKET_MAP.remove(key);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package org.ruoyi.system.util;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* @author https://www.wdbyte.com
|
||||
*/
|
||||
@Slf4j
|
||||
public class XmlUtil {
|
||||
|
||||
public static String xml2json(String requestBody) {
|
||||
requestBody = StringUtils.trim(requestBody);
|
||||
XmlMapper xmlMapper = new XmlMapper();
|
||||
JsonNode node = null;
|
||||
try {
|
||||
node = xmlMapper.readTree(requestBody.getBytes());
|
||||
ObjectMapper jsonMapper = new ObjectMapper();
|
||||
return jsonMapper.writeValueAsString(node);
|
||||
} catch (Exception e) {
|
||||
log.error("xml 2 json error,msg:" + e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user