5 Commits

Author SHA1 Message Date
ageer
256f72c487 feat: 支付模块引用 2025-05-03 15:37:56 +08:00
ageer
009aa5f1a5 feat: 添加接口说明 2025-05-03 15:27:46 +08:00
ageer
d22d2cb708 fix(接口文档): 修复接口文档/v3/api-docs无法正常访问 2025-05-03 14:31:20 +08:00
ageer
59104028b6 feat: 会话管理 2025-05-03 10:45:29 +08:00
ageer
c2f6a8321a feat: 会话管理 2025-05-03 10:41:50 +08:00
31 changed files with 589 additions and 57 deletions

View File

@@ -20,7 +20,7 @@
<java.version>17</java.version>
<mysql.version>8.0.33</mysql.version>
<mybatis.version>3.5.16</mybatis.version>
<springdoc.version>2.1.0</springdoc.version>
<springdoc.version>2.8.5</springdoc.version>
<therapi-javadoc.version>0.15.0</therapi-javadoc.version>
<poi.version>5.2.3</poi.version>
<easyexcel.version>3.2.1</easyexcel.version>

View File

@@ -1,8 +1,6 @@
package org.ruoyi.controller;
import cn.dev33.satoken.annotation.SaIgnore;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

View File

@@ -215,11 +215,16 @@ mybatis-encryptor:
publicKey:
privateKey:
# Swagger配置
swagger:
springdoc:
api-docs:
# 是否开启接口文档
enabled: true
# swagger-ui:
# # 持久化认证数据
# persistAuthorization: true
info:
# 标题
title: '标题:${ruoyi.name}多租户管理系统_接口文档'
title: '标题:RuoYi-Vue-Plus多租户管理系统_接口文档'
# 描述
description: '描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...'
# 版本
@@ -236,24 +241,10 @@ swagger:
type: APIKEY
in: HEADER
name: ${sa-token.token-name}
springdoc:
api-docs:
# 是否开启接口文档
enabled: true
swagger-ui:
# 持久化认证数据
persistAuthorization: true
#这里定义了两个分组,可定义多个,也可以不定义
group-configs:
- group: 1.演示模块
packages-to-scan: org.ruoyi.demo
- group: 2.通用模块
packages-to-scan: org.ruoyi.web
- group: 3.系统模块
- group: 1.系统模块
packages-to-scan: org.ruoyi.system
- group: 4.代码生成模块
packages-to-scan: org.ruoyi.generator
# 防止XSS攻击
xss:

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

View File

@@ -159,12 +159,20 @@
<version>${revision}</version>
</dependency>
<!-- 微信模块 -->
<dependency>
<groupId>org.ruoyi</groupId>
<artifactId>ruoyi-chat</artifactId>
<artifactId>ruoyi-common-wechat</artifactId>
<version>${revision}</version>
</dependency>
<!-- 支付模块 -->
<dependency>
<groupId>org.ruoyi</groupId>
<artifactId>ruoyi-common-pay</artifactId>
<version>${revision}</version>
</dependency>
</dependencies>
</dependencyManagement>

View File

