From d568781ce942f617ce6309e9c1704c2cf0254b9e Mon Sep 17 00:00:00 2001 From: wangys <3401275564@qq.com> Date: Wed, 19 Nov 2025 15:11:30 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AF=BE=E7=A8=8B=E3=80=81=E6=96=87=E7=AB=A0?= =?UTF-8?q?=E5=AE=A1=E6=A0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../.bin/mysql/sql/createTableCourse.sql | 1 + .../.bin/mysql/sql/createTableCrontab.sql | 1 + .../.bin/mysql/sql/createTableResource.sql | 1 + .../news/resource/ResourceAuditService.java | 25 ++++++ .../dto/crontab/TbDataCollectionItem.java | 13 ++++ .../xyzh/common/dto/resource/TbResource.java | 15 ++++ .../xyzh/common/dto/study/TbCourseNode.java | 11 +++ .../xyzh/common/vo/DataCollectionItemVO.java | 13 ++++ .../task/newsTask/NewsCrawlerTask.java | 76 +++++++++++++------ .../mapper/DataCollectionItemMapper.xml | 5 +- .../service/impl/NCResourceServiceImpl.java | 54 +++++++++++-- .../impl/ResourceAuditServiceImpl.java | 34 +++++++++ .../main/resources/mapper/ResourceMapper.xml | 17 +++-- schoolNewsServ/study/pom.xml | 5 ++ .../xyzh/study/mapper/CourseNodeMapper.java | 4 + .../service/impl/SCCourseServiceImpl.java | 73 ++++++++++++++++++ .../resources/mapper/CourseNodeMapper.xml | 55 ++++++++++---- schoolNewsWeb/src/types/crontab/index.ts | 1 + schoolNewsWeb/src/types/enums/index.ts | 12 ++- schoolNewsWeb/src/types/resource/index.ts | 1 + schoolNewsWeb/src/types/study/index.ts | 1 + .../manage/resource/ArticleManagementView.vue | 10 ++- .../public/article/components/ArticleAdd.vue | 10 ++- .../public/course/components/CourseList.vue | 6 +- 24 files changed, 379 insertions(+), 65 deletions(-) create mode 100644 schoolNewsServ/api/api-news/src/main/java/org/xyzh/api/news/resource/ResourceAuditService.java create mode 100644 schoolNewsServ/news/src/main/java/org/xyzh/news/service/impl/ResourceAuditServiceImpl.java diff --git a/schoolNewsServ/.bin/mysql/sql/createTableCourse.sql b/schoolNewsServ/.bin/mysql/sql/createTableCourse.sql index 42829fd..dde00b8 100644 --- a/schoolNewsServ/.bin/mysql/sql/createTableCourse.sql +++ b/schoolNewsServ/.bin/mysql/sql/createTableCourse.sql @@ -84,6 +84,7 @@ CREATE TABLE `tb_course_node` ( `duration` INT(11) DEFAULT 0 COMMENT '节点时长(分钟)', `order_num` INT(4) DEFAULT 0 COMMENT '排序号', `is_required` TINYINT(1) DEFAULT 1 COMMENT '是否必修(1必修 0选修)', + `is_audited` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否已审核', `creator` VARCHAR(50) DEFAULT NULL COMMENT '创建者', `updater` VARCHAR(50) DEFAULT NULL COMMENT '更新者', `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', diff --git a/schoolNewsServ/.bin/mysql/sql/createTableCrontab.sql b/schoolNewsServ/.bin/mysql/sql/createTableCrontab.sql index dd9ddb5..cc8f900 100644 --- a/schoolNewsServ/.bin/mysql/sql/createTableCrontab.sql +++ b/schoolNewsServ/.bin/mysql/sql/createTableCrontab.sql @@ -80,6 +80,7 @@ CREATE TABLE `tb_data_collection_item` ( `images` TEXT DEFAULT NULL COMMENT '图片列表(JSON)', `tags` VARCHAR(500) DEFAULT NULL COMMENT '标签(逗号分隔)', `status` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '状态(0未处理 1已转换为资源 2已忽略)', + `is_audited` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否已审核', `execute_status` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '执行状态(0未执行 1已执行)', `execute_message` TEXT DEFAULT NULL COMMENT '执行结果信息', `resource_id` VARCHAR(64) DEFAULT NULL COMMENT '转换后的资源ID', diff --git a/schoolNewsServ/.bin/mysql/sql/createTableResource.sql b/schoolNewsServ/.bin/mysql/sql/createTableResource.sql index ab4458d..c18b9f5 100644 --- a/schoolNewsServ/.bin/mysql/sql/createTableResource.sql +++ b/schoolNewsServ/.bin/mysql/sql/createTableResource.sql @@ -16,6 +16,7 @@ CREATE TABLE `tb_resource` ( `like_count` INT(11) DEFAULT 0 COMMENT '点赞次数', `collect_count` INT(11) DEFAULT 0 COMMENT '收藏次数', `status` INT(4) DEFAULT 0 COMMENT '状态(0草稿 1已发布 2下架)', + `is_audited` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否已审核', `is_recommend` TINYINT(1) DEFAULT 0 COMMENT '是否推荐', `is_banner` TINYINT(1) DEFAULT 0 COMMENT '是否轮播', `publish_time` TIMESTAMP NULL DEFAULT NULL COMMENT '发布时间', diff --git a/schoolNewsServ/api/api-news/src/main/java/org/xyzh/api/news/resource/ResourceAuditService.java b/schoolNewsServ/api/api-news/src/main/java/org/xyzh/api/news/resource/ResourceAuditService.java new file mode 100644 index 0000000..2c63e7b --- /dev/null +++ b/schoolNewsServ/api/api-news/src/main/java/org/xyzh/api/news/resource/ResourceAuditService.java @@ -0,0 +1,25 @@ +package org.xyzh.api.news.resource; + +import org.xyzh.common.core.domain.ResultDomain; + +/** + * @description 资源审核服务接口 + * @filename ResourceAuditService.java + * @author yslg + */ +public interface ResourceAuditService { + + /** + * 文本内容审核 + * @param text 待审核文本 + * @return ResultDomain 审核结果(true 表示通过) + */ + ResultDomain auditText(String text); + + /** + * 根据文件ID进行审核(fileId 对应 tb_sys_file.id) + * @param fileId 文件ID + * @return ResultDomain 审核结果(true 表示通过) + */ + ResultDomain auditByFileId(String fileId); +} diff --git a/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/dto/crontab/TbDataCollectionItem.java b/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/dto/crontab/TbDataCollectionItem.java index b804d2c..29db79d 100644 --- a/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/dto/crontab/TbDataCollectionItem.java +++ b/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/dto/crontab/TbDataCollectionItem.java @@ -114,6 +114,19 @@ public class TbDataCollectionItem extends BaseDTO { * @description 单条新闻执行消息(记录错误信息或成功提示) */ private String executeMessage; + + /** + * @description 是否已审核 + */ + private Boolean isAudited; + + public Boolean getIsAudited() { + return isAudited; + } + + public void setIsAudited(Boolean isAudited) { + this.isAudited = isAudited; + } public String getTaskId() { return taskId; diff --git a/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/dto/resource/TbResource.java b/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/dto/resource/TbResource.java index 8c41f2c..fbfcae2 100644 --- a/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/dto/resource/TbResource.java +++ b/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/dto/resource/TbResource.java @@ -84,6 +84,11 @@ public class TbResource extends BaseDTO { */ private Boolean isRecommend; + /** + * @description 是否已审核 + */ + private Boolean isAudited; + /** * @description 是否轮播 */ @@ -176,6 +181,16 @@ public class TbResource extends BaseDTO { this.sourceUrl = sourceUrl; } + + + public Boolean getIsAudited() { + return isAudited; + } + + public void setIsAudited(Boolean isAudited) { + this.isAudited = isAudited; + } + public Integer getViewCount() { return viewCount; } diff --git a/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/dto/study/TbCourseNode.java b/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/dto/study/TbCourseNode.java index 321aae0..2f87b01 100644 --- a/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/dto/study/TbCourseNode.java +++ b/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/dto/study/TbCourseNode.java @@ -85,7 +85,18 @@ public class TbCourseNode extends BaseDTO { * @description 是否删除 */ private Boolean deleted; + /** + * @description 是否已审核 + */ + private Boolean isAudited; + public Boolean getIsAudited() { + return isAudited; + } + + public void setIsAudited(Boolean isAudited) { + this.isAudited = isAudited; + } public String getNodeID() { return nodeID; } diff --git a/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/vo/DataCollectionItemVO.java b/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/vo/DataCollectionItemVO.java index 364d2ed..9ef31e9 100644 --- a/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/vo/DataCollectionItemVO.java +++ b/schoolNewsServ/common/common-dto/src/main/java/org/xyzh/common/vo/DataCollectionItemVO.java @@ -91,6 +91,11 @@ public class DataCollectionItemVO implements Serializable { */ private Integer status; + /** + * 是否已审核 + */ + private Boolean isAudited; + /** * 转换后的资源ID */ @@ -194,6 +199,14 @@ public class DataCollectionItemVO implements Serializable { // ==================== Getter/Setter ==================== + public Boolean getIsAudited() { + return isAudited; + } + + public void setIsAudited(Boolean isAudited) { + this.isAudited = isAudited; + } + public String getId() { return id; } diff --git a/schoolNewsServ/crontab/src/main/java/org/xyzh/crontab/task/newsTask/NewsCrawlerTask.java b/schoolNewsServ/crontab/src/main/java/org/xyzh/crontab/task/newsTask/NewsCrawlerTask.java index 36a6e68..d36d7ba 100644 --- a/schoolNewsServ/crontab/src/main/java/org/xyzh/crontab/task/newsTask/NewsCrawlerTask.java +++ b/schoolNewsServ/crontab/src/main/java/org/xyzh/crontab/task/newsTask/NewsCrawlerTask.java @@ -9,6 +9,7 @@ import org.xyzh.api.crontab.DataCollectionItemService; import org.xyzh.api.crontab.EmailDefaultService; import org.xyzh.api.crontab.EmailRecipientService; import org.xyzh.api.crontab.TaskMetaService; +import org.xyzh.api.news.resource.ResourceAuditService; import org.xyzh.api.news.resource.ResourceService; import org.xyzh.api.system.role.RoleService; import org.xyzh.common.core.domain.ResultDomain; @@ -65,6 +66,9 @@ public class NewsCrawlerTask extends PythonCommandTask { @Autowired private EmailRecipientService emailRecipientService; + + @Autowired + private ResourceAuditService auditService; @Autowired private EmailUtils emailUtils; @@ -196,7 +200,6 @@ public class NewsCrawlerTask extends PythonCommandTask { logger.info("开始保存 {} 条新闻到数据库,任务ID: {},日志ID: {}", newsList.size(), taskId, logId); try { - List itemList = new ArrayList<>(); ResultDomain metaResult = taskMetaService.getTaskMetaByTaskId(taskId); if (!metaResult.isSuccess() || metaResult.getData() == null) { throw new Exception("未找到任务元数据: taskId=" + taskId); @@ -206,7 +209,9 @@ public class NewsCrawlerTask extends PythonCommandTask { Date now = new Date(); SimpleDateFormat parser = new SimpleDateFormat("yyyy年MM月dd日HH:mm"); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - + List itemList = new ArrayList<>(); + List notPassList = new ArrayList<>(); + List passList = new ArrayList<>(); for (ArticleStruct news : newsList) { try { TbDataCollectionItem item = new TbDataCollectionItem(); @@ -260,7 +265,14 @@ public class NewsCrawlerTask extends PythonCommandTask { // 状态和时间 item.setStatus(0); // 未处理 item.setCrawlTime(now); - + ResultDomain pass = auditService.auditText(item.getContent()); + if(pass.isSuccess() && pass.getData()){ + item.setIsAudited(true); + passList.add(item); + }else{ + item.setIsAudited(false); + notPassList.add(item); + } itemList.add(item); } catch (Exception e) { logger.error("转换新闻数据失败: ", e); @@ -269,26 +281,40 @@ public class NewsCrawlerTask extends PythonCommandTask { // 批量保存 Set insertedUrls = new HashSet<>(); - ResultDomain dataResult = new ResultDomain<>(); - if (!itemList.isEmpty()) { - dataResult = itemService.batchCreateItems(itemList); - if (dataResult.isSuccess()) { - logger.info("成功保存 {} 条新闻到数据库", itemList.size()); - insertedUrls.addAll(dataResult.getDataList().stream().map(TbDataCollectionItem::getSourceUrl).toList()); + ResultDomain passDataResult = new ResultDomain<>(); + if (!passList.isEmpty()) { + passDataResult = itemService.batchCreateItems(passList); + if (passDataResult.isSuccess()) { + logger.info("成功保存 {} 条新闻到数据库", passList.size()); + insertedUrls.addAll(passDataResult.getDataList().stream().map(TbDataCollectionItem::getSourceUrl).toList()); } else { - logger.error("保存新闻到数据库失败: {}", dataResult.getMessage()); + logger.error("保存新闻到数据库失败: {}", passDataResult.getMessage()); } } else { logger.warn("没有有效的新闻数据需要保存"); } + ResultDomain notPassDataResult = new ResultDomain<>(); + if (!notPassList.isEmpty()) { + notPassDataResult = itemService.batchCreateItems(notPassList); + if (notPassDataResult.isSuccess()) { + logger.info("成功保存 {} 条新闻到数据库", notPassList.size()); + insertedUrls.addAll(notPassDataResult.getDataList().stream().map(TbDataCollectionItem::getSourceUrl).toList()); + } else { + logger.error("保存新闻到数据库失败: {}", notPassDataResult.getMessage()); + } + } else { + logger.warn("没有有效的新闻数据需要保存"); + } + // 自动发布并记录成功发布的 URL 集合 Set publishedUrls = new HashSet<>(); if (taskMeta.getAutoPublish().booleanValue()){ - publishedUrls = publishNewsToArticle(dataResult.getDataList(), task, logId); + publishedUrls = publishNewsToArticle(passDataResult.getDataList(), task, logId); } + Set notPathUrls = new HashSet<>(notPassList.stream().map(TbDataCollectionItem::getSourceUrl).toList()); // 发送邮件通知,包含自动发布与新增信息 - sendEmailNotification(task.getTaskId(), task, newsList, insertedUrls, publishedUrls); + sendEmailNotification(task.getTaskId(), task, newsList, insertedUrls, publishedUrls, notPathUrls); } catch (Exception e) { logger.error("保存新闻数据到数据库异常: ", e); @@ -300,7 +326,9 @@ public class NewsCrawlerTask extends PythonCommandTask { */ private void sendEmailNotification(String taskId, TbCrontabTask task, List newsList, Set insertedUrls, - Set publishedUrls) { + Set publishedUrls, + Set notPassUrls + ) { try { List recipients = new ArrayList<>(); @@ -336,7 +364,7 @@ public class NewsCrawlerTask extends PythonCommandTask { // 5. 构建邮件内容 String subject = "【新闻爬虫通知】" + task.getTaskName() + " 执行完成"; - String content = buildEmailContent(task.getTaskName(), newsList, insertedUrls, publishedUrls); + String content = buildEmailContent(task.getTaskName(), newsList, insertedUrls, publishedUrls, notPassUrls); // 6. 发送邮件 int successCount = 0; @@ -357,8 +385,9 @@ public class NewsCrawlerTask extends PythonCommandTask { * 构建邮件HTML内容 */ private String buildEmailContent(String taskName, List newsList, - java.util.Set insertedUrls, - java.util.Set publishedUrls) { + Set insertedUrls, + Set publishedUrls, + Set notPathUrls) { StringBuilder html = new StringBuilder(); html.append("") .append("") @@ -416,6 +445,7 @@ public class NewsCrawlerTask extends PythonCommandTask { html.append(" | 查看原文"); } + // 入库标记(新增 / 历史已存在) if (news.getUrl() != null && !news.getUrl().isEmpty() && insertedUrls != null) { if (insertedUrls.contains(news.getUrl())) { @@ -425,6 +455,12 @@ public class NewsCrawlerTask extends PythonCommandTask { } } + // 如果该未审核通过,追加标记 + if (notPathUrls != null && !notPathUrls.isEmpty() + && news.getUrl() != null && notPathUrls.contains(news.getUrl())) { + html.append(" | 【未通过审核】"); + } + // 如果该新闻已自动发布,追加标记 if (publishedUrls != null && !publishedUrls.isEmpty() && news.getUrl() != null && publishedUrls.contains(news.getUrl())) { @@ -435,12 +471,6 @@ public class NewsCrawlerTask extends PythonCommandTask { .append(""); } - if (newsList.size() > 10) { - html.append("

") - .append("还有 ").append(newsList.size() - 10).append(" 条新闻未显示,请登录系统查看详情") - .append("

"); - } - html.append(""); // news-list html.append(""); // content @@ -498,7 +528,7 @@ public class NewsCrawlerTask extends PythonCommandTask { resource.setAuthor(item.getAuthor()); resource.setSource(item.getSource()); resource.setSourceUrl(item.getSourceUrl()); - + resource.setIsAudited(true); // 发布时间:优先使用采集表中的时间 Date publishTime = item.getPublishTime() != null ? item.getPublishTime() : now; resource.setPublishTime(publishTime); diff --git a/schoolNewsServ/crontab/src/main/resources/mapper/DataCollectionItemMapper.xml b/schoolNewsServ/crontab/src/main/resources/mapper/DataCollectionItemMapper.xml index ea3bef2..ae11a22 100644 --- a/schoolNewsServ/crontab/src/main/resources/mapper/DataCollectionItemMapper.xml +++ b/schoolNewsServ/crontab/src/main/resources/mapper/DataCollectionItemMapper.xml @@ -21,6 +21,7 @@ + @@ -51,6 +52,7 @@ + @@ -77,7 +79,7 @@ id, task_id, log_id, title, content, summary, source, source_url, category, author, - publish_time, cover_image, images, tags, status, resource_id, crawl_time, process_time, + publish_time, cover_image, images, tags, status, is_audited, resource_id, crawl_time, process_time, processor, execute_status, execute_message, create_time, update_time, delete_time, deleted @@ -98,6 +100,7 @@ i.images, i.tags, i.status, + i.is_audited, i.resource_id, i.crawl_time, i.process_time, diff --git a/schoolNewsServ/news/src/main/java/org/xyzh/news/service/impl/NCResourceServiceImpl.java b/schoolNewsServ/news/src/main/java/org/xyzh/news/service/impl/NCResourceServiceImpl.java index 0ee9201..45640de 100644 --- a/schoolNewsServ/news/src/main/java/org/xyzh/news/service/impl/NCResourceServiceImpl.java +++ b/schoolNewsServ/news/src/main/java/org/xyzh/news/service/impl/NCResourceServiceImpl.java @@ -22,6 +22,7 @@ import org.xyzh.common.vo.TaskItemVO; import org.xyzh.news.mapper.ResourceMapper; import org.xyzh.news.mapper.ResourceTagMapper; import org.xyzh.system.utils.LoginUtil; +import org.xyzh.api.news.resource.ResourceAuditService; import org.xyzh.api.news.resource.ResourceService; import org.xyzh.api.system.permission.ResourcePermissionService; import org.xyzh.common.vo.UserDeptRoleVO; @@ -54,6 +55,9 @@ public class NCResourceServiceImpl implements ResourceService { @Autowired private ResourcePermissionService resourcePermissionService; + @Autowired + private ResourceAuditService auditService; + @Override public ResultDomain getResourceList(TbResource filter) { ResultDomain resultDomain = new ResultDomain<>(); @@ -256,6 +260,9 @@ public class NCResourceServiceImpl implements ResourceService { if (resourceVO.getResource().getStatus() == null) { resourceVO.getResource().setStatus(0); // 默认草稿状态 } + if (resourceVO.getResource().getIsAudited() == null) { + resourceVO.getResource().setIsAudited(false); // 默认草稿状态 + } if (resourceVO.getResource().getViewCount() == null) { resourceVO.getResource().setViewCount(0); } @@ -271,6 +278,14 @@ public class NCResourceServiceImpl implements ResourceService { if (resourceVO.getResource().getIsBanner() == null) { resourceVO.getResource().setIsBanner(false); } + TbResource resource = resourceVO.getResource(); + if(resource.getStatus()==1 && !resource.getIsAudited()){ + // 进行审核 + ResultDomain pass =auditService.auditText(resource.getContent()); + if(pass.isSuccess() && pass.getData()){ + resource.setIsAudited(true); + } + } // 插入数据库 int result = resourceMapper.insertResource(resourceVO.getResource()); @@ -345,14 +360,9 @@ public class NCResourceServiceImpl implements ResourceService { return resultDomain; } - // 如果修改了标题,检查标题是否已被使用 - if (StringUtils.hasText(resource.getTitle()) && !resource.getTitle().equals(existing.getTitle())) { - List userDeptRoles = LoginUtil.getCurrentDeptRole(); - int count = resourceMapper.countByTitle(resource.getTitle(), resource.getResourceID(), userDeptRoles); - if (count > 0) { - resultDomain.fail("资源标题已存在"); - return resultDomain; - } + resource.setIsAudited(existing.getIsAudited()); + if(!existing.getContent().equals(resource.getContent())){ + resource.setIsAudited(false); } Date now = new Date(); // tag先删后增 @@ -447,7 +457,20 @@ public class NCResourceServiceImpl implements ResourceService { resultDomain.fail("资源不存在"); return resultDomain; } + if (status == 1 && !resource.getIsAudited()) { + ResultDomain pass = auditService.auditText(resource.getContent()); + if (pass.isSuccess() && pass.getData()) { + resource.setIsAudited(true); + } else { + // 审核失败,标记状态为3(审核失败) + resource.setStatus(3); + resource.setUpdateTime(new Date()); + resourceMapper.updateResource(resource); + resultDomain.fail("审核失败"); + return resultDomain; + } + } // 更新状态 resource.setStatus(status); resource.setUpdateTime(new Date()); @@ -488,6 +511,21 @@ public class NCResourceServiceImpl implements ResourceService { return resultDomain; } + if (!resource.getIsAudited()) { + ResultDomain pass = auditService.auditText(resource.getContent()); + if (pass.isSuccess() && pass.getData()) { + resource.setIsAudited(true); + } else { + // 审核失败,标记状态为3(审核失败) + resource.setStatus(3); + resource.setUpdateTime(new Date()); + resourceMapper.updateResource(resource); + + resultDomain.fail("审核失败"); + return resultDomain; + } + } + // 更新状态为已发布 resource.setStatus(1); resource.setPublishTime(new Date()); diff --git a/schoolNewsServ/news/src/main/java/org/xyzh/news/service/impl/ResourceAuditServiceImpl.java b/schoolNewsServ/news/src/main/java/org/xyzh/news/service/impl/ResourceAuditServiceImpl.java new file mode 100644 index 0000000..776a30f --- /dev/null +++ b/schoolNewsServ/news/src/main/java/org/xyzh/news/service/impl/ResourceAuditServiceImpl.java @@ -0,0 +1,34 @@ +package org.xyzh.news.service.impl; + +import org.springframework.stereotype.Service; +import org.xyzh.api.news.resource.ResourceAuditService; +import org.xyzh.common.core.domain.ResultDomain; + +/** + * @description 资源审核服务实现类 + * @filename ResourceAuditServiceImpl.java + */ +@Service +public class ResourceAuditServiceImpl implements ResourceAuditService { + + @Override + public ResultDomain auditText(String text) { + ResultDomain result = new ResultDomain(); + // TODO: 文本审核逻辑(敏感词、违规词等规则校验) + // 示例:直接通过 + result.success("审核通过", Boolean.TRUE); + return result; + } + + @Override + public ResultDomain auditByFileId(String fileId) { + ResultDomain result = new ResultDomain(); + // TODO: + // 1. 根据 tb_sys_file.id 查询文件信息 + // 2. 读取文件内容,提取文本 + // 3. 调用 auditText(text) 进行审核 + // 4. 审核通过后,更新对应业务记录(tb_resource / tb_data_collection_item / tb_course_node) 的 is_audited = 1 + result.success("审核通过", Boolean.TRUE); + return result; + } +} diff --git a/schoolNewsServ/news/src/main/resources/mapper/ResourceMapper.xml b/schoolNewsServ/news/src/main/resources/mapper/ResourceMapper.xml index ffaff9c..ec08000 100644 --- a/schoolNewsServ/news/src/main/resources/mapper/ResourceMapper.xml +++ b/schoolNewsServ/news/src/main/resources/mapper/ResourceMapper.xml @@ -18,6 +18,7 @@ + @@ -32,7 +33,7 @@ id, resource_id, title, content, summary, cover_image, tag_id, author, source, - source_url, view_count, like_count, collect_count, status, is_recommend, + source_url, view_count, like_count, collect_count, status, is_audited, is_recommend, is_banner, publish_time, creator, updater, create_time, update_time, delete_time, deleted @@ -205,10 +206,10 @@ INSERT INTO tb_resource ( - id, resource_id, title, content, summary, cover_image, tag_id, author, source, + id, resource_id, title, content, summary, cover_image, tag_id, author, source, is_audited, source_url, creator,create_time ) VALUES ( - #{id}, #{resourceID}, #{title}, #{content}, #{summary}, #{coverImage}, #{tagID}, #{author}, #{source}, + #{id}, #{resourceID}, #{title}, #{content}, #{summary}, #{coverImage}, #{tagID}, #{author}, #{source}, #{isAudited}, #{sourceUrl}, #{creator}, #{createTime} ) @@ -259,6 +260,9 @@ is_banner = #{isBanner}, + + is_audited = #{isAudited}, + publish_time = #{publishTime}, @@ -287,14 +291,14 @@ INSERT INTO tb_resource ( - id, resource_id, title, content, summary, cover_image, tag_id, author, source, - source_url, status, is_recommend, is_banner, publish_time, + id, resource_id, title, content, summary, cover_image, tag_id, author, is_audited, + source, source_url, status, is_recommend, is_banner, publish_time, creator, updater, create_time, update_time, deleted ) VALUES ( #{item.id}, #{item.resourceID}, #{item.title}, #{item.content}, #{item.summary}, #{item.coverImage}, - #{item.tagID}, #{item.author}, #{item.source}, #{item.sourceUrl}, + #{item.tagID}, #{item.author}, #{item.isAudited}, #{item.source}, #{item.sourceUrl}, #{item.status}, #{item.isRecommend}, #{item.isBanner}, #{item.publishTime}, #{item.creator}, #{item.updater}, #{item.createTime}, #{item.updateTime}, #{item.deleted} ) @@ -360,6 +364,7 @@ + diff --git a/schoolNewsServ/study/pom.xml b/schoolNewsServ/study/pom.xml index b81a823..a5c45dc 100644 --- a/schoolNewsServ/study/pom.xml +++ b/schoolNewsServ/study/pom.xml @@ -27,6 +27,11 @@ api-study 1.0.0 + + org.xyzh + api-new + 1.0.0 + org.xyzh system diff --git a/schoolNewsServ/study/src/main/java/org/xyzh/study/mapper/CourseNodeMapper.java b/schoolNewsServ/study/src/main/java/org/xyzh/study/mapper/CourseNodeMapper.java index a33b5b1..2f8d60b 100644 --- a/schoolNewsServ/study/src/main/java/org/xyzh/study/mapper/CourseNodeMapper.java +++ b/schoolNewsServ/study/src/main/java/org/xyzh/study/mapper/CourseNodeMapper.java @@ -64,6 +64,8 @@ public interface CourseNodeMapper extends BaseMapper { */ List selectByChapterId(@Param("chapterId") String chapterId); + List selectByCourseId(@Param("courseId")String courseId); + /** * @description 根据节点名称查询节点 * @param name 节点名称 @@ -146,6 +148,8 @@ public interface CourseNodeMapper extends BaseMapper { */ int batchDeleteCourseNodes(@Param("nodeIDs") List nodeIDs); + int batchUpdateNodeAudited(@Param("courseNodeList")List nodeList); + /** * @description 根据章节ID批量删除节点 * @param chapterId 章节ID diff --git a/schoolNewsServ/study/src/main/java/org/xyzh/study/service/impl/SCCourseServiceImpl.java b/schoolNewsServ/study/src/main/java/org/xyzh/study/service/impl/SCCourseServiceImpl.java index d9aac3c..58d41a9 100644 --- a/schoolNewsServ/study/src/main/java/org/xyzh/study/service/impl/SCCourseServiceImpl.java +++ b/schoolNewsServ/study/src/main/java/org/xyzh/study/service/impl/SCCourseServiceImpl.java @@ -13,21 +13,26 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; 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.study.TbCourse; import org.xyzh.common.dto.study.TbCourseChapter; import org.xyzh.common.dto.study.TbCourseNode; import org.xyzh.common.dto.user.TbSysUser; import org.xyzh.common.utils.IDUtils; import org.xyzh.common.vo.CourseItemVO; +import org.xyzh.common.vo.ResourceVO; import org.xyzh.study.mapper.CourseMapper; import org.xyzh.study.mapper.CourseChapterMapper; import org.xyzh.study.mapper.CourseNodeMapper; import org.xyzh.study.service.SCCourseService; import org.xyzh.system.utils.LoginUtil; +import org.xyzh.api.news.resource.ResourceAuditService; +import org.xyzh.api.news.resource.ResourceService; import org.xyzh.api.system.permission.ResourcePermissionService; import org.xyzh.common.vo.UserDeptRoleVO; import org.xyzh.common.core.enums.ResourceType; @@ -53,6 +58,12 @@ public class SCCourseServiceImpl implements SCCourseService { @Autowired private CourseNodeMapper courseNodeMapper; + @Autowired + private ResourceAuditService auditService; + + @Autowired + private ResourceService resourceService; + @Autowired private ResourcePermissionService resourcePermissionService; @@ -414,8 +425,70 @@ public class SCCourseServiceImpl implements SCCourseService { } @Override + @Transactional public ResultDomain updateCourseStatus(TbCourse course) { ResultDomain resultDomain = new ResultDomain<>(); + if(course.getStatus()==1){ // 发布前审核 + // 获取所有课程节点 + List nodeList = courseNodeMapper.selectByCourseId(course.getCourseID()); + List notPassList = new ArrayList<>(); + for(TbCourseNode node: nodeList){ + if(!node.getIsAudited()){ + // 重新审核 + int type = node.getNodeType(); + // auditService. + if(type==1){ //文章类型 + ResultDomain resourceDomain = resourceService.getResourceById(node.getResourceID()); + if (resourceDomain.isSuccess()) { + if (!resourceDomain.getData().getResource().getIsAudited()) { + ResultDomain pass = auditService.auditText(resourceDomain.getData().getResource().getContent()); + if(!pass.isSuccess() || !pass.getData()){ + // 审核失败,标记课程状态为3(审核失败) + course.setStatus(3); + course.setUpdateTime(new Date()); + courseMapper.updateCourse(course); + + resultDomain.fail("课程节点:"+node.getName()+"审核未通过"); + return resultDomain; + } + } + } + }else if (type == 2){ + ResultDomain pass = auditService.auditByFileId(node.getResourceID()); + if(!pass.isSuccess() || !pass.getData()){ + // 审核失败,标记课程状态为3(审核失败) + course.setStatus(3); + course.setUpdateTime(new Date()); + courseMapper.updateCourse(course); + + resultDomain.fail("课程节点:"+node.getName()+"审核未通过"); + return resultDomain; + } + }else{ + ResultDomain pass = auditService.auditText(node.getContent()); + if(!pass.isSuccess() || !pass.getData()){ + // 审核失败,标记课程状态为3(审核失败) + course.setStatus(3); + course.setUpdateTime(new Date()); + courseMapper.updateCourse(course); + + resultDomain.fail("课程节点:"+node.getName()+"审核未通过"); + return resultDomain; + } + } + node.setIsAudited(true); + notPassList.add(node); + } + } + if(!notPassList.isEmpty()){ + int i = courseNodeMapper.batchUpdateNodeAudited(notPassList); + if(i<=0){ + resultDomain.fail("课程节点审核状态更新失败"); + return resultDomain; + } + } + + } int result = courseMapper.updateCourse(course); if (result > 0) { resultDomain.success("更新课程状态成功", course); diff --git a/schoolNewsServ/study/src/main/resources/mapper/CourseNodeMapper.xml b/schoolNewsServ/study/src/main/resources/mapper/CourseNodeMapper.xml index c3afcb5..bf1d0cb 100644 --- a/schoolNewsServ/study/src/main/resources/mapper/CourseNodeMapper.xml +++ b/schoolNewsServ/study/src/main/resources/mapper/CourseNodeMapper.xml @@ -15,6 +15,7 @@ + @@ -46,7 +47,7 @@ - id, node_id, chapter_id, name, content, node_type, resource_id, video_url, duration, order_num, is_required, + id, node_id, chapter_id, name, content, node_type, resource_id, video_url, duration, order_num, is_required, is_audited, creator, updater, create_time, update_time, delete_time, deleted @@ -98,6 +99,20 @@ ORDER BY order_num ASC, create_time ASC + + +
@@ -65,7 +66,8 @@ @@ -75,7 +77,7 @@ 编辑