diff --git a/README.md b/README.md
index c6f074f..dd82440 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,192 @@
-# agent-skill-backend
+# 可学AI-skills平台后端
-agent-skill-backend
+## 项目简介
+
+可学AI-skills平台是一个基于Spring Boot的智能技能管理系统,提供技能生成、内容管理、用户认证、支付等功能。
+
+## 技术栈
+
+- **基础框架**:Spring Boot 3.2.2
+- **持久层**:MyBatis 3.0.3
+- **数据库**:MySQL
+- **缓存**:Redis
+- **认证**:Sa-Token 1.38.0
+- **模板引擎**:Thymeleaf
+- **API文档**:Swagger 3.0.0
+- **文件处理**:sevenzipjbinding 16.02-2.01
+- **短信服务**:SMS4J 3.3.5
+- **分布式锁**:Redisson 3.23.5
+- **AI集成**:DeepSeek、GLM-4.6v
+
+## 项目结构
+
+```
+backend/
+├── .mvn/ # Maven包装器
+├── db/ # 数据库脚本
+├── src/
+│ ├── main/
+│ │ ├── java/com/kexue/skills/ # 主源码
+│ │ │ ├── annotation/ # 自定义注解
+│ │ │ ├── aspect/ # AOP切面
+│ │ │ ├── common/ # 通用工具和常量
+│ │ │ ├── config/ # 配置类
+│ │ │ ├── controller/ # 控制器
+│ │ │ ├── entity/ # 实体类
+│ │ │ ├── exception/ # 异常处理
+│ │ │ ├── interceptor/ # 拦截器
+│ │ │ ├── mapper/ # 数据访问层
+│ │ │ ├── service/ # 服务层
+│ │ │ ├── task/ # 定时任务
+│ │ │ ├── utils/ # 工具类
+│ │ │ └── SkillsApp.java # 应用入口
+│ │ └── resources/ # 资源文件
+│ │ ├── mapper/ # MyBatis映射文件
+│ │ ├── sql/ # SQL脚本
+│ │ ├── static/ # 静态资源
+│ │ ├── templates/ # Thymeleaf模板
+│ │ ├── application-*.yml # 配置文件
+│ │ └── logback-spring.xml # 日志配置
+│ └── test/ # 测试代码
+├── .gitignore # Git忽略文件
+├── Dockerfile # Docker构建文件
+├── README.md # 项目说明
+├── mvnw.cmd # Maven包装器脚本
+└── pom.xml # Maven依赖配置
+```
+
+## 核心功能
+
+### 1. 用户认证与授权
+- 基于Sa-Token的认证系统
+- 支持账号密码登录
+- 支持手机验证码登录
+- 角色权限管理
+- 防重复提交
+
+### 2. 内容管理系统
+- 内容分类管理
+- 内容标签管理
+- 内容发布与管理
+- 内容点赞与浏览统计
+
+### 3. 技能生成系统
+- 技能上传与解析(支持RAR等压缩格式)
+- 技能结构分析
+- 技能介绍生成
+
+### 4. 支付系统
+- 微信支付集成
+- 支付宝集成
+- 支付订单管理
+
+### 5. 账户管理
+- 账户余额管理
+- 积分管理
+- 交易记录
+
+### 6. 系统管理
+- 菜单管理
+- 角色管理
+- 字典管理
+- 系统日志
+
+### 7. AI集成
+- DeepSeek模型集成
+- GLM-4.6v模型集成
+- 智能内容生成
+
+## 快速开始
+
+### 环境要求
+- JDK 17+
+- Maven 3.6+
+- MySQL 5.7+
+- Redis 5.0+
+
+### 配置说明
+1. 修改 `application-dev.yml` 文件中的数据库连接信息
+2. 修改 `application.yml` 文件中的Redis连接信息
+3. 修改 `application.yml` 文件中的AI模型API密钥
+4. 修改 `application.yml` 文件中的短信服务配置
+
+### 数据库初始化
+1. 执行 `db/create_tables.sql` 创建数据库表
+2. 执行 `db/init_data.sql` 初始化基础数据
+
+### 启动项目
+```bash
+# 编译项目
+mvn clean compile
+
+# 运行项目
+mvn spring-boot:run
+```
+
+### 访问地址
+- 项目首页:http://localhost:8080
+- Swagger文档:http://localhost:8080/doc.html
+
+## 主要API
+
+### 用户认证
+- `POST /api/login` - 用户登录
+- `POST /api/logout` - 用户登出
+- `GET /api/currentUser` - 获取当前用户信息
+
+### 内容管理
+- `GET /api/cms/content/list` - 获取内容列表
+- `POST /api/cms/content/save` - 保存内容
+- `DELETE /api/cms/content/delete` - 删除内容
+
+### 技能管理
+- `POST /api/skill/upload` - 上传技能
+- `POST /api/skill/analyze` - 分析技能结构
+- `POST /api/skill/genIntroduce` - 生成技能介绍
+
+### 支付管理
+- `POST /api/pay/wx` - 微信支付
+- `POST /api/pay/alipay` - 支付宝支付
+- `GET /api/payment/order/list` - 获取支付订单列表
+
+## 部署说明
+
+### Docker部署
+1. 构建Docker镜像
+```bash
+docker build -t agent-skills .
+```
+
+2. 运行Docker容器
+```bash
+docker run -p 8080:8080 --name agent-skills agent-skills
+```
+
+### 生产环境部署
+1. 打包项目
+```bash
+mvn clean package -DskipTests
+
+配置文件直接打在jar包内
+```
+
+2. 部署jar包
+```bash
+java -jar agentSkills.jar --spring.profiles.active=prod
+或者执行脚本启动
+./start.sh
+```
+
+## 注意事项
+
+1. 项目使用Redis作为缓存,需要确保Redis服务正常运行
+2. 项目使用阿里云短信服务,需要配置相关参数
+3. 项目使用AI模型API,需要配置相关API密钥
+
+## 许可证
+
+本项目仅供内部使用,未经授权不得用于商业用途。
+
+## 联系方式
+
+如有问题,请联系项目维护人员。
diff --git a/pom.xml b/pom.xml
index 5f44968..a5089f3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -146,11 +146,11 @@
1.3.2
-
+
- javax.servlet
- javax.servlet-api
- 4.0.1
+ jakarta.servlet
+ jakarta.servlet-api
+ 6.0.0
provided
diff --git a/src/main/java/com/kexue/skills/common/util/SkillZipParser.java b/src/main/java/com/kexue/skills/common/util/SkillZipParser.java
index 36ab985..2ebdb5c 100644
--- a/src/main/java/com/kexue/skills/common/util/SkillZipParser.java
+++ b/src/main/java/com/kexue/skills/common/util/SkillZipParser.java
@@ -84,93 +84,7 @@ public class SkillZipParser {
return generateYaml(skillStructure);
}
- /**
- * 解析skill zip包并生成yaml描述
- * @param zipFilePath zip文件路径
- * @param author 作者
- * @param defaultSkillName 默认技能名称
- * @return 包含技能信息和yaml描述的Map
- * @throws IOException 解析过程中的IO异常
- * @throws SevenZipException 解析RAR文件时的异常
- */
- public static Map parseSkillZip(String zipFilePath, String author, String defaultSkillName) throws IOException, SevenZipException {
- // 检查文件扩展名
- String fileExtension = "";
- if (zipFilePath.contains(".")) {
- int dotIndex = zipFilePath.lastIndexOf(".");
- fileExtension = zipFilePath.substring(dotIndex).toLowerCase();
- }
-
- // 根据文件类型选择不同的解析方法
- if (".rar".equals(fileExtension)) {
- return parseRarFile(zipFilePath, author, defaultSkillName);
- } else {
- // 默认为zip文件
- try (ZipFile zipFile = new ZipFile(zipFilePath, StandardCharsets.UTF_8)) {
- // 从压缩文件中提取技能信息
- Map skillInfo = extractSkillInfo(zipFile, defaultSkillName);
- String skillName = (String) skillInfo.get("name");
- String skillDescription = (String) skillInfo.get("description");
- List skillTags = (List) skillInfo.get("tags");
-
- // 生成技能包结构
- Map skillStructure = generateSkillStructure(zipFile, skillName, skillDescription, skillTags, author);
-
- // 生成yaml
- String yamlContent = generateYaml(skillStructure);
-
- // 构建返回结果
- Map result = new LinkedHashMap<>();
- result.put("name", skillName);
- result.put("description", skillDescription);
- result.put("tags", skillTags);
- result.put("yamlContent", yamlContent);
- // 包含md文件的完整内容
- if (skillInfo.containsKey("skillMdText")) {
- result.put("skillMdText", skillInfo.get("skillMdText"));
- }
-
- return result;
- }
- }
- }
-
- /**
- * 解析rar文件
- * @param rarFilePath rar文件路径
- * @param author 作者
- * @param defaultSkillName 默认技能名称
- * @return 技能信息
- * @throws IOException 解析过程中的IO异常
- * @throws SevenZipException 解析RAR文件时的异常
- */
- private static Map parseRarFile(String rarFilePath, String author, String defaultSkillName) throws IOException, SevenZipException {
- // 从rar文件中提取技能信息
- Map skillInfo = extractSkillInfoFromRar(rarFilePath, defaultSkillName);
- String skillName = (String) skillInfo.get("name");
- String skillDescription = (String) skillInfo.get("description");
- List skillTags = (List) skillInfo.get("tags");
- // 生成技能包结构
- Map skillStructure = generateSkillStructureFromRar(rarFilePath, skillName, skillDescription, skillTags, author);
-
- // 生成yaml
- String yamlContent = generateYaml(skillStructure);
-
- // 构建返回结果
- Map result = new LinkedHashMap<>();
- result.put("name", skillName);
- result.put("description", skillDescription);
- result.put("tags", skillTags);
- result.put("yamlContent", yamlContent);
- // 包含md文件的完整内容
- if (skillInfo.containsKey("skillMdText")) {
- result.put("skillMdText", skillInfo.get("skillMdText"));
- }
-
- return result;
- }
-
/**
* 从rar文件中提取技能信息
* @param rarFilePath rar文件路径
@@ -197,7 +111,7 @@ public class SkillZipParser {
// 使用简单接口
ISimpleInArchive simpleInArchive = archive.getSimpleInterface();
- // 遍历所有文件条目
+ // 首先尝试在根目录查找md文件
for (ISimpleInArchiveItem item : simpleInArchive.getArchiveItems()) {
// 检查是否是根目录下的md文件
String path = item.getPath();
@@ -224,6 +138,55 @@ public class SkillZipParser {
break; // 找到一个md文件后就停止
}
}
+
+ // 如果根目录没有找到md文件,检查根目录下的文件夹
+ if (!foundMdFile) {
+ // 收集根目录下的文件夹
+ List rootFolders = new ArrayList<>();
+ for (ISimpleInArchiveItem item : simpleInArchive.getArchiveItems()) {
+ if (item.isFolder()) {
+ String path = item.getPath();
+ // 确保是根目录下的文件夹(路径中不包含/)
+ if (!path.contains("/") && !path.contains("\\")) {
+ rootFolders.add(path);
+ }
+ }
+ }
+
+ // 检查每个根目录文件夹下的md文件
+ for (String folder : rootFolders) {
+ for (ISimpleInArchiveItem item : simpleInArchive.getArchiveItems()) {
+ if (!item.isFolder()) {
+ String path = item.getPath();
+ // 检查是否是该文件夹下的md文件
+ if (path.endsWith(".md") && (path.equals(folder + "/skill.md") || path.equals(folder + "/SKILL.md") ||
+ path.equals(folder + "/readme.md") || path.equals(folder + "/README.md"))) {
+ // 读取文件内容
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ item.extractSlow(data -> {
+ try {
+ outputStream.write(data);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ return data.length;
+ });
+
+ String content = outputStream.toString(StandardCharsets.UTF_8);
+
+ // 存储md文件的完整内容
+ skillInfo.put("skillMdText", content);
+
+ // 解析md内容
+ parseSkillsMd(content, skillInfo);
+ foundMdFile = true;
+ break; // 找到一个md文件后就停止
+ }
+ }
+ }
+ if (foundMdFile) break; // 找到一个md文件后就停止
+ }
+ }
}
// 如果没有找到 md 文件,使用默认值
@@ -276,17 +239,59 @@ public class SkillZipParser {
}
}
}
+
+ // 如果根目录没有找到md文件,检查根目录下的文件夹
+ if (!foundMdFile) {
+ // 收集根目录下的文件夹
+ List rootFolders = new ArrayList<>();
+ entries = zipFile.entries();
+ while (entries.hasMoreElements()) {
+ ZipEntry entry = entries.nextElement();
+ if (entry.isDirectory()) {
+ String path = entry.getName();
+ // 确保是根目录下的文件夹(路径中不包含/,或者以/结尾且前面没有/)
+ if (path.endsWith("/") && !path.substring(0, path.length() - 1).contains("/")) {
+ rootFolders.add(path.substring(0, path.length() - 1));
+ }
+ }
+ }
+
+ // 检查每个根目录文件夹下的md文件
+ for (String folder : rootFolders) {
+ entries = zipFile.entries();
+ while (entries.hasMoreElements()) {
+ ZipEntry entry = entries.nextElement();
+ if (!entry.isDirectory()) {
+ String path = entry.getName();
+ // 检查是否是该文件夹下的md文件
+ if (path.endsWith(".md") && (path.equals(folder + "/skill.md") || path.equals(folder + "/SKILL.md") ||
+ path.equals(folder + "/readme.md") || path.equals(folder + "/README.md"))) {
+ try (InputStream inputStream = zipFile.getInputStream(entry);
+ BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
+ StringBuilder content = new StringBuilder();
+ String line;
+ while ((line = reader.readLine()) != null) {
+ content.append(line).append("\n");
+ }
+
+ // 存储md文件的完整内容
+ skillInfo.put("skillMdText", content.toString());
+
+ // 解析md内容
+ parseSkillsMd(content.toString(), skillInfo);
+ foundMdFile = true;
+ break; // 找到一个md文件后就停止
+ }
+ }
+ }
+ }
+ if (foundMdFile) break; // 找到一个md文件后就停止
+ }
+ }
// 如果没有找到 md 文件,使用默认值
if (!foundMdFile) {
skillInfo.put("name", defaultSkillName);
- skillInfo.put("description", "Skill uploaded ");
- skillInfo.put("tags", Arrays.asList("10001", "10002"));
- } else {
- // 确保 tags 不为 null
- if (!skillInfo.containsKey("tags")) {
- skillInfo.put("tags", Arrays.asList("10001"));
- }
}
return skillInfo;
diff --git a/src/main/java/com/kexue/skills/controller/CmsContentController.java b/src/main/java/com/kexue/skills/controller/CmsContentController.java
index 75b94ac..ae7fef4 100644
--- a/src/main/java/com/kexue/skills/controller/CmsContentController.java
+++ b/src/main/java/com/kexue/skills/controller/CmsContentController.java
@@ -8,6 +8,7 @@ import com.kexue.skills.entity.CmsContent;
import com.kexue.skills.entity.base.IdDto;
import com.kexue.skills.entity.dto.CmsContentDto;
import com.kexue.skills.entity.dto.QueryContentDto;
+import com.kexue.skills.entity.request.ImportPathDto;
import com.kexue.skills.service.CmsContentService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -312,4 +313,24 @@ public class CmsContentController {
String title = cmsContentService.getTitle(contentId);
return CommonResult.success(title);
}
+
+ /**
+ * 从指定目录导入Excel数据到CmsContent
+ *
+ * @param importPathDto 导入路径请求参数
+ * @param createBy 创建人
+ * @return 导入结果
+ */
+ @PostMapping("/importFromPath")
+ @Operation(summary = "从目录导入Excel数据", description = "从指定目录导入Excel数据到CmsContent")
+ @RequireAuth
+ public CommonResult importFromPath(@RequestBody ImportPathDto importPathDto, @RequestParam("createBy") String createBy) {
+ try {
+ int successCount = cmsContentService.importFromPath(importPathDto, createBy);
+ return CommonResult.success(successCount);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return CommonResult.failed("导入失败:" + e.getMessage());
+ }
+ }
}
\ No newline at end of file
diff --git a/src/main/java/com/kexue/skills/controller/PayController.java b/src/main/java/com/kexue/skills/controller/PayController.java
index 9ab4f2d..3a6656b 100644
--- a/src/main/java/com/kexue/skills/controller/PayController.java
+++ b/src/main/java/com/kexue/skills/controller/PayController.java
@@ -10,8 +10,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
-import javax.annotation.Resource;
-import javax.servlet.http.HttpServletRequest;
+import jakarta.annotation.Resource;
+import jakarta.servlet.http.HttpServletRequest;
import java.util.Map;
/**
diff --git a/src/main/java/com/kexue/skills/controller/SkillGenController.java b/src/main/java/com/kexue/skills/controller/SkillGenController.java
index 46fcc55..5472534 100644
--- a/src/main/java/com/kexue/skills/controller/SkillGenController.java
+++ b/src/main/java/com/kexue/skills/controller/SkillGenController.java
@@ -42,18 +42,6 @@ public class SkillGenController {
return CommonResult.success(skillGenService.preGenerateV2(request));
}
- /**
- * 生成技能V2
- *
- * @param request 生成请求
- * @return 生成结果
- */
- @PostMapping("/preGenerateV2")
- @Operation(summary = "预生成技能V2", description = "使用新模型生成技能")
- public CommonResult preGenerateV2(@RequestBody SkillPreGenRequest request) {
- return CommonResult.success(skillGenService.preGenerateV2(request));
- }
-
@PostMapping("/generate")
@Operation(summary = "生成技能", description = "生成技能")
public CommonResult generate(@RequestBody SkillGenRequest request) {
diff --git a/src/main/java/com/kexue/skills/controller/SysUserController.java b/src/main/java/com/kexue/skills/controller/SysUserController.java
index 72f2499..e3b32a5 100644
--- a/src/main/java/com/kexue/skills/controller/SysUserController.java
+++ b/src/main/java/com/kexue/skills/controller/SysUserController.java
@@ -3,9 +3,7 @@ package com.kexue.skills.controller;
import com.kexue.skills.annotation.RequireAuth;
import com.kexue.skills.entity.SysUser;
import com.kexue.skills.entity.dto.SysUserDto;
-import com.kexue.skills.entity.request.ResetPasswordDto;
-import com.kexue.skills.entity.request.ResetPwdDto;
-import com.kexue.skills.entity.request.AdminResetPasswordDto;
+import com.kexue.skills.entity.request.*;
import com.kexue.skills.exception.BizException;
import com.kexue.skills.service.SysUserService;
import org.springframework.web.bind.annotation.*;
@@ -17,7 +15,6 @@ import com.kexue.skills.common.CacheManager;
import com.github.pagehelper.PageInfo;
import com.kexue.skills.common.CommonResult;
import com.kexue.skills.entity.base.IdDto;
-import com.kexue.skills.entity.request.LoginUserDto;
import org.redisson.api.RedissonClient;
/**
@@ -86,7 +83,7 @@ public class SysUserController {
*/
@PostMapping("/update")
@Operation(summary = "更新用户", description = "更新用户")
- public CommonResult update(@RequestBody SysUser SysUser) {
+ public CommonResult update(@RequestBody SysUserUpdateDto SysUser) {
return CommonResult.success(sysUserService.update(SysUser));
}
diff --git a/src/main/java/com/kexue/skills/entity/CmsContent.java b/src/main/java/com/kexue/skills/entity/CmsContent.java
index 3b71248..b5314e6 100644
--- a/src/main/java/com/kexue/skills/entity/CmsContent.java
+++ b/src/main/java/com/kexue/skills/entity/CmsContent.java
@@ -97,14 +97,14 @@ public class CmsContent extends BaseEntity implements Serializable {
@Schema(description ="审核人名称")
private String reviewerName;
- @Schema(description ="审核状态(1草稿,2待审核,3审核通过,4审核拒绝)")
+ @Schema(description ="审核状态(1未发布,2待审核,3审核通过,4审核未通过)")
private Integer auditStatus;
@Schema(description ="审核意见")
private String auditComment;
- @Schema(description ="发布状态(1未发布,2已发布,3已下架)")
- private Integer publishStatus;
+ @Schema(description ="发布状态(1未发布,2已发布,3已下架)--> 公有还是私有:1私有,2公有")
+ private Integer publishStatus;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@Schema(description ="发布时间")
diff --git a/src/main/java/com/kexue/skills/entity/request/ImportPathDto.java b/src/main/java/com/kexue/skills/entity/request/ImportPathDto.java
new file mode 100644
index 0000000..29716bf
--- /dev/null
+++ b/src/main/java/com/kexue/skills/entity/request/ImportPathDto.java
@@ -0,0 +1,26 @@
+package com.kexue.skills.entity.request;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 导入路径请求参数
+ *
+ * @author 王志维
+ * @since 2025-02-21 23:01:48
+ */
+@Data
+@Schema(name = "ImportPathDto", description = "导入路径请求参数")
+public class ImportPathDto implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @Schema(description = "是否追加,true表示追加,false表示清空表")
+ private boolean append;
+
+ @Schema(description = "文件目录")
+ private String filePath;
+
+}
diff --git a/src/main/java/com/kexue/skills/entity/request/SysUserUpdateDto.java b/src/main/java/com/kexue/skills/entity/request/SysUserUpdateDto.java
new file mode 100644
index 0000000..6fcd206
--- /dev/null
+++ b/src/main/java/com/kexue/skills/entity/request/SysUserUpdateDto.java
@@ -0,0 +1,38 @@
+package com.kexue.skills.entity.request;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 用户更新请求参数
+ *
+ * @author 王志维
+ * @since 2025-02-21 23:01:48
+ */
+@Data
+@Schema(name = "SysUserUpdateDto", description = "用户更新请求参数")
+public class SysUserUpdateDto implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @Schema(description = "用户ID")
+ private Long userId;
+
+ @Schema(description = "用户名")
+ private String userName;
+
+ @Schema(description = "密码")
+ private String password;
+
+ @Schema(description = "邮箱")
+ private String email;
+
+ @Schema(description = "手机号")
+ private String tel;
+
+ @Schema(description = "状态(1-正常,0-禁用)")
+ private Integer enable;
+
+}
diff --git a/src/main/java/com/kexue/skills/mapper/CmsContentMapper.java b/src/main/java/com/kexue/skills/mapper/CmsContentMapper.java
index c05c1f8..7898f6c 100644
--- a/src/main/java/com/kexue/skills/mapper/CmsContentMapper.java
+++ b/src/main/java/com/kexue/skills/mapper/CmsContentMapper.java
@@ -225,4 +225,11 @@ public interface CmsContentMapper {
* @return 总记录数
*/
int getPageListByUserCreatedCount(@Param("userId") Long userId, @Param("publishStatus") Integer publishStatus);
+
+ /**
+ * 清空表数据
+ *
+ * @return 影响行数
+ */
+ int truncateTable();
}
\ No newline at end of file
diff --git a/src/main/java/com/kexue/skills/service/CmsContentService.java b/src/main/java/com/kexue/skills/service/CmsContentService.java
index 44c80c4..a1abb98 100644
--- a/src/main/java/com/kexue/skills/service/CmsContentService.java
+++ b/src/main/java/com/kexue/skills/service/CmsContentService.java
@@ -3,6 +3,7 @@ package com.kexue.skills.service;
import com.github.pagehelper.PageInfo;
import com.kexue.skills.entity.CmsContent;
import com.kexue.skills.entity.dto.CmsContentDto;
+import com.kexue.skills.entity.request.ImportPathDto;
import java.util.List;
@@ -191,4 +192,13 @@ public interface CmsContentService extends BaseService {
* @return title字段的内容
*/
String getTitle(Long contentId);
+
+ /**
+ * 从指定目录导入Excel数据到CmsContent
+ *
+ * @param importPathDto 导入路径请求参数
+ * @param createBy 创建人
+ * @return 导入结果
+ */
+ int importFromPath(ImportPathDto importPathDto, String createBy);
}
\ No newline at end of file
diff --git a/src/main/java/com/kexue/skills/service/PayService.java b/src/main/java/com/kexue/skills/service/PayService.java
index 93db4f1..f62750e 100644
--- a/src/main/java/com/kexue/skills/service/PayService.java
+++ b/src/main/java/com/kexue/skills/service/PayService.java
@@ -1,7 +1,7 @@
package com.kexue.skills.service;
import com.kexue.skills.entity.PaymentOrder;
-import javax.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletRequest;
import java.util.Map;
/**
diff --git a/src/main/java/com/kexue/skills/service/SysUserService.java b/src/main/java/com/kexue/skills/service/SysUserService.java
index bebcf3e..734d418 100644
--- a/src/main/java/com/kexue/skills/service/SysUserService.java
+++ b/src/main/java/com/kexue/skills/service/SysUserService.java
@@ -7,6 +7,7 @@ import com.kexue.skills.entity.request.LoginDto;
import com.kexue.skills.entity.request.LoginUserDto;
import com.kexue.skills.entity.request.PhoneLoginDto;
import com.kexue.skills.entity.request.ResetPasswordDto;
+import com.kexue.skills.entity.request.SysUserUpdateDto;
import java.util.List;
@@ -59,6 +60,14 @@ public interface SysUserService extends BaseService {
*/
SysUser update(SysUser sysUser);
+ /**
+ * 修改用户数据
+ *
+ * @param sysUserUpdateDto 用户更新请求参数
+ * @return 实例对象
+ */
+ SysUser update(SysUserUpdateDto sysUserUpdateDto);
+
/**
* 通过主键删除数据
*
diff --git a/src/main/java/com/kexue/skills/service/impl/CmsContentServiceImpl.java b/src/main/java/com/kexue/skills/service/impl/CmsContentServiceImpl.java
index 6aeabd1..cbd47e4 100644
--- a/src/main/java/com/kexue/skills/service/impl/CmsContentServiceImpl.java
+++ b/src/main/java/com/kexue/skills/service/impl/CmsContentServiceImpl.java
@@ -10,6 +10,7 @@ import com.kexue.skills.entity.CmsContentView;
import com.kexue.skills.entity.CmsContentLike;
import com.kexue.skills.entity.base.BaseQueryDto;
import com.kexue.skills.entity.dto.CmsContentDto;
+import com.kexue.skills.entity.request.ImportPathDto;
import com.kexue.skills.mapper.CmsContentMapper;
import com.kexue.skills.mapper.CmsContentViewMapper;
import com.kexue.skills.mapper.CmsContentLikeMapper;
@@ -21,6 +22,8 @@ import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;
@@ -311,9 +314,16 @@ public class CmsContentServiceImpl implements CmsContentService {
if (cmsContent.getCommentCount() == null) {
cmsContent.setCommentCount(0);
}
+ if (cmsContent.getShareCount() == null) {
+ cmsContent.setShareCount(0);
+ }
if (cmsContent.getSort() == null) {
cmsContent.setSort(0);
}
+ if (cmsContent.getIsOfficial() == null) {
+ cmsContent.setIsOfficial(false);
+ }
+ cmsContent.setAuthorId(StpUtil.getLoginIdAsLong());
// 保存数据
this.cmsContentMapper.insert(cmsContent);
return cmsContent;
@@ -729,7 +739,7 @@ public class CmsContentServiceImpl implements CmsContentService {
@Override
public int importFromExcel(byte[] fileBytes, String createBy) {
int successCount = 0;
- final int BATCH_SIZE = 100; // 批量处理大小
+ final int BATCH_SIZE = 10; // 批量处理大小
try (InputStream inputStream = new ByteArrayInputStream(fileBytes);
ExcelReader reader = ExcelUtil.getReader(inputStream)) {
@@ -757,76 +767,91 @@ public class CmsContentServiceImpl implements CmsContentService {
// 从第二行开始读取数据(第一行为标题行)
for (int rowIndex = 1; rowIndex < totalRows; rowIndex++) {
- List