搜索、小助手推荐位

This commit is contained in:
2025-11-18 11:48:01 +08:00
parent 2ce3684711
commit 049b6f2cf3
18 changed files with 1280 additions and 23 deletions

View File

@@ -17,6 +17,7 @@ import org.xyzh.common.dto.user.TbSysUser;
import org.xyzh.common.dto.usercenter.TbUserCollection;
import org.xyzh.common.utils.TimeUtils;
import org.xyzh.common.vo.ResourceVO;
import org.xyzh.common.vo.TaskItemVO;
import org.xyzh.system.utils.LoginUtil;
/**
* @description 资源控制器
@@ -192,4 +193,9 @@ public class ResourceController {
@RequestParam(value = "status", required = false) Integer status) {
return resourceService.searchResources(keyword, tagID, status);
}
@PostMapping("/search")
public ResultDomain<TaskItemVO> searchResources(@RequestBody PageRequest<TbResource> filter) {
return resourceService.searchItem(filter);
}
}

View File

@@ -6,6 +6,7 @@ import org.apache.ibatis.annotations.Param;
import org.xyzh.common.core.page.PageParam;
import org.xyzh.common.dto.resource.TbResource;
import org.xyzh.common.vo.ResourceVO;
import org.xyzh.common.vo.TaskItemVO;
import org.xyzh.common.vo.UserDeptRoleVO;
import java.util.List;
@@ -205,4 +206,6 @@ public interface ResourceMapper extends BaseMapper<TbResource> {
* @since 2025-10-15
*/
int incrementViewCount(@Param("resourceID") String resourceID);
List<TaskItemVO> selectItem(@Param("filter") TbResource filter, @Param("pageParam") PageParam pageParam, @Param("userDeptRoles") List<UserDeptRoleVO> userDeptRoles);
}

View File

@@ -9,6 +9,7 @@ import org.springframework.util.StringUtils;
import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.common.core.page.PageDomain;
import org.xyzh.common.core.page.PageParam;
import org.xyzh.common.core.page.PageRequest;
import org.xyzh.common.dto.resource.TbResource;
import org.xyzh.common.dto.resource.TbResourceTag;
import org.xyzh.common.dto.resource.TbTag;
@@ -17,6 +18,7 @@ import org.xyzh.common.dto.usercenter.TbUserCollection;
import org.xyzh.common.utils.IDUtils;
import org.xyzh.common.vo.ResourceVO;
import org.xyzh.common.vo.TagVO;
import org.xyzh.common.vo.TaskItemVO;
import org.xyzh.news.mapper.ResourceMapper;
import org.xyzh.news.mapper.ResourceTagMapper;
import org.xyzh.system.utils.LoginUtil;
@@ -771,4 +773,23 @@ public class NCResourceServiceImpl implements ResourceService {
return resultDomain;
}
}
@Override
public ResultDomain<TaskItemVO> searchItem(PageRequest<TbResource> filter) {
ResultDomain<TaskItemVO> resultDomain = new ResultDomain<>();
try {
List<UserDeptRoleVO> userDeptRoles = LoginUtil.getCurrentDeptRole();
List<TaskItemVO> list = resourceMapper.selectItem(filter.getFilter(), filter.getPageParam(), userDeptRoles);
if (list == null || list.isEmpty()) {
resultDomain.fail("搜索资源失败: 没有找到资源");
return resultDomain;
}
resultDomain.success("搜索资源成功", list);
return resultDomain;
} catch (Exception e) {
logger.error("搜索资源异常: {}", e.getMessage(), e);
resultDomain.fail("搜索资源失败: " + e.getMessage());
return resultDomain;
}
}
}

View File

