...
 
Commits (9)
    https://gitcode.net/u011197448/oneblog/-/commit/98ed472ec2cccde5235c2d012813d688aa20da01 :memo: docker config 2021-10-20T16:52:25+08:00 yadong.zhang yadong.zhang0415@gmail.com https://gitcode.net/u011197448/oneblog/-/commit/57a97335b01d4b76189f494a1630793619992df5 :bulb: 升级到2.2.9 2021-10-24T00:36:00+08:00 yadong.zhang yadong.zhang0415@gmail.com https://gitcode.net/u011197448/oneblog/-/commit/44ba58eee51bf1380c1838cea170d938293fcd45 :bulb: 增加友情链接,不建议删除,请支持一下开源 2021-10-24T00:36:25+08:00 yadong.zhang yadong.zhang0415@gmail.com https://gitcode.net/u011197448/oneblog/-/commit/13eeb9b5174dc0630aa982b5b1e76c8beea25b20 :bulb: 优化页面样式 2021-10-24T00:38:45+08:00 yadong.zhang yadong.zhang0415@gmail.com https://gitcode.net/u011197448/oneblog/-/commit/fb6b0f044ec135aadb2b44bc4a8869d15b072620 :see_no_evil: 更新 .gitignore 文件 2021-10-24T00:39:05+08:00 yadong.zhang yadong.zhang0415@gmail.com https://gitcode.net/u011197448/oneblog/-/commit/8cda4bfbef121f6b43432e0d114701c5d80eabf2 :fire: 新增【自定义页面】的功能,方便对接第三方的网站验证 2021-10-24T00:39:59+08:00 yadong.zhang yadong.zhang0415@gmail.com https://gitcode.net/u011197448/oneblog/-/commit/8747dc2cf5a51d10d431d34f3f77c23d31517e0d :fire: 新增【自定义页面】的功能,方便对接第三方的网站验证 2021-10-24T01:05:27+08:00 yadong.zhang yadong.zhang0415@gmail.com https://gitcode.net/u011197448/oneblog/-/commit/2ee6190bf10b3bc3069e3358045dbbe65e6a9d0f :fire: Fixed Gitee Issue #I4AA1J 2021-10-24T01:07:38+08:00 yadong.zhang yadong.zhang0415@gmail.com https://gitcode.net/u011197448/oneblog/-/commit/29f6a37da43ed8959bcacf095d97543da37bec85 :memo: Writing docs. 2021-10-24T01:17:07+08:00 yadong.zhang yadong.zhang0415@gmail.com
