...
 
Commits (10)
    https://gitcode.net/u011197448/oneblog/-/commit/7dfe30728db22ed1c21fb161af28a79ec2dcb530 :bulb: 每晚凌晨12点自动检查友联,对于私自取消友联的网站实行自动封禁 2021-11-01T21:34:08+08:00 yadong.zhang yadong.zhang0415@gmail.com https://gitcode.net/u011197448/oneblog/-/commit/32077bce59692db19646b49dd214cc06bc346a88 :sparkles: 文章支持设置【登录后可见】 2021-11-01T21:53:53+08:00 yadong.zhang yadong.zhang0415@gmail.com https://gitcode.net/u011197448/oneblog/-/commit/02edfb2cc645929278add7b8a0a02d2734c4fde8 :sparkles: 文章支持设置【登录后可见】 2021-11-01T21:58:00+08:00 yadong.zhang yadong.zhang0415@gmail.com https://gitcode.net/u011197448/oneblog/-/commit/a1a1339931ffce90d77b578697a871f997a7c6d3 :sparkles: 文章支持设置【登录后可见】 2021-11-01T21:58:37+08:00 yadong.zhang yadong.zhang0415@gmail.com https://gitcode.net/u011197448/oneblog/-/commit/c838b2d9822d4277d96ad92fd9d970545b678a8a :bulb: 优化web端的分类展示,支持以滚动菜单的形式展示分类,防止因分类太多导致菜单栏溢出的问题 2021-11-02T12:57:03+08:00 yadong.zhang yadong.zhang0415@gmail.com https://gitcode.net/u011197448/oneblog/-/commit/4046d225b922da74164f22fad3699c482032c910 :bulb: 优化侧边栏文章列表的 header 样式 2021-11-02T13:31:34+08:00 yadong.zhang yadong.zhang0415@gmail.com https://gitcode.net/u011197448/oneblog/-/commit/3063e7cbb89256fa58ae2399c035cf9d6bab2f0b :bulb: 优化广告位,增加【首页顶部】广告位 2021-11-02T13:52:12+08:00 yadong.zhang yadong.zhang0415@gmail.com https://gitcode.net/u011197448/oneblog/-/commit/8d9157aa6b9e55f6dde8eeeeb58a205d5a058b93 :bulb: 支持禁用一言插件(该插件部分时候加载较慢) 2021-11-02T14:07:54+08:00 yadong.zhang yadong.zhang0415@gmail.com https://gitcode.net/u011197448/oneblog/-/commit/fc814fd81f932b2b4148197aebc4fc209f0a18aa :bulb: 优化代码 2021-11-02T20:32:22+08:00 yadong.zhang yadong.zhang0415@gmail.com https://gitcode.net/u011197448/oneblog/-/commit/4401b4b710a687ce08e0e88abfb39929e51bf456 :bookmark: 升级到 2.3.3 2021-11-05T17:38:21+08:00 yadong.zhang yadong.zhang0415@gmail.com
