resultMap修正
This commit is contained in:
@@ -430,6 +430,8 @@ class XxqgCrawler(BaseCrawler):
|
|||||||
if is_page():
|
if is_page():
|
||||||
pass
|
pass
|
||||||
logger.info(f"解析文章详情完成: {news_item.url}")
|
logger.info(f"解析文章详情完成: {news_item.url}")
|
||||||
|
if news_item.contentRows:
|
||||||
|
news_item.executeStatus = 1
|
||||||
return news_item
|
return news_item
|
||||||
|
|
||||||
|
|
||||||
@@ -586,7 +588,7 @@ class XxqgCrawler(BaseCrawler):
|
|||||||
# json.dump([item.model_dump() for item in resultDomain.dataList] if resultDomain.dataList else [], f, ensure_ascii=False, indent=4)
|
# json.dump([item.model_dump() for item in resultDomain.dataList] if resultDomain.dataList else [], f, ensure_ascii=False, indent=4)
|
||||||
return resultDomain
|
return resultDomain
|
||||||
|
|
||||||
def crawl_base(self, config: CrawlerConfig, yesterday=True, start:Optional[str]=None, end:Optional[str]=None) -> ResultDomain:
|
def crawl_base(self, config: UrlConfig, yesterday=True, start:Optional[str]=None, end:Optional[str]=None) -> ResultDomain:
|
||||||
news_list = []
|
news_list = []
|
||||||
resultDomain = ResultDomain(code=0, message="", success=True, dataList=news_list)
|
resultDomain = ResultDomain(code=0, message="", success=True, dataList=news_list)
|
||||||
|
|
||||||
@@ -616,7 +618,7 @@ class XxqgCrawler(BaseCrawler):
|
|||||||
time.sleep(3) # 等待所有请求完成
|
time.sleep(3) # 等待所有请求完成
|
||||||
request_list = self.driver.requests
|
request_list = self.driver.requests
|
||||||
json_request = []
|
json_request = []
|
||||||
target_path = config.params.get("path")
|
target_path = config.params.get("path", "")
|
||||||
target_request = None
|
target_request = None
|
||||||
logger.info(f"开始查找目标JSON请求,共有 {len(request_list)} 个请求")
|
logger.info(f"开始查找目标JSON请求,共有 {len(request_list)} 个请求")
|
||||||
|
|
||||||
|
|||||||
@@ -101,24 +101,31 @@
|
|||||||
<!-- MyBatis Mapper 日志配置 - 打印SQL -->
|
<!-- MyBatis Mapper 日志配置 - 打印SQL -->
|
||||||
<Logger name="org.xyzh.achievement.mapper" level="debug" additivity="false">
|
<Logger name="org.xyzh.achievement.mapper" level="debug" additivity="false">
|
||||||
<AppenderRef ref="Console"/>
|
<AppenderRef ref="Console"/>
|
||||||
|
<AppenderRef ref="Filelog"/>
|
||||||
</Logger>
|
</Logger>
|
||||||
<Logger name="org.xyzh.ai.mapper" level="debug" additivity="false">
|
<Logger name="org.xyzh.ai.mapper" level="debug" additivity="false">
|
||||||
<AppenderRef ref="Console"/>
|
<AppenderRef ref="Console"/>
|
||||||
|
<AppenderRef ref="Filelog"/>
|
||||||
</Logger>
|
</Logger>
|
||||||
<Logger name="org.xyzh.system.mapper" level="debug" additivity="false">
|
<Logger name="org.xyzh.system.mapper" level="debug" additivity="false">
|
||||||
<AppenderRef ref="Console"/>
|
<AppenderRef ref="Console"/>
|
||||||
|
<AppenderRef ref="Filelog"/>
|
||||||
</Logger>
|
</Logger>
|
||||||
<Logger name="org.xyzh.news.mapper" level="debug" additivity="false">
|
<Logger name="org.xyzh.news.mapper" level="debug" additivity="false">
|
||||||
<AppenderRef ref="Console"/>
|
<AppenderRef ref="Console"/>
|
||||||
|
<AppenderRef ref="Filelog"/>
|
||||||
</Logger>
|
</Logger>
|
||||||
<Logger name="org.xyzh.study.mapper" level="debug" additivity="false">
|
<Logger name="org.xyzh.study.mapper" level="debug" additivity="false">
|
||||||
<AppenderRef ref="Console"/>
|
<AppenderRef ref="Console"/>
|
||||||
|
<AppenderRef ref="Filelog"/>
|
||||||
</Logger>
|
</Logger>
|
||||||
<Logger name="org.xyzh.crontab.mapper" level="debug" additivity="false">
|
<Logger name="org.xyzh.crontab.mapper" level="debug" additivity="false">
|
||||||
<AppenderRef ref="Console"/>
|
<AppenderRef ref="Console"/>
|
||||||
|
<AppenderRef ref="Filelog"/>
|
||||||
</Logger>
|
</Logger>
|
||||||
<Logger name="org.xyzh.message.mapper" level="debug" additivity="false">
|
<Logger name="org.xyzh.message.mapper" level="debug" additivity="false">
|
||||||
<AppenderRef ref="Console"/>
|
<AppenderRef ref="Console"/>
|
||||||
|
<AppenderRef ref="Filelog"/>
|
||||||
</Logger>
|
</Logger>
|
||||||
<!-- 项目包日志配置 - Auth模块 -->
|
<!-- 项目包日志配置 - Auth模块 -->
|
||||||
<Logger name="org.xyzh.auth" level="debug" additivity="false">
|
<Logger name="org.xyzh.auth" level="debug" additivity="false">
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package org.xyzh.common.dto;
|
|||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -53,6 +54,41 @@ public class BaseDTO implements Serializable{
|
|||||||
*/
|
*/
|
||||||
private boolean deleted;
|
private boolean deleted;
|
||||||
|
|
||||||
|
private List<OrderType> orderTypes;
|
||||||
|
|
||||||
|
public static class OrderType {
|
||||||
|
private String field;
|
||||||
|
private String order;
|
||||||
|
|
||||||
|
// 无参构造函数(Jackson反序列化需要)
|
||||||
|
public OrderType() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public OrderType(String field, String order) {
|
||||||
|
this.field = field;
|
||||||
|
this.order = order;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getField() {
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setField(String field) {
|
||||||
|
this.field = field;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOrder() {
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOrder(String order) {
|
||||||
|
if("ASC".equals(order.toUpperCase()) || "DESC".equals(order.toUpperCase())) {
|
||||||
|
this.order = order.toUpperCase();
|
||||||
|
}else{
|
||||||
|
throw new IllegalArgumentException("order must be ASC or DESC");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public BaseDTO() {
|
public BaseDTO() {
|
||||||
@@ -174,6 +210,14 @@ public class BaseDTO implements Serializable{
|
|||||||
this.deleted = deleted;
|
this.deleted = deleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<OrderType> getOrderTypes() {
|
||||||
|
return orderTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOrderTypes(List<OrderType> orderTypes) {
|
||||||
|
this.orderTypes = orderTypes;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString(){
|
public String toString(){
|
||||||
return "BaseDTO { id=" + id + ", createTime=" + createTime + ", updateTime=" + updateTime + ", deleteTime=" + deleteTime + ", deleted=" + deleted + " }";
|
return "BaseDTO { id=" + id + ", createTime=" + createTime + ", updateTime=" + updateTime + ", deleteTime=" + deleteTime + ", deleted=" + deleted + " }";
|
||||||
|
|||||||
@@ -323,7 +323,16 @@ public class NewsCrawlerTask extends PythonCommandTask {
|
|||||||
// 自动发布并记录成功发布的 URL 集合
|
// 自动发布并记录成功发布的 URL 集合
|
||||||
Set<String> publishedUrls = new HashSet<>();
|
Set<String> publishedUrls = new HashSet<>();
|
||||||
if (taskMeta.getAutoPublish().booleanValue()){
|
if (taskMeta.getAutoPublish().booleanValue()){
|
||||||
publishedUrls = publishNewsToArticle(passDataResult.getDataList(), task, logId);
|
// 合并通过审核和未通过审核的采集项,都进行自动发布
|
||||||
|
// 通过审核的会发布为status=1,未通过审核的会发布为status=4
|
||||||
|
List<TbDataCollectionItem> allItems = new ArrayList<>();
|
||||||
|
if (passDataResult.getDataList() != null) {
|
||||||
|
allItems.addAll(passDataResult.getDataList());
|
||||||
|
}
|
||||||
|
if (notPassDataResult.getDataList() != null) {
|
||||||
|
allItems.addAll(notPassDataResult.getDataList());
|
||||||
|
}
|
||||||
|
publishedUrls = publishNewsToArticle(allItems, task, logId);
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<String> notPathUrls = new HashSet<>(notPassList.stream().map(TbDataCollectionItem::getSourceUrl).toList());
|
Set<String> notPathUrls = new HashSet<>(notPassList.stream().map(TbDataCollectionItem::getSourceUrl).toList());
|
||||||
|
|||||||
@@ -169,8 +169,9 @@ public class NCResourceServiceImpl implements ResourceService {
|
|||||||
}
|
}
|
||||||
// 获取当前用户的部门角色
|
// 获取当前用户的部门角色
|
||||||
List<UserDeptRoleVO> userDeptRoles = LoginUtil.getCurrentDeptRole();
|
List<UserDeptRoleVO> userDeptRoles = LoginUtil.getCurrentDeptRole();
|
||||||
// 直接查询ResourceVO列表,SQL已经LEFT JOIN了recommend表
|
// 直接查询ResourceVO列表
|
||||||
List<ResourceVO> resourceVOList = resourceMapper.selectResourcesPageOrderByViewCount(filter, pageParam, userDeptRoles);
|
List<ResourceVO> resourceVOList = resourceMapper.selectResourcesPageOrderByViewCount(filter, pageParam, userDeptRoles);
|
||||||
|
logger.info("资源数量{}",resourceVOList.size());
|
||||||
long total = resourceMapper.countResources(filter, userDeptRoles);
|
long total = resourceMapper.countResources(filter, userDeptRoles);
|
||||||
pageParam.setTotalElements(total);
|
pageParam.setTotalElements(total);
|
||||||
pageParam.setTotalPages((int) Math.ceil((double) total / pageParam.getPageSize()));
|
pageParam.setTotalPages((int) Math.ceil((double) total / pageParam.getPageSize()));
|
||||||
|
|||||||
@@ -347,11 +347,12 @@
|
|||||||
|
|
||||||
<!-- ResourceVO结果映射(包含推荐信息) -->
|
<!-- ResourceVO结果映射(包含推荐信息) -->
|
||||||
<resultMap id="ResourceVOResultMap" type="org.xyzh.common.vo.ResourceVO">
|
<resultMap id="ResourceVOResultMap" type="org.xyzh.common.vo.ResourceVO">
|
||||||
|
<id column="resource_id" property="resource.resourceID" jdbcType="VARCHAR"/>
|
||||||
<result column="is_top_recommend" property="isTopRecommend" jdbcType="BOOLEAN"/>
|
<result column="is_top_recommend" property="isTopRecommend" jdbcType="BOOLEAN"/>
|
||||||
<result column="is_ideological_recommend" property="isIdeologicalRecommend" jdbcType="BOOLEAN"/>
|
<result column="is_ideological_recommend" property="isIdeologicalRecommend" jdbcType="BOOLEAN"/>
|
||||||
<association property="resource" javaType="org.xyzh.common.dto.resource.TbResource">
|
<association property="resource" javaType="org.xyzh.common.dto.resource.TbResource">
|
||||||
<id column="id" property="id" jdbcType="VARCHAR"/>
|
<id column="resource_id" property="resourceID" jdbcType="VARCHAR"/>
|
||||||
<result column="resource_id" property="resourceID" jdbcType="VARCHAR"/>
|
<result column="id" property="id" jdbcType="VARCHAR"/>
|
||||||
<result column="title" property="title" jdbcType="VARCHAR"/>
|
<result column="title" property="title" jdbcType="VARCHAR"/>
|
||||||
<result column="content" property="content" jdbcType="LONGVARCHAR"/>
|
<result column="content" property="content" jdbcType="LONGVARCHAR"/>
|
||||||
<result column="summary" property="summary" jdbcType="VARCHAR"/>
|
<result column="summary" property="summary" jdbcType="VARCHAR"/>
|
||||||
@@ -408,13 +409,21 @@
|
|||||||
r.author, r.source, r.source_url, r.view_count, r.like_count, r.collect_count,
|
r.author, r.source, r.source_url, r.view_count, r.like_count, r.collect_count,
|
||||||
r.status, r.is_recommend, r.is_banner, r.publish_time, r.creator, r.updater,
|
r.status, r.is_recommend, r.is_banner, r.publish_time, r.creator, r.updater,
|
||||||
r.create_time, r.update_time, r.delete_time, r.deleted
|
r.create_time, r.update_time, r.delete_time, r.deleted
|
||||||
|
<if test="filter.orderTypes != null and filter.orderTypes.size() > 0">
|
||||||
|
ORDER BY
|
||||||
|
<foreach collection="filter.orderTypes" item="orderType" separator=", ">
|
||||||
|
r.${orderType.field} ${orderType.order}
|
||||||
|
</foreach>
|
||||||
|
</if>
|
||||||
|
<if test="filter.orderTypes == null or filter.orderTypes.size() == 0">
|
||||||
ORDER BY r.view_count DESC, r.publish_time DESC, r.create_time DESC
|
ORDER BY r.view_count DESC, r.publish_time DESC, r.create_time DESC
|
||||||
|
</if>
|
||||||
LIMIT #{pageParam.pageSize} OFFSET #{pageParam.offset}
|
LIMIT #{pageParam.pageSize} OFFSET #{pageParam.offset}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<!-- 统计资源总数 - 添加权限过滤 -->
|
<!-- 统计资源总数 - 添加权限过滤 -->
|
||||||
<select id="countResources" resultType="long">
|
<select id="countResources" resultType="long">
|
||||||
SELECT COUNT(DISTINCT r.id)
|
SELECT COUNT(DISTINCT r.resource_id)
|
||||||
FROM tb_resource r
|
FROM tb_resource r
|
||||||
<include refid="Permission_Filter"/>
|
<include refid="Permission_Filter"/>
|
||||||
WHERE r.deleted = 0
|
WHERE r.deleted = 0
|
||||||
|
|||||||
@@ -18,6 +18,13 @@ export interface BaseDTO {
|
|||||||
deleteTime?: string;
|
deleteTime?: string;
|
||||||
/** 是否删除 */
|
/** 是否删除 */
|
||||||
deleted?: boolean;
|
deleted?: boolean;
|
||||||
|
|
||||||
|
orderTypes?: OrderType[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OrderType {
|
||||||
|
field: string;
|
||||||
|
order: 'ASC' | 'DESC';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -40,6 +40,11 @@
|
|||||||
<p class="section-desc">查看和分析热门文章的访问统计数据</p>
|
<p class="section-desc">查看和分析热门文章的访问统计数据</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="filter-controls">
|
<div class="filter-controls">
|
||||||
|
<el-select v-model="sortOrder" @change="loadHotArticles" placeholder="排序规则" style="width: 150px; margin-right: 10px;">
|
||||||
|
<el-option label="默认排序" value="default" />
|
||||||
|
<el-option label="浏览量排序" value="viewCount" />
|
||||||
|
<el-option label="发布时间排序" value="publishTime" />
|
||||||
|
</el-select>
|
||||||
<el-select v-model="hotArticleLimit" @change="loadHotArticles" placeholder="显示数量">
|
<el-select v-model="hotArticleLimit" @change="loadHotArticles" placeholder="显示数量">
|
||||||
<el-option label="前10名" :value="10" />
|
<el-option label="前10名" :value="10" />
|
||||||
<el-option label="前20名" :value="20" />
|
<el-option label="前20名" :value="20" />
|
||||||
@@ -381,6 +386,7 @@ const ideologicalRecommends = ref<ResourceRecommendVO[]>([]);
|
|||||||
// 热门文章列表
|
// 热门文章列表
|
||||||
const hotArticles = ref<ResourceVO[]>([]);
|
const hotArticles = ref<ResourceVO[]>([]);
|
||||||
const hotArticleLimit = ref<number>(20);
|
const hotArticleLimit = ref<number>(20);
|
||||||
|
const sortOrder = ref<string>('default'); // 排序规则:default-默认, viewCount-浏览量, publishTime-发布时间
|
||||||
|
|
||||||
// 添加至TOP的加载状态
|
// 添加至TOP的加载状态
|
||||||
const addingToTop = ref<Set<string>>(new Set());
|
const addingToTop = ref<Set<string>>(new Set());
|
||||||
@@ -473,21 +479,31 @@ async function loadTabData(tab: string) {
|
|||||||
async function loadHotArticles() {
|
async function loadHotArticles() {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
try {
|
try {
|
||||||
// 获取已发布的文章,按浏览量排序
|
// 构建过滤条件
|
||||||
|
const filter: any = {
|
||||||
|
status: 1 // 只显示已发布的
|
||||||
|
};
|
||||||
|
|
||||||
|
// 根据排序规则设置orderTypes
|
||||||
|
if (sortOrder.value === 'viewCount') {
|
||||||
|
filter.orderTypes = [{ field: 'view_count', order: 'DESC' }];
|
||||||
|
} else if (sortOrder.value === 'publishTime') {
|
||||||
|
filter.orderTypes = [{ field: 'publish_time', order: 'DESC' }];
|
||||||
|
}
|
||||||
|
// default情况下orderTypes为空,使用SQL中的默认排序
|
||||||
|
|
||||||
|
// 获取已发布的文章
|
||||||
const result = await resourceApi.getResourcePageOrderByViewCount(
|
const result = await resourceApi.getResourcePageOrderByViewCount(
|
||||||
{
|
{
|
||||||
pageNumber: 1,
|
pageNumber: 1,
|
||||||
pageSize: hotArticleLimit.value
|
pageSize: hotArticleLimit.value
|
||||||
},
|
},
|
||||||
{
|
filter
|
||||||
status: 1 // 只显示已发布的
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result.success && result.pageDomain?.dataList) {
|
if (result.success && result.pageDomain?.dataList) {
|
||||||
// 按浏览量降序排序
|
// 直接使用后端返回的排序结果
|
||||||
hotArticles.value = result.pageDomain.dataList
|
hotArticles.value = result.pageDomain.dataList;
|
||||||
.sort((a, b) => (b.resource?.viewCount || 0) - (a.resource?.viewCount || 0));
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('加载热门文章失败:', error);
|
console.error('加载热门文章失败:', error);
|
||||||
@@ -542,7 +558,7 @@ async function searchResources() {
|
|||||||
const result = await resourceApi.getResourcePageOrderByViewCount(
|
const result = await resourceApi.getResourcePageOrderByViewCount(
|
||||||
{ pageNumber: 1, pageSize: 50 },
|
{ pageNumber: 1, pageSize: 50 },
|
||||||
{
|
{
|
||||||
keyword: searchKeyword.value,
|
title: searchKeyword.value,
|
||||||
status: 1 // 只显示已发布的
|
status: 1 // 只显示已发布的
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -1055,6 +1071,11 @@ async function addToIdeologicalRecommends(resourceID?: string) {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.stat-title {
|
||||||
|
min-width: 0; /* 允许flex子元素缩小到内容以下 */
|
||||||
|
overflow: hidden; /* 隐藏溢出内容 */
|
||||||
|
}
|
||||||
|
|
||||||
.stat-actions {
|
.stat-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
Reference in New Issue
Block a user