feat: optimize source project pages and SEO

This commit is contained in:
王鹏
2026-08-25 11:08:59 +08:00
parent e528aa4876
commit 695fac5e3a
42 changed files with 5038 additions and 1025 deletions

View File

@@ -14,6 +14,7 @@ import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.web.service.SysPermissionService;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
@@ -66,7 +67,7 @@ public class CmsBlogController extends BaseController
startPage();
//状态为发布
cmsBlog.setStatus("1");
List<CmsBlog> list = cmsBlogService.selectCmsBlogList(cmsBlog);
List<CmsBlog> list = cmsBlogService.selectCmsBlogCardList(cmsBlog);
return getDataTable(list);
}
@@ -74,7 +75,7 @@ public class CmsBlogController extends BaseController
* 首页获取文章详细信息
*/
@GetMapping(value = { "/cms/detail/", "/cms/detail/{id}" })
public AjaxResult getInfoDetail(@PathVariable(value = "id", required = false) Long id)
public ResponseEntity<AjaxResult> getInfoDetail(@PathVariable(value = "id", required = false) Long id)
{
AjaxResult ajax = AjaxResult.success();
CmsType cmsType = new CmsType();
@@ -83,9 +84,14 @@ public class CmsBlogController extends BaseController
ajax.put("tags", cmsTagService.selectCmsTagList(cmsTag));
if (StringUtils.isNotNull(id))
{
ajax.put(AjaxResult.DATA_TAG, cmsBlogService.selectCmsBlogById(id));
CmsBlog blog = cmsBlogService.selectPublishedCmsBlogById(id);
if (blog == null)
{
return ResponseEntity.notFound().build();
}
ajax.put(AjaxResult.DATA_TAG, blog);
}
return ajax;
return ResponseEntity.ok(ajax);
}
/**
@@ -127,14 +133,18 @@ public class CmsBlogController extends BaseController
* 首页增加阅读量
*/
@GetMapping("/cms/addBlogViews/{id}")
public AjaxResult addBlogViews(@PathVariable(value = "id", required = false) Long id)
public ResponseEntity<AjaxResult> addBlogViews(@PathVariable(value = "id", required = false) Long id)
{
CmsBlog cmsBlog = cmsBlogService.selectCmsBlogById(id);
CmsBlog cmsBlog = cmsBlogService.selectPublishedCmsBlogById(id);
if (cmsBlog == null)
{
return ResponseEntity.notFound().build();
}
Long views = cmsBlog.getViews();
views+=Long.parseLong("1");
views = views == null ? 1L : views + 1L;
cmsBlog.setViews(views);
cmsBlogService.updateCmsBlog(cmsBlog);
return AjaxResult.success(id);
return ResponseEntity.ok(AjaxResult.success(id));
}
/**

View File

@@ -8,6 +8,7 @@ package com.ruoyi.cms.blog.domain;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.cms.tag.domain.CmsTag;
/**
* @Author: WangNing
@@ -18,6 +19,7 @@ public class CmsBlogTag {
private Long tagId;
private Long blogId;
private Long[] tagIds;
private CmsTag tag;
public Long getTagId() {
return tagId;
@@ -43,6 +45,14 @@ public class CmsBlogTag {
this.tagIds = tagIds;
}
public CmsTag getTag() {
return tag;
}
public void setTag(CmsTag tag) {
this.tag = tag;
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)

View File

@@ -8,6 +8,7 @@ package com.ruoyi.cms.blog.domain;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.cms.type.domain.CmsType;
/**
* @Author: WangNing
@@ -18,6 +19,7 @@ public class CmsBlogType {
private Long typeId;
private Long blogId;
private Long[] typeIds;
private CmsType type;
public Long getTypeId() {
return typeId;
@@ -43,6 +45,14 @@ public class CmsBlogType {
this.typeIds = typeIds;
}
public CmsType getType() {
return type;
}
public void setType(CmsType type) {
this.type = type;
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)

View File

@@ -20,6 +20,11 @@ public interface CmsBlogMapper
*/
public CmsBlog selectCmsBlogById(Long id);
/**
* Query a public detail page. Drafts must behave like missing pages.
*/
public CmsBlog selectPublishedCmsBlogById(Long id);
/**
* 查询文章管理列表
*
@@ -28,6 +33,16 @@ public interface CmsBlogMapper
*/
public List<CmsBlog> selectCmsBlogList(CmsBlog cmsBlog);
/**
* 查询首页卡片所需的轻量字段
*/
public List<CmsBlog> selectCmsBlogCardList(CmsBlog cmsBlog);
/**
* 批量读取缺少封面的文章正文,用于提取首图
*/
public List<CmsBlog> selectCmsBlogContentByIds(List<Long> ids);
public List<CmsBlog> selectCmsBlogListBetweenCreateTime(@Param("title") String title,@Param("type") String type,@Param("top") String top,@Param("status") String status,@Param("createTimeBegin") String createTimeBegin,@Param("createTimeEnd") String createTimeEnd,@Param("createBy") String createBy);
/**

View File

@@ -27,6 +27,10 @@ public interface CmsBlogTagMapper {
* 查询文件列表
*/
public List<CmsBlogTag> selectBlogTagList(Long blogId);
/**
* 批量查询博客及其标签,避免列表页逐条查询
*/
public List<CmsBlogTag> selectBlogTagsByBlogIds(List<Long> blogIds);
/**
* 通过tagId删除blog文件关联
*/