@@ -56,6 +56,12 @@ public class ChatRequest {
*/
private Long userId;
/**
* 会话id
*/
private Long sessionId;
/**
* 应用ID
*/

View File

@@ -6,7 +6,7 @@ import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import lombok.RequiredArgsConstructor;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.doc.config.properties.SwaggerProperties;
import org.ruoyi.common.doc.config.properties.SpringDocProperties;
import org.ruoyi.common.doc.handler.OpenApiHandler;
import org.springdoc.core.configuration.SpringDocConfiguration;
import org.springdoc.core.customizers.OpenApiBuilderCustomizer;
@@ -36,26 +36,26 @@ import java.util.Set;
*/
@RequiredArgsConstructor
@AutoConfiguration(before = SpringDocConfiguration.class)
@EnableConfigurationProperties(SwaggerProperties.class)
@EnableConfigurationProperties(SpringDocProperties.class)
@ConditionalOnProperty(name = "springdoc.api-docs.enabled", havingValue = "true", matchIfMissing = true)
public class SwaggerConfig {
public class SpringDocConfig {
private final ServerProperties serverProperties;
@Bean
@ConditionalOnMissingBean(OpenAPI.class)
public OpenAPI openApi(SwaggerProperties swaggerProperties) {
public OpenAPI openApi(SpringDocProperties properties) {
OpenAPI openApi = new OpenAPI();
// 文档基本信息
SwaggerProperties.InfoProperties infoProperties = swaggerProperties.getInfo();
SpringDocProperties.InfoProperties infoProperties = properties.getInfo();
Info info = convertInfo(infoProperties);
openApi.info(info);
// 扩展文档信息
openApi.externalDocs(swaggerProperties.getExternalDocs());
openApi.tags(swaggerProperties.getTags());
openApi.paths(swaggerProperties.getPaths());
openApi.components(swaggerProperties.getComponents());
Set<String> keySet = swaggerProperties.getComponents().getSecuritySchemes().keySet();
openApi.externalDocs(properties.getExternalDocs());
openApi.tags(properties.getTags());
openApi.paths(properties.getPaths());
openApi.components(properties.getComponents());
Set<String> keySet = properties.getComponents().getSecuritySchemes().keySet();
List<SecurityRequirement> list = new ArrayList<>();
SecurityRequirement securityRequirement = new SecurityRequirement();
keySet.forEach(securityRequirement::addList);
@@ -65,7 +65,7 @@ public class SwaggerConfig {
return openApi;
}
private Info convertInfo(SwaggerProperties.InfoProperties infoProperties) {
private Info convertInfo(SpringDocProperties.InfoProperties infoProperties) {
Info info = new Info();
info.setTitle(infoProperties.getTitle());
info.setDescription(infoProperties.getDescription());

View File

@@ -18,8 +18,8 @@ import java.util.List;
* @author Lion Li
*/
@Data
@ConfigurationProperties(prefix = "swagger")
public class SwaggerProperties {
@ConfigurationProperties(prefix = "springdoc")
public class SpringDocProperties {
/**
* 文档基本信息

View File

@@ -11,6 +11,7 @@ import io.swagger.v3.oas.models.Paths;
import io.swagger.v3.oas.models.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.ruoyi.common.core.utils.StreamUtils;
import org.springdoc.core.customizers.OpenApiBuilderCustomizer;
import org.springdoc.core.customizers.ServerBaseUrlCustomizer;
import org.springdoc.core.properties.SpringDocConfigProperties;
@@ -154,11 +155,11 @@ public class OpenApiHandler extends OpenAPIService {
if (!CollectionUtils.isEmpty(tagsStr))
tagsStr = tagsStr.stream()
.map(str -> propertyResolverUtils.resolve(str, locale))
.collect(Collectors.toSet());
.map(str -> propertyResolverUtils.resolve(str, locale))
.collect(Collectors.toSet());
if (springdocTags.containsKey(handlerMethod)) {
Tag tag = springdocTags.get(handlerMethod);
io.swagger.v3.oas.models.tags.Tag tag = springdocTags.get(handlerMethod);
tagsStr.add(tag.getName());
if (openAPI.getTags() == null || !openAPI.getTags().contains(tag)) {
openAPI.addTagsItem(tag);
@@ -182,7 +183,7 @@ public class OpenApiHandler extends OpenAPIService {
if (javadocProvider.isPresent()) {
String description = javadocProvider.get().getClassJavadoc(handlerMethod.getBeanType());
if (StringUtils.isNotBlank(description)) {
Tag tag = new Tag();
io.swagger.v3.oas.models.tags.Tag tag = new io.swagger.v3.oas.models.tags.Tag();
// 自定义部分 修改使用java注释当tag名
List<String> list = IoUtil.readLines(new StringReader(description), new ArrayList<>());
@@ -203,7 +204,7 @@ public class OpenApiHandler extends OpenAPIService {
if (!CollectionUtils.isEmpty(tags)) {
// Existing tags
List<Tag> openApiTags = openAPI.getTags();
List<io.swagger.v3.oas.models.tags.Tag> openApiTags = openAPI.getTags();
if (!CollectionUtils.isEmpty(openApiTags))
tags.addAll(openApiTags);
openAPI.setTags(new ArrayList<>(tags));
@@ -211,7 +212,7 @@ public class OpenApiHandler extends OpenAPIService {
// Handle SecurityRequirement at operation level
io.swagger.v3.oas.annotations.security.SecurityRequirement[] securityRequirements = securityParser
.getSecurityRequirements(handlerMethod);
.getSecurityRequirements(handlerMethod);
if (securityRequirements != null) {
if (securityRequirements.length == 0)
operation.setSecurity(Collections.emptyList());
@@ -222,23 +223,23 @@ public class OpenApiHandler extends OpenAPIService {
return operation;
}
private void buildTagsFromMethod(Method method, Set<Tag> tags, Set<String> tagsStr, Locale locale) {
private void buildTagsFromMethod(Method method, Set<io.swagger.v3.oas.models.tags.Tag> tags, Set<String> tagsStr, Locale locale) {
// method tags
Set<Tags> tagsSet = AnnotatedElementUtils
.findAllMergedAnnotations(method, Tags.class);
.findAllMergedAnnotations(method, Tags.class);
Set<io.swagger.v3.oas.annotations.tags.Tag> methodTags = tagsSet.stream()
.flatMap(x -> Stream.of(x.value())).collect(Collectors.toSet());
.flatMap(x -> Stream.of(x.value())).collect(Collectors.toSet());
methodTags.addAll(AnnotatedElementUtils.findAllMergedAnnotations(method, io.swagger.v3.oas.annotations.tags.Tag.class));
if (!CollectionUtils.isEmpty(methodTags)) {
tagsStr.addAll(methodTags.stream().map(tag -> propertyResolverUtils.resolve(tag.name(), locale)).collect(Collectors.toSet()));
tagsStr.addAll(StreamUtils.toSet(methodTags, tag -> propertyResolverUtils.resolve(tag.name(), locale)));
List<io.swagger.v3.oas.annotations.tags.Tag> allTags = new ArrayList<>(methodTags);
addTags(allTags, tags, locale);
}
}
private void addTags(List<io.swagger.v3.oas.annotations.tags.Tag> sourceTags, Set<Tag> tags, Locale locale) {
Optional<Set<Tag>> optionalTagSet = AnnotationsUtils
.getTags(sourceTags.toArray(new io.swagger.v3.oas.annotations.tags.Tag[0]), true);
private void addTags(List<io.swagger.v3.oas.annotations.tags.Tag> sourceTags, Set<io.swagger.v3.oas.models.tags.Tag> tags, Locale locale) {
Optional<Set<io.swagger.v3.oas.models.tags.Tag>> optionalTagSet = AnnotationsUtils
.getTags(sourceTags.toArray(new io.swagger.v3.oas.annotations.tags.Tag[0]), true);
optionalTagSet.ifPresent(tagsSet -> {
tagsSet.forEach(tag -> {
tag.name(propertyResolverUtils.resolve(tag.getName(), locale));

View File

@@ -1 +1 @@
org.ruoyi.common.doc.config.SwaggerConfig
org.ruoyi.common.doc.config.SpringDocConfig

View File

@@ -34,6 +34,11 @@ public class ChatMessage extends BaseEntity {
*/
private Long userId;
/**
* 会话id
*/
private Long sessionId;
/**
* 消息内容
*/

View File

@@ -0,0 +1,51 @@
package org.ruoyi.domain;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.ruoyi.core.domain.BaseEntity;
import java.io.Serial;
/**
* 会话管理对象 chat_session
*
* @author ageerle
* @date 2025-05-03
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("chat_session")
public class ChatSession extends BaseEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "id")
private Long id;
/**
* 用户id
*/
private Long userId;
/**
* 会话标题
*/
private String sessionTitle;
/**
* 会话内容
*/
private String sessionContent;
/**
* 备注
*/
private String remark;
}

View File

@@ -40,6 +40,11 @@ public class ChatMessageBo extends BaseEntity {
@NotBlank(message = "消息内容不能为空", groups = { AddGroup.class, EditGroup.class })
private String content;
/**
* 会话id
*/
private Long sessionId;
/**
* 对话角色
*/

View File

@@ -0,0 +1,54 @@
package org.ruoyi.domain.bo;
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.core.domain.BaseEntity;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
import org.ruoyi.domain.ChatSession;
/**
* 会话管理业务对象 chat_session
*
* @author ageerle
* @date 2025-05-03
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = ChatSession.class, reverseConvertGenerate = false)
public class ChatSessionBo extends BaseEntity {
/**
* 主键
*/
@NotNull(message = "主键不能为空", groups = { EditGroup.class })
private Long id;
/**
* 用户id
*/
@NotNull(message = "用户id不能为空", groups = { AddGroup.class, EditGroup.class })
private Long userId;
/**
* 会话标题
*/
@NotBlank(message = "会话标题不能为空", groups = { AddGroup.class, EditGroup.class })
private String sessionTitle;
/**
* 会话内容
*/
@NotBlank(message = "会话内容不能为空", groups = { AddGroup.class, EditGroup.class })
private String sessionContent;
/**
* 备注
*/
@NotBlank(message = "备注不能为空", groups = { AddGroup.class, EditGroup.class })
private String remark;
}

View File

@@ -41,6 +41,11 @@ public class ChatMessageVo implements Serializable {
@ExcelProperty(value = "用户id")
private Long userId;
/**
* 会话id
*/
private Long sessionId;
/**
* 消息内容
*/

View File

@@ -0,0 +1,59 @@
package org.ruoyi.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.domain.ChatSession;
import java.io.Serial;
import java.io.Serializable;
/**
* 会话管理视图对象 chat_session
*
* @author ageerle
* @date 2025-05-03
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = ChatSession.class)
public class ChatSessionVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@ExcelProperty(value = "主键")
private Long id;
/**
* 用户id
*/
@ExcelProperty(value = "用户id")
private Long userId;
/**
* 会话标题
*/
@ExcelProperty(value = "会话标题")
private String sessionTitle;
/**
* 会话内容
*/
@ExcelProperty(value = "会话内容")
private String sessionContent;
/**
* 备注
*/
@ExcelProperty(value = "备注")
private String remark;
}

View File

@@ -0,0 +1,15 @@
package org.ruoyi.mapper;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.domain.ChatSession;
import org.ruoyi.domain.vo.ChatSessionVo;
/**
* 会话管理Mapper接口
*
* @author ageerle
* @date 2025-05-03
*/
public interface ChatSessionMapper extends BaseMapperPlus<ChatSession, ChatSessionVo> {
}

View File

@@ -0,0 +1,48 @@
package org.ruoyi.service;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.domain.bo.ChatSessionBo;
import org.ruoyi.domain.vo.ChatSessionVo;
import java.util.Collection;
import java.util.List;
/**
* 会话管理Service接口
*
* @author ageerle
* @date 2025-05-03
*/
public interface IChatSessionService {
/**
* 查询会话管理
*/
ChatSessionVo queryById(Long id);
/**
* 查询会话管理列表
*/
TableDataInfo<ChatSessionVo> queryPageList(ChatSessionBo bo, PageQuery pageQuery);
/**
* 查询会话管理列表
*/
List<ChatSessionVo> queryList(ChatSessionBo bo);
/**
* 新增会话管理
*/
Boolean insertByBo(ChatSessionBo bo);
/**
* 修改会话管理
*/
Boolean updateByBo(ChatSessionBo bo);
/**
* 校验并批量删除会话管理信息
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@@ -0,0 +1,111 @@
package org.ruoyi.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import lombok.RequiredArgsConstructor;
import org.ruoyi.domain.ChatSession;
import org.ruoyi.domain.bo.ChatSessionBo;
import org.ruoyi.domain.vo.ChatSessionVo;
import org.ruoyi.mapper.ChatSessionMapper;
import org.ruoyi.service.IChatSessionService;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* 会话管理Service业务层处理
*
* @author ageerle
* @date 2025-05-03
*/
@RequiredArgsConstructor
@Service
public class ChatSessionServiceImpl implements IChatSessionService {
private final ChatSessionMapper baseMapper;
/**
* 查询会话管理
*/
@Override
public ChatSessionVo queryById(Long id){
return baseMapper.selectVoById(id);
}
/**
* 查询会话管理列表
*/
@Override
public TableDataInfo<ChatSessionVo> queryPageList(ChatSessionBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<ChatSession> lqw = buildQueryWrapper(bo);
Page<ChatSessionVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询会话管理列表
*/
@Override
public List<ChatSessionVo> queryList(ChatSessionBo bo) {
LambdaQueryWrapper<ChatSession> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<ChatSession> buildQueryWrapper(ChatSessionBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<ChatSession> lqw = Wrappers.lambdaQuery();
lqw.eq(bo.getUserId() != null, ChatSession::getUserId, bo.getUserId());
lqw.eq(StringUtils.isNotBlank(bo.getSessionTitle()), ChatSession::getSessionTitle, bo.getSessionTitle());
lqw.eq(StringUtils.isNotBlank(bo.getSessionContent()), ChatSession::getSessionContent, bo.getSessionContent());
return lqw;
}
/**
* 新增会话管理
*/
@Override
public Boolean insertByBo(ChatSessionBo bo) {
ChatSession add = MapstructUtils.convert(bo, ChatSession.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改会话管理
*/
@Override
public Boolean updateByBo(ChatSessionBo bo) {
ChatSession update = MapstructUtils.convert(bo, ChatSession.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(ChatSession entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 批量删除会话管理
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteBatchIds(ids) > 0;
}
}

View File

@@ -0,0 +1,105 @@
package org.ruoyi.chat.controller.chat;
import java.util.List;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.ruoyi.common.excel.utils.ExcelUtil;
import org.ruoyi.common.idempotent.annotation.RepeatSubmit;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.domain.bo.ChatSessionBo;
import org.ruoyi.domain.vo.ChatSessionVo;
import org.ruoyi.service.IChatSessionService;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.core.page.PageQuery;
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.log.enums.BusinessType;
/**
* 会话管理
*
* @author ageerle
* @date 2025-05-03
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/session")
public class ChatSessionController extends BaseController {
private final IChatSessionService chatSessionService;
/**
* 查询会话管理列表
*/
@SaCheckPermission("system:session:list")
@GetMapping("/list")
public TableDataInfo<ChatSessionVo> list(ChatSessionBo bo, PageQuery pageQuery) {
return chatSessionService.queryPageList(bo, pageQuery);
}
/**
* 导出会话管理列表
*/
@SaCheckPermission("system:session:export")
@Log(title = "会话管理", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(ChatSessionBo bo, HttpServletResponse response) {
List<ChatSessionVo> list = chatSessionService.queryList(bo);
ExcelUtil.exportExcel(list, "会话管理", ChatSessionVo.class, response);
}
/**
* 获取会话管理详细信息
*
* @param id 主键
*/
@SaCheckPermission("system:session:query")
@GetMapping("/{id}")
public R<ChatSessionVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(chatSessionService.queryById(id));
}
/**
* 新增会话管理
*/
@SaCheckPermission("system:session:add")
@Log(title = "会话管理", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody ChatSessionBo bo) {
return toAjax(chatSessionService.insertByBo(bo));
}
/**
* 修改会话管理
*/
@SaCheckPermission("system:session:edit")
@Log(title = "会话管理", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody ChatSessionBo bo) {
return toAjax(chatSessionService.updateByBo(bo));
}
/**
* 删除会话管理
*
* @param ids 主键串
*/
@SaCheckPermission("system:session:remove")
@Log(title = "会话管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(chatSessionService.deleteWithValidByIds(List.of(ids), true));
}
}

View File

@@ -30,7 +30,10 @@ import org.springframework.web.multipart.MultipartFile;
import java.util.List;
/**
* @author ageer
* 知识库管理
*
* @author ageerle
* @date 2025-05-03
*/
@Validated
@RequiredArgsConstructor

View File

@@ -16,6 +16,12 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 绘画(换脸)任务查询
*
* @author ageerle
* @date 2025-05-03
*/
@Api(tags = "任务查询")
@RestController
@RequestMapping("/mj")

View File

@@ -14,10 +14,10 @@ import org.ruoyi.common.core.utils.OkHttpUtil;
import org.springframework.web.bind.annotation.*;
/**
* 描述:文生视频
* 文生视频
*
* @author ageerle@163.com
* date 2024/6/27
* @author ageerle
* @date 2025-05-03
*/
@RestController
@RequestMapping("/luma")

View File

@@ -15,9 +15,14 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Optional;
/**
* 绘画任务提交
*
* @author ageerle
* @date 2025-05-03
*/
@Api(tags = "任务提交")
@RestController
@RequestMapping("/mj/submit")

View File

@@ -14,6 +14,13 @@ import org.ruoyi.chat.service.chat.IChatCostService;
import org.ruoyi.common.core.utils.OkHttpUtil;
import org.springframework.web.bind.annotation.*;
/**
* 文生歌曲任务提交
*
* @author ageerle
* @date 2025-05-03
*/
@RestController
@RequestMapping("/sunoapi")
@RequiredArgsConstructor

View File

@@ -11,6 +11,13 @@ import org.ruoyi.chat.domain.dto.TaskConditionDTO;
import org.ruoyi.chat.util.MjOkHttpUtil;
import org.springframework.web.bind.annotation.*;
/**
* 绘画任务查询
*
* @author ageerle
* @date 2025-05-03
*/
@Api(tags = "任务查询")
@RestController
@RequestMapping("/mj/task")

View File

@@ -46,6 +46,7 @@ public class ChatCostServiceImpl implements IChatCostService {
/**
* 扣除用户余额
*/
@Override
public void deductToken(ChatRequest chatRequest) {
int tokens = TikTokensUtil.tokens(chatRequest.getModel(), chatRequest.getPrompt());
@@ -53,6 +54,7 @@ public class ChatCostServiceImpl implements IChatCostService {
String modelName = chatRequest.getModel();
ChatMessageBo chatMessageBo = new ChatMessageBo();
chatMessageBo.setSessionId(chatRequest.getSessionId());
Object userId = LocalCache.CACHE.get("userId");
if(userId!=null){

View File

@@ -24,9 +24,12 @@ import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.core.utils.file.FileUtils;
import org.ruoyi.common.core.utils.file.MimeTypeUtils;
import org.ruoyi.common.redis.utils.RedisUtils;
import org.ruoyi.domain.ChatSession;
import org.ruoyi.domain.bo.ChatSessionBo;
import org.ruoyi.domain.vo.ChatModelVo;
import org.ruoyi.service.EmbeddingService;
import org.ruoyi.service.IChatModelService;
import org.ruoyi.service.IChatSessionService;
import org.ruoyi.service.VectorStoreService;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
@@ -65,6 +68,8 @@ public class SseServiceImpl implements ISseService {
private final OllamaServiceImpl ollamaService;
private final IChatSessionService chatSessionService;
private ChatModelVo chatModelVo;
@@ -80,6 +85,15 @@ public class SseServiceImpl implements ISseService {
}else {
LocalCache.CACHE.put("userId", chatCostService.getUserId());
chatRequest.setUserId(chatCostService.getUserId());
// 保存会话信息
if(chatRequest.getSessionId()==null){
ChatSessionBo chatSessionBo = new ChatSessionBo();
chatSessionBo.setUserId(chatCostService.getUserId());
chatSessionBo.setSessionTitle(getFirst10Characters(chatRequest.getPrompt()));
chatSessionBo.setSessionContent(chatRequest.getPrompt());
chatSessionService.insertByBo(chatSessionBo);
chatRequest.setSessionId(chatSessionBo.getId());
}
// 保存消息记录 并扣除费用
chatCostService.deductToken(chatRequest);
}
@@ -92,6 +106,23 @@ public class SseServiceImpl implements ISseService {
return sseEmitter;
}
/**
* 获取对话标题
*
* @param str 原字符
* @return 截取后的字符
*/
public static String getFirst10Characters(String str) {
// 判断字符串长度
if (str.length() > 10) {
// 如果长度大于10截取前10个字符
return str.substring(0, 10);
} else {
// 如果长度不足10返回整个字符串
return str;
}
}
/**
* 检查未登录用户是否超过当日对话次数限制
*

View File

@@ -9,7 +9,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* @author https://www.wdbyte.com
* 企业微信应用
*
* @author ageerle
* @date 2025-05-03
*/
@Slf4j
@RestController

View File

@@ -13,7 +13,10 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author https://www.wdbyte.com
* 微信公众号登录
*
* @author ageerle
* @date 2025-05-03
*/
@Slf4j
@RestController

View File

@@ -13,7 +13,10 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
/**
* @author <a href="https://github.com/binarywang">Binary Wang</a>
* 微信公众号登录校验
*
* @author ageerle
* @date 2025-05-03
*/
@RestController
@RequestMapping("/wx/cp")