完成管理后台新闻列表页搜索

This commit is contained in:
xpecya 2024-12-10 23:29:01 +08:00
parent 9da2a1efe1
commit 5a61e92888
14 changed files with 487 additions and 39 deletions

View File

@ -82,7 +82,7 @@ public class ColumnController {
@RequestParam(value = "keyword", required = false) String keyword, @RequestParam(value = "keyword", required = false) String keyword,
@RequestParam(value = "page", required = false, defaultValue = "1") int page, @RequestParam(value = "page", required = false, defaultValue = "1") int page,
@RequestParam(value = "size", required = false, defaultValue = "10") int size, @RequestParam(value = "size", required = false, defaultValue = "10") int size,
@RequestParam(value = "orderBy", required = false, defaultValue = "id") String orderBy, @RequestParam(value = "orderBy", required = false, defaultValue = "order") String orderBy,
@RequestParam(value = "direction", required = false, defaultValue = "asc") String direction) { @RequestParam(value = "direction", required = false, defaultValue = "asc") String direction) {
return queryColumn(token, 1L, false, keyword, null, page, size, orderBy, direction); return queryColumn(token, 1L, false, keyword, null, page, size, orderBy, direction);
} }
@ -94,7 +94,7 @@ public class ColumnController {
@RequestParam(value = "keyword", required = false) String keyword, @RequestParam(value = "keyword", required = false) String keyword,
@RequestParam(value = "page", required = false, defaultValue = "1") int page, @RequestParam(value = "page", required = false, defaultValue = "1") int page,
@RequestParam(value = "size", required = false, defaultValue = "10") int size, @RequestParam(value = "size", required = false, defaultValue = "10") int size,
@RequestParam(value = "orderBy", required = false, defaultValue = "id") String orderBy, @RequestParam(value = "orderBy", required = false, defaultValue = "order") String orderBy,
@RequestParam(value = "direction", required = false, defaultValue = "asc") String direction) { @RequestParam(value = "direction", required = false, defaultValue = "asc") String direction) {
return queryColumn(token, parent, needChildren, keyword, 1L, page, size, orderBy, direction); return queryColumn(token, parent, needChildren, keyword, 1L, page, size, orderBy, direction);
} }

View File

@ -0,0 +1,66 @@
package com.jinrui.reference.admin.controller;
import com.jinrui.reference.admin.model.entity.AdminUser;
import com.jinrui.reference.core.model.vo.news.NewsVO;
import com.jinrui.reference.admin.service.AdminJwtService;
import com.jinrui.reference.core.model.vo.PageObject;
import com.jinrui.reference.core.service.NewsService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/news")
public class NewsController {
private static final Logger log = LoggerFactory.getLogger(NewsController.class);
private final NewsService newsService;
public NewsController(NewsService newsService) {
this.newsService = newsService;
}
@GetMapping
public PageObject<NewsVO> queryNews(@RequestHeader("auth-token") String token,
@RequestParam(value = "keyword", required = false) String keyword,
@RequestParam(value = "column", required = false) Long column,
@RequestParam(value = "status", required = false) Integer status,
@RequestParam(value = "page", required = false, defaultValue = "1") int page,
@RequestParam(value = "size", required = false, defaultValue = "10") int size,
@RequestParam(value = "last", required = false) Integer last,
@RequestParam(value = "current", required = false) Integer current,
@RequestParam(value = "orderBy", required = false, defaultValue = "id") String orderBy,
@RequestParam(value = "direction", required = false, defaultValue = "asc") String direction) {
if (!StringUtils.hasText(token)) {
return PageObject.failedPage("登陆Token为空!");
}
try {
AdminUser adminUser = AdminJwtService.parseToken(token);
if (adminUser == null) {
log.warn("解析token {}拿不到AdminUser对象!", token);
return PageObject.failedPage("登陆Token有误请联系系统管理员!");
}
if (!adminUser.isActive()) {
log.warn("当前用户已被封禁! id = {}", adminUser.getId());
return PageObject.failedPage("当前用户已被封禁!请联系系统管理员!");
}
log.info("path: /news, method: GET, request user id: {}, keyword: {}, column: {}, status: {}, " +
"page: {}, size: {}, last: {}, current: {}, orderBy: {}, direction: {}",
adminUser.getId(), keyword, column, status, page, size, last, current, orderBy, direction);
} catch (Exception e) {
log.error("解析登陆Token出错!", e);
return PageObject.failedPage(500, "服务端错误,请联系系统管理员!");
}
return newsService.queryNews(keyword, column, status, page, size, last, current, orderBy, direction);
}
}