@@ -323,6 +323,9 @@
<if test="filter.author != null and filter.author != ''">
AND r.author LIKE CONCAT('%', #{filter.author}, '%')
</if>
<if test="filter.title != null and filter.title != ''">
AND r.title LIKE CONCAT('%', #{filter.title}, '%')
</if>
<if test="filter.status != null">
AND r.status = #{filter.status}
</if>
@@ -451,4 +454,116 @@
</update>
<!-- selectItem -->
<!-- 联合模糊查询文章和课程,时间排序 -->
<select id="selectItem" resultType="org.xyzh.common.vo.TaskItemVO">
SELECT * FROM (
-- 查询文章资源
SELECT DISTINCT
1 AS itemType,
r.resource_id AS resourceID,
r.title AS resourceName,
NULL AS courseID,
NULL AS courseName,
r.author,
r.cover_image AS coverImage,
r.summary,
r.view_count AS viewCount,
r.publish_time AS publishTime,
r.create_time AS createTime
FROM tb_resource r
INNER JOIN tb_resource_permission rp ON r.resource_id = rp.resource_id
AND rp.resource_type = 1
AND rp.deleted = 0
AND rp.can_read = 1
AND (
-- 全局权限:所有用户可访问
(rp.dept_id IS NULL AND rp.role_id IS NULL)
<if test="userDeptRoles != null and userDeptRoles.size() > 0">
OR EXISTS (
SELECT 1
FROM (
<foreach collection="userDeptRoles" item="udr" separator=" UNION ALL ">
SELECT #{udr.deptID} AS dept_id, #{udr.deptPath} AS dept_path, #{udr.roleID} AS role_id
</foreach>
) user_roles
LEFT JOIN tb_sys_dept perm_dept ON perm_dept.dept_id = rp.dept_id AND perm_dept.deleted = 0
WHERE
-- 部门级权限当前部门或父部门通过dept_path判断继承关系
(rp.role_id IS NULL AND rp.dept_id IS NOT NULL
AND user_roles.dept_path LIKE CONCAT(perm_dept.dept_path, '%'))
-- 角色级权限:跨部门的角色权限
OR (rp.dept_id IS NULL AND rp.role_id = user_roles.role_id)
-- 精确权限:特定部门的特定角色
OR (rp.dept_id = user_roles.dept_id AND rp.role_id = user_roles.role_id)
)
</if>
)
WHERE r.deleted = 0
<if test="filter.status != null">
AND r.status = #{filter.status}
</if>
<if test="filter.title != null and filter.title != ''">
AND (r.title LIKE CONCAT('%', #{filter.title}, '%')
OR r.summary LIKE CONCAT('%', #{filter.title}, '%'))
</if>
UNION ALL
-- 查询课程资源
SELECT DISTINCT
2 AS itemType,
NULL AS resourceID,
NULL AS resourceName,
c.course_id AS courseID,
c.name AS courseName,
c.teacher AS author,
c.cover_image AS coverImage,
c.description AS summary,
c.view_count AS viewCount,
NULL AS publishTime,
c.create_time AS createTime
FROM tb_course c
INNER JOIN tb_resource_permission rp ON c.course_id = rp.resource_id
AND rp.resource_type = 2
AND rp.deleted = 0
AND rp.can_read = 1
AND (
-- 全局权限:所有用户可访问
(rp.dept_id IS NULL AND rp.role_id IS NULL)
<if test="userDeptRoles != null and userDeptRoles.size() > 0">
OR EXISTS (
SELECT 1
FROM (
<foreach collection="userDeptRoles" item="udr" separator=" UNION ALL ">
SELECT #{udr.deptID} AS dept_id, #{udr.deptPath} AS dept_path, #{udr.roleID} AS role_id
</foreach>
) user_roles
LEFT JOIN tb_sys_dept perm_dept ON perm_dept.dept_id = rp.dept_id AND perm_dept.deleted = 0
WHERE
-- 部门级权限当前部门或父部门通过dept_path判断继承关系
(rp.role_id IS NULL AND rp.dept_id IS NOT NULL
AND user_roles.dept_path LIKE CONCAT(perm_dept.dept_path, '%'))
-- 角色级权限:跨部门的角色权限
OR (rp.dept_id IS NULL AND rp.role_id = user_roles.role_id)
-- 精确权限:特定部门的特定角色
OR (rp.dept_id = user_roles.dept_id AND rp.role_id = user_roles.role_id)
)
</if>
)
WHERE c.deleted = 0
<if test="filter.status != null">
AND c.status = #{filter.status}
</if>
<if test="filter.title != null and filter.title != ''">
AND (c.name LIKE CONCAT('%', #{filter.title}, '%')
OR c.description LIKE CONCAT('%', #{filter.title}, '%'))
</if>
) AS combined_results
-- 按时间倒序排列,优先使用发布时间,其次使用创建时间
ORDER BY COALESCE(publishTime, createTime) DESC
<if test="pageParam != null">
LIMIT #{pageParam.offset}, #{pageParam.pageSize}
</if>
</select>
</mapper>