......@@ -21,3 +21,4 @@
hs_err_pid*
/.idea/
*.iml
/logdir_IS_UNDEFINED/
......@@ -218,4 +218,11 @@ public class RenderController {
public ModelAndView socials(Model model) {
return ResultUtil.view("social/list");
}
@RequiresPermissions("page")
@BussinessLog("进入配置自定义页面")
@GetMapping("/page")
public ModelAndView page(Model model) {
return ResultUtil.view("page/page");
}
}
/*
* Powered By [rapid-framework]
* Web Site: http://www.rapid-framework.org.cn
* Google Code: http://code.google.com/p/rapid-framework/
* Since 2008 - 2021
*/
package com.zyd.blog.controller;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zyd.blog.business.entity.Page;
import com.zyd.blog.business.enums.ResponseStatus;
import com.zyd.blog.business.service.BizPageService;
import com.zyd.blog.business.vo.PageConditionVO;
import com.zyd.blog.framework.object.PageResult;
import com.zyd.blog.framework.object.ResponseVO;
import com.zyd.blog.util.ResultUtil;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author yadong.zhang email:yadong.zhang(a)innodev.com.cn
* @version 1.0
* @date 2021/10/23 00:19
* @since 1.0
*/
@RestController
@RequestMapping("/page")
public class RestPageController {
@Autowired
private BizPageService bizPageService;
@RequiresPermissions("page")
@PostMapping("/list")
public PageResult list(PageConditionVO vo) {
PageHelper.startPage(vo.getPageNumber() - 1, vo.getPageSize());
PageInfo<Page> pageInfo = bizPageService.findPageBreakByCondition(vo);
return ResultUtil.tablePage(pageInfo);
}
@RequiresPermissions("page:add")
@PostMapping(value = "/add")
public ResponseVO add(Page page) {
Page dbPage = bizPageService.getByUrl(page.getUrl());
if (dbPage != null) {
return ResultUtil.error(page.getUrl() + " 已存在!");
}
bizPageService.insert(page);
return ResultUtil.success("成功");
}
@RequiresPermissions(value = {"page:batchDelete", "page:delete"}, logical = Logical.OR)
@PostMapping(value = "/remove")
public ResponseVO remove(Long[] ids) {
if (null == ids) {
return ResultUtil.error(500, "请至少选择一条记录");
}
for (Long id : ids) {
bizPageService.removeByPrimaryKey(id);
}
return ResultUtil.success("成功删除 [" + ids.length + "] 条记录");
}
@RequiresPermissions("page:edit")
@PostMapping("/get/{id}")
public ResponseVO get(@PathVariable Long id) {
return ResultUtil.success(null, this.bizPageService.getByPrimaryKey(id));
}
@RequiresPermissions("page:edit")
@PostMapping("/edit")
public ResponseVO edit(Page page) {
try {
Page dbPage = bizPageService.getByPrimaryKey(page.getId());
if (null != dbPage && !dbPage.getUrl().equals(page.getUrl())) {
dbPage = bizPageService.getByUrl(page.getUrl());
if (dbPage != null) {
return ResultUtil.error(page.getUrl() + " 已存在!");
}
}
bizPageService.updateSelective(page);
} catch (Exception e) {
e.printStackTrace();
return ResultUtil.error("数据修改失败!");
}
return ResultUtil.success(ResponseStatus.SUCCESS);
}
}
<#include "/include/macros.ftl">
<@header></@header>
<div class="clearfix"></div>
<div class="row">
<div class="col-md-12 col-sm-12 col-xs-12">
<ol class="breadcrumb">
<li><a href="/">首页</a></li>
<li class="active">自定义页面管理</li>
</ol>
<div class="x_panel">
<div class="x_content">
<div class="btn-group hidden-xs" id="toolbar">
<@shiro.hasPermission name="page:add">
<button id="btn_add" type="button" class="btn btn-info" title="新增自定义页面">
<i class="fa fa-plus"></i> 新增自定义页面
</button>
</@shiro.hasPermission>
<@shiro.hasPermission name="page:batchDelete">
<button id="btn_delete_ids" type="button" class="btn btn-danger" title="批量删除">
<i class="fa fa-trash-o"></i> 批量删除
</button>
</@shiro.hasPermission>
</div>
<table id="tablelist">
</table>
</div>
</div>
</div>
</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-3" for="url">页面URL <span class="required">*</span></label>
<div class="col-md-7 col-sm-7 col-xs-7">
<input type="text" class="form-control" name="url" id="url" required="required" placeholder="url"/>
<small style="font-size: 12px;">不包含域名部分,比如 <span class="red">https://www.baidu.com/</span><span class="green">asd</span>,则提取出来的 url 为 <strong><span class="green">asd</span></strong>。目前仅支持 .xml,.txt,.html 结尾的三种页面</small>
</div>
</div>
<div class="item form-group">
<label class="control-label col-md-3 col-sm-3 col-xs-3" for="content">页面内容 <span class="required">*</span></label>
<div class="col-md-7 col-sm-7 col-xs-7">
<textarea class="form-control col-md-7 col-xs-12" id="content" name="content" rows="15" placeholder="请输入页面内容"></textarea>
</div>
</div>
</@addOrUpdateMOdal>
<@footer>
<script>
/**
* 操作按钮
* @param code
* @param row
* @param index
* @returns {string}
*/
function operateFormatter(code, row, index) {
var trId = row.id;
var url = row.url;
var operateBtn = [
'<a class="btn btn-xs btn-link" href="${config.siteUrl!}/' + url + '" target="_blank"><i class="fa fa-rocket fa-fw"></i>预览</a>',
'<@shiro.hasPermission name="page:edit"><a class="btn btn-xs btn-primary btn-update" data-id="' + trId + '"><i class="fa fa-edit"></i>编辑</a></@shiro.hasPermission>',
'<@shiro.hasPermission name="page:delete"><a class="btn btn-xs btn-danger btn-remove" data-id="' + trId + '"><i class="fa fa-trash-o"></i>删除</a></@shiro.hasPermission>'
];
return operateBtn.join('');
}
$(function () {
var options = {
modalName: "自定义页面",
url: "/page/list",
getInfoUrl: "/page/get/{id}",
updateUrl: "/page/edit",
removeUrl: "/page/remove",
createUrl: "/page/add",
columns: [
{
checkbox: true
},
{
field: 'id',
title: 'ID',
width: '80px',
editable: false
},
{
field: 'url',
title: '页面URL',
width: '150px',
formatter: function (code) {
return code ? code : '-';
}
},
{
field: 'content',
title: '内容',
width: '350px',
formatter: function (code, row, index) {
var content = code;
if(!content) {
return '-';
}
return content.length > 30 ? (content.substr(0, 30) + '...') : content;
}
},
{
field: 'createTime',
title: '添加日期',
align: 'center',
width: '120px',
formatter: function (code) {
return new Date(code).format("yyyy-MM-dd hh:mm:ss")
}
},
{
field: 'updateTime',
title: '更新日期',
align: 'center',
width: '120px',
formatter: function (code) {
return new Date(code).format("yyyy-MM-dd hh:mm:ss")
}
},
{
field: 'operate',
title: '操作',
width: '120px',
formatter: operateFormatter //自定义方法,添加操作按钮
}
]
};
// 初始化table组件
var table = new Table(options);
table.init();
});
</script>
</@footer>
/*
* Powered By [rapid-framework]
* Web Site: http://www.rapid-framework.org.cn
* Google Code: http://code.google.com/p/rapid-framework/
* Since 2008 - 2021
*/
package com.zyd.blog.business.entity;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.zyd.blog.persistence.beans.BizPage;
import java.util.Date;
/**
* @author yadong.zhang email:yadong.zhang(a)innodev.com.cn
* @version 1.0
* @date 2021/10/23 00:19
* @since 1.0
*/
public class Page {
private static final long serialVersionUID = 1L;
private final BizPage bizPage;
public Page() {
this.bizPage = new BizPage();
}
public Page(BizPage bizPage) {
this.bizPage = bizPage;
}
@JsonIgnore
public BizPage getBizPage() {
return this.bizPage;
}
public Long getId() {
return this.bizPage.getId();
}
public void setId(Long id) {
this.bizPage.setId(id);
}
public String getUrl() {
return this.bizPage.getUrl();
}
public void setUrl(String url) {
this.bizPage.setUrl(url);
}
public String getContent() {
return this.bizPage.getContent();
}
public void setContent(String content) {
this.bizPage.setContent(content);
}
public Date getCreateTime() {
return this.bizPage.getCreateTime();
}
public void setCreateTime(Date createTime) {
this.bizPage.setCreateTime(createTime);
}
public Date getUpdateTime() {
return this.bizPage.getUpdateTime();
}
public void setUpdateTime(Date updateTime) {
this.bizPage.setUpdateTime(updateTime);
}
}
/*
* Powered By [rapid-framework]
* Web Site: http://www.rapid-framework.org.cn
* Google Code: http://code.google.com/p/rapid-framework/
* Since 2008 - 2021
*/
package com.zyd.blog.business.service;
import com.zyd.blog.framework.object.AbstractService;
import com.zyd.blog.business.entity.Page;
import com.zyd.blog.business.vo.PageConditionVO;
import com.github.pagehelper.PageInfo;
/**
* @author yadong.zhang email:yadong.zhang(a)innodev.com.cn
* @version 1.0
* @date 2021/10/23 00:19
* @since 1.0
*/
public interface BizPageService extends AbstractService<Page, Long> {
/**
* 分页查询
*
* @param vo
* @return
*/
PageInfo<Page> findPageBreakByCondition(PageConditionVO vo);
Page getByUrl(String url);
}
/*
* Powered By [rapid-framework]
* Web Site: http://www.rapid-framework.org.cn
* Google Code: http://code.google.com/p/rapid-framework/
* Since 2008 - 2021
*/
package com.zyd.blog.business.service.impl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zyd.blog.business.entity.Page;
import com.zyd.blog.business.service.BizPageService;
import com.zyd.blog.business.vo.PageConditionVO;
import com.zyd.blog.persistence.beans.BizPage;
import com.zyd.blog.persistence.mapper.BizPageMapper;
import org.springframework.beans.factory.annotation.Autowired;
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;
import java.util.List;
/**
* @author yadong.zhang email:yadong.zhang(a)innodev.com.cn
* @version 1.0
* @date 2021/10/23 00:19
* @since 1.0
*/
@Service
public class BizPageServiceImpl implements BizPageService {
@Autowired
private BizPageMapper bizPageMapper;
/**
* 分页查询
*
* @param vo
* @return
*/
@Override
public PageInfo<Page> findPageBreakByCondition(PageConditionVO vo) {
PageHelper.startPage(vo.getPageNumber(), vo.getPageSize());
List<BizPage> list = bizPageMapper.findPageBreakByCondition(vo);
if (CollectionUtils.isEmpty(list)) {
return null;
}
List<Page> boList = new ArrayList<>();
for (BizPage bizPage : list) {
boList.add(new Page(bizPage));
}
PageInfo bean = new PageInfo<BizPage>(list);
bean.setList(boList);
return bean;
}
@Override
public Page getByUrl(String url) {
if (StringUtils.isEmpty(url)) {
return null;
}
Example example = new Example(BizPage.class);
Example.Criteria criteria = example.createCriteria();
criteria.andEqualTo("url", url);
List<BizPage> list = bizPageMapper.selectByExample(example);
return CollectionUtils.isEmpty(list) ? null : new Page(list.get(0));
}
/**
* 保存一个实体,null的属性不会保存,会使用数据库默认值
*
* @param entity
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Page insert(Page entity) {
Assert.notNull(entity, "Page不可为空!");
entity.setUpdateTime(new Date());
entity.setCreateTime(new Date());
bizPageMapper.insertSelective(entity.getBizPage());
return entity;
}
/**
* 根据主键字段进行删除,方法参数必须包含完整的主键属性
*
* @param primaryKey
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
public boolean removeByPrimaryKey(Long primaryKey) {
return bizPageMapper.deleteByPrimaryKey(primaryKey) > 0;
}
/**
* 根据主键更新属性不为null的值
*
* @param entity
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
public boolean updateSelective(Page entity) {
Assert.notNull(entity, "Page不可为空!");
entity.setUpdateTime(new Date());
return bizPageMapper.updateByPrimaryKeySelective(entity.getBizPage()) > 0;
}
/**
* 根据主键字段进行查询,方法参数必须包含完整的主键属性,查询条件使用等号
*
* @param primaryKey
* @return
*/
@Override
public Page getByPrimaryKey(Long primaryKey) {
Assert.notNull(primaryKey, "PrimaryKey不可为空!");
BizPage entity = bizPageMapper.selectByPrimaryKey(primaryKey);
return null == entity ? null : new Page(entity);
}
/**
* 查询全部结果,listByEntity(null)方法能达到同样的效果
*
* @return
*/
@Override
public List<Page> listAll() {
List<BizPage> entityList = bizPageMapper.selectAll();
if (CollectionUtils.isEmpty(entityList)) {
return null;
}
List<Page> list = new ArrayList<>();
for (BizPage entity : entityList) {
list.add(new Page(entity));
}
return list;
}
}
/*
* Powered By [rapid-framework]
* Web Site: http://www.rapid-framework.org.cn
* Google Code: http://code.google.com/p/rapid-framework/
* Since 2008 - 2021
*/
package com.zyd.blog.business.vo;
import com.zyd.blog.framework.object.BaseConditionVO;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author yadong.zhang email:yadong.zhang(a)innodev.com.cn
* @version 1.0
* @date 2021/10/23 00:19
* @since 1.0
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class PageConditionVO extends BaseConditionVO {
}
package com.zyd.blog.persistence.beans;
import com.zyd.blog.framework.object.AbstractDO;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
* @date 2021/10/23 00:05
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class BizPage extends AbstractDO {
private String url;
private String content;
}
package com.zyd.blog.persistence.mapper;
import com.zyd.blog.business.vo.PageConditionVO;
import com.zyd.blog.persistence.beans.BizPage;
import com.zyd.blog.plugin.BaseMapper;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
* @version 1.0.0
* @since 1.0.0
*/
@Repository
public interface BizPageMapper extends BaseMapper<BizPage> {
/**
* 分页查询
*
* @param vo
* @return
*/
List<BizPage> findPageBreakByCondition(PageConditionVO vo);
}
......@@ -86,5 +86,5 @@ pagehelper:
params: count=countSql
app:
version: v2.2.8
enableRedisCache: false
version: v2.2.9
enableRedisCache: ${ONEBLOG_ENABLE_REDIS_CACHE:false}
<?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.zyd.blog.persistence.mapper.BizPageMapper">
<resultMap id="rm" type="com.zyd.blog.persistence.beans.BizPage">
<result property="id" jdbcType="BIGINT" column="id"/>
<result property="url" jdbcType="VARCHAR" column="url"/>
<result property="content" jdbcType="LONGVARCHAR" column="content"/>
<result property="createTime" jdbcType="TIMESTAMP" column="create_time"/>
<result property="updateTime" jdbcType="TIMESTAMP" column="update_time"/>
</resultMap>
<sql id="Base_Column_List">
id,
url,
content,
create_time,
update_time
</sql>
<select id="findPageBreakByCondition" parameterType="com.zyd.blog.business.vo.PageConditionVO" resultMap="rm">
SELECT
t.id,
t.url,
t.content,
t.create_time,
t.update_time
FROM
biz_page t
WHERE
1 = 1
ORDER BY t.create_time DESC
</select>
</mapper>
package com.zyd.blog.controller;
import com.zyd.blog.business.entity.Page;
import com.zyd.blog.business.service.BizPageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
/**
* @author yadong.zhang email:yadong.zhang(a)innodev.com.cn
* @version 1.0
* @date 2021/10/23 00:19
* @since 1.0
*/
@RestController
public class RestPageController {
@Autowired
private BizPageService bizPageService;
@GetMapping(value = "/{filename}.xml", produces = {"application/xml"})
public String xml(@PathVariable("filename") String filename) {
return this.getContent(filename + ".xml");
}
@GetMapping(value = "/{filename}.txt", produces = {"text/plain"})
public String txt(@PathVariable("filename") String filename) {
return this.getContent(filename + ".txt");
}
@GetMapping(value = "/.well-known/{url}/{filename}.txt", produces = {"text/plain"})
public String multiPath(@PathVariable("url") String url, @PathVariable("filename") String filename) {
return this.getContent(".well-known/" + url + "/" + filename + ".txt");
}
@GetMapping(value = "/{filename}.html", produces = {"text/html"})
public String html(@PathVariable("filename") String filename) {
return this.getContent(filename + ".html");
}
private String getContent(String url) {
Page page = bizPageService.getByUrl(url);
return null == page ? "" : page.getContent();
}
}
......@@ -1152,7 +1152,7 @@ article .thumbnail a img {
background: #999;
}
.art-top {
background: #e63946!important;
background: #ff9800!important;
}
.art-type {
background: #999;
......
......@@ -206,12 +206,15 @@ $(function () {
initArticeMenu();
initScrollMenu();
console.group("关于OneBlog");
console.group("关于 OneBlog");
console.log("OneBlog,一个简洁美观、功能强大并且自适应的Java博客\n欢迎进QQ交流群(190886500)");
console.groupEnd();
console.log("%c生活真他妈好玩,因为生活老他妈玩我!", "color:green;font-size:20px;font-weight:blod");
console.group("推荐开源");
console.log("%c开源不易,所以原谅我在此推一下不算广告的广告!", "color:red;font-size:12px;font-weight:blod");
console.log("%c① JustAuth,开箱即用的整合第三方登录的开源组件:https://github.com/justauth/JustAuth", "color:green;font-size:12px;font-weight:blod");
console.log("%c② JAP,一款开源的登录认证中间件,支持 Form、 OAuth2.0、OIDC、Http Basic、Digest、Bearer、LDAP、SAML、MFA、SSO 等:https://gitee.com/fujieid/jap", "color:green;font-size:12px;font-weight:blod");
console.log("%c欢迎关注、star、推荐", "color:green;font-size:12px;font-weight:blod");
console.groupEnd();
console.log("爱谁谁...");
$('.to-top').toTop({
autohide: true,//返回顶部按钮是否自动隐藏。可以设置true或false。默认为true
......
......@@ -135,6 +135,12 @@
<#if url?? && (url == "index")>
<div class="inline external-links">
<a>友情链接:</a>
<a href="https://justauth.wiki" target="_blank" title="开箱即用的整合第三方登录的开源组件" data-toggle="tooltip" data-placement="right">
JustAuth
</a>
<a href="https://justauth.plus" target="_blank" title="一款开源的登录认证中间件,支持 Form、 OAuth2.0、OIDC、Http Basic、Digest、Bearer、LDAP、SAML、MFA、SSO 等" data-toggle="tooltip" data-placement="right">
JAP
</a>
<#if indexLinkList?? && (indexLinkList?size > 0)>
<#list indexLinkList as item>
<a href="${item.url}" target="_blank" title="${item.description!}" data-toggle="tooltip" data-placement="right">
......
## 具体内容请参考 docs/docker/mysql/dblog.sql 文件
## 具体内容请参考 docs/docker/mysql/init_data.sql 文件
......@@ -7,39 +7,24 @@
################################### readme ###################################
# 20210423
ALTER TABLE `dblog`.`biz_article`
ADD COLUMN `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '文章私密访问时的密钥' AFTER `comment`;
# 20211023
-- ----------------------------
-- Table structure for biz_page
-- ----------------------------
DROP TABLE IF EXISTS `biz_page`;
CREATE TABLE `biz_page` (
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '自定义页面的url(不包含域名部分)',
`content` mediumtext CHARACTER SET utf8 COLLATE utf8_general_ci 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
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
# 20210427
INSERT INTO `dblog`.`sys_resources` VALUES (76, '社会化登录配置管理', 'menu', '/socials', 'socials', 40, 7, 0, 1, '', now(), now());
INSERT INTO `dblog`.`sys_resources` VALUES (77, '新增社会化登录配置', 'button', NULL, 'social:add', 76, 2, 0, 1, NULL, now(), now());
INSERT INTO `dblog`.`sys_resources` VALUES (78, '批量删除社会化登录配置', 'button', NULL, 'social:batchDelete', 76, 3, 0, 1, NULL, now(), now());
INSERT INTO `dblog`.`sys_resources` VALUES (79, '编辑社会化登录配置', 'button', NULL, 'social:edit,social:get', 76, 4, 0, 1, NULL, now(), now());
INSERT INTO `dblog`.`sys_resources` VALUES (80, '删除社会化登录配置', 'button', NULL, 'social:delete', 76, 5, 0, 1, NULL, now(), now());
DROP TABLE IF EXISTS `dblog`.`sys_social_config`;
CREATE TABLE `dblog`.`sys_social_config` (
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`client_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '应用ID',
`client_secret` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '应用密钥',
`redirect_uri` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '认证成功后跳转的地址',
`platform_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '应用名',
`platform` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '第三方平台',
`logo` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '应用 LOGO',
`alipay_public_key` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '支付宝公钥',
`union_id` bit(1) NULL DEFAULT NULL COMMENT '是否需要申请unionid',
`stack_overflow_key` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'Stack Overflow Key',
`agent_id` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '授权方的网页应用ID',
`scope` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '授权范围',
`available` bit(1) NULL DEFAULT b'1' COMMENT '当前配置是否可用',
`create_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '记录创建时间',
`update_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '记录更新时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '社会化登录应用' ROW_FORMAT = Dynamic;
# 20210606
ALTER TABLE `dblog`.`sys_config`
MODIFY COLUMN `config_value` longtext CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '配置项内容' AFTER `config_key`;
# 20211023
INSERT INTO `dblog`.`sys_resources` VALUES (81, '自定义页面管理', 'menu', '/page', 'page', 40, 7, 0, 1, '', now(), now());
INSERT INTO `dblog`.`sys_resources` VALUES (82, '新增自定义页面', 'button', NULL, 'page:add', 81, 2, 0, 1, NULL, now(), now());
INSERT INTO `dblog`.`sys_resources` VALUES (83, '批量删除自定义页面', 'button', NULL, 'page:batchDelete', 81, 3, 0, 1, NULL, now(), now());
INSERT INTO `dblog`.`sys_resources` VALUES (84, '编辑自定义页面', 'button', NULL, 'page:edit,page:get', 81, 4, 0, 1, NULL, now(), now());
INSERT INTO `dblog`.`sys_resources` VALUES (85, '删除自定义页面', 'button', NULL, 'page:delete', 81, 5, 0, 1, NULL, now(), now());
......@@ -3,6 +3,16 @@ MYSQL_ROOT_HOST=%
# 默认的工作目录, 默认是 windows 盘符,如果运行到其他操作系统中时,注意修改该配置
ONEBLOG_APP_DIR=D://var/.oneblog
# 对外暴露的端口
# redis
ONEBLOG_EXPORT_PORT_REDIS=63799
# mysql
ONEBLOG_EXPORT_PORT_MYSQL=33066
# blog-admin,默认为 8085
ONEBLOG_EXPORT_PORT_ADMIN=8085
# blog-web,默认为 8443
ONEBLOG_EXPORT_PORT_WEB=8443
# redis 配置
ONEBLOG_REDIS_DATABASE_INDEX=1
ONEBLOG_REDIS_HOST=blog-redis
......@@ -25,7 +35,11 @@ ONEBLOG_MAIL_USERNAME=
ONEBLOG_MAIL_PASSWORD=
# oneblog 自定义配置
# 是否启用kaptcha验证码
# 是否启用 kaptcha 验证码
ONEBLOG_APP_ENABLE_KAPTCHA=false
# 启用后,项目在启动时会打印数据库(Mysql和Redis)链接信息(包含密码)
ONEBLOG_APP_ENABLE_PRINT_CONFIG=true
# 是否启用 redis 切面缓存。
# 优先级高于 {@link com.zyd.blog.business.annotation.RedisCache#enable()} 注解的配置
# 开发环境建议关闭,线上环境建议打开
ONEBLOG_ENABLE_REDIS_CACHE=true
......@@ -11,7 +11,7 @@ services:
hostname: blog-redis
command: redis-server --appendonly yes --requirepass ${ONEBLOG_REDIS_PASSWORD} --bind blog-redis
ports:
- 63799:6379
- ${ONEBLOG_EXPORT_PORT_REDIS}:6379
volumes:
- ${ONEBLOG_APP_DIR}/redis/:/data/
healthcheck:
......@@ -33,7 +33,7 @@ services:
volumes:
- ${ONEBLOG_APP_DIR}/mysql:/var/lib/mysql
ports:
- 33066:3306
- ${ONEBLOG_EXPORT_PORT_MYSQL}:3306
command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci
healthcheck:
test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost" ]
......@@ -48,22 +48,8 @@ services:
restart: always
container_name: blog-admin
hostname: blog-admin
environment:
ONEBLOG_REDIS_DATABASE_INDEX:
ONEBLOG_REDIS_HOST:
ONEBLOG_REDIS_PORT:
ONEBLOG_REDIS_PASSWORD:
ONEBLOG_DATASOURCE_HOST:
ONEBLOG_DATASOURCE_PORT:
ONEBLOG_DATASOURCE_DATABASE_NAME:
ONEBLOG_DATASOURCE_USERNAME:
ONEBLOG_DATASOURCE_PASSWORD:
ONEBLOG_MAIL_HOST:
ONEBLOG_MAIL_PORT:
ONEBLOG_MAIL_USERNAME:
ONEBLOG_MAIL_PASSWORD:
ONEBLOG_APP_ENABLE_KAPTCHA:
ONEBLOG_APP_ENABLE_PRINT_CONFIG:
env_file:
- .env
volumes:
- ${ONEBLOG_APP_DIR}:/var/tmp/oneblog
depends_on:
......@@ -75,7 +61,7 @@ services:
- blog-redis
- blog-mysql
ports:
- 8085:8085
- ${ONEBLOG_EXPORT_PORT_ADMIN}:8085
networks:
- oneblog
......@@ -85,22 +71,8 @@ services:
restart: always
container_name: blog-web
hostname: blog-web
environment:
ONEBLOG_REDIS_DATABASE_INDEX:
ONEBLOG_REDIS_HOST:
ONEBLOG_REDIS_PORT:
ONEBLOG_REDIS_PASSWORD:
ONEBLOG_DATASOURCE_HOST:
ONEBLOG_DATASOURCE_PORT:
ONEBLOG_DATASOURCE_DATABASE_NAME:
ONEBLOG_DATASOURCE_USERNAME:
ONEBLOG_DATASOURCE_PASSWORD:
ONEBLOG_MAIL_HOST:
ONEBLOG_MAIL_PORT:
ONEBLOG_MAIL_USERNAME:
ONEBLOG_MAIL_PASSWORD:
ONEBLOG_APP_ENABLE_KAPTCHA:
ONEBLOG_APP_ENABLE_PRINT_CONFIG:
env_file:
- .env
volumes:
- ${ONEBLOG_APP_DIR}:/var/tmp/oneblog
depends_on:
......@@ -112,7 +84,7 @@ services:
- blog-redis
- blog-mysql
ports:
- 8443:8443
- ${ONEBLOG_EXPORT_PORT_WEB}:8443
networks:
- oneblog
......
......@@ -50,22 +50,8 @@ services:
restart: always
container_name: blog-admin
hostname: blog-admin
environment:
ONEBLOG_REDIS_DATABASE_INDEX:
ONEBLOG_REDIS_HOST:
ONEBLOG_REDIS_PORT:
ONEBLOG_REDIS_PASSWORD:
ONEBLOG_DATASOURCE_HOST:
ONEBLOG_DATASOURCE_PORT:
ONEBLOG_DATASOURCE_DATABASE_NAME:
ONEBLOG_DATASOURCE_USERNAME:
ONEBLOG_DATASOURCE_PASSWORD:
ONEBLOG_MAIL_HOST:
ONEBLOG_MAIL_PORT:
ONEBLOG_MAIL_USERNAME:
ONEBLOG_MAIL_PASSWORD:
ONEBLOG_APP_ENABLE_KAPTCHA:
ONEBLOG_APP_ENABLE_PRINT_CONFIG:
env_file:
- .env
volumes:
- ${ONEBLOG_APP_DIR}:/var/tmp/oneblog
depends_on:
......@@ -88,22 +74,8 @@ services:
restart: always
container_name: blog-web
hostname: blog-web
environment:
ONEBLOG_REDIS_DATABASE_INDEX:
ONEBLOG_REDIS_HOST:
ONEBLOG_REDIS_PORT:
ONEBLOG_REDIS_PASSWORD:
ONEBLOG_DATASOURCE_HOST:
ONEBLOG_DATASOURCE_PORT:
ONEBLOG_DATASOURCE_DATABASE_NAME:
ONEBLOG_DATASOURCE_USERNAME:
ONEBLOG_DATASOURCE_PASSWORD:
ONEBLOG_MAIL_HOST:
ONEBLOG_MAIL_PORT:
ONEBLOG_MAIL_USERNAME:
ONEBLOG_MAIL_PASSWORD:
ONEBLOG_APP_ENABLE_KAPTCHA:
ONEBLOG_APP_ENABLE_PRINT_CONFIG:
env_file:
- .env
volumes:
- ${ONEBLOG_APP_DIR}:/var/tmp/oneblog
depends_on:
......
......@@ -396,5 +396,18 @@ CREATE TABLE `sys_social_config` (
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '社会化登录应用' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for biz_page
-- ----------------------------
DROP TABLE IF EXISTS `biz_page`;
CREATE TABLE `biz_page` (
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '自定义页面的url(不包含域名部分)',
`content` mediumtext CHARACTER SET utf8 COLLATE utf8_general_ci 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
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
......@@ -189,6 +189,13 @@ INSERT INTO `dblog`.`sys_resources` VALUES (78, '批量删除社会化登录配
INSERT INTO `dblog`.`sys_resources` VALUES (79, '编辑社会化登录配置', 'button', NULL, 'social:edit,social:get', 76, 4, 0, 1, NULL, now(), now());
INSERT INTO `dblog`.`sys_resources` VALUES (80, '删除社会化登录配置', 'button', NULL, 'social:delete', 76, 5, 0, 1, NULL, now(), now());
# 20211023
INSERT INTO `dblog`.`sys_resources` VALUES (81, '自定义页面管理', 'menu', '/page', 'page', 40, 7, 0, 1, '', now(), now());
INSERT INTO `dblog`.`sys_resources` VALUES (82, '新增自定义页面', 'button', NULL, 'page:add', 81, 2, 0, 1, NULL, now(), now());
INSERT INTO `dblog`.`sys_resources` VALUES (83, '批量删除自定义页面', 'button', NULL, 'page:batchDelete', 81, 3, 0, 1, NULL, now(), now());
INSERT INTO `dblog`.`sys_resources` VALUES (84, '编辑自定义页面', 'button', NULL, 'page:edit,page:get', 81, 4, 0, 1, NULL, now(), now());
INSERT INTO `dblog`.`sys_resources` VALUES (85, '删除自定义页面', 'button', NULL, 'page:delete', 81, 5, 0, 1, NULL, now(), now());
# 清空系统角色
TRUNCATE TABLE `dblog`.`sys_role`;
# 初始化系统角色
......
......@@ -25,7 +25,7 @@
</parent>
<properties>
<oneblog.version>2.2.8</oneblog.version>
<oneblog.version>2.2.9</oneblog.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
......
......@@ -3,6 +3,43 @@
----
### 2021-10-23
1. 优化页面样式。
2. 新增【自定义页面】的功能,方便对接第三方的网站验证(比如:百度站长通过文件验证时,需要将验证文件上传到服务器,现在可以直接在后台添加映射)。
比如在使用七牛云的 SSL 证书时,需要[对域名所有权进行验证](https://developer.qiniu.com/ssl/3667/ssl-certificate-of-free-dns-validation-guide)。当使用文件验证时,需要将文件放到项目根目录下,然后重新打包、上传、部署,非常不方便。
![img.png](./docs/_media/img.png)
现在可以通过【自定义页面】功能快速完成文件地址映射:
![img.png](./docs/_media/blog-page.png)
访问 http://localhost:8443/.well-known/pki-validation/fileauth.txt
![img.png](./docs/_media/blog-page-verify.png)
再比如在百度站长平台添加网站时,一般也需要对域名进行验证,此时也可以选择【文件验证】,如下:
![img.png](./docs/_media/baidu-site.png)
先将该文件下载下来,查看源码后获得授权码,然后通过【自定义页面】功能快速完成文件地址映射:
![img.png](./docs/_media/blog-page-baidu.png)
访问 http://localhost:8443/baidu_verify_code-PHAfH7AwQ4.html
![img.png](./docs/_media/blog-page-verify2.png)
> 注意:目前该功能仅支持以下格式的url映射:
> 1. http://domain/{x}.xml
> 2. http://domain/{x}.txt
> 3. http://domain/{x}.html
> 4. http://domain/.well-known/{x}/{x}.txt
>
> 对于其他类型的 url 格式,请提交 issue
### 2021-06-06
1. 处理了一批 Issue
......