feat: 添加批量导入功能
1. 添加用户、课程任务和部门的批量导入功能 2. 优化错误处理逻辑,提供更详细的错误信息 3. 更新API文档,添加批量导入接口说明
This commit is contained in:
@ -1,14 +1,68 @@
|
||||
package com.huertian.jinduguanli.common;
|
||||
|
||||
public class ErrorCode {
|
||||
/**
|
||||
* 操作成功
|
||||
*/
|
||||
public static final int SUCCESS = 10000;
|
||||
|
||||
/**
|
||||
* 系统内部错误
|
||||
*/
|
||||
public static final int SYSTEM_ERROR = 10001;
|
||||
|
||||
/**
|
||||
* 参数校验错误
|
||||
*/
|
||||
public static final int INVALID_PARAM = 10002;
|
||||
|
||||
/**
|
||||
* 用户不存在
|
||||
*/
|
||||
public static final int USER_NOT_FOUND = 10003;
|
||||
|
||||
/**
|
||||
* 用户不存在或已被禁用
|
||||
*/
|
||||
public static final int USER_NOT_FOUND_OR_DISABLED = 10004;
|
||||
|
||||
/**
|
||||
* 邮箱已存在
|
||||
*/
|
||||
public static final int EMAIL_EXISTS = 10005;
|
||||
public static final int PASSWORD_INCORRECT = 10006;
|
||||
|
||||
/**
|
||||
* 业务逻辑错误
|
||||
*/
|
||||
public static final int BUSINESS_ERROR = 10006;
|
||||
|
||||
/**
|
||||
* 无效的令牌
|
||||
*/
|
||||
public static final int INVALID_TOKEN = 10007;
|
||||
|
||||
/**
|
||||
* 未授权访问
|
||||
*/
|
||||
public static final int UNAUTHORIZED = 10008;
|
||||
|
||||
/**
|
||||
* 用户名已存在
|
||||
*/
|
||||
public static final int USERNAME_EXISTS = 10009;
|
||||
|
||||
/**
|
||||
* 密码错误
|
||||
*/
|
||||
public static final int PASSWORD_INCORRECT = 10010;
|
||||
|
||||
/**
|
||||
* 参数为空
|
||||
*/
|
||||
public static final int PARAM_IS_BLANK = 10011;
|
||||
|
||||
/**
|
||||
* 参数错误
|
||||
*/
|
||||
public static final int PARAM_ERROR = 10012;
|
||||
}
|
||||
|
||||
@ -0,0 +1,130 @@
|
||||
package com.huertian.jinduguanli.controller;
|
||||
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.huertian.jinduguanli.common.ApiResponse;
|
||||
import com.huertian.jinduguanli.common.ErrorCode;
|
||||
import com.huertian.jinduguanli.dto.DepartmentImportDTO;
|
||||
import com.huertian.jinduguanli.dto.LessonTaskImportDTO;
|
||||
import com.huertian.jinduguanli.dto.UserImportDTO;
|
||||
import com.huertian.jinduguanli.service.DepartmentService;
|
||||
import com.huertian.jinduguanli.service.LessonTaskService;
|
||||
import com.huertian.jinduguanli.service.UserService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/api/import")
|
||||
public class ImportController {
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@Autowired
|
||||
private LessonTaskService lessonTaskService;
|
||||
|
||||
@Autowired
|
||||
private DepartmentService departmentService;
|
||||
|
||||
@PostMapping("/users")
|
||||
public ApiResponse<String> importUsers(@RequestParam("file") MultipartFile file) {
|
||||
if (file.isEmpty()) {
|
||||
return new ApiResponse<>(ErrorCode.INVALID_PARAM, "文件不能为空", null);
|
||||
}
|
||||
|
||||
String originalFilename = file.getOriginalFilename();
|
||||
if (!isValidExcelFile(originalFilename)) {
|
||||
return new ApiResponse<>(ErrorCode.INVALID_PARAM, "只支持.xlsx格式的文件", null);
|
||||
}
|
||||
|
||||
try {
|
||||
log.info("开始导入用户数据,文件名:{}", originalFilename);
|
||||
List<UserImportDTO> userList = EasyExcel.read(file.getInputStream())
|
||||
.head(UserImportDTO.class)
|
||||
.sheet()
|
||||
.doReadSync();
|
||||
log.info("读取到{}条用户数据", userList.size());
|
||||
|
||||
for (int i = 0; i < userList.size(); i++) {
|
||||
log.info("第{}行数据:{}", i + 1, userList.get(i));
|
||||
}
|
||||
|
||||
return userService.batchImportUsers(userList);
|
||||
} catch (Exception e) {
|
||||
log.error("导入用户数据失败", e);
|
||||
return new ApiResponse<>(ErrorCode.SYSTEM_ERROR, "导入用户数据失败:" + e.getMessage(), null);
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/lesson-tasks")
|
||||
public ApiResponse<String> importLessonTasks(@RequestParam("file") MultipartFile file) {
|
||||
if (file.isEmpty()) {
|
||||
return new ApiResponse<>(ErrorCode.INVALID_PARAM, "文件不能为空", null);
|
||||
}
|
||||
|
||||
String originalFilename = file.getOriginalFilename();
|
||||
if (!isValidExcelFile(originalFilename)) {
|
||||
return new ApiResponse<>(ErrorCode.INVALID_PARAM, "只支持.xlsx格式的文件", null);
|
||||
}
|
||||
|
||||
try {
|
||||
log.info("开始导入课程任务数据,文件名:{}", originalFilename);
|
||||
List<LessonTaskImportDTO> taskList = EasyExcel.read(file.getInputStream())
|
||||
.head(LessonTaskImportDTO.class)
|
||||
.sheet()
|
||||
.doReadSync();
|
||||
log.info("读取到{}条课程任务数据", taskList.size());
|
||||
|
||||
for (int i = 0; i < taskList.size(); i++) {
|
||||
log.info("第{}行数据:{}", i + 1, taskList.get(i));
|
||||
}
|
||||
|
||||
return lessonTaskService.batchImportLessonTasks(taskList);
|
||||
} catch (Exception e) {
|
||||
log.error("导入课程任务数据失败", e);
|
||||
return new ApiResponse<>(ErrorCode.SYSTEM_ERROR, "导入课程任务数据失败:" + e.getMessage(), null);
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/departments")
|
||||
public ApiResponse<String> importDepartments(@RequestParam("file") MultipartFile file) {
|
||||
if (file.isEmpty()) {
|
||||
return new ApiResponse<>(ErrorCode.INVALID_PARAM, "文件不能为空", null);
|
||||
}
|
||||
|
||||
String originalFilename = file.getOriginalFilename();
|
||||
if (!isValidExcelFile(originalFilename)) {
|
||||
return new ApiResponse<>(ErrorCode.INVALID_PARAM, "只支持.xlsx格式的文件", null);
|
||||
}
|
||||
|
||||
try {
|
||||
log.info("开始导入部门数据,文件名:{}", originalFilename);
|
||||
List<DepartmentImportDTO> departmentList = EasyExcel.read(file.getInputStream())
|
||||
.head(DepartmentImportDTO.class)
|
||||
.sheet()
|
||||
.doReadSync();
|
||||
log.info("读取到{}条部门数据", departmentList.size());
|
||||
|
||||
for (int i = 0; i < departmentList.size(); i++) {
|
||||
log.info("第{}行数据:{}", i + 1, departmentList.get(i));
|
||||
}
|
||||
|
||||
return departmentService.batchImportDepartments(departmentList);
|
||||
} catch (Exception e) {
|
||||
log.error("导入部门数据失败", e);
|
||||
return new ApiResponse<>(ErrorCode.SYSTEM_ERROR, "导入部门数据失败:" + e.getMessage(), null);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isValidExcelFile(String filename) {
|
||||
return StringUtils.isNotBlank(filename) && filename.toLowerCase().endsWith(".xlsx");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package com.huertian.jinduguanli.dto;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
public class DepartmentImportDTO {
|
||||
@ExcelProperty("部门名称")
|
||||
private String departmentName;
|
||||
|
||||
@ExcelProperty("部门描述")
|
||||
private String description;
|
||||
|
||||
public String getDepartmentName() {
|
||||
return departmentName;
|
||||
}
|
||||
|
||||
public void setDepartmentName(String departmentName) {
|
||||
this.departmentName = departmentName;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
package com.huertian.jinduguanli.dto;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
public class LessonTaskImportDTO {
|
||||
@ExcelProperty("课程名称")
|
||||
private String lessonName;
|
||||
|
||||
@ExcelProperty("微课名称")
|
||||
private String microLessonName;
|
||||
|
||||
@ExcelProperty("教师账号")
|
||||
private String teacherEmail;
|
||||
|
||||
public String getLessonName() {
|
||||
return lessonName;
|
||||
}
|
||||
|
||||
public void setLessonName(String lessonName) {
|
||||
this.lessonName = lessonName;
|
||||
}
|
||||
|
||||
public String getMicroLessonName() {
|
||||
return microLessonName;
|
||||
}
|
||||
|
||||
public void setMicroLessonName(String microLessonName) {
|
||||
this.microLessonName = microLessonName;
|
||||
}
|
||||
|
||||
public String getTeacherEmail() {
|
||||
return teacherEmail;
|
||||
}
|
||||
|
||||
public void setTeacherEmail(String teacherEmail) {
|
||||
this.teacherEmail = teacherEmail;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,61 @@
|
||||
package com.huertian.jinduguanli.dto;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
public class UserImportDTO {
|
||||
@ExcelProperty(index = 0)
|
||||
private String username;
|
||||
|
||||
@ExcelProperty(index = 1)
|
||||
private String email;
|
||||
|
||||
@ExcelProperty(index = 2)
|
||||
private String password;
|
||||
|
||||
@ExcelProperty(index = 3)
|
||||
private String departmentName;
|
||||
|
||||
@ExcelProperty(index = 4)
|
||||
private String roleAndJob;
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getDepartmentName() {
|
||||
return departmentName;
|
||||
}
|
||||
|
||||
public void setDepartmentName(String departmentName) {
|
||||
this.departmentName = departmentName;
|
||||
}
|
||||
|
||||
public String getRoleAndJob() {
|
||||
return roleAndJob;
|
||||
}
|
||||
|
||||
public void setRoleAndJob(String roleAndJob) {
|
||||
this.roleAndJob = roleAndJob;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package com.huertian.jinduguanli.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Entity
|
||||
@Table(name = "departments")
|
||||
public class Department {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(unique = true)
|
||||
private String name;
|
||||
|
||||
private String description;
|
||||
|
||||
private Long createdAt;
|
||||
|
||||
private Long updatedAt;
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
package com.huertian.jinduguanli.repository;
|
||||
|
||||
import com.huertian.jinduguanli.entity.Department;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface DepartmentRepository extends JpaRepository<Department, Long> {
|
||||
Department findByName(String name);
|
||||
}
|
||||
@ -0,0 +1,76 @@
|
||||
package com.huertian.jinduguanli.service;
|
||||
|
||||
import com.huertian.jinduguanli.common.ApiResponse;
|
||||
import com.huertian.jinduguanli.common.ErrorCode;
|
||||
import com.huertian.jinduguanli.dto.DepartmentImportDTO;
|
||||
import com.huertian.jinduguanli.entity.Department;
|
||||
import com.huertian.jinduguanli.repository.DepartmentRepository;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class DepartmentService {
|
||||
private static final Logger logger = LoggerFactory.getLogger(DepartmentService.class);
|
||||
private final DepartmentRepository departmentRepository;
|
||||
|
||||
@Autowired
|
||||
public DepartmentService(DepartmentRepository departmentRepository) {
|
||||
this.departmentRepository = departmentRepository;
|
||||
}
|
||||
|
||||
public ApiResponse<String> batchImportDepartments(List<DepartmentImportDTO> departmentList) {
|
||||
if (departmentList == null || departmentList.isEmpty()) {
|
||||
return new ApiResponse<>(ErrorCode.PARAM_ERROR, "导入数据不能为空", null);
|
||||
}
|
||||
|
||||
StringBuilder errorMsg = new StringBuilder();
|
||||
int successCount = 0;
|
||||
|
||||
for (int i = 0; i < departmentList.size(); i++) {
|
||||
DepartmentImportDTO dto = departmentList.get(i);
|
||||
try {
|
||||
// 基本数据验证
|
||||
if (StringUtils.isBlank(dto.getDepartmentName())) {
|
||||
errorMsg.append(String.format("第%d行部门名称不能为空;", i + 2));
|
||||
continue;
|
||||
}
|
||||
|
||||
// 检查部门名称是否已存在
|
||||
if (departmentRepository.findByName(dto.getDepartmentName()) != null) {
|
||||
errorMsg.append(String.format("第%d行部门名称已存在;", i + 2));
|
||||
continue;
|
||||
}
|
||||
|
||||
// 创建部门
|
||||
Department department = new Department();
|
||||
department.setName(dto.getDepartmentName());
|
||||
department.setDescription(dto.getDescription());
|
||||
department.setCreatedAt(System.currentTimeMillis() / 1000);
|
||||
department.setUpdatedAt(System.currentTimeMillis() / 1000);
|
||||
|
||||
departmentRepository.save(department);
|
||||
successCount++;
|
||||
} catch (Exception e) {
|
||||
logger.error("导入第{}行数据失败", i + 2, e);
|
||||
errorMsg.append(String.format("第%d行导入失败;", i + 2));
|
||||
}
|
||||
}
|
||||
|
||||
String resultMsg = String.format("成功导入%d条数据", successCount);
|
||||
if (errorMsg.length() > 0) {
|
||||
resultMsg += "。错误信息:" + errorMsg;
|
||||
}
|
||||
|
||||
// 如果没有成功导入任何数据,返回错误状态
|
||||
if (successCount == 0) {
|
||||
return new ApiResponse<>(ErrorCode.PARAM_ERROR, resultMsg, null);
|
||||
}
|
||||
|
||||
return ApiResponse.success(resultMsg);
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,12 @@
|
||||
package com.huertian.jinduguanli.service;
|
||||
|
||||
import com.huertian.jinduguanli.common.ApiResponse;
|
||||
import com.huertian.jinduguanli.common.ErrorCode;
|
||||
import com.huertian.jinduguanli.dto.LessonTaskDTO;
|
||||
import com.huertian.jinduguanli.dto.LessonTaskImportDTO;
|
||||
import com.huertian.jinduguanli.dto.LessonTaskRequest;
|
||||
import com.huertian.jinduguanli.entity.LessonTask;
|
||||
import com.huertian.jinduguanli.entity.User;
|
||||
import com.huertian.jinduguanli.repository.LessonTaskRepository;
|
||||
import jakarta.persistence.EntityNotFoundException;
|
||||
import org.slf4j.Logger;
|
||||
@ -15,13 +19,20 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@Service
|
||||
public class LessonTaskService {
|
||||
private static final Logger logger = LoggerFactory.getLogger(LessonTaskService.class);
|
||||
private final LessonTaskRepository lessonTaskRepository;
|
||||
private final UserService userService; // 添加 UserService 的依赖
|
||||
|
||||
public LessonTaskService(LessonTaskRepository lessonTaskRepository) {
|
||||
public LessonTaskService(LessonTaskRepository lessonTaskRepository, UserService userService) {
|
||||
this.lessonTaskRepository = lessonTaskRepository;
|
||||
this.userService = userService;
|
||||
}
|
||||
|
||||
@Cacheable(value = "lessonTasks", key = "#userId != null ? 'user:' + #userId + ':page:' + #pageable.pageNumber : 'all:page:' + #pageable.pageNumber")
|
||||
@ -192,6 +203,74 @@ public class LessonTaskService {
|
||||
return lessonTaskRepository.findByDepartmentIdAndUserStatus(departmentId, userStatus, pageable);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public ApiResponse<String> batchImportLessonTasks(List<LessonTaskImportDTO> taskList) {
|
||||
if (taskList == null || taskList.isEmpty()) {
|
||||
logger.error("导入任务列表为空");
|
||||
return new ApiResponse<>(ErrorCode.PARAM_IS_BLANK, "导入任务列表为空", null);
|
||||
}
|
||||
|
||||
StringBuilder errorMsg = new StringBuilder();
|
||||
int successCount = 0;
|
||||
|
||||
for (int i = 0; i < taskList.size(); i++) {
|
||||
LessonTaskImportDTO dto = taskList.get(i);
|
||||
try {
|
||||
// 基本数据验证
|
||||
if (StringUtils.isBlank(dto.getLessonName())) {
|
||||
errorMsg.append(String.format("第%d行课程名称不能为空;", i + 2));
|
||||
continue;
|
||||
}
|
||||
if (StringUtils.isBlank(dto.getMicroLessonName())) {
|
||||
errorMsg.append(String.format("第%d行微课名称不能为空;", i + 2));
|
||||
continue;
|
||||
}
|
||||
if (StringUtils.isBlank(dto.getTeacherEmail())) {
|
||||
errorMsg.append(String.format("第%d行教师账号不能为空;", i + 2));
|
||||
continue;
|
||||
}
|
||||
|
||||
// 查找教师用户ID
|
||||
ApiResponse<User> teacherResponse = userService.findTeacherByEmail(dto.getTeacherEmail());
|
||||
if (teacherResponse.getCode() != ErrorCode.SUCCESS) {
|
||||
errorMsg.append(String.format("第%d行未找到教师用户(%s);", i + 2, dto.getTeacherEmail()));
|
||||
continue;
|
||||
}
|
||||
|
||||
LessonTask task = new LessonTask();
|
||||
task.setCourseName(dto.getLessonName());
|
||||
task.setMicroLessonName(dto.getMicroLessonName());
|
||||
task.setUserId(teacherResponse.getData().getId());
|
||||
task.setProgressStatus(0); // 初始状态:未开始
|
||||
task.setCreatedAt(System.currentTimeMillis() / 1000);
|
||||
task.setUpdatedAt(System.currentTimeMillis() / 1000);
|
||||
|
||||
try {
|
||||
lessonTaskRepository.save(task);
|
||||
successCount++;
|
||||
} catch (Exception e) {
|
||||
logger.error("保存课程任务失败", e);
|
||||
errorMsg.append(String.format("第%d行保存失败: %s;", i + 2, e.getMessage()));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("导入第{}行数据失败", i + 2, e);
|
||||
errorMsg.append(String.format("第%d行导入失败: %s;", i + 2, e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
String resultMsg = String.format("成功导入%d条数据", successCount);
|
||||
if (errorMsg.length() > 0) {
|
||||
resultMsg += "。错误信息:" + errorMsg;
|
||||
}
|
||||
|
||||
// 如果没有成功导入任何数据,返回错误状态
|
||||
if (successCount == 0) {
|
||||
return new ApiResponse<>(ErrorCode.PARAM_ERROR, resultMsg, null);
|
||||
}
|
||||
|
||||
return ApiResponse.success(resultMsg);
|
||||
}
|
||||
|
||||
private void validateRequest(LessonTaskRequest request) {
|
||||
if (request.getCourseName() == null || request.getCourseName().trim().isEmpty()) {
|
||||
throw new IllegalArgumentException("课程名称不能为空");
|
||||
|
||||
@ -2,13 +2,13 @@ package com.huertian.jinduguanli.service;
|
||||
|
||||
import com.huertian.jinduguanli.common.ApiResponse;
|
||||
import com.huertian.jinduguanli.common.ErrorCode;
|
||||
import com.huertian.jinduguanli.dto.CreateUserRequest;
|
||||
import com.huertian.jinduguanli.dto.LoginResponse;
|
||||
import com.huertian.jinduguanli.dto.UserLoginRequest;
|
||||
import com.huertian.jinduguanli.dto.UserPageResponse;
|
||||
import com.huertian.jinduguanli.dto.*;
|
||||
import com.huertian.jinduguanli.entity.Department;
|
||||
import com.huertian.jinduguanli.entity.User;
|
||||
import com.huertian.jinduguanli.repository.DepartmentRepository;
|
||||
import com.huertian.jinduguanli.repository.UserRepository;
|
||||
import com.huertian.jinduguanli.security.service.JwtService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -28,13 +28,16 @@ public class UserService implements UserDetailsService {
|
||||
private final UserRepository userRepository;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
private final JwtService jwtService;
|
||||
private final DepartmentRepository departmentRepository;
|
||||
private static final Logger logger = LoggerFactory.getLogger(UserService.class);
|
||||
|
||||
@Autowired
|
||||
public UserService(JwtService jwtService, PasswordEncoder passwordEncoder, UserRepository userRepository) {
|
||||
public UserService(JwtService jwtService, PasswordEncoder passwordEncoder, UserRepository userRepository,
|
||||
DepartmentRepository departmentRepository) {
|
||||
this.jwtService = jwtService;
|
||||
this.passwordEncoder = passwordEncoder;
|
||||
this.userRepository = userRepository;
|
||||
this.departmentRepository = departmentRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -77,7 +80,7 @@ public class UserService implements UserDetailsService {
|
||||
user.setCreatorId(request.getCreatorId());
|
||||
user.setStatus(1);
|
||||
// 时间戳由 @PrePersist 处理,这里不需要手动设置
|
||||
|
||||
|
||||
userRepository.save(user);
|
||||
|
||||
return ApiResponse.success();
|
||||
@ -183,22 +186,83 @@ public class UserService implements UserDetailsService {
|
||||
return new ApiResponse<>(ErrorCode.USER_NOT_FOUND, "用户不存在", null);
|
||||
}
|
||||
|
||||
// 验证用户是否为教师角色且为课程制作教师岗位
|
||||
if (user.getRoles() != 1) {
|
||||
return new ApiResponse<>(ErrorCode.INVALID_PARAM, "非教师用户", null);
|
||||
}
|
||||
|
||||
if (user.getJobs() != 1) {
|
||||
return new ApiResponse<>(ErrorCode.INVALID_PARAM, "非课程制作教师", null);
|
||||
}
|
||||
|
||||
if (user.getStatus() != 1) {
|
||||
return new ApiResponse<>(ErrorCode.INVALID_PARAM, "用户状态异常", null);
|
||||
}
|
||||
|
||||
// 清除敏感信息
|
||||
user.setPassword(null);
|
||||
|
||||
return ApiResponse.success(user);
|
||||
}
|
||||
|
||||
public ApiResponse<String> batchImportUsers(List<UserImportDTO> userList) {
|
||||
if (userList == null || userList.isEmpty()) {
|
||||
return new ApiResponse<>(ErrorCode.PARAM_ERROR, "导入数据不能为空", null);
|
||||
}
|
||||
|
||||
StringBuilder errorMsg = new StringBuilder();
|
||||
int successCount = 0;
|
||||
|
||||
for (int i = 0; i < userList.size(); i++) {
|
||||
UserImportDTO dto = userList.get(i);
|
||||
try {
|
||||
// 基本数据验证
|
||||
if (StringUtils.isBlank(dto.getUsername()) ||
|
||||
StringUtils.isBlank(dto.getEmail()) ||
|
||||
StringUtils.isBlank(dto.getPassword()) ||
|
||||
StringUtils.isBlank(dto.getDepartmentName()) ||
|
||||
StringUtils.isBlank(dto.getRoleAndJob())) {
|
||||
errorMsg.append(String.format("第%d行数据不完整;", i + 2));
|
||||
continue;
|
||||
}
|
||||
|
||||
// 检查邮箱是否已存在
|
||||
if (userRepository.findByEmail(dto.getEmail()).isPresent()) {
|
||||
errorMsg.append(String.format("第%d行邮箱已存在;", i + 2));
|
||||
continue;
|
||||
}
|
||||
|
||||
// 查找部门ID
|
||||
Department department = departmentRepository.findByName(dto.getDepartmentName());
|
||||
logger.info("查找部门:{},结果:{}", dto.getDepartmentName(), department);
|
||||
if (department == null) {
|
||||
errorMsg.append(String.format("第%d行部门不存在;", i + 2));
|
||||
continue;
|
||||
}
|
||||
|
||||
// 创建新用户
|
||||
User user = new User();
|
||||
user.setUsername(dto.getUsername());
|
||||
user.setEmail(dto.getEmail());
|
||||
user.setPassword(passwordEncoder.encode(dto.getPassword()));
|
||||
user.setDepartmentId(department.getId());
|
||||
user.setRoles(0); // 默认角色
|
||||
user.setJobs(0); // 默认工作
|
||||
user.setStatus(1); // 设置状态为正常
|
||||
user.setCreatedAt(System.currentTimeMillis() / 1000);
|
||||
user.setUpdatedAt(System.currentTimeMillis() / 1000);
|
||||
|
||||
try {
|
||||
userRepository.save(user);
|
||||
successCount++;
|
||||
} catch (Exception e) {
|
||||
logger.error("保存用户失败", e);
|
||||
errorMsg.append(String.format("第%d行保存失败: %s;", i + 2, e.getMessage()));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("导入第{}行数据失败", i + 2, e);
|
||||
errorMsg.append(String.format("第%d行导入失败;", i + 2));
|
||||
}
|
||||
}
|
||||
|
||||
String resultMsg = String.format("成功导入%d条数据", successCount);
|
||||
if (errorMsg.length() > 0) {
|
||||
resultMsg += "。错误信息:" + errorMsg;
|
||||
}
|
||||
|
||||
// 如果没有成功导入任何数据,返回错误状态
|
||||
if (successCount == 0) {
|
||||
return new ApiResponse<>(ErrorCode.PARAM_ERROR, resultMsg, null);
|
||||
}
|
||||
|
||||
return ApiResponse.success(resultMsg);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user