定时任务增加系统定时任务
This commit is contained in:
@@ -275,3 +275,56 @@ INSERT INTO `tb_crontab_task_meta` (
|
||||
NOW()
|
||||
);
|
||||
|
||||
-- 9. 热门资源推荐任务
|
||||
INSERT INTO `tb_crontab_task_meta` (
|
||||
`id`, `meta_id`, `name`, `description`, `category`,
|
||||
`bean_name`, `method_name`, `script_path`, `param_schema`, `auto_publish`,
|
||||
`sort_order`, `creator`, `create_time`
|
||||
) VALUES (
|
||||
'9',
|
||||
'top_recommend_task',
|
||||
'热门资源推荐',
|
||||
'每天凌晨1点自动更新热门推荐资源(浏览量TOP10+最新发布TOP10)',
|
||||
'系统内部任务',
|
||||
'topRecommendTask',
|
||||
'execute',
|
||||
'',
|
||||
'[]',
|
||||
0,
|
||||
9,
|
||||
'system',
|
||||
NOW()
|
||||
);
|
||||
|
||||
-- 创建热门资源推荐任务实例
|
||||
INSERT INTO `tb_crontab_task` (
|
||||
`id`, `task_id`, `meta_id`, `task_name`,`task_group`, `description`,`bean_name`,
|
||||
`cron_expression`, `method_name`, `method_params`, `status`, `creator`, `create_time`
|
||||
) VALUES (
|
||||
'9',
|
||||
'task_top_recommend_daily',
|
||||
'top_recommend_task',
|
||||
'每日热门资源推荐更新',
|
||||
'系统内部任务',
|
||||
'每天凌晨1点自动更新热门推荐资源列表',
|
||||
'topRecommendTask',
|
||||
'0 0 1 * * ?',
|
||||
'execute',
|
||||
'{}',
|
||||
1,
|
||||
'system',
|
||||
NOW()
|
||||
);
|
||||
-- 赋予root用户和superadmin角色对热门资源推荐任务的读写执行权限
|
||||
INSERT INTO `tb_resource_permission` (`id`, `resource_type`, `resource_id`, `dept_id`,
|
||||
`role_id`, `can_read`, `can_write`, `can_execute`, `creator`, `updater`,
|
||||
`create_time`, `update_time`, `delete_time`, `deleted`)
|
||||
VALUES ('671f0c40642e6a69c2be9b6d7a4e986e', 7, 'task_top_recommend_daily', 'root_department',
|
||||
'superadmin', 1, 1, 1, '1', NULL,
|
||||
'2025-11-25 13:57:16', '2025-11-25 13:57:16', NULL, 0);
|
||||
INSERT INTO `tb_resource_permission` (`id`, `resource_type`, `resource_id`, `dept_id`,
|
||||
`role_id`, `can_read`, `can_write`, `can_execute`, `creator`, `updater`,
|
||||
`create_time`, `update_time`, `delete_time`, `deleted`)
|
||||
VALUES ('c365853b6a0e38a9c504962de4403e57', 7, 'task_top_recommend_daily', NULL, NULL,
|
||||
1, 0, 0, '1', NULL,
|
||||
'2025-11-25 13:57:16', '2025-11-25 13:57:16', NULL, 0);
|
||||
|
||||
@@ -170,6 +170,7 @@ INSERT INTO `tb_sys_menu` VALUES
|
||||
('8001', 'menu_admin_meta_email_default', '默认接收人配置', 'menu_admin_crontab_manage', '/admin/manage/crontab/meta-email-default', 'admin/manage/crontab/MetaEmailDefaultView', NULL, 1, 0, 'SidebarLayout', '1', NULL, '2025-11-18 18:00:00', '2025-11-18 18:00:00', NULL, 0),
|
||||
('8002', 'menu_admin_crontab_log', '执行日志', 'menu_admin_crontab_manage', '/admin/manage/crontab/log', 'admin/manage/crontab/LogManagementView', NULL, 2, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0),
|
||||
('8003', 'menu_admin_news_crawler', '新闻爬虫配置', 'menu_admin_crontab_manage', '/admin/manage/crontab/news-crawler', 'admin/manage/crontab/NewsCrawlerView', NULL, 3, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0),
|
||||
('8004', 'menu_admin_system_task', '系统定时任务配置', 'menu_admin_crontab_manage', '/admin/manage/crontab/system-task', 'admin/manage/crontab/SystemTaskView', NULL, 4, 0, 'SidebarLayout', '1', NULL, '2025-11-25 13:45:00', '2025-11-25 13:45:00', NULL, 0),
|
||||
-- 消息通知模块菜单 (9000-9999)
|
||||
('9001', 'menu_admin_message_manage', '消息管理', NULL, '/admin/manage/message', 'admin/manage/message/MessageManageView', 'admin/notice.svg', 9, 0, 'SidebarLayout', '1', NULL, '2025-11-13 10:00:00', '2025-11-13 10:00:00', NULL, 0),
|
||||
-- 用户端消息中心菜单 (650-699)
|
||||
@@ -238,6 +239,7 @@ INSERT INTO `tb_sys_menu_permission` (id, permission_id, menu_id, creator, creat
|
||||
('233', 'perm_crontab_manage', 'menu_admin_crontab_task', '1', now()),
|
||||
('234', 'perm_crontab_manage', 'menu_admin_crontab_log', '1', now()),
|
||||
('235', 'perm_crontab_manage', 'menu_admin_news_crawler', '1', now()),
|
||||
('252', 'perm_crontab_manage', 'menu_admin_system_task', '1', now()),
|
||||
|
||||
-- 消息通知管理菜单权限关联
|
||||
('240', 'perm_message_manage', 'menu_admin_message_manage', '1', now()),
|
||||
|
||||
@@ -46,7 +46,8 @@ public interface ResourceService {
|
||||
* @author yslg
|
||||
* @since 2025-10-15
|
||||
*/
|
||||
ResultDomain<ResourceVO> getResourcePageOrderByViewCount(TbResource filter, PageParam pageParam);
|
||||
ResultDomain<ResourceVO> getResourcePageOrder(TbResource filter, PageParam pageParam);
|
||||
|
||||
/**
|
||||
* @description 根据ID获取资源详情
|
||||
* @param resourceID 资源ID
|
||||
|
||||
@@ -42,7 +42,7 @@ public class CrontabController {
|
||||
public ResultDomain<TbCrontabTaskMeta> getEnabledCrontabList(@RequestParam(required = false) String param) {
|
||||
try {
|
||||
// 从数据库查询所有任务元数据
|
||||
ResultDomain<TbCrontabTaskMeta> result = taskMetaService.getAllTaskMeta();
|
||||
ResultDomain<TbCrontabTaskMeta> result = taskMetaService.getTaskMetaByCategory(param);
|
||||
result.getDataList().forEach(item->{
|
||||
item.setBeanName("");
|
||||
item.setMethodName("");
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
package org.xyzh.crontab.task.recommendTask;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.xyzh.api.news.recommend.ResourceRecommendService;
|
||||
import org.xyzh.api.news.resource.ResourceService;
|
||||
import org.xyzh.common.core.domain.ResultDomain;
|
||||
import org.xyzh.common.core.page.PageParam;
|
||||
import org.xyzh.common.dto.BaseDTO;
|
||||
import org.xyzh.common.dto.resource.TbResource;
|
||||
import org.xyzh.common.dto.resource.TbResourceRecommend;
|
||||
import org.xyzh.common.utils.IDUtils;
|
||||
import org.xyzh.common.vo.ResourceVO;
|
||||
import org.xyzh.crontab.pojo.TaskParams;
|
||||
import org.xyzh.crontab.task.BaseTask;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @description 热门资源推荐定时任务 - 每天凌晨1点自动更新热门推荐
|
||||
* @filename TopRecommendTask.java
|
||||
* @author yslg
|
||||
* @copyright xyzh
|
||||
* @since 2025-11-25
|
||||
*/
|
||||
@Component("topRecommendTask")
|
||||
public class TopRecommendTask extends BaseTask {
|
||||
|
||||
@Autowired
|
||||
private ResourceService resourceService;
|
||||
|
||||
@Autowired
|
||||
private ResourceRecommendService resourceRecommendService;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
protected void doExecute(TaskParams taskParams) throws Exception {
|
||||
logger.info("开始执行热门资源推荐任务");
|
||||
|
||||
try {
|
||||
// 1. 清除旧的热门推荐(recommend_type = 1)
|
||||
// clearOldRecommends();
|
||||
|
||||
// 2. 获取浏览量前10的资源
|
||||
List<ResourceVO> topViewCountResources = getTopResourcesByViewCount(10);
|
||||
logger.info("获取到浏览量前10的资源数量: {}", topViewCountResources.size());
|
||||
|
||||
// 3. 获取发布时间前10的资源
|
||||
List<ResourceVO> topPublishTimeResources = getTopResourcesByPublishTime(10);
|
||||
logger.info("获取到发布时间前10的资源数量: {}", topPublishTimeResources.size());
|
||||
|
||||
// 4. 合并并去重(使用 Set 确保资源ID唯一)
|
||||
Set<String> resourceIds = new HashSet<>();
|
||||
List<TbResourceRecommend> recommendList = new ArrayList<>();
|
||||
int orderNum = 1;
|
||||
|
||||
// 添加浏览量前10
|
||||
for (ResourceVO vo : topViewCountResources) {
|
||||
if (vo.getResource() != null && resourceIds.add(vo.getResource().getResourceID())) {
|
||||
recommendList.add(createRecommend(vo.getResource().getResourceID(), orderNum++));
|
||||
}
|
||||
}
|
||||
|
||||
// 添加发布时间前10
|
||||
for (ResourceVO vo : topPublishTimeResources) {
|
||||
if (vo.getResource() != null && resourceIds.add(vo.getResource().getResourceID())) {
|
||||
recommendList.add(createRecommend(vo.getResource().getResourceID(), orderNum++));
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 批量插入新推荐
|
||||
if (!recommendList.isEmpty()) {
|
||||
for (TbResourceRecommend recommend : recommendList) {
|
||||
ResultDomain<TbResourceRecommend> addResult = resourceRecommendService.addRecommend(recommend);
|
||||
if (!addResult.isSuccess()) {
|
||||
logger.warn("插入推荐失败: 资源ID={}, 原因={}", recommend.getResourceID(), addResult.getMessage());
|
||||
}
|
||||
}
|
||||
logger.info("成功插入{}条热门推荐记录", recommendList.size());
|
||||
} else {
|
||||
logger.warn("没有找到符合条件的资源,未插入推荐记录");
|
||||
}
|
||||
|
||||
logger.info("热门资源推荐任务执行成功,共推荐{}个资源", resourceIds.size());
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("热门资源推荐任务执行失败: {}", e.getMessage(), e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除旧的热门推荐记录
|
||||
*/
|
||||
private void clearOldRecommends() {
|
||||
logger.info("清除旧的热门推荐记录(recommend_type = 1)");
|
||||
// 暂时跳过清除逻辑,Service层方法待添加
|
||||
// TODO: 实现 deleteRecommendsByType 方法后启用
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取浏览量前N的资源
|
||||
*/
|
||||
private List<ResourceVO> getTopResourcesByViewCount(int limit) {
|
||||
TbResource filter = new TbResource();
|
||||
filter.setStatus(1); // 只查询已发布的资源
|
||||
|
||||
// 设置排序:按浏览量降序
|
||||
List<BaseDTO.OrderType> orderTypes = new ArrayList<>();
|
||||
orderTypes.add(new BaseDTO.OrderType("view_count", "DESC"));
|
||||
orderTypes.add(new BaseDTO.OrderType("publish_time", "DESC"));
|
||||
filter.setOrderTypes(orderTypes);
|
||||
|
||||
PageParam pageParam = new PageParam();
|
||||
pageParam.setPageSize(limit);
|
||||
pageParam.setOffset(0L);
|
||||
|
||||
ResultDomain<ResourceVO> result = resourceService.getResourcePageOrder(filter, pageParam);
|
||||
if (result.isSuccess() && result.getDataList() != null) {
|
||||
return result.getDataList();
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取发布时间前N的资源(最新发布)
|
||||
*/
|
||||
private List<ResourceVO> getTopResourcesByPublishTime(int limit) {
|
||||
TbResource filter = new TbResource();
|
||||
filter.setStatus(1); // 只查询已发布的资源
|
||||
|
||||
// 设置排序:按发布时间降序
|
||||
List<BaseDTO.OrderType> orderTypes = new ArrayList<>();
|
||||
orderTypes.add(new BaseDTO.OrderType("publish_time", "DESC"));
|
||||
orderTypes.add(new BaseDTO.OrderType("create_time", "DESC"));
|
||||
filter.setOrderTypes(orderTypes);
|
||||
|
||||
PageParam pageParam = new PageParam();
|
||||
pageParam.setPageSize(limit);
|
||||
pageParam.setOffset(0L);
|
||||
|
||||
ResultDomain<ResourceVO> result = resourceService.getResourcePageOrder(filter, pageParam);
|
||||
if (result.isSuccess() && result.getDataList() != null) {
|
||||
return result.getDataList();
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建推荐记录
|
||||
*/
|
||||
private TbResourceRecommend createRecommend(String resourceId, int orderNum) {
|
||||
TbResourceRecommend recommend = new TbResourceRecommend();
|
||||
recommend.setID(IDUtils.generateID());
|
||||
recommend.setResourceID(resourceId);
|
||||
recommend.setRecommendType(1); // 1-热门资源推荐
|
||||
recommend.setOrderNum(orderNum);
|
||||
recommend.setCreateTime(new Date());
|
||||
recommend.setUpdateTime(new Date());
|
||||
recommend.setDeleted(false);
|
||||
return recommend;
|
||||
}
|
||||
}
|
||||
@@ -274,7 +274,7 @@
|
||||
AND ct.task_name LIKE CONCAT('%', #{filter.taskName}, '%')
|
||||
</if>
|
||||
<if test="filter.taskGroup != null and filter.taskGroup != ''">
|
||||
AND ct.task_group = #{filter.taskGroup}
|
||||
AND ct.task_group LIKE CONCAT('%', #{filter.taskGroup}, '%')
|
||||
</if>
|
||||
<if test="filter.status != null">
|
||||
AND ct.status = #{filter.status}
|
||||
@@ -337,7 +337,7 @@
|
||||
AND ct.task_name LIKE CONCAT('%', #{filter.taskName}, '%')
|
||||
</if>
|
||||
<if test="filter.taskGroup != null and filter.taskGroup != ''">
|
||||
AND ct.task_group = #{filter.taskGroup}
|
||||
AND ct.task_group LIKE CONCAT('%', #{filter.taskGroup}, '%')
|
||||
</if>
|
||||
<if test="filter.status != null">
|
||||
AND ct.status = #{filter.status}
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
<select id="selectTaskMetaByCategory" resultMap="BaseResultMap">
|
||||
SELECT <include refid="Base_Column_List" />
|
||||
FROM tb_crontab_task_meta
|
||||
WHERE category = #{category}
|
||||
WHERE category LIKE CONCAT('%', #{category}, '%')
|
||||
AND deleted = 0
|
||||
ORDER BY sort_order ASC
|
||||
</select>
|
||||
|
||||
@@ -59,7 +59,7 @@ public class ResourceController {
|
||||
public ResultDomain<ResourceVO> getResourcePageOrderByViewCount(@RequestBody PageRequest<TbResource> request) {
|
||||
TbResource filter = request.getFilter();
|
||||
PageParam pageParam = request.getPageParam();
|
||||
return resourceService.getResourcePageOrderByViewCount(filter, pageParam);
|
||||
return resourceService.getResourcePageOrder(filter, pageParam);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -176,7 +176,7 @@ public interface ResourceMapper extends BaseMapper<TbResource> {
|
||||
* @author yslg
|
||||
* @since 2025-10-15
|
||||
*/
|
||||
List<ResourceVO> selectResourcesPageOrderByViewCount(@Param("filter") TbResource filter, @Param("pageParam") PageParam pageParam, @Param("userDeptRoles") List<UserDeptRoleVO> userDeptRoles);
|
||||
List<ResourceVO> selectResourcesPageOrder(@Param("filter") TbResource filter, @Param("pageParam") PageParam pageParam, @Param("userDeptRoles") List<UserDeptRoleVO> userDeptRoles);
|
||||
|
||||
/**
|
||||
* @description 统计资源总数
|
||||
|
||||
@@ -161,7 +161,7 @@ public class NCResourceServiceImpl implements ResourceService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<ResourceVO> getResourcePageOrderByViewCount(TbResource filter, PageParam pageParam) {
|
||||
public ResultDomain<ResourceVO> getResourcePageOrder(TbResource filter, PageParam pageParam) {
|
||||
ResultDomain<ResourceVO> resultDomain = new ResultDomain<>();
|
||||
try {
|
||||
if (filter == null) {
|
||||
@@ -170,7 +170,7 @@ public class NCResourceServiceImpl implements ResourceService {
|
||||
// 获取当前用户的部门角色
|
||||
List<UserDeptRoleVO> userDeptRoles = LoginUtil.getCurrentDeptRole();
|
||||
// 直接查询ResourceVO列表
|
||||
List<ResourceVO> resourceVOList = resourceMapper.selectResourcesPageOrderByViewCount(filter, pageParam, userDeptRoles);
|
||||
List<ResourceVO> resourceVOList = resourceMapper.selectResourcesPageOrder(filter, pageParam, userDeptRoles);
|
||||
logger.info("资源数量{}",resourceVOList.size());
|
||||
long total = resourceMapper.countResources(filter, userDeptRoles);
|
||||
pageParam.setTotalElements(total);
|
||||
@@ -284,6 +284,7 @@ public class NCResourceServiceImpl implements ResourceService {
|
||||
// 进行审核
|
||||
ResultDomain<String> pass =auditService.auditText(resource.getTitle() + " "+resource.getContent());
|
||||
if(pass.isSuccess()){
|
||||
resource.setPublishTime(new Date());
|
||||
resource.setIsAudited(true);
|
||||
}else {
|
||||
auditService.sendAuditResultMessage(resource.getCreator(), "文章"+resource.getTitle(), pass.getDataList());
|
||||
@@ -509,6 +510,7 @@ public class NCResourceServiceImpl implements ResourceService {
|
||||
ResultDomain<String> pass = auditService.auditText(resource.getTitle()+" "+resource.getContent());
|
||||
if (pass.isSuccess()) {
|
||||
resource.setIsAudited(true);
|
||||
resource.setPublishTime(new Date());
|
||||
} else {
|
||||
// 审核失败,标记状态为4(审核失败)
|
||||
resource.setStatus(4);
|
||||
@@ -562,6 +564,7 @@ public class NCResourceServiceImpl implements ResourceService {
|
||||
ResultDomain<String> pass = auditService.auditText(resource.getTitle()+" "+resource.getContent());
|
||||
if (pass.isSuccess()) {
|
||||
resource.setIsAudited(true);
|
||||
resource.setPublishTime(new Date());
|
||||
} else {
|
||||
// 审核失败,标记状态为3(审核失败)
|
||||
resource.setStatus(3);
|
||||
|
||||
@@ -378,7 +378,7 @@
|
||||
</association>
|
||||
</resultMap>
|
||||
|
||||
<select id="selectResourcesPageOrderByViewCount" resultMap="ResourceVOResultMap">
|
||||
<select id="selectResourcesPageOrder" resultMap="ResourceVOResultMap">
|
||||
SELECT
|
||||
r.*,
|
||||
MAX(CASE WHEN rec.recommend_type = 1 THEN 1 ELSE 0 END) AS is_top_recommend,
|
||||
|
||||
Reference in New Issue
Block a user