View File

@ -0,0 +1,13 @@
logging:
level:
root: DEBUG
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/reference?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8&allowMultiQueries=true
username: root
password: Aa123456@
redis:
host: 127.0.0.1
port: 6379

View File

@ -1,19 +1,8 @@
server: server:
port: 13579
compression: compression:
enabled: true enabled: true
servlet: servlet:
context-path: /admin context-path: /admin
oss:
ak: LTAI5t8z9QNdCG6b54mDgx8p
sk: F3M41hTgH8g99ZgVWyelj42825YbZM
roleArn: acs:ram::1647420045565932:role/ramoss
endPoint: oss-cn-hangzhou.aliyuncs.com
region: oss-cn-hangzhou
bucketName: lengfeng-test
baseUrl: https://lengfeng-test.oss-cn-hangzhou.aliyuncs.com
sts:
endPoint: sts.cn-hangzhou.aliyuncs.com
spring: spring:
datasource: datasource:
type: com.zaxxer.hikari.HikariDataSource type: com.zaxxer.hikari.HikariDataSource

View File

@ -10,13 +10,3 @@ oss:
baseUrl: https://lengfeng-test.oss-cn-hangzhou.aliyuncs.com baseUrl: https://lengfeng-test.oss-cn-hangzhou.aliyuncs.com
sts: sts:
endPoint: sts.cn-hangzhou.aliyuncs.com endPoint: sts.cn-hangzhou.aliyuncs.com
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/reference?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8&allowMultiQueries=true
username: root
password: Aa123456@
redis:
host: 127.0.0.1
port: 6379

View File

@ -1,6 +1,8 @@
package com.jinrui.reference.core.mapper; package com.jinrui.reference.core.mapper;
import com.jinrui.reference.core.model.entity.Column; import com.jinrui.reference.core.model.entity.Column;
import com.jinrui.reference.core.model.entity.DraftColumnRel;
import com.jinrui.reference.core.model.entity.NewsColumnRel;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Result; import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results; import org.apache.ibatis.annotations.Results;
@ -9,6 +11,7 @@ import org.apache.ibatis.type.JdbcType;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Set;
public interface ColumnMapper { public interface ColumnMapper {
@ -33,9 +36,50 @@ public interface ColumnMapper {
"and id &lt;&gt; #{exclude}" + "and id &lt;&gt; #{exclude}" +
"</if>" + "</if>" +
"</where>" + "</where>" +
"order by `#{orderBy}` #{direction}" + "order by concat('`', #{orderBy}, '`') " +
"<if test=\"'desc'.equals(direction)\">" +
"desc" +
"</if>" +
"</script>") "</script>")
List<Column> queryColumn(@Param("parent") Long parent, @Param("keyword") String keyword, List<Column> queryColumn(@Param("parent") Long parent, @Param("keyword") String keyword,
@Param("exclude") Long exclude, @Param("orderBy") String orderBy, @Param("exclude") Long exclude, @Param("orderBy") String orderBy,
@Param("direction") String direction); @Param("direction") String direction);
@Results({
@Result(column = "id", property = "id", id = true),
@Result(column = "parent_id", property = "parentId"),
@Result(column = "name", property = "name"),
@Result(column = "order", property = "order"),
@Result(column = "create_time", property = "createTime", javaType = Date.class, jdbcType = JdbcType.TIMESTAMP),
@Result(column = "update_time", property = "updateTime", javaType = Date.class, jdbcType = JdbcType.TIMESTAMP)
})
@Select("select * from `column`")
List<Column> queryAll();
@Results({
@Result(column = "id", property = "id", id = true),
@Result(column = "draft_id", property = "draftId"),
@Result(column = "column_id", property = "columnId"),
@Result(column = "type", property = "type")
})
@Select("<script>" +
"select * from draft_column_rel where draft_id in " +
"<foreach collection=\"set\" item=\"id\" open=\"(\" close=\")\" separator=\",\">\n" +
"#{id}\n" +
"</foreach>" +
"</script>")
List<DraftColumnRel> queryDraftRel(@Param("set") Set<Long> set);
@Results({
@Result(column = "id", property = "id", id = true),
@Result(column = "news_id", property = "newsId"),
@Result(column = "column_id", property = "columnId")
})
@Select("<script>" +
"select * from news_column_rel where news_id in " +
"<foreach collection=\"set\" item=\"id\" open=\"(\" close=\")\" separator=\",\">\n" +
"#{id}\n" +
"</foreach>" +
"</script>")
List<NewsColumnRel> queryNewsRel(@Param("set") Set<Long> set);
} }

