feat: 临时访问主题色配置

This commit is contained in:
xiaozzzi 2024-04-16 18:24:01 +08:00
parent f999b2176b
commit c5866839fd
5 changed files with 100 additions and 32 deletions

View File

@ -9,6 +9,8 @@ import cn.hutool.core.util.ZipUtil;
import com.blossom.backend.base.param.ParamEnum;
import com.blossom.backend.base.param.ParamService;
import com.blossom.backend.base.param.pojo.ParamEntity;
import com.blossom.backend.base.paramu.UserParamEnum;
import com.blossom.backend.base.paramu.UserParamService;
import com.blossom.backend.base.user.UserService;
import com.blossom.backend.base.user.pojo.UserEntity;
import com.blossom.backend.server.article.backup.pojo.BackupFile;
@ -56,6 +58,9 @@ public class ArticleBackupService {
@Autowired
private ParamService paramService;
@Autowired
private UserParamService userParamService;
@Autowired
private UserService userService;
@ -126,6 +131,8 @@ public class ArticleBackupService {
// 用户信息
UserEntity user = userService.selectById(userId);
final String BLOG_COLOR = userParamService.getValue(userId, UserParamEnum.WEB_BLOG_COLOR).getParamValue();
final File backLogFile = new File(backupFile.getRootPath() + "/" + "log.txt");
final List<String> backLogs = new ArrayList<>();
log.info("[文章备份] 开始备份, 本次备份文件名称 [{}], 用户ID [{}]", backupFile.getFilename(), userId);
@ -186,7 +193,7 @@ public class ArticleBackupService {
articleDetail.setName(article.getN());
// 文章 markdown 内容
String content = getContentByType(articleDetail, type, user);
String content = getContentByType(articleDetail, type, user, BLOG_COLOR);
content = formatContent(content, toLocal, article.getI(), article.getN());
String id = String.valueOf(articleDetail.getId());
String version = String.valueOf(articleDetail.getVersion());
@ -357,14 +364,14 @@ public class ArticleBackupService {
* @param type 类型
* @return 对应的内容
*/
private String getContentByType(ArticleEntity article, BackupTypeEnum type, UserEntity user) {
private String getContentByType(ArticleEntity article, BackupTypeEnum type, UserEntity user, String blogColor) {
if (type == BackupTypeEnum.MARKDOWN) {
return StrUtil.isBlank(article.getMarkdown()) ? "文章无内容" : article.getMarkdown();
} else if (type == BackupTypeEnum.HTML) {
ArticleEntity export = new ArticleEntity();
export.setName(article.getName().substring(article.getName().lastIndexOf("/")));
export.setHtml(article.getHtml());
return ArticleUtil.toHtml(article, user);
return ArticleUtil.toHtml(article, user, blogColor);
}
return "";
}

View File

@ -7,6 +7,8 @@ import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.blossom.backend.base.auth.AuthContext;
import com.blossom.backend.base.auth.annotation.AuthIgnore;
import com.blossom.backend.base.paramu.UserParamEnum;
import com.blossom.backend.base.paramu.UserParamService;
import com.blossom.backend.base.user.UserService;
import com.blossom.backend.server.article.draft.pojo.*;
import com.blossom.backend.server.article.open.ArticleOpenService;
@ -60,6 +62,7 @@ public class ArticleController {
private final DocService docService;
private final DocSortChecker docSortChecker;
private final ImportManager importManager;
private final UserParamService userParamService;
/**
* 查询列表
@ -260,7 +263,9 @@ public class ArticleController {
if (StrUtil.isBlank(article.getHtml())) {
article.setHtml("<span>文章无内容</span>");
}
String reportHtml = ArticleUtil.toHtml(article, userService.selectById(AuthContext.getUserId()));
String reportHtml = ArticleUtil.toHtml(article,
userService.selectById(AuthContext.getUserId()),
userParamService.getValue(AuthContext.getUserId(), UserParamEnum.WEB_BLOG_COLOR).getParamValue());
try (InputStream is = new ByteArrayInputStream(reportHtml.getBytes(StandardCharsets.UTF_8));
BufferedInputStream bis = new BufferedInputStream(is)) {
String filename = URLEncodeUtil.encode(article.getName() + ".html");
@ -331,6 +336,9 @@ public class ArticleController {
XzException404.throwBy(ObjUtil.isNull(visit), "文章不存在或您无权限查看");
ArticleEntity article = baseService.selectById(visit.getArticleId(), false, false, true, visit.getUserId());
resp.setContentType("text/html");
return ArticleUtil.toHtml(article, userService.selectById(visit.getUserId()));
return ArticleUtil.toHtml(
article,
userService.selectById(visit.getUserId()),
userParamService.getValue(visit.getUserId(), UserParamEnum.WEB_BLOG_COLOR).getParamValue());
}
}

View File

@ -102,6 +102,32 @@ public class ArticleUtil {
}
/**
*
*/
private static final String SCRIPT_TAG_BLOG_COLOR = " <script>\n" +
" window.addEventListener('load', function() {\n" +
" const rgb = '{BLOSSOM_WEB_BLOG_COLOR}'\n" +
" if (rgb && !rgb.toLowerCase().startsWith('rgb(')) {\n" +
" return\n" +
" }\n" +
" const prefix = rgb.substring(4, rgb.length - 1)\n" +
" let text = `:root {\n" +
" --bl-color-primary: ${rgb};\n" +
" }`\n" +
"\n" +
" let themeStyleTag = document.createElement('style')\n" +
" themeStyleTag.type = 'text/css'\n" +
" themeStyleTag.id = 'BLOSSOM_TEMPVISIT_STYLE_TAG'\n" +
" themeStyleTag.innerHTML = text\n" +
" document\n" +
" .getElementsByTagName('head')\n" +
" .item(0)\n" +
" .appendChild(themeStyleTag)\n" +
" });\n" +
" </script>" +
"</head>";
private static final String prefix = "\n" +
"<body><div class=\"header\">\n" +
@ -115,7 +141,7 @@ public class ArticleUtil {
"</div><div class=\"content \">\n" +
" <div class=\"toc\" id=\"blossom-toc\">\n" +
" <div style=\"font-size: 15px;color:#727272;padding:10px 0\">《{BLOSSOM_EXPORT_HTML_ARTICLE_NAME}》</div>\n" +
" <div style=\"font-size: 20px;color:#727272;border-bottom:2px solid #eaeaea;padding-bottom: 10px\">目录</div>\n" +
" <div style=\"font-size: 20px;color:#727272;border-bottom:2px solid #eaeaea;padding-bottom: 10px;margin-bottom: 10px;\">目录</div>\n" +
" </div><div class=\"main bl-preview\" id=\"blossom-view\">";
private static final String suffix = "</div></div></body></html>";
@ -136,15 +162,19 @@ public class ArticleUtil {
/**
* 将文章转换为 html 格式
*
* @param article 文章
* @param user 用户, 用户获取作者
* @param article 文章
* @param user 用户, 用户获取作者
* @param blogColor 主颜色
* @return html 内容
*/
public static String toHtml(ArticleEntity article, UserEntity user) {
return htmlTag + prefix
public static String toHtml(ArticleEntity article, UserEntity user, String blogColor) {
return htmlTag +
SCRIPT_TAG_BLOG_COLOR
.replaceAll("\\{BLOSSOM_WEB_BLOG_COLOR}", blogColor) +
// 替换作者, 文章名称
.replaceAll("\\{BLOSSOM_EXPORT_HTML_AUTHOR}", user.getNickName())
.replaceAll("\\{BLOSSOM_EXPORT_HTML_ARTICLE_NAME}", article.getName()) +
prefix
.replaceAll("\\{BLOSSOM_EXPORT_HTML_AUTHOR}", user.getNickName())
.replaceAll("\\{BLOSSOM_EXPORT_HTML_ARTICLE_NAME}", article.getName()) +
article.getHtml() + suffix;
}

View File

@ -1397,7 +1397,7 @@
padding-left: 15px;
border-right: 1px solid #eeeeee;
overflow-x: hidden;
overflow-y: scroll
overflow-y: scroll;
}
.toc > h1,
@ -1406,50 +1406,78 @@
.toc > h4,
.toc > h5,
.toc > h6 {
margin: 0;
margin-top: 0;
margin-bottom: 0;
line-height: 27px;
font-size: 15px;
font-weight: 300;
cursor: pointer;
color: #727272
color: #727272;
position: relative;
}
.toc > h1::after,
.toc > h2::after,
.toc > h3::after,
.toc > h4::after,
.toc > h5::after,
.toc > h6::after {
content: "";
position: absolute;
top: 20%;
left: -5px;
width: 2px;
height: 60%;
background: var(--bl-color-primary);
border-radius: 10px;
opacity: 0;
transition: opacity 0.1s;
}
.toc > h1:hover,
.toc > h2:hover,
.toc > h3:hover,
.toc > h4:hover,
.toc > h5:hover,
.toc > h6:hover {
color: #3b3b3b
color: var(--bl-color-primary);
}
.toc-h1 {
margin-top: 5px !important;
padding-top: 5px
.toc > h1:hover::after,
.toc > h2:hover::after,
.toc > h3:hover::after,
.toc > h4:hover::after,
.toc > h5:hover::after,
.toc > h6:hover::after {
opacity: 1;
}
.toc-h2 {
padding-left: 10px
margin-left: 10px;
}
.toc-h3 {
padding-left: 20px
margin-left: 20px;
}
.toc-h4 {
padding-left: 30px
margin-left: 30px;
}
.toc-h5 {
padding-left: 40px
margin-left: 40px;
}
.toc-h6 {
padding-left: 50px
margin-left: 50px;
}
</style>
<!--blossom styles-->
<style type="text/css">
:root {
--bl-color-primary: rgb(104, 104, 104);
--bl-editor-color: #707070;
--bl-editor-bg-color: #FFFFFF;
--bl-editor-gutters-bg-color: #f5f5f5;
@ -1594,7 +1622,7 @@
}
.bl-preview a {
color: #ad8cf2;
color: var(--bl-color-primary);
font-weight: bold;
}
@ -2021,19 +2049,15 @@
}
function onHtmlEventDispatch(t, _ty, event, type, data) {
// copy pre code
if (type === 'copyPreCode') {
let code = document.getElementById(data)
if (code) {
// navigator.clipboard.writeText(code.innerText)
// navigator clipboard 需要https等安全上下文
if (navigator.clipboard && window.isSecureContext) {
// navigator clipboard 向剪贴板写文本
return navigator.clipboard.writeText(code.innerText)
} else {
// 创建text area
let textArea = document.createElement('textarea')
textArea.value = code.innerText
// 使text area不在viewport同时设置不可见
textArea.style.position = 'absolute'
textArea.style.opacity = '0'
textArea.style.left = '-999999px'
@ -2051,6 +2075,5 @@
}
}
</script>
</head>

View File

@ -46,7 +46,7 @@
@change="changeBlogColor" />
<div class="color-item" v-for="color in colors" :key="color" :style="{ backgroundColor: color }" @click="changeBlogColor(color)"></div>
</bl-row>
<div class="conf-tip">博客主题色主要影响专题样式颜色以及文章中的链接颜色</div>
<div class="conf-tip">博客主题色主要影响专题样式颜色以及文章中的链接颜色以及文章临时访问中的链接颜色</div>
</el-form-item>
<el-form-item label="博客名称">