View File

@@ -27,6 +27,10 @@ public interface CmsBlogTypeMapper {
* 查询博客列表
*/
public List<CmsBlogType> selectBlogTypeList(Long blogId);
/**
* 批量查询博客及其分类,避免列表页逐条查询
*/
public List<CmsBlogType> selectBlogTypesByBlogIds(List<Long> blogIds);
/**
* 通过typeId删除blog文件关联
*/

View File

@@ -19,6 +19,14 @@ public interface ICmsBlogService
*/
public CmsBlog selectCmsBlogById(Long id);
/**
* Query an indexable public detail page.
*
* @param id content primary key
* @return published content, or null when it must not be indexed
*/
public CmsBlog selectPublishedCmsBlogById(Long id);
/**
* 查询文章管理列表
*
@@ -27,6 +35,11 @@ public interface ICmsBlogService
*/
public List<CmsBlog> selectCmsBlogList(CmsBlog cmsBlog);
/**
* 查询首页项目卡片列表
*/
public List<CmsBlog> selectCmsBlogCardList(CmsBlog cmsBlog);
/**
* 查询推荐文章列表
*/

View File

@@ -1,7 +1,9 @@
package com.ruoyi.cms.blog.service.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -54,6 +56,10 @@ public class CmsBlogServiceImpl implements ICmsBlogService
public CmsBlog selectCmsBlogById(Long id)
{
CmsBlog blog = cmsBlogMapper.selectCmsBlogById(id);
if (blog == null)
{
return null;
}
//查询标签列表
List<CmsBlogTag> blogTagList = cmsBlogTagMapper.selectBlogTagList(id);
Long[] tagIds = new Long[blogTagList.size()];
@@ -83,6 +89,13 @@ public class CmsBlogServiceImpl implements ICmsBlogService
return blog;
}
@Override
public CmsBlog selectPublishedCmsBlogById(Long id)
{
CmsBlog blog = selectCmsBlogById(id);
return blog != null && "1".equals(blog.getStatus()) ? blog : null;
}
/**
* 查询文章管理列表
*
@@ -103,18 +116,19 @@ public class CmsBlogServiceImpl implements ICmsBlogService
return blogList;
}
@Override
public List<CmsBlog> selectCmsBlogCardList(CmsBlog cmsBlog)
{
return prepareBlogCards(cmsBlogMapper.selectCmsBlogCardList(cmsBlog));
}
/**
* 查询推荐文章列表
*/
@Override
public List<CmsBlog> selectCmsBlogListRecommend(CmsBlog cmsBlog) {
List<CmsBlog> cmsBlogList = cmsBlogMapper.selectCmsBlogListRecommend(cmsBlog);
// 为每个博客设置首页图片(如果为空,则从content中提取)
for (CmsBlog blog : cmsBlogList) {
setDefaultBlogPicFromContent(blog);
}
List<CmsBlog> blogList = BlogListAddTypeAndTag(cmsBlogList);
return blogList;
return prepareBlogCards(cmsBlogList);
}
/**
@@ -123,12 +137,7 @@ public class CmsBlogServiceImpl implements ICmsBlogService
@Override
public List<CmsBlog> selectCmsBlogListByTypeId(Long id) {
List<CmsBlog> cmsBlogList = cmsBlogMapper.selectCmsBlogListByTypeId(id);
// 为每个博客设置首页图片(如果为空,则从content中提取)
for (CmsBlog blog : cmsBlogList) {
setDefaultBlogPicFromContent(blog);
}
List<CmsBlog> blogList = BlogListAddTypeAndTag(cmsBlogList);
return blogList;
return prepareBlogCards(cmsBlogList);
}
/**
@@ -137,12 +146,7 @@ public class CmsBlogServiceImpl implements ICmsBlogService
@Override
public List<CmsBlog> selectCmsBlogListByTagId(Long id) {
List<CmsBlog> cmsBlogList = cmsBlogMapper.selectCmsBlogListByTagId(id);
// 为每个博客设置首页图片(如果为空,则从content中提取)
for (CmsBlog blog : cmsBlogList) {
setDefaultBlogPicFromContent(blog);
}
List<CmsBlog> blogList = BlogListAddTypeAndTag(cmsBlogList);
return blogList;
return prepareBlogCards(cmsBlogList);
}
/**
@@ -307,30 +311,71 @@ public class CmsBlogServiceImpl implements ICmsBlogService
return null;
}
private List<CmsBlog> BlogListAddTypeAndTag(List<CmsBlog> cmsBlogList){
if (cmsBlogList==null||cmsBlogList.size()<0){
/**
* 列表不返回正文;仅对没有独立封面的项目批量读取正文并提取首图。
*/
private List<CmsBlog> prepareBlogCards(List<CmsBlog> cmsBlogList) {
if (cmsBlogList == null || cmsBlogList.isEmpty()) {
return cmsBlogList;
}
Map<Long, CmsBlog> missingCoverBlogs = new HashMap<>();
for (CmsBlog blog : cmsBlogList) {
Long blogId = blog.getId();
//查询标签列表
List<CmsBlogTag> blogTagList = cmsBlogTagMapper.selectBlogTagList(blogId);
List<CmsTag> cmsTagList = new ArrayList<>();
blogTagList.forEach((CmsBlogTag cmsBlogTag)->{
Long tagId = cmsBlogTag.getTagId();
CmsTag cmsTag = cmsTagMapper.selectCmsTagByTagId(tagId);
cmsTagList.add(cmsTag);
});
blog.setTags(cmsTagList);
//查询分类列表
List<CmsBlogType> blogTypeList = cmsBlogTypeMapper.selectBlogTypeList(blogId);
List<CmsType> cmsTypeList = new ArrayList<>();
blogTypeList.forEach((CmsBlogType cmsBlogType)->{
Long typeId = cmsBlogType.getTypeId();
CmsType cmsType = cmsTypeMapper.selectCmsTypeByTypeId(typeId);
cmsTypeList.add(cmsType);
});
blog.setTypes(cmsTypeList);
boolean hasCover = (blog.getBlogPic() != null && !blog.getBlogPic().trim().isEmpty())
|| (blog.getBlogPicLink() != null && !blog.getBlogPicLink().trim().isEmpty());
if (!hasCover) {
missingCoverBlogs.put(blog.getId(), blog);
}
}
if (!missingCoverBlogs.isEmpty()) {
List<Long> ids = new ArrayList<>(missingCoverBlogs.keySet());
for (CmsBlog contentBlog : cmsBlogMapper.selectCmsBlogContentByIds(ids)) {
CmsBlog targetBlog = missingCoverBlogs.get(contentBlog.getId());
if (targetBlog == null || contentBlog.getContent() == null) {
continue;
}
String firstImageUrl = extractFirstImageFromContent(contentBlog.getContent());
if (firstImageUrl != null && !firstImageUrl.trim().isEmpty()) {
targetBlog.setBlogPicType("0");
targetBlog.setBlogPicLink(firstImageUrl);
}
}
}
return BlogListAddTypeAndTag(cmsBlogList);
}
private List<CmsBlog> BlogListAddTypeAndTag(List<CmsBlog> cmsBlogList){
if (cmsBlogList == null || cmsBlogList.isEmpty()) {
return cmsBlogList;
}
List<Long> blogIds = new ArrayList<>();
Map<Long, List<CmsTag>> tagsByBlogId = new HashMap<>();
Map<Long, List<CmsType>> typesByBlogId = new HashMap<>();
for (CmsBlog blog : cmsBlogList) {
blogIds.add(blog.getId());
tagsByBlogId.put(blog.getId(), new ArrayList<>());
typesByBlogId.put(blog.getId(), new ArrayList<>());
}
for (CmsBlogTag relation : cmsBlogTagMapper.selectBlogTagsByBlogIds(blogIds)) {
List<CmsTag> tags = tagsByBlogId.get(relation.getBlogId());
if (tags != null && relation.getTag() != null) {
tags.add(relation.getTag());
}
}
for (CmsBlogType relation : cmsBlogTypeMapper.selectBlogTypesByBlogIds(blogIds)) {
List<CmsType> types = typesByBlogId.get(relation.getBlogId());
if (types != null && relation.getType() != null) {
types.add(relation.getType());
}
}
for (CmsBlog blog : cmsBlogList) {
blog.setTags(tagsByBlogId.get(blog.getId()));
blog.setTypes(typesByBlogId.get(blog.getId()));
}
return cmsBlogList;
}

View File

@@ -0,0 +1,36 @@
package com.ruoyi.cms.sitemap.controller;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;
import com.ruoyi.cms.sitemap.service.SitemapService;
import org.springframework.http.CacheControl;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Public XML sitemap endpoint.
*/
@RestController
public class SitemapController
{
private static final MediaType APPLICATION_XML_UTF8 =
new MediaType("application", "xml", StandardCharsets.UTF_8);
private final SitemapService sitemapService;
public SitemapController(SitemapService sitemapService)
{
this.sitemapService = sitemapService;
}
@GetMapping(value = "/sitemap.xml", produces = MediaType.APPLICATION_XML_VALUE)
public ResponseEntity<String> sitemap()
{
return ResponseEntity.ok()
.contentType(APPLICATION_XML_UTF8)
.cacheControl(CacheControl.maxAge(10, TimeUnit.MINUTES).cachePublic())
.body(sitemapService.buildSitemap());
}
}

View File

@@ -0,0 +1,45 @@
package com.ruoyi.cms.sitemap.domain;
import java.util.Date;
/**
* A canonical, indexable URL source used to build the public sitemap.
*/
public class SitemapUrl
{
private Long id;
private String pageType;
private Date lastModified;
public Long getId()
{
return id;
}
public void setId(Long id)
{
this.id = id;
}
public String getPageType()
{
return pageType;
}
public void setPageType(String pageType)
{
this.pageType = pageType;
}
public Date getLastModified()
{
return lastModified;
}
public void setLastModified(Date lastModified)
{
this.lastModified = lastModified;
}
}

View File

@@ -0,0 +1,14 @@
package com.ruoyi.cms.sitemap.mapper;
import java.util.List;
import com.ruoyi.cms.sitemap.domain.SitemapUrl;
/**
* Queries only URLs that have a real, published public page.
*/
public interface SitemapMapper
{
public List<SitemapUrl> selectIndexableCategories();
public List<SitemapUrl> selectIndexableContent();
}

View File

@@ -0,0 +1,128 @@
package com.ruoyi.cms.sitemap.service;
import java.io.StringWriter;
import java.net.URI;
import java.time.format.DateTimeFormatter;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import com.ruoyi.cms.sitemap.domain.SitemapUrl;
import com.ruoyi.cms.sitemap.mapper.SitemapMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
/**
* Builds the UTF-8 sitemap from canonical URLs backed by published data.
*/
@Service
public class SitemapService
{
private static final String SITEMAP_NAMESPACE = "http://www.sitemaps.org/schemas/sitemap/0.9";
private final SitemapMapper sitemapMapper;
private final String siteUrl;
public SitemapService(SitemapMapper sitemapMapper,
@Value("${seo.site-url:https://www.yidaima.cn}") String siteUrl)
{
this.sitemapMapper = sitemapMapper;
this.siteUrl = normalizeSiteUrl(siteUrl);
}
public String buildSitemap()
{
Map<String, SitemapUrl> canonicalUrls = new LinkedHashMap<>();
addUrls(canonicalUrls, sitemapMapper.selectIndexableCategories());
addUrls(canonicalUrls, sitemapMapper.selectIndexableContent());
try
{
StringWriter output = new StringWriter();
XMLStreamWriter xml = XMLOutputFactory.newFactory().createXMLStreamWriter(output);
xml.writeStartDocument("UTF-8", "1.0");
xml.writeStartElement("urlset");
xml.writeDefaultNamespace(SITEMAP_NAMESPACE);
for (Map.Entry<String, SitemapUrl> entry : canonicalUrls.entrySet())
{
xml.writeStartElement("url");
writeElement(xml, "loc", siteUrl + entry.getKey());
if (entry.getValue().getLastModified() != null)
{
writeElement(xml, "lastmod",
DateTimeFormatter.ISO_INSTANT.format(entry.getValue().getLastModified().toInstant()));
}
xml.writeEndElement();
}
xml.writeEndElement();
xml.writeEndDocument();
xml.close();
return output.toString();
}
catch (XMLStreamException exception)
{
throw new IllegalStateException("Unable to generate sitemap XML", exception);
}
}
private void addUrls(Map<String, SitemapUrl> canonicalUrls, List<SitemapUrl> urls)
{
if (urls == null)
{
return;
}
for (SitemapUrl url : urls)
{
if (url == null || url.getId() == null || !isSupportedPageType(url.getPageType()))
{
continue;
}
canonicalUrls.putIfAbsent("/" + url.getPageType() + "/" + url.getId(), url);
}
}
private boolean isSupportedPageType(String pageType)
{
return "category".equals(pageType) || "source".equals(pageType) || "article".equals(pageType);
}
private void writeElement(XMLStreamWriter xml, String name, String value) throws XMLStreamException
{
xml.writeStartElement(name);
xml.writeCharacters(value);
xml.writeEndElement();
}
private String normalizeSiteUrl(String configuredSiteUrl)
{
String value = configuredSiteUrl == null ? "" : configuredSiteUrl.trim();
while (value.endsWith("/"))
{
value = value.substring(0, value.length() - 1);
}
URI uri;
try
{
uri = URI.create(value);
}
catch (IllegalArgumentException exception)
{
throw new IllegalStateException("seo.site-url must be an absolute HTTP(S) URL", exception);
}
if (uri.getHost() == null
|| (!"http".equalsIgnoreCase(uri.getScheme()) && !"https".equalsIgnoreCase(uri.getScheme()))
|| uri.getQuery() != null || uri.getFragment() != null)
{
throw new IllegalStateException("seo.site-url must be an absolute HTTP(S) URL without query or fragment");
}
return value;
}
}

View File

@@ -47,12 +47,7 @@ public class CmsTagServiceImpl implements ICmsTagService
@Override
public List<CmsTag> selectCmsTagList(CmsTag cmsTag)
{
List<CmsTag> cmsTagList = cmsTagMapper.selectCmsTagList(cmsTag);
for (CmsTag tag : cmsTagList) {
int blogNum = cmsBlogTagMapper.countBlogByTagId(tag.getTagId());
tag.setBlogNum(blogNum);
}
return cmsTagList;
return cmsTagMapper.selectCmsTagList(cmsTag);
}
/**

View File

@@ -51,12 +51,7 @@ public class CmsTypeServiceImpl implements ICmsTypeService
@Override
public List<CmsType> selectCmsTypeList(CmsType cmsType)
{
List<CmsType> cmsTypeList = cmsTypeMapper.selectCmsTypeList(cmsType);
for (CmsType type : cmsTypeList) {
int blogNum = cmsBlogTypeMapper.countBlogByTypeId(type.getTypeId());
type.setBlogNum(blogNum);
}
return cmsTypeList;
return cmsTypeMapper.selectCmsTypeList(cmsType);
}
/**

View File

@@ -29,6 +29,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
select id, create_by, create_time, update_by, update_time, title, type, content, content_type, content_markdown, Top, views, status, blog_pic_type, blog_pic, blog_pic_link, blog_desc, blog_files from cms_blog
</sql>
<sql id="selectCmsBlogCardVo">
select id, create_by, create_time, update_time, title, type, Top, views, status,
blog_pic_type, blog_pic, blog_pic_link, blog_desc
from cms_blog
</sql>
<select id="selectCmsBlogList" parameterType="CmsBlog" resultMap="CmsBlogResult">
<include refid="selectCmsBlogVo"/>
<where>
@@ -42,25 +48,55 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</where>
ORDER BY Top DESC, create_time DESC
</select>
<select id="selectCmsBlogCardList" parameterType="CmsBlog" resultMap="CmsBlogResult">
<include refid="selectCmsBlogCardVo"/>
<where>
<if test="title != null and title != ''"> and title like concat('%', #{title}, '%')</if>
<if test="type != null and type != ''"> and type = #{type}</if>
<if test="top != null and top != ''"> and Top = #{top}</if>
<if test="views != null "> and views = #{views}</if>
<if test="status != null and status != ''"> and status = #{status}</if>
<if test="createBy != null and createBy != ''"> and create_by = #{createBy}</if>
</where>
ORDER BY Top DESC, create_time DESC
</select>
<select id="selectCmsBlogContentByIds" resultMap="CmsBlogResult">
select id, content
from cms_blog
where id in
<foreach collection="list" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
<select id="selectCmsBlogById" parameterType="Long" resultMap="CmsBlogResult">
<include refid="selectCmsBlogVo"/>
where id = #{id}
</select>
<select id="selectCmsBlogListByTypeId" parameterType="Long" resultMap="CmsBlogResult">
<select id="selectPublishedCmsBlogById" parameterType="Long" resultMap="CmsBlogResult">
<include refid="selectCmsBlogVo"/>
where id = #{id} and status = '1'
</select>
<select id="selectCmsBlogListByTypeId" parameterType="Long" resultMap="CmsBlogResult">
<include refid="selectCmsBlogCardVo"/>
<where>
<if test="id != null and id != ''"> and id in (SELECT blog_id FROM cms_blog_type WHERE type_id = #{id})</if>
and status = '1'
</where>
ORDER BY Top DESC, create_time DESC
</select>
<select id="selectCmsBlogListByTagId" parameterType="Long" resultMap="CmsBlogResult">
<include refid="selectCmsBlogVo"/>
<include refid="selectCmsBlogCardVo"/>
<where>
<if test="id != null and id != ''"> and id in (SELECT blog_id FROM cms_blog_tag WHERE tag_id = #{id})</if>
and status = '1'
</where>
ORDER BY Top DESC, create_time DESC
</select>
<select id="selectCmsBlogListRecommend" parameterType="CmsBlog" resultMap="CmsBlogResult">
<include refid="selectCmsBlogVo"/>
<include refid="selectCmsBlogCardVo"/>
<where>
<if test="title != null and title != ''"> and title like concat('%', #{title}, '%')</if>
<if test="type != null and type != ''"> and type = #{type}</if>
@@ -188,4 +224,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="createBy != null and createBy != ''"> and create_by = #{createBy}</if>
</where>
</select>
</mapper>
</mapper>

View File

@@ -5,6 +5,14 @@
<result property="tagId" column="tag_id" />
<result property="blogId" column="blog_id" />
</resultMap>
<resultMap type="cmsBlogTag" id="blogTagWithTagResult">
<result property="tagId" column="tag_id" />
<result property="blogId" column="blog_id" />
<association property="tag" javaType="com.ruoyi.cms.tag.domain.CmsTag">
<id property="tagId" column="tag_id" />
<result property="tagName" column="tag_name" />
</association>
</resultMap>
<insert id="batchBlogTag">
insert into cms_blog_tag(tag_id, blog_id) values
@@ -30,7 +38,16 @@
<select id="selectBlogTagList" parameterType="Long" resultMap="blogTagResult">
select tag_id, blog_id from cms_blog_tag where blog_id = #{blogId}
</select>
<select id="selectBlogTagsByBlogIds" resultMap="blogTagWithTagResult">
select bt.blog_id, t.tag_id, t.tag_name
from cms_blog_tag bt
inner join cms_tag t on t.tag_id = bt.tag_id
where bt.blog_id in
<foreach collection="list" item="blogId" open="(" separator="," close=")">
#{blogId}
</foreach>
</select>
<select id="countBlogByTagId" parameterType="Long" resultType="java.lang.Integer">
select count(*) from cms_blog_tag where tag_id=#{tagId}
</select>
</mapper>
</mapper>

View File

@@ -5,6 +5,14 @@
<result property="typeId" column="type_id" />
<result property="blogId" column="blog_id" />
</resultMap>
<resultMap type="CmsBlogType" id="blogTypeWithTypeResult">
<result property="typeId" column="type_id" />
<result property="blogId" column="blog_id" />
<association property="type" javaType="com.ruoyi.cms.type.domain.CmsType">
<id property="typeId" column="type_id" />
<result property="typeName" column="type_name" />
</association>
</resultMap>
<insert id="batchBlogType">
insert into cms_blog_type(type_id, blog_id) values
@@ -30,7 +38,16 @@
<select id="selectBlogTypeList" parameterType="Long" resultMap="blogTypeResult">
select type_id, blog_id from cms_blog_type where blog_id = #{blogId}
</select>
<select id="selectBlogTypesByBlogIds" resultMap="blogTypeWithTypeResult">
select bt.blog_id, t.type_id, t.type_name
from cms_blog_type bt
inner join cms_type t on t.type_id = bt.type_id
where bt.blog_id in
<foreach collection="list" item="blogId" open="(" separator="," close=")">
#{blogId}
</foreach>
</select>
<select id="countBlogByTypeId" parameterType="Long" resultType="java.lang.Integer">
select count(*) from cms_blog_type where type_id=#{typeId}
</select>
</mapper>
</mapper>

View File

@@ -11,6 +11,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<result property="tagName" column="tag_name" />
<result property="blogNum" column="blog_num" />
</resultMap>
<sql id="selectCmsTagVo">
@@ -18,12 +19,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</sql>
<select id="selectCmsTagList" parameterType="CmsTag" resultMap="CmsTagResult">
<include refid="selectCmsTagVo"/>
select t.tag_id, t.create_by, t.create_time, t.update_by, t.update_time, t.tag_name,
count(bt.blog_id) as blog_num
from cms_tag t
left join cms_blog_tag bt on bt.tag_id = t.tag_id
<where>
<if test="tagName != null and tagName != ''"> and tag_name like concat('%', #{tagName}, '%')</if>
<if test="createBy != null and createBy != ''"> and create_by = #{createBy}</if>
<if test="tagName != null and tagName != ''"> and t.tag_name like concat('%', #{tagName}, '%')</if>
<if test="createBy != null and createBy != ''"> and t.create_by = #{createBy}</if>
</where>
ORDER BY create_time DESC
group by t.tag_id, t.create_by, t.create_time, t.update_by, t.update_time, t.tag_name
ORDER BY t.create_time DESC
</select>
<select id="selectCmsTagByTagId" parameterType="Long" resultMap="CmsTagResult">
@@ -75,4 +80,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
#{tagId}
</foreach>
</delete>
</mapper>
</mapper>

View File

@@ -14,6 +14,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="typePicType" column="type_pic_type" />
<result property="typePic" column="type_pic" />
<result property="typePicLink" column="type_pic_link" />
<result property="blogNum" column="blog_num" />
</resultMap>
<sql id="selectCmsTypeVo">
@@ -21,13 +22,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</sql>
<select id="selectCmsTypeList" parameterType="CmsType" resultMap="CmsTypeResult">
<include refid="selectCmsTypeVo"/>
select t.type_id, t.create_by, t.create_time, t.update_by, t.update_time, t.type_name,
t.type_pic_type, t.type_pic, t.type_pic_link, count(bt.blog_id) as blog_num
from cms_type t
left join cms_blog_type bt on bt.type_id = t.type_id
<where>
<if test="typeName != null and typeName != ''"> and type_name like concat('%', #{typeName}, '%')</if>
<if test="typePic != null and typePic != ''"> and type_pic = #{typePic}</if>
<if test="createBy != null and createBy != ''"> and create_by = #{createBy}</if>
<if test="typeName != null and typeName != ''"> and t.type_name like concat('%', #{typeName}, '%')</if>
<if test="typePic != null and typePic != ''"> and t.type_pic = #{typePic}</if>
<if test="createBy != null and createBy != ''"> and t.create_by = #{createBy}</if>
</where>
ORDER BY create_time DESC
group by t.type_id, t.create_by, t.create_time, t.update_by, t.update_time, t.type_name,
t.type_pic_type, t.type_pic, t.type_pic_link
ORDER BY t.create_time DESC
</select>
<select id="selectCmsTypeByTypeId" parameterType="Long" resultMap="CmsTypeResult">
@@ -88,4 +94,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
#{typeId}
</foreach>
</delete>
</mapper>
</mapper>

View File

@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.cms.sitemap.mapper.SitemapMapper">
<resultMap type="com.ruoyi.cms.sitemap.domain.SitemapUrl" id="SitemapUrlResult">
<result property="id" column="id" />
<result property="pageType" column="page_type" />
<result property="lastModified" column="last_modified" />
</resultMap>
<!-- Empty categories do not have an indexable category page. -->
<select id="selectIndexableCategories" resultMap="SitemapUrlResult">
SELECT
t.type_id AS id,
'category' AS page_type,
CASE
WHEN COALESCE(t.update_time, t.create_time) > MAX(COALESCE(b.update_time, b.create_time))
THEN COALESCE(t.update_time, t.create_time)
ELSE MAX(COALESCE(b.update_time, b.create_time))
END AS last_modified
FROM cms_type t
INNER JOIN cms_blog_type bt ON bt.type_id = t.type_id
INNER JOIN cms_blog b ON b.id = bt.blog_id AND b.status = '1'
GROUP BY t.type_id, t.update_time, t.create_time
ORDER BY t.type_id
</select>
<!-- Published content has exactly one article or source canonical URL. -->
<select id="selectIndexableContent" resultMap="SitemapUrlResult">
SELECT
b.id,
CASE
WHEN b.blog_files IS NOT NULL
AND LOWER(REPLACE(TRIM(b.blog_files), ' ', '')) NOT IN ('', '[]', 'null')
THEN 'source'
ELSE 'article'
END AS page_type,
COALESCE(b.update_time, b.create_time) AS last_modified
FROM cms_blog b
WHERE b.status = '1'
ORDER BY b.id
</select>
</mapper>