......@@ -12,7 +12,7 @@
<parent>
<groupId>com.zyd</groupId>
<artifactId>blog</artifactId>
<version>2.3.2</version>
<version>2.3.3</version>
</parent>
<dependencies>
......
package com.zyd.blog.core.schedule;
import com.zyd.blog.business.entity.Link;
import com.zyd.blog.business.enums.ConfigKeyEnum;
import com.zyd.blog.business.service.SysConfigService;
import com.zyd.blog.business.service.SysLinkService;
import com.zyd.blog.business.util.LinksUtil;
import com.zyd.blog.persistence.beans.SysConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.List;
/**
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
* @version 1.0.0
* @since 1.0.0
*/
@Slf4j
@Component
public class FriendlyLinkTask {
@Autowired
private SysLinkService sysLinkService;
@Autowired
private SysConfigService sysConfigService;
@Value("${app.enableAutoCheckLink}")
private boolean enableAutoCheckLink;
/**
* 每晚凌晨12点,检查友情链接
*/
@Scheduled(cron = "0 0 0 * * ?")
public void check() {
// 未开启自动检查友联的功能
if (!enableAutoCheckLink) {
return;
}
List<Link> linkList = sysLinkService.listAll();
if (CollectionUtils.isEmpty(linkList)) {
return;
}
SysConfig sysConfig = sysConfigService.getByKey(ConfigKeyEnum.DOMAIN.getKey());
if (StringUtils.isEmpty(sysConfig)) {
return;
}
String domain = sysConfig.getConfigValue();
for (Link link : linkList) {
if (!link.isStatus()) {
// 被禁用的网站如果又包含了本站链接,说明其已经恢复本站的友联
// 因此自动恢复其友联
if (LinksUtil.hasLinkByHtml(link.getUrl(), domain)
|| LinksUtil.hasLinkByChinaz(link.getUrl(), domain)) {
link.setStatus(true);
link.setDescription("");
sysLinkService.updateSelective(link);
}
continue;
}
// 已经不存在本站链接,自动下架该网站的友联
if (!(LinksUtil.hasLinkByHtml(link.getUrl(), domain))
&& !LinksUtil.hasLinkByChinaz(link.getUrl(), domain)) {
link.setStatus(false);
link.setDescription("系统检测到该网站已经取消本站的链接,因此自动封禁其友链");
sysLinkService.updateSelective(link);
log.info("系统监测到该网站([{}])已经私自取消本站链接,因此自动下架的友联", link.getName());
}
}
}
}
......@@ -17,6 +17,10 @@ logging:
app:
# 是否启用kaptcha验证码
enableKaptcha: ${ONEBLOG_APP_ENABLE_KAPTCHA:false}
# 是否启用自动校验友情链接的功能
# 请选择打开,一旦打开,每晚凌晨12点会自动检查友联,对于不包含本站链接的网站实行自动封禁
# 目前暂时没实现白名单的功能
enableAutoCheckLink: ${ONEBLOG_APP_ENABLE_CHECK_LINK:false}
# 启用后,项目在启动时会打印数据库(Mysql和Redis)链接信息(包含密码)
# 代码请参考
enabledPrintConfig: ${ONEBLOG_APP_ENABLE_PRINT_CONFIG:false}
......
......@@ -23,6 +23,15 @@
</div>
<@addOrUpdateMOdal defaultTitle="添加分类">
<input type="hidden" name="id">
<div class="item form-group">
<label class="control-label col-md-3 col-sm-3 col-xs-12" for="type">显示位置 <span class="required">*</span></label>
<div class="col-md-6 col-sm-6 col-xs-6">
<select id="position" name="position" class="form-control col-md-5 col-xs-5" required="required">
<option value="nav">顶部菜单(不适宜太多)</option>
<option value="scrollmenu">首页滚动菜单(理论上可以有无限多个横向排列)</option>
</select>
</div>
</div>
<div class="item form-group">
<label class="control-label col-md-3 col-sm-3 col-xs-12" for="name">名称 <span class="required">*</span></label>
<div class="col-md-6 col-sm-6 col-xs-12">
......@@ -131,6 +140,13 @@
}
return '<a href="' + appConfig.wwwPath + '/type/' + parent.id + '" target="_blank">' + parent.name + '</a>';
}
}, {
field: 'position',
title: '显示位置',
width: '100px',
formatter: function (code) {
return code ? code : '-';
}
}, {
field: 'description',
title: '描述',
......
......@@ -50,6 +50,9 @@
<li role="presentation" class="">
<a href="#tab_hunter" role="tab" id="hunter-tab" data-toggle="tab" aria-expanded="false"><i class="fa fa-bug fa-fw"></i> Hunter 配置</a>
</li>
<li role="presentation" class="">
<a href="#tab_plugin" role="tab" id="plugin-tab" data-toggle="tab" aria-expanded="false"><i class="fa fa-plug fa-fw"></i> Plugin</a>
</li>
</ul>
<div id="myTabContent" class="tab-content">
<div role="tabpanel" class="tab-pane fade active in" id="tab_basic"
......@@ -651,6 +654,26 @@
</div>
</form>
</div>
<div role="tabpanel" class="tab-pane fade" id="tab_plugin" aria-labelledby="plugin-tab">
<form class="form-horizontal form-label-left" novalidate>
<div class="item form-group">
<label class="control-label col-md-3 col-sm-3 col-xs-12" for="maintenance">启用 Hitokoto(一言)
<i class="fa fa-question-circle" title="一言,随机显示一句话的插件,该插件部分时候加载较慢,如果不需要请自行关闭"></i> </label>
<div class="col-md-6 col-sm-6 col-xs-12 fixed-radio-checkbox">
<ul class="list-unstyled list-inline">
<li><label for="maintenance" class="pointer"> <input type="radio" class="square" checked name="enableHitokoto" value="1"> 显示 </label> </li>
<li><label for="maintenance" class="pointer"> <input type="radio" class="square" name="enableHitokoto" value="0"> 关闭 </label></li>
</ul>
</div>
</div>
<div class="item form-group">
<label class="control-label col-md-3 col-sm-3 col-xs-12" for="comment"></label>
<div class="col-md-6 col-sm-6 col-xs-12">
<button type="button" class="btn btn-primary saveBtn"><i class="fa fa-save"> 保存</i></button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
......
......@@ -183,6 +183,15 @@
<input type="text" class="square form-control" name="password" placeholder="请输入文章密码">
</div>
</div>
<div class="item form-group">
<label class="control-label col-md-2 col-sm-2 col-xs-12" for="comment">登录后可见? </label>
<div class="col-md-10 col-sm-10 col-xs-12 fixed-radio-checkbox">
<ul class="list-unstyled list-inline">
<li><input type="radio" class="square" name="requiredAuth" value="1"></li>
<li><input type="radio" class="square" checked name="requiredAuth" value="0"></li>
</ul>
</div>
</div>
</div>
</div>
</div>
......
......@@ -12,7 +12,7 @@
<parent>
<groupId>com.zyd</groupId>
<artifactId>blog</artifactId>
<version>2.3.2</version>
<version>2.3.3</version>
</parent>
<dependencies>
......
......@@ -12,7 +12,7 @@
<parent>
<groupId>com.zyd</groupId>
<artifactId>blog</artifactId>
<version>2.3.2</version>
<version>2.3.3</version>
</parent>
<dependencies>
......
......@@ -142,6 +142,15 @@ public class Article {
this.bizArticle.setRecommended(value);
}
public boolean getRequiredAuth() {
Boolean value = this.bizArticle.getRequiredAuth();
return value != null && value;
}
public void setRequiredAuth(Boolean requiredAuth) {
this.bizArticle.setRequiredAuth(requiredAuth);
}
public boolean isOriginal() {
Boolean value = this.bizArticle.getOriginal();
return value != null ? value : false;
......
......@@ -90,6 +90,14 @@ public class Type {
this.bizType.setIcon(icon);
}
public String getPosition() {
return this.bizType.getPosition();
}
public void setPosition(String position) {
this.bizType.setPosition(position);
}
public Date getCreateTime() {
return this.bizType.getCreateTime();
}
......
......@@ -19,6 +19,10 @@ import java.util.Map;
@AllArgsConstructor
public enum AdPositionEnum {
/**
* 首页顶部
*/
HOMEPAGE_TOP("首页顶部"),
/**
* 每次刷新页面都弹窗显示,AdType 必须为 POP
*/
......
......@@ -245,6 +245,11 @@ public enum ConfigKeyEnum {
* blog-hunter 配置文件,如果没有添加该配置,则默认取 src/main/resources/HunterConfig.json
*/
BLOG_HUNTER_CONFIG("blogHunterConfig"),
/**
* 启用 Hitokoto(一言)。一言,随机显示一句话的插件,该插件部分时候加载较慢,如果不需要请自行关闭
*/
ENABLE_HITOKOTO("enableHitokoto"),
;
private final String key;
......
......@@ -30,4 +30,6 @@ public interface BizTypeService extends AbstractService<Type, Long> {
List<Type> listParent();
List<Type> listTypeForMenu();
List<Type> listTypeByPosition(String position);
}
......@@ -15,6 +15,8 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;
import java.util.ArrayList;
import java.util.Date;
......@@ -64,6 +66,17 @@ public class BizTypeServiceImpl implements BizTypeService {
return getTypes(entityList);
}
@Override
public List<Type> listTypeByPosition(String position) {
Example example = new Example(BizType.class);
Example.Criteria criteria = example.createCriteria();
criteria.andEqualTo("position", StringUtils.isEmpty(position) ? "scrollmenu" : position)
.andEqualTo("available", true);
example.setOrderByClause("sort ASC");
List<BizType> entityList = bizTypeMapper.selectByExample(example);
return getTypes(entityList);
}
private List<Type> getTypes(List<BizType> list) {
if (CollectionUtils.isEmpty(list)) {
return null;
......
......@@ -64,6 +64,11 @@ public class CustomTags extends BaseTag {
return bizTypeService.listTypeForMenu();
}
public Object scrollmenus(Map params) {
String position = getParam(params, "position");
return bizTypeService.listTypeByPosition(position);
}
public Object tagsList(Map params) {
return bizTagsService.listAll();
}
......
......@@ -38,6 +38,7 @@ public class BizArticle extends AbstractDO {
private String keywords;
private Boolean comment;
private String password;
private Boolean requiredAuth;
private String editorType;
@Transient
private Integer lookCount;
......
......@@ -23,6 +23,7 @@ public class BizType extends AbstractDO {
private Integer sort;
private Boolean available;
private String icon;
private String position;
@Transient
......
......@@ -86,5 +86,5 @@ pagehelper:
params: count=countSql
app:
version: v2.3.2
version: v2.3.3
enableRedisCache: ${ONEBLOG_ENABLE_REDIS_CACHE:false}
......@@ -23,6 +23,7 @@
<result property="updateTime" jdbcType="TIMESTAMP" column="update_time"/>
<result property="comment" jdbcType="BIT" column="comment"/>
<result property="password" jdbcType="VARCHAR" column="password"/>
<result property="requiredAuth" jdbcType="BIT" column="required_auth"/>
<result property="lookCount" jdbcType="INTEGER" column="look_count"/>
<result property="commentCount" jdbcType="INTEGER" column="comment_count"/>
......@@ -58,6 +59,7 @@
a.`comment`,
a.`editor_type`,
a.`password`,
a.`required_auth`,
a.create_time,
a.update_time,
btype.id AS btype_id,
......@@ -159,6 +161,7 @@
a.keywords,
a.`comment`,
a.`password`,
a.`required_auth`,
a.create_time,
a.update_time,
btype.id AS btype_id,
......
......@@ -10,6 +10,7 @@
<result property="sort" jdbcType="INTEGER" column="sort"/>
<result property="available" jdbcType="BIT" column="available"/>
<result property="icon" jdbcType="VARCHAR" column="icon"/>
<result property="position" jdbcType="VARCHAR" column="position"/>
<result property="createTime" jdbcType="TIMESTAMP" column="create_time"/>
<result property="updateTime" jdbcType="TIMESTAMP" column="update_time"/>
<association property="parent" javaType="com.zyd.blog.persistence.beans.BizType">
......@@ -19,6 +20,7 @@
<result property="description" jdbcType="VARCHAR" column="parent_description"/>
<result property="available" jdbcType="BIT" column="parent_available"/>
<result property="icon" jdbcType="VARCHAR" column="parent_icon"/>
<result property="position" jdbcType="VARCHAR" column="parent_position"/>
</association>
<collection property="nodes" column="node_id" javaType="ArrayList" ofType="com.zyd.blog.persistence.beans.BizType">
<result property="id" jdbcType="BIGINT" column="node_id"/>
......@@ -27,6 +29,7 @@
<result property="description" jdbcType="VARCHAR" column="node_description"/>
<result property="available" jdbcType="BIT" column="node_available"/>
<result property="icon" jdbcType="VARCHAR" column="node_icon"/>
<result property="position" jdbcType="VARCHAR" column="node_position"/>
</collection>
</resultMap>
......@@ -38,7 +41,8 @@
parent.`name` parent_name,
parent.description parent_description,
parent.available parent_available,
parent.icon parent_icon
parent.icon parent_icon,
parent.position parent_position
FROM
biz_type t
LEFT JOIN biz_type parent ON t.pid = parent.id
......@@ -83,13 +87,15 @@
node.`name` node_name,
node.description node_description,
node.available node_available,
node.icon node_icon
node.icon node_icon,
node.position node_position
FROM
biz_type t
LEFT JOIN biz_type parent ON t.pid = parent.id
LEFT JOIN biz_type node ON node.pid = t.id
WHERE
t.available = 1
AND t.position = 'nav'
AND (t.pid IS NULL OR t.pid = '')
ORDER BY
t.sort ASC
......
......@@ -12,7 +12,7 @@
<parent>
<groupId>com.zyd</groupId>
<artifactId>blog</artifactId>
<version>2.3.2</version>
<version>2.3.3</version>
</parent>
<properties>
......
......@@ -12,7 +12,7 @@
<parent>
<groupId>com.zyd</groupId>
<artifactId>blog</artifactId>
<version>2.3.2</version>
<version>2.3.3</version>
</parent>
<dependencies>
......
......@@ -3,6 +3,7 @@ package com.zyd.blog.controller;
import com.github.pagehelper.PageInfo;
import com.zyd.blog.business.annotation.BussinessLog;
import com.zyd.blog.business.entity.Article;
import com.zyd.blog.business.entity.User;
import com.zyd.blog.business.enums.ArticleStatusEnum;
import com.zyd.blog.business.enums.PlatformEnum;
import com.zyd.blog.business.service.BizArticleArchivesService;
......@@ -11,6 +12,7 @@ import com.zyd.blog.business.service.SysLinkService;
import com.zyd.blog.business.service.SysUpdateRecordeService;
import com.zyd.blog.business.vo.ArticleConditionVO;
import com.zyd.blog.util.ResultUtil;
import com.zyd.blog.util.SessionUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
......@@ -19,7 +21,6 @@ import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.Map;
......@@ -188,11 +189,17 @@ public class RenderController {
if (article == null || ArticleStatusEnum.UNPUBLISHED.getCode() == article.getStatusEnum().getCode()) {
return ResultUtil.forward("/error/404");
}
if(article.getPrivate()) {
if (article.getPrivate()) {
article.setPassword(null);
article.setContent(null);
article.setContentMd(null);
}
if (article.getRequiredAuth()) {
User sessionUser = SessionUtil.getUser();
if (null != sessionUser) {
article.setRequiredAuth(false);
}
}
model.addAttribute("article", article);
// 上一篇下一篇
model.addAttribute("other", bizArticleService.getPrevAndNextArticles(article.getCreateTime()));
......
......@@ -18,7 +18,7 @@ braum:
limit:
access:
type: redis
threshold: 15
threshold: 30
interval: 5000
####################################自定义配置##########################################
......
......@@ -500,7 +500,7 @@ a:-webkit-any-link {
}
.article-blockquote-green {
background: #427e53;
background: #4dab68;
}
.article-original-green {
background: #5FB878;
......@@ -541,10 +541,11 @@ a:-webkit-any-link {
/* 面包屑导航 */
.breadcrumb {
padding: 4px;
padding: 10px;
margin-bottom: 10px;
list-style: none;
background-color: #ffffff;
border-radius: 0;
}
/* 面包屑导航 */
......@@ -841,22 +842,19 @@ span.separation:AFTER {
}
.sidebar-module .sidebar-tabs {
background-color: #eee;
text-align: center;
background-color: unset;
margin-left: -9px;
margin-right: -9px;
}
.sidebar-module .sidebar-tabs li.active {
font-weight: 700;
.sidebar-module .sidebar-tabs li.active, .sidebar-module .sidebar-tabs li.active a {
background-color: #eee!important;
}
.sidebar-module .sidebar-tabs li.hover {
background-color: #333;
}
.sidebar-module .sidebar-tabs li a:hover {
.sidebar-module .sidebar-tabs li.hover, .sidebar-module .sidebar-tabs li:hover a {
font-weight: 700;
background-color: #333;
background-color: #333!important;
}
.sidebar-module .tab-content .empty-list {
......@@ -1051,10 +1049,10 @@ span.separation:AFTER {
.separateline span {
position: relative;
top: -14px;
top: -12px;
padding: 2px 4px;
/*border:1px solid #d6d6d6;*/
background-color: #ffffff;
background-color: #ffffffa3;
color: #006741 !important;
}
......@@ -2479,6 +2477,7 @@ nav a:first-child .meta-nav {
.about-main {
font-size: 14px;
padding: 0 15px;
text-align: center;
}
.about-img {
......@@ -3611,8 +3610,8 @@ img {
/* 广告 */
.ad-mark {
padding: 8px;
position: relative;
margin-bottom: 10px;
}
.ad-mark:after {
......@@ -3623,3 +3622,49 @@ img {
color: #e8e8e8;
font-size: 12px;
}
div.scrollmenu {
overflow: auto;
white-space: nowrap;
background-color: #ffffff!important;
}
div.scrollmenu a, div.scrollmenu span {
display: inline-block;
color: #333;
text-align: center;
padding: 10px;
text-decoration: none;
}
div.scrollmenu a.active, div.scrollmenu a:hover {
background-color: #eeeeee!important;
}
.ob-alert {
background: #fffcef;
padding: 15px;
color: #db7c22;
border: 1px solid #ffbb76;
}
.ob-alert .title {
display: flex;
align-items: center;
margin-bottom: 10px;
font-size: 15px;
font-weight: 500
}
.ob-alert .title .icon {
width: 20px;
height: 20px;
margin-right: 8px
}
.ob-alert .content {
padding: 0;
padding-left: 28px;
}
......@@ -43,6 +43,8 @@
</div>
<@footer>
<script src="https://v1.hitokoto.cn/?encode=js&c=i&select=%23hitokoto" defer></script>
<#if (config.enableHitokoto == 1 || config.enableHitokoto == "1")>
<script src="https://v1.hitokoto.cn/?encode=js&c=i&select=.hitokoto" defer></script>
</#if>
</@footer>
</@compress>
......@@ -18,7 +18,9 @@
<@zhydTag method="siteInfo">
<div class="archives-meta"> 站点统计:${siteInfo.typeCount!(0)}个分类&nbsp;&nbsp; ${siteInfo.tagCount!(0)}个标签&nbsp;&nbsp; ${siteInfo.articleCount!(0)}篇文章&nbsp;&nbsp; ${siteInfo.commentCount!(0)}条留言&nbsp;&nbsp; 最后更新:${siteInfo.lastUpdateTime} </div>
</@zhydTag>
<p class="blog-description hitokoto"></p>
<#if (config.enableHitokoto == 1 || config.enableHitokoto == "1")>
<p class="blog-description hitokoto"></p>
</#if>
</div>
<div class="archives-body">
<div class="archives-box overflow-initial">
......@@ -48,9 +50,6 @@
</#list>
</div>
</div>
<div class="article-footer overflow-initial">
<span class="blog-description hitokoto num"></span>
</div>
</div>
</div>
</div>
......@@ -79,6 +78,8 @@
})();
});
</script>
<script src="https://v1.hitokoto.cn/?encode=js&c=i&select=.hitokoto%27);dom=$('.hitokoto');for(var i=0;i<dom.length;i%2B%2B){dom[i].innerText=hitokoto;}})()//" defer></script>
<#if (config.enableHitokoto == 1 || config.enableHitokoto == "1")>
<script src="https://v1.hitokoto.cn/?encode=js&c=i&select=.hitokoto" defer></script>
</#if>
</@footer>
</@compress>
......@@ -39,15 +39,34 @@
<strong>${article.title}</strong>
</h1>
<div class="blog-info-body ${article.isMarkdown?string('markdown-body editor-preview-active-side', '')}">
<#if article.private>
${article.description!}
<br>
<#-- 文章最后修改日期的判断 -->
<#assign intervalDayNum=((.now?long - article.updateTime?long)?abs / (1000 * 60 * 60 * 24))?int>
<#if intervalDayNum gt 1>
<div class="ob-alert">
<div class="title">
<i class="fa fa-bullhorn fa-fw"></i>
<span class="text">温馨提示:</span>
</div>
<div class="content">
本文最后更新于 ${article.updateTime?string('yyyy年MM月dd日')},已超过 ${intervalDayNum} 天没有更新。若文章内的图片失效(无法正常加载),请留言反馈或直接<a href="mailto:${config.authorEmail}" target="_blank" title="点击给我发邮件" rel="external nofollow"><i class="fa fa fa-envelope fa-fw"></i>联系我</a>。
</div>
</div>
</#if>
<#if article.requiredAuth>
<div class="alert alert-warning alert-dismissible fade in red" role="alert">
<i class="fa fa-lock fa-fw"></i> 文章已被加密,需要 <a href="javascript:void(0)" data-toggle="modal" data-target="#lockModal">输入密码</a> 才能查看文章详情
<i class="fa fa-lock fa-fw"></i> 该文章已被加密,需要 <a href="javascript:void(0)" data-toggle="modal" data-target="#oauth" rel="nofollow" title="授权登录">登录后</a> 才能查看文章详情
</div>
<#else >
${article.content}
<#if article.private>
${article.description!}
<br>
<div class="alert alert-warning alert-dismissible fade in red" role="alert">
<i class="fa fa-lock fa-fw"></i> 文章已被加密,需要 <a href="javascript:void(0)" data-toggle="modal" data-target="#lockModal">输入密码</a> 才能查看文章详情
</div>
<#else >
${article.content}
</#if>
</#if>
</div>
<div class="separateline"><span>正文到此结束</span></div>
......@@ -91,10 +110,14 @@
<a href="javascript:;;" class="c-label" data-original-title="暂无相关标签" data-toggle="tooltip" data-placement="bottom" target="_blank">暂无相关标签</a>
</#if>
</li>
<li>
<strong>本文链接:</strong>
${config.siteUrl}/article/${article.id?c}
</li>
<li>
<strong>版权声明:</strong>
<#if article.original?string('true','false') == 'true'>
站原创文章,于${article.createTime?string('yyyy年MM月dd日')}由<a href="${config.siteUrl}" target="_blank" data-original-title="${config.siteName}" data-toggle="tooltip" data-placement="bottom"><strong>${config.authorName}</strong></a>发布,转载请注明出处
文由<a href="${config.siteUrl}" target="_blank" data-original-title="${config.siteName}" data-toggle="tooltip" data-placement="bottom"><strong>${config.authorName}</strong></a>原创发布,转载请遵循《<a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh" target="_blank" rel="nofollow">署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)</a>》许可协议授权
<#else>
本文为互联网转载文章,出处已在文章中说明(部分除外)。如果侵权,请<a target="_blank" href="mailto:${config.authorEmail}" title="点击给我发邮件" data-toggle="tooltip" data-placement="bottom"><strong>联系本站长</strong></a>删除,谢谢。
</#if>
......@@ -103,7 +126,7 @@
</div>
</div>
<#-- 广告位 -->
<div class="blog-body ad-mark" id="ARTICLE_BOTTOM" style="display: none"></div>
<div class="ad-mark" id="ARTICLE_BOTTOM" style="display: none"></div>
<div class="blog-body prev-next">
<nav class="nav-single wow" data-wow-delay="0.3s">
<#if other.prev>
......@@ -197,16 +220,18 @@
<div class="clear"></div>
</div>
<#-- 广告位 -->
<div class="blog-body ad-mark" id="COMMENT_BOX_TOP" style="display: none"></div>
<#--评论-->
<#if article.comment>
<div class="blog-body clear overflow-initial expansion">
<div id="comment-box" data-id="${article.id?c}"></div>
</div>
<#else>
<div class="blog-body clear overflow-initial expansion gray">
<i class="fa fa-close fa-fw"></i>该篇文章的评论功能已被站长关闭
</div>
<div class="ad-mark" id="COMMENT_BOX_TOP" style="display: none"></div>
<#if !article.requiredAuth>
<#--评论-->
<#if article.comment>
<div class="blog-body clear overflow-initial expansion">
<div id="comment-box" data-id="${article.id?c}"></div>
</div>
<#else>
<div class="blog-body clear overflow-initial expansion gray">
<i class="fa fa-close fa-fw"></i>该篇文章的评论功能已被站长关闭
</div>
</#if>
</#if>
</div>
<#include "layout/sidebar.ftl"/>
......@@ -239,7 +264,9 @@
var coverImg = $("#cover-img").attr("src") || "${config.staticWebSite}/img/default.png";
window._bd_share_config={"common":{"bdSnsKey":{},"bdText":bdText,"bdMini":"2","bdMiniList":["mshare","qzone","tsina","bdysc","weixin","renren","tqq","kaixin001","tqf","tieba","douban","bdhome","sqq","youdao","sdo","qingbiji","mail","isohu","ty","fbook","twi","linkedin","h163","evernotecn","copy","print"],"bdPic":coverImg,"bdStyle":"1","bdSize":"24"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];
</script>
<script src="https://v1.hitokoto.cn/?encode=js&c=i&select=%23hitokoto" defer></script>
<#if (config.enableHitokoto == 1 || config.enableHitokoto == "1")>
<script src="https://v1.hitokoto.cn/?encode=js&c=i&select=.hitokoto" defer></script>
</#if>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/highlight.js@9.12.0/lib/highlight.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/simplemde@1.11.2/dist/simplemde.min.js"></script>
......
......@@ -34,9 +34,11 @@
</ul>
</#if>
</div>
<div class="article-footer overflow-initial">
<span class="blog-description hitokoto num"></span>
</div>
<#if (config.enableHitokoto == 1 || config.enableHitokoto == "1")>
<div class="article-footer overflow-initial">
<span class="blog-description hitokoto num"></span>
</div>
</#if>
</div>
</div>
</div>
......@@ -44,6 +46,8 @@
</div>
</div>
<@footer>
<script src="https://v1.hitokoto.cn/?encode=js&c=i&select=.hitokoto" defer></script>
<#if (config.enableHitokoto == 1 || config.enableHitokoto == "1")>
<script src="https://v1.hitokoto.cn/?encode=js&c=i&select=.hitokoto" defer></script>
</#if>
</@footer>
</@compress>
......@@ -45,9 +45,7 @@
</div>
</#if>
<#-- 广告位 -->
<div class="col-sm-12 blog-main">
<div class="blog-body ad-mark" id="COMMENT_BOX_TOP" style="display: none"></div>
</div>
<div class="col-sm-12 ad-mark" id="COMMENT_BOX_TOP" style="display: none"></div>
<#if config.comment! && config.comment == 1>
<div class="col-sm-12 blog-main">
<div class="blog-body expansion">
......@@ -63,7 +61,9 @@
</div>
<@footer>
<script src="https://v1.hitokoto.cn/?encode=js&c=i&select=%23hitokoto" defer></script>
<#if (config.enableHitokoto == 1 || config.enableHitokoto == "1")>
<script src="https://v1.hitokoto.cn/?encode=js&c=i&select=.hitokoto" defer></script>
</#if>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/highlight.js@9.12.0/lib/highlight.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/simplemde@1.11.2/dist/simplemde.min.js"></script>
......
......@@ -67,7 +67,9 @@
<div class="col-sm-12 blog-main">
<div class="blog-header">
<h4>${title}</h4>
<p class="blog-description" id="hitokoto"></p>
<#if (config.enableHitokoto == 1 || config.enableHitokoto == "1")>
<p class="blog-description hitokoto"></p>
</#if>
<div>
<a href="javascript:void(0);" target="_blank" title="点击QQ联系我" onclick="window.open('tencent://message/?uin=${config.qq}&amp;Site=www.${config.domain}&amp;Menu=yes')" rel="external nofollow"><i class="fa fa fa-qq fa-fw"></i>QQ联系</a>
|
......
......@@ -7,6 +7,8 @@
</@header>
<div class="container custome-container">
<#-- 广告位 -->
<div class="ad-mark" id="HOMEPAGE_TOP" style="display: none;margin-bottom: 10px"></div>
<@prompt></@prompt>
<nav class="breadcrumb">
<div class="notify"><i class="fa fa-bullhorn fa-fw"></i></div>
......@@ -59,6 +61,28 @@
</div>
</#if>
</@articleTag>
<@zhydTag method="scrollmenus" position="scrollmenu">
<#if scrollmenus?? && scrollmenus?size gt 0>
<div class="blog-body expansion" style="padding: 0;">
<div class="scrollmenu nav-tags">
<span>更多分类:</span>
<#list scrollmenus as item>
<a href="/type/${item.id?c}" id="scrollmenu-${item.id?c}"><i class="${item.icon!}"></i>${item.name!}</a>
</#list>
</div>
</div>
</#if>
</@zhydTag>
<#-- <div class="separateline"><span>以下为最新文章</span></div>-->
<#-- <div class="blog-body expansion" style="padding: 0;margin-bottom: 0;border-bottom: 1px solid #eeeeee;">
<div class="scrollmenu nav-tags">
<a href="/type/1" id="scrollmenu-1" class="red" style="color: red">最新文章</a>
<a href="/type/1" id="scrollmenu-1">置顶文章</a>
<a href="/type/1" id="scrollmenu-1">热门文章</a>
<a href="/type/1" id="scrollmenu-1">评论最多</a>
<a href="/type/1" id="scrollmenu-1">点赞最多</a>
</div>
</div>-->
<#if page.list?? && (page.list?size > 0)>
<#list page.list as item>
<article class="fade-in">
......@@ -157,5 +181,13 @@
</div>
</div>
</div>
<@footer></@footer>
<@footer>
<script>
var typeMatch = location.href.match(/\/type\/([0-9]+)/);
if(null != typeMatch) {
var typeId = typeMatch[1];
$("#scrollmenu-" + typeId).addClass("active").attr("href", "javascript:void(0)");
}
</script>
</@footer>
</@compress>
<div class="col-sm-3 blog-sidebar">
<#-- 广告位 -->
<div class="sidebar-module ad-mark" id="SIDEBAR_TOP" style="display: none"></div>
<#if articleDetail??>
<div class="ad-mark" id="SIDEBAR_TOP" style="display: none"></div>
<#if articleDetail?? && (config.enableHitokoto == 1 || config.enableHitokoto == "1")>
<div class="sidebar-module">
<h5 class="custom-title"><i class="fa fa-hand-peace-o fa-fw icon"></i><strong>说给你听</strong><small></small></h5>
<div class="div-quote">
<i class="fa fa-quote-left fa-fw"></i><p id="hitokoto" style="margin-left: 15px;"></p>
<i class="fa fa-quote-left fa-fw"></i><p class="hitokoto" style="margin-left: 15px;"></p>
</div>
</div>
<#else>
......@@ -66,7 +66,7 @@
</#if>
</@zhydTag>
</div>
<@zhydTag method="recentComments" pageSize="10">
<@zhydTag method="recentComments" pageSize="5">
<#if recentComments?? && recentComments?size gt 0>
<div class="sidebar-module">
<h5 class="custom-title"><i class="fa fa-comments fa-fw icon"></i><strong>近期评论</strong><small></small></h5>
......@@ -181,5 +181,5 @@
</ul>
</div>
<#-- 广告位 -->
<div class="sidebar-module ad-mark" id="SIDEBAR_BOTTOM" style="display: none"></div>
<div class="ad-mark" id="SIDEBAR_BOTTOM" style="display: none"></div>
</div>
......@@ -245,6 +245,8 @@
})
});
</script>
<script src="https://v1.hitokoto.cn/?encode=js&c=i&select=%23hitokoto" defer></script>
<#if (config.enableHitokoto == 1 || config.enableHitokoto == "1")>
<script src="https://v1.hitokoto.cn/?encode=js&c=i&select=.hitokoto" defer></script>
</#if>
</@footer>
</@compress>
......@@ -39,3 +39,9 @@ ALTER TABLE `dblog`.`biz_article` ADD COLUMN `editor_type` varchar(10) NULL COMM
# 修改旧文章的编辑器类型
UPDATE `dblog`.`biz_article` SET `editor_type` = 'we' WHERE is_markdown is null || is_markdown = 0;
UPDATE `dblog`.`biz_article` SET `editor_type` = 'md' WHERE is_markdown = 1;
# 20211101
ALTER TABLE `dblog`.`biz_article` ADD COLUMN `required_auth` tinyint(1) UNSIGNED NULL DEFAULT NULL COMMENT '该文章是否登录后才可访问' AFTER `password`;
ALTER TABLE `dblog`.`biz_type` ADD COLUMN `position` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '分类在web端显示的位置,可选:nav、scrollmenu' AFTER `icon`;
UPDATE `dblog`.`biz_type` SET `position` = 'nav';
......@@ -37,6 +37,10 @@ ONEBLOG_MAIL_PASSWORD=
# oneblog 自定义配置
# 是否启用 kaptcha 验证码
ONEBLOG_APP_ENABLE_KAPTCHA=false
# 是否启用自动校验友情链接的功能
# 请选择打开,一旦打开,每晚凌晨12点会自动检查友联,对于不包含本站链接的网站实行自动封禁
# 目前暂时没实现白名单的功能
ONEBLOG_APP_ENABLE_CHECK_LINK=false
# 启用后,项目在启动时会打印数据库(Mysql和Redis)链接信息(包含密码)
ONEBLOG_APP_ENABLE_PRINT_CONFIG=true
# 是否启用 redis 切面缓存。
......
......@@ -43,6 +43,7 @@ CREATE TABLE `biz_article` (
`keywords` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '文章关键字,优化搜索',
`comment` tinyint(1) UNSIGNED NULL DEFAULT 1 COMMENT '是否开启评论',
`password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '文章私密访问时的密钥',
`required_auth` tinyint(1) UNSIGNED NULL DEFAULT NULL COMMENT '该文章是否登录后才可访问',
`create_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP COMMENT '添加时间',
`update_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`) USING BTREE
......@@ -147,6 +148,7 @@ CREATE TABLE `biz_type` (
`description` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '类型介绍',
`sort` int(10) NULL DEFAULT NULL COMMENT '排序',
`icon` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '图标',
`position` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '分类在web端显示的位置,可选:nav、scrollmenu',
`available` tinyint(1) UNSIGNED NULL DEFAULT 1 COMMENT '是否可用',
`create_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP COMMENT '添加时间',
`update_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
......
此差异已折叠。
......@@ -5,7 +5,7 @@
<groupId>com.zyd</groupId>
<artifactId>blog</artifactId>
<version>2.3.2</version>
<version>2.3.3</version>
<packaging>pom</packaging>
<modules>
<module>blog-core</module>
......@@ -59,27 +59,27 @@
<dependency>
<groupId>com.zyd</groupId>
<artifactId>blog-core</artifactId>
<version>2.3.2</version>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>com.zyd</groupId>
<artifactId>blog-admin</artifactId>
<version>2.3.2</version>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>com.zyd</groupId>
<artifactId>blog-web</artifactId>
<version>2.3.2</version>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>com.zyd</groupId>
<artifactId>blog-file</artifactId>
<version>2.3.2</version>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>com.zyd</groupId>
<artifactId>blog-codegen</artifactId>
<version>2.3.2</version>
<version>2.3.3</version>
</dependency>
</dependencies>
</dependencyManagement>
......
......@@ -3,6 +3,14 @@
----
### 2021-11-01
- 增加定时任务:“每晚凌晨12点自动检查友联,对于私自取消友联的网站实行自动封禁”
- 文章支持设置【登录后可见】
- 优化web端的分类展示,支持以滚动菜单的形式展示分类,防止因分类太多导致菜单栏溢出的问题
- 支持禁用一言插件(该插件部分时候加载较慢)
- 文章长期未修改时,向用户提示
### 2021-10-29
- wangEditor 升级到 4.7.9
......