View File

@ -0,0 +1,73 @@
package com.jinrui.reference.core.mapper;
import com.jinrui.reference.core.model.entity.News;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface NewsMapper {
@Select("<script>" +
"select " +
"news.id as id," +
"news.draft_id as draftId," +
"news.title as title," +
"news.status as status," +
"news.create_time as createTime," +
"news.publish_time as publishTime," +
"news.update_time as updateTime " +
"from news " +
"<if test=\"column != null\">" +
"inner join news_column_rel on news.id = news_column_rel.news_id " +
"</if>" +
"<where>" +
"<if test=\"keyword != null and !keyword.isEmpty()\">" +
"news.keyword like concat('%', #{keyword}, '%') " +
"</if>" +
"<if test=\"column != null\">" +
"and news_column_rel.column_id = #{column} " +
"</if>" +
"<if test=\"status != null\">" +
"and news.status = #{status} " +
"</if>" +
"<if test=\"last != null\">" +
"and news.id &gt; #{last}" +
"</if>" +
"</where>" +
"order by concat('`', #{orderBy}, '`') " +
"<if test=\"'desc'.equals(direction)\">" +
"desc" +
"</if>" +
"limit ${limit} offset ${offset}" +
"</script>")
List<News> queryNews(@Param("keyword") String keyword,
@Param("column") Long column,
@Param("status") Integer status,
@Param("last") Integer last,
@Param("orderBy") String orderBy,
@Param("direction") String direction,
@Param("limit") int limit,
@Param("offset") int offset);
@Select("<script>" +
"select count(news.*) from news " +
"<if test=\"column != null\">" +
"inner join news_column_rel on news.id = news_column_rel.news_id " +
"</if>" +
"<where>" +
"<if test=\"keyword != null and !keyword.isEmpty()\">" +
"news.keyword like concat('%', #{keyword}, '%') " +
"</if>" +
"<if test=\"column != null\">" +
"and news_column_rel.column_id = #{column} " +
"</if>" +
"<if test=\"status != null\">" +
"and news.status = #{status} " +
"</if>" +
"</where>" +
"</script>")
int queryTotal(@Param("keyword") String keyword,
@Param("column") Long column,
@Param("status") Integer status);
}

View File

