This commit is contained in:
王昊 2025-11-25 18:13:51 +08:00
parent 5ce697523a
commit 24fdc236b1
10 changed files with 308 additions and 10 deletions

View File

@ -9,21 +9,33 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import xyz.playedu.common.annotation.Log;
import xyz.playedu.common.constant.BusinessTypeConstant;
import xyz.playedu.common.constant.CommonConstant;
import xyz.playedu.common.domain.Department;
import xyz.playedu.common.domain.Group;
import xyz.playedu.common.domain.User;
import xyz.playedu.common.domain.UserGroup;
import xyz.playedu.common.exception.NotFoundException;
import xyz.playedu.common.service.*;
import xyz.playedu.common.types.JsonResponse;
import xyz.playedu.common.types.paginate.PaginationResult;
import xyz.playedu.common.util.StringUtil;
import xyz.playedu.course.constants.CourseConstant;
import xyz.playedu.course.domain.Course;
import xyz.playedu.course.domain.CourseDepartmentUser;
import xyz.playedu.jc.domain.BookDepartmentUser;
import xyz.playedu.jc.domain.JCResource;
import xyz.playedu.jc.domain.Textbook;
import xyz.playedu.jc.domain.dto.TextbookRequestDTO;
import xyz.playedu.jc.service.IBookDepartmentUserService;
import xyz.playedu.jc.service.ITextbookService;
import xyz.playedu.jc.service.JCIResourceService;
import xyz.playedu.knowledge.domain.KnowledgeMessages;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 教材管理 后台接口
@ -38,17 +50,222 @@ public class TextbookController {
@Autowired
private IBookDepartmentUserService bookDepartmentUserService;
@Autowired
private JCIResourceService jciResourceService;
@Autowired private DepartmentService departmentService;
@Autowired private UserGroupService userGroupService;
@Autowired private UserDepartmentService userDepartmentService;
@Autowired private UserService userService;
@Autowired private GroupService groupService;
@GetMapping("/index")
public JsonResponse index(@RequestParam HashMap<String, Object> params) {
/** 调用服务层分页查询方法Service 层已包含完整的分页信息 */
PaginationResult<Textbook> result = textbookService.paginate(params);
HashMap<String, Object> data = new HashMap<>();
data.put("data", result.getData());
data.put("total", result.getTotal());
// 课程封面资源ID
List<Integer> rids = new ArrayList<>();
rids.addAll(result.getData().stream().map(Textbook::getThumb).toList());
List<Integer> bookIds = result.getData().stream().map(Textbook::getId).toList();
// data.put("course_category_ids", courseService.getCategoryIdsGroup(courseIds));
// data.put("categories", categoryService.id2name());
// data.put("departments", departmentService.id2name());
// Map<Integer, Integer> courseIdRecordCountMap = new HashMap<>();
// doGetRecords(courseIds)
// .forEach(
// (key, value) -> {
// courseIdRecordCountMap.put(key, value.size());
// });
// data.put("records", courseIdRecordCountMap);
// 获取签名url
data.put("resource_url", jciResourceService.chunksPreSignUrlByIds(rids));
// 指派范围
Map<Integer, Integer> book_user_count = new HashMap<>();
List<BookDepartmentUser> courseDepartmentUserList =
bookDepartmentUserService.chunksByBookIds(bookIds);
if (StringUtil.isNotEmpty(courseDepartmentUserList)) {
List<Integer> depIds =
courseDepartmentUserList.stream()
.filter(
courseDepartmentUser ->
CourseConstant.COURSE_TYPE_DEP
== courseDepartmentUser.getType())
.map(BookDepartmentUser::getRangeId)
.distinct()
.toList();
Map<Integer, Department> depMap = new HashMap<>();
if (StringUtil.isNotEmpty(depIds)) {
depMap =
departmentService.chunk(depIds).stream()
.collect(Collectors.toMap(Department::getId, e -> e));
}
Map<Integer, Department> finalDepMap = depMap;
courseDepartmentUserList.stream()
.collect(Collectors.groupingBy(BookDepartmentUser::getBookId))
.forEach(
(key, value) -> {
if (StringUtil.isNotEmpty(value)) {
List<Integer> courseDepIds = new ArrayList<>();
List<Integer> courseUserIds = new ArrayList<>();
value.forEach(
courseDepartmentUser -> {
if (CourseConstant.COURSE_TYPE_DEP
== courseDepartmentUser.getType()) {
Department dep =
finalDepMap.get(
courseDepartmentUser
.getRangeId());
if (StringUtil.isNotNull(dep)) {
courseDepIds.add(dep.getId());
String parentChain = "";
if (StringUtil.isEmpty(
dep.getParentChain())) {
parentChain = dep.getId() + "";
} else {
parentChain =
dep.getParentChain()
+ ","
+ dep.getId();
}
List<Department> childDepartmentList =
departmentService
.getChildDepartmentsByParentChain(
dep.getId(),
parentChain);
if (StringUtil.isNotEmpty(
childDepartmentList)) {
courseDepIds.addAll(
childDepartmentList.stream()
.map(Department::getId)
.toList());
}
}
} else if (CourseConstant.COURSE_TYPE_GROUP
== courseDepartmentUser.getType()) {
List<UserGroup> userGroupList =
userGroupService.chunksByGroupIds(
new ArrayList<>() {
{
add(
courseDepartmentUser
.getRangeId());
}
});
if (StringUtil.isNotEmpty(userGroupList)) {
courseUserIds.addAll(
userGroupList.stream()
.map(UserGroup::getUserId)
.toList());
}
} else {
courseUserIds.add(
courseDepartmentUser.getRangeId());
}
});
if (StringUtil.isNotEmpty(courseDepIds)) {
List<Integer> departmentUserIds =
userDepartmentService.getUserIdsByDepIds(
courseDepIds);
if (StringUtil.isNotEmpty(departmentUserIds)) {
courseUserIds.addAll(departmentUserIds);
}
}
// 过滤本地逻辑删除的学员
List<Integer> userIds =
userService.chunks(courseUserIds).stream()
.filter(
user ->
user.getDeleted().intValue()
== CommonConstant.ZERO
.intValue())
.map(User::getId)
.toList();
book_user_count.put(
key, userIds.stream().distinct().toList().size());
}
});
}
data.put("course_user_count", book_user_count);
/** 直接返回 Service 层的结果 */
return JsonResponse.data(result);
return JsonResponse.data(data);
}
@GetMapping("/{id}")
@Log(title = "线上课-编辑", businessType = BusinessTypeConstant.GET)
public JsonResponse edit(@PathVariable(name = "id") Integer id) throws NotFoundException {
Textbook textbook = textbookService.findOrFail(id);
HashMap<String, Object> data = new HashMap<>();
data.put("textbook", textbook);
List<Integer> rids = new ArrayList<>();
rids.add(textbook.getThumb());
// 获取签名url
data.put("resource_url", jciResourceService.chunksPreSignUrlByIds(rids));
// 指派范围
List<BookDepartmentUser> courseDepartmentUserList =
bookDepartmentUserService.chunksByCourseId(id);
if (StringUtil.isNotEmpty(courseDepartmentUserList)) {
Map<Integer, String> deps =
departmentService
.chunk(
courseDepartmentUserList.stream()
.filter(
dto ->
CourseConstant.COURSE_TYPE_DEP
== dto.getType())
.map(BookDepartmentUser::getRangeId)
.toList())
.stream()
.collect(Collectors.toMap(Department::getId, Department::getName));
data.put("deps", deps);
Map<Integer, String> users =
userService
.chunks(
courseDepartmentUserList.stream()
.filter(
dto ->
CourseConstant.COURSE_TYPE_USER
== dto.getType())
.map(BookDepartmentUser::getRangeId)
.toList())
.stream()
.filter(
user ->
user.getDeleted().intValue()
== CommonConstant.ZERO.intValue())
.collect(Collectors.toMap(User::getId, User::getName));
data.put("users", users);
Map<Integer, String> groups =
groupService
.chunkByIds(
courseDepartmentUserList.stream()
.filter(
dto ->
CourseConstant.COURSE_TYPE_GROUP
== dto.getType())
.map(BookDepartmentUser::getRangeId)
.toList())
.stream()
.collect(Collectors.toMap(Group::getId, Group::getName));
data.put("groups", groups);
} else {
data.put("deps", new HashMap<>());
data.put("users", new HashMap<>());
data.put("groups", new HashMap<>());
}
return JsonResponse.data(data);
}
@GetMapping("/list")
public JsonResponse list() {
@ -56,11 +273,11 @@ public class TextbookController {
return JsonResponse.data(list);
}
@GetMapping("/{id}")
public JsonResponse detail(@PathVariable("id") Integer id) {
Textbook one = textbookService.getById(id);
return JsonResponse.data(one);
}
// @GetMapping("/{id}")
// public JsonResponse detail(@PathVariable("id") Integer id) {
// Textbook one = textbookService.getById(id);
// return JsonResponse.data(one);
// }
// @Transactional
@PostMapping

View File

@ -31,8 +31,8 @@ public class JCResource {
@TableField("name")
private String name;
@TableField("konwledge_code")
private String konwledgeCode;
@TableField("knowledge_code")
private String knowledgeCode;
/** 文本描述 AI分析或自动填入 */

View File

@ -25,7 +25,7 @@ public class Textbook {
/** 封面地址 */
@TableField("thumb")
private String thumb;
private Integer thumb;
/** 简介 */
@TableField("short_desc")

View File

@ -26,7 +26,7 @@ public class TextbookRequestDTO {
/** 封面地址 */
@TableField("thumb")
private String thumb;
private Integer thumb;
/** 简介 */
@TableField("short_desc")

View File

@ -1,8 +1,15 @@
package xyz.playedu.jc.service;
import com.baomidou.mybatisplus.extension.service.IService;
import xyz.playedu.course.domain.CourseDepartmentUser;
import xyz.playedu.jc.domain.BookDepartmentUser;
import java.util.List;
public interface IBookDepartmentUserService extends IService<BookDepartmentUser> {
void removeByBookId(Integer bookId);
List<BookDepartmentUser> chunksByBookIds(List<Integer> bookIds);
List<BookDepartmentUser> chunksByCourseId(Integer courseId);
}

View File

@ -1,7 +1,9 @@
package xyz.playedu.jc.service;
import com.baomidou.mybatisplus.extension.service.IService;
import xyz.playedu.common.exception.NotFoundException;
import xyz.playedu.common.types.paginate.PaginationResult;
import xyz.playedu.jc.domain.JCResource;
import xyz.playedu.jc.domain.Textbook;
import java.util.HashMap;
@ -12,4 +14,7 @@ import java.util.HashMap;
public interface ITextbookService extends IService<Textbook> {
PaginationResult<Textbook> paginate(HashMap<String, Object> params);
Textbook findOrFail(Integer id) throws NotFoundException;
}

View File

@ -1,7 +1,14 @@
package xyz.playedu.jc.service;
import com.baomidou.mybatisplus.extension.service.IService;
import xyz.playedu.common.exception.NotFoundException;
import xyz.playedu.course.domain.Course;
import xyz.playedu.jc.domain.JCResource;
import java.util.List;
import java.util.Map;
public interface JCIResourceService extends IService<JCResource> {
Map<Integer, String> chunksPreSignUrlByIds(List<Integer> ids);
}

View File

@ -2,10 +2,13 @@ package xyz.playedu.jc.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import xyz.playedu.course.domain.CourseDepartmentUser;
import xyz.playedu.jc.domain.BookDepartmentUser;
import xyz.playedu.jc.mapper.BookDepartmentUserMapper;
import xyz.playedu.jc.service.IBookDepartmentUserService;
import java.util.List;
@Service
public class BookDepartmentUserServiceImpl
extends ServiceImpl<BookDepartmentUserMapper, BookDepartmentUser>
@ -15,4 +18,15 @@ public class BookDepartmentUserServiceImpl
public void removeByBookId(Integer bookId) {
remove(query().getWrapper().eq("book_id", bookId));
}
@Override
public List<BookDepartmentUser> chunksByBookIds(List<Integer> bookIds) {
return List.of();
}
@Override
public List<BookDepartmentUser> chunksByCourseId(Integer bookId) {
return list(query().getWrapper().eq("book_id", bookId));
}
}

View File

@ -1,13 +1,50 @@
package xyz.playedu.jc.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import xyz.playedu.common.exception.NotFoundException;
import xyz.playedu.common.service.AppConfigService;
import xyz.playedu.common.util.S3Util;
import xyz.playedu.common.util.StringUtil;
import xyz.playedu.course.domain.Course;
import xyz.playedu.jc.domain.JCResource;
import xyz.playedu.jc.mapper.JCResourceMapper;
import xyz.playedu.jc.service.JCIResourceService;
import xyz.playedu.resource.domain.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class JCResourceServiceImpl
extends ServiceImpl<JCResourceMapper, JCResource>
implements JCIResourceService {
@Autowired
private AppConfigService appConfigService;
@Override
public Map<Integer, String> chunksPreSignUrlByIds(List<Integer> ids) {
S3Util s3Util = new S3Util(appConfigService.getS3Config());
Map<Integer, String> preSignUrlMap = new HashMap<>();
if (StringUtil.isNotEmpty(ids)) {
List<JCResource> resourceList = list(query().getWrapper().in("id", ids));
if (StringUtil.isNotEmpty(resourceList)) {
resourceList.forEach(
resource -> {
String name = resource.getName() + "." + resource.getExtension();
String url = s3Util.generateDownloadUrl(resource.getPath(), name);
if (StringUtil.isNotEmpty(url)) {
preSignUrlMap.put(resource.getId(), url);
}
});
}
}
return preSignUrlMap;
}
}

View File

@ -7,7 +7,9 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.springframework.stereotype.Service;
import xyz.playedu.common.exception.NotFoundException;
import xyz.playedu.common.types.paginate.PaginationResult;
import xyz.playedu.jc.domain.JCResource;
import xyz.playedu.jc.domain.Textbook;
import xyz.playedu.jc.mapper.TextbookMapper;
import xyz.playedu.jc.service.ITextbookService;
@ -85,4 +87,13 @@ public class TextbookServiceImpl
return emptyResult;
}
}
@Override
public Textbook findOrFail(Integer id) throws NotFoundException {
Textbook textbook = getOne(query().getWrapper().eq("id", id));
if (textbook == null) {
throw new NotFoundException("课程不存在");
}
return textbook;
}
}