@ -32,7 +32,10 @@ public interface TagMapper {
"and id &lt;&gt; #{exclude}" + "and id &lt;&gt; #{exclude}" +
"</if>" + "</if>" +
"</where>" + "</where>" +
"order by #{orderBy} #{direction}" + "order by concat('`', #{orderBy}, '`') " +
"<if test=\"'desc'.equals(direction)\">" +
"desc" +
"</if>" +
"</script>") "</script>")
List<Tag> queryTag(@Param("parent") Long parent, @Param("keyword") String keyword, @Param("exclude") Long exclude, List<Tag> queryTag(@Param("parent") Long parent, @Param("keyword") String keyword, @Param("exclude") Long exclude,
@Param("orderBy") String orderBy, @Param("direction") String direction); @Param("orderBy") String orderBy, @Param("direction") String direction);

View File

@ -21,6 +21,11 @@ public class DraftColumnRel {
*/ */
private Long columnId; private Long columnId;
/**
* 展示方式 前端会传
*/
private Integer type;
public Long getId() { public Long getId() {
return id; return id;
} }
@ -44,4 +49,12 @@ public class DraftColumnRel {
public void setColumnId(Long columnId) { public void setColumnId(Long columnId) {
this.columnId = columnId; this.columnId = columnId;
} }
public Integer getType() {
return type;
}
public void setType(Integer type) {
this.type = type;
}
} }

View File

@ -21,6 +21,11 @@ public class NewsColumnRel {
*/ */
private Long columnId; private Long columnId;
/**
* 展示方式 前端会传
*/
private Integer type;
public Long getId() { public Long getId() {
return id; return id;
} }
@ -44,4 +49,12 @@ public class NewsColumnRel {
public void setColumnId(Long columnId) { public void setColumnId(Long columnId) {
this.columnId = columnId; this.columnId = columnId;
} }
public Integer getType() {
return type;
}
public void setType(Integer type) {
this.type = type;
}
} }

View File

@ -0,0 +1,115 @@
package com.jinrui.reference.core.model.vo.news;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.jinrui.reference.core.model.entity.News;
import com.jinrui.reference.core.model.vo.column.ColumnVO;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 后台新闻列表VO
*/
@SuppressWarnings("unused")
public class NewsVO {
/**
* 新闻ID
*/
private Long id;
/**
* 新闻标题
*/
private String title;
/**
* 栏目列表
*/
private final List<ColumnVO> columns = new ArrayList<>();
/**
* 新闻状态 0-草稿 | 1-未发布 | 2-已发布
*/
private Integer status;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**
* 发布时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date publishTime;
/**
* 修改时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
public NewsVO(News news) {
this.id = news.getId();
this.title = news.getTitle();
this.status = news.getStatus();
this.createTime = news.getCreateTime();
this.publishTime = news.getPublishTime();
this.updateTime = news.getUpdateTime();
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public List<ColumnVO> getColumns() {
return columns;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getPublishTime() {
return publishTime;
}
public void setPublishTime(Date publishTime) {
this.publishTime = publishTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
}

View File

@ -0,0 +1,129 @@
package com.jinrui.reference.core.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jinrui.reference.core.mapper.ColumnMapper;
import com.jinrui.reference.core.mapper.NewsMapper;
import com.jinrui.reference.core.model.entity.Column;
import com.jinrui.reference.core.model.entity.DraftColumnRel;
import com.jinrui.reference.core.model.entity.News;
import com.jinrui.reference.core.model.entity.NewsColumnRel;
import com.jinrui.reference.core.model.vo.PageObject;
import com.jinrui.reference.core.model.vo.column.ColumnVO;
import com.jinrui.reference.core.model.vo.news.NewsVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
@Service
public class NewsService {
private static final Logger log = LoggerFactory.getLogger(NewsService.class);
private final NewsMapper newsMapper;
private final ColumnMapper columnMapper;
private final ObjectMapper objectMapper;
public NewsService(NewsMapper newsMapper,
ColumnMapper columnMapper,
ObjectMapper objectMapper) {
this.newsMapper = newsMapper;
this.columnMapper = columnMapper;
this.objectMapper = objectMapper;
}
public PageObject<NewsVO> queryNews(String keyword, Long column, Integer status, int page, int size,
Integer last, Integer current, String orderBy, String direction) {
int offset = 0;
if (current != null) {
offset = (Math.max(0, page - current)) * size;
}
List<News> newsList;
try {
newsList = newsMapper.queryNews(keyword, column, status, last, orderBy, direction, size, offset);
} catch (Exception e) {
log.error("搜索新闻异常!", e);
return PageObject.failedPage(500, "服务器错误,请联系系统管理员!");
}
PageObject<NewsVO> pageObject = new PageObject<>();
if (page == 1) {
try {
int total = newsMapper.queryTotal(keyword, column, status);
pageObject.setTotal(total);
} catch (Exception e) {
log.error("获取新闻总数异常!", e);
return PageObject.failedPage(500, "服务器错误,请联系系统管理员!");
}
}
pageObject.setCode(200);
pageObject.setCurrent(page);
size = Math.min(newsList.size(), size);
pageObject.setSize(size);
if (CollectionUtils.isEmpty(newsList)) {
log.info("搜索结果为空!");
pageObject.setData(new ArrayList<>());
return pageObject;
}
Map<Long, NewsVO> newsMap = new HashMap<>();
Map<Long, NewsVO> draftMap = new HashMap<>();
List<NewsVO> resultList = new ArrayList<>();
for (News news : newsList) {
NewsVO newsVO = new NewsVO(news);
Long draftId = news.getDraftId();
if (draftId != null) {
draftMap.put(draftId, newsVO);
} else {
newsMap.put(newsVO.getId(), newsVO);
}
resultList.add(newsVO);
}
List<Column> columns = columnMapper.queryAll();
Map<Long, ColumnVO> columnMap = columns.stream()
.map(ColumnVO::new)
.collect(Collectors.toMap(ColumnVO::getId, Function.identity()));
if (!CollectionUtils.isEmpty(draftMap)) {
List<DraftColumnRel> draftRelList = columnMapper.queryDraftRel(draftMap.keySet());
for (DraftColumnRel rel : draftRelList) {
Long draftId = rel.getDraftId();
Long columnId = rel.getColumnId();
ColumnVO columnObject = columnMap.get(columnId);
NewsVO newsVO = draftMap.get(draftId);
List<ColumnVO> columnList = newsVO.getColumns();
columnList.add(columnObject);
}
}
if (!CollectionUtils.isEmpty(newsMap)) {
List<NewsColumnRel> newsRelList = columnMapper.queryNewsRel(newsMap.keySet());
for (NewsColumnRel rel : newsRelList) {
Long newsId = rel.getNewsId();
Long columnId = rel.getColumnId();
ColumnVO columnObject = columnMap.get(columnId);
NewsVO newsVO = newsMap.get(newsId);
List<ColumnVO> columnList = newsVO.getColumns();
columnList.add(columnObject);
}
}
pageObject.setData(resultList);
try {
String pageString = objectMapper.writeValueAsString(pageObject);
log.info("分页搜索结果: {}", pageString);
} catch (JsonProcessingException e) {
log.error("json解析异常", e);
}
return pageObject;
}
}

View File

@ -16,5 +16,5 @@ redis:
port: 6379 port: 6379
password: Xgf_redis password: Xgf_redis
wechat: wechat:
appId: wx78d5f5d37762207c appId: wx8ecb60de28c389de
secret: d1ca9d77886d138cb1f6ac30f259f194 secret: d8f6ac07fbcdebfa2769b67687fee27e

View File

@ -11,5 +11,5 @@ redis:
host: 127.0.0.1 host: 127.0.0.1
port: 6379 port: 6379
wechat: wechat:
appId: wx78d5f5d37762207c appId: wx8ecb60de28c389de
secret: d1ca9d77886d138cb1f6ac30f259f194 secret: d8f6ac07fbcdebfa2769b67687fee27e