添加文章ai摘要功能,修改了关于页面的打赏样式,修复51la网站统计

This commit is contained in:
1152958806@qq.com 2023-06-30 01:28:19 +08:00
parent 1cccca40a7
commit 8995b546e4
11 changed files with 1221 additions and 750 deletions

View File

@ -635,7 +635,7 @@ spec:
- $formkit: radio
name: enable_footer_group
label: 启用页脚友链
value: true
value: false
options:
- label: 启用
value: true
@ -671,39 +671,6 @@ spec:
label: 最近发布文章
value: 4
help: "最近发布的文章数量"
- $formkit: group
name: reward
label: 打赏
value:
enable_reward:
wxPay:
alipay:
reward_md_url:
children:
- $formkit: radio
name: enable_reward
help: 启用文章打赏,请正确填写名称和二维码图片链接
value: true
options:
- label: 启用
value: true
- label: 禁用
value: false
- $formkit: attachment
name: wxPay
label: 微信
help: 微信二维码图片链接
placeholder: 请填写微信二维码图片链接
- $formkit: attachment
name: alipay
label: 支付宝
help: 支付宝二维码图片链接
placeholder: 请填写支付宝二维码图片链接
- $formkit: url
name: reward_md_url
label: 赞赏者名单地址
placeholder: "请输入赞赏者名单地址"
value: "/about"
- $formkit: group
name: post_edit
label: 运营模式与责任
@ -740,6 +707,67 @@ spec:
label: 版权声明
placeholder: '本文是原创文章,采用 <a target="_blank" href="/cc">CC BY-NC-ND 4.0</a> 协议,完整转载请注明来自 <a href="/" target="_blank" >程序员小航</a>'
help: "版权声明内容,支持填入 HTML 标签"
- group: aiDescription
label: 文章ai摘要
formSchema:
- $formkit: radio
name: enable
label: 启用ai 摘要
value: false
options:
- label: 启用
value: true
- label: 禁用
value: false
- $formkit: text
name: gptName
label: 名称
placeholder: 请输入内容
value: KunKunYu
- $formkit: radio
name: mode
label: 模式
value: local
options:
- label: 本地
value: local
- label: ai
value: tianli
- $formkit: radio
name: switchBtn
label: 显示切换按钮
value: false
options:
- label:
value: true
- label:
value: false
- $formkit: url
name: btnLink
label: 链接地址
placeholder: 输入链接地址
value: https://afdian.net/item/f18c2e08db4411eda2f25254001e7c00
- $formkit: number
name: randomNum
label: 标签数量
value: 3
help: "按钮最大的随机次数,也就是一篇文章最大随机出来几种"
- $formkit: number
name: basicWordCount
label: 标签数量
value: 1000
help: "最低获取字符数, 最小1000, 最大1999"
- $formkit: text
name: key
label: key
value: xxxx
placeholder: 请输入key
- $formkit: url
name: Referer
label: 你的博客地址
help: 注意保留最后的斜杠
value: https://xx.xx/
- group: about
label: 个人
@ -1000,6 +1028,7 @@ spec:
- $formkit: text
name: LingQueMonitorID
label: 51la网站统计配置
help: 统计ID
placeholder: 请输入内容
value: https://v6-widget.51.la/v6/K48u6B53QKqNs741/quote.js
- $formkit: group
@ -1064,14 +1093,29 @@ spec:
value:
enable_reward:
name:
content:
wxPay:
alipay:
enable_reward_wz:
reward_md_url:
children:
- $formkit: radio
name: enable_reward
help: 启用文章打赏,请正确填写名称和二维码图片链接
name: enable_reward_wz
help: 启用文章页面打赏
value: false
options:
- label: 启用
value: true
- label: 禁用
value: false
- $formkit: url
name: reward_md_url
label: 赞赏者名单地址
placeholder: "请输入赞赏者名单地址"
value: "/about"
- $formkit: radio
name: enable_reward
help: 启用关于页面打赏
value: false
options:
- label: 启用
value: true
@ -1082,11 +1126,6 @@ spec:
label: 按钮名称
placeholder: 请输入内容
value: 赞赏作者
- $formkit: text
name: content
label: 内容
placeholder: 请输入内容
value: 感谢你赐予我前进的力量
- $formkit: attachment
name: wxPay
label: 微信
@ -1189,7 +1228,7 @@ spec:
- $formkit: radio
name: switch
label: 开关
value: false
value: true
options:
- label: 打开
value: true

View File

@ -611,8 +611,7 @@
<div class="card-content">
<div class="author-content-item-tips" th:text="${theme.config.about.game.game_tips}">
</div>
<span class="author-content-item-title"
</div><span class="author-content-item-title"
th:text="${theme.config.about.game.game_title}"></span>
<div class="content-bottom">
<div class="icon-group">
@ -627,8 +626,7 @@
<div class="card-content">
<div class="author-content-item-tips" th:text="${theme.config.about.game2.game2_tips}">
</div>
<span class="author-content-item-title"
</div><span class="author-content-item-title"
th:text="${theme.config.about.game2.game2_title}"></span>
<div class="content-bottom">
<div class="tips" th:text="${theme.config.about.game2.game2_uid}"></div>
@ -683,10 +681,8 @@
<span class="author-content-item-title">访问统计</span>
<div id="statistic"></div>
<div class="post-tips">统计信息来自 <a href="https://invite.51.la/1NzKqTeb?target=V6"
rel="noopener nofollow"
target="_blank">51la网站统计</a></div>
<div class="banner-button-group"><a class="banner-button"
onclick="pjax.loadUrl('/archives')"
rel="noopener nofollow" target="_blank">51la网站统计</a></div>
<div class="banner-button-group"><a class="banner-button" onclick="pjax.loadUrl('/archives')"
data-pjax-state=""><i
class="anzhiyufont anzhiyu-icon-arrow-circle-right"></i><span
class="banner-button-text">文章隧道</span></a></div>
@ -694,7 +690,7 @@
</div>
<script>
// 链接替换即可,不需要后面的参数
fetch("[[${theme.config.about.LingQueMonitorID}]]")
fetch("https://v6-widget.51.la/v6/[[${theme.config.about.LingQueMonitorID}]]/quote.js")
.then(res => res.text())
.then(data => {
let title = ["最近活跃", "今日人数", "今日访问", "昨日人数", "昨日访问", "本月访问", "总访问量"];
@ -734,8 +730,7 @@
class="selfInfo-content" th:style="'color:' + ${texts[1].authorInfoColor}"
th:text="${texts[1].authorInfoContent}">计算机科学</span>
</div>
<div><span class="selfInfo-title"
th:text="${texts[2].authorInfoTitle}">现在职业</span><span
<div><span class="selfInfo-title" th:text="${texts[2].authorInfoTitle}">现在职业</span><span
class="selfInfo-content" th:style="'color:' + ${texts[2].authorInfoColor}"
th:text="${texts[2].authorInfoContent}">BI工程师</span>
</div>
@ -770,47 +765,53 @@
<div class="author-content">
<div class="author-content-item single reward">
<div class="author-content-item-tips">致谢</div>
<span class="author-content-item-title"
th:text="${theme.config.aboutReward.title}">赞赏名单</span>
<div class="author-content-item-description" th:text="${theme.config.aboutReward.content}">
感谢赞赏的人,因为你们,让我感受到写博客这件事情能够给你们创造了价值。这会让我在这条路上走得更远。
<span class="author-content-item-title" >[[${theme.config.aboutReward.title}]]</span>
<div class="author-content-item-description" >
[[${theme.config.aboutReward.content}]]
</div>
<div class="post-reward" th:if="${theme.config.aboutReward.reward.enable_reward}">
<div class="post-reward" onclick="AddRewardMask()"></div>
<div class="reward-button" title="赞赏作者"><i class="heofont icon-hand-heart-fill"></i>
[[${theme.config.aboutReward.reward.name}]]
<div th:if="${theme.config.aboutReward.reward.enable_reward}" class="about-reward">
<div id="con"></div>
<div id="TA-con" onclick="heo.rewardShowConsole()">
<div id="text-con">
<div id="linght"></div>
<div id="TA">[[${theme.config.aboutReward.reward.name}]]</div>
</div>
<div class="reward-main">
<ul class="reward-all">
<span class="reward-title">
[[${theme.config.aboutReward.reward.content}]]</span>
<ul class="reward-group">
<li class="reward-item">
<a href="" target="_blank"
th:href="@{${theme.config.aboutReward.reward.wxPay}}">
<img alt="微信" class="post-qr-code-img"
th:src="${theme.config.aboutReward.reward.wxPay}">
</a>
<div class="post-qr-code-desc">
微信
</div>
</li>
<li class="reward-item">
<a href="" target="_blank"
th:href="@{${theme.config.aboutReward.reward.alipay}}">
<img alt="支付宝" class="post-qr-code-img"
th:src="${theme.config.aboutReward.reward.alipay}">
</a>
<div class="post-qr-code-desc">
支付宝
</div>
</li>
</ul>
</ul>
<div id="tube-con"><svg viewBox="0 0 1028 385" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 77H234.226L307.006 24H790" stroke="#e5e9ef" stroke-width="20"></path>
<path d="M0 140H233.035L329.72 71H1028" stroke="#e5e9ef" stroke-width="20"></path>
<path d="M1 255H234.226L307.006 307H790" stroke="#e5e9ef" stroke-width="20"></path>
<path d="M0 305H233.035L329.72 375H1028" stroke="#e5e9ef" stroke-width="20"></path>
<rect y="186" width="236" height="24" fill="#e5e9ef"></rect>
<ellipse cx="790" cy="25.5" rx="25" ry="25.5" fill="#e5e9ef"></ellipse>
<circle r="14" transform="matrix(1 0 0 -1 790 25)" fill="white"></circle>
<ellipse cx="790" cy="307.5" rx="25" ry="25.5" fill="#e5e9ef"></ellipse>
<circle r="14" transform="matrix(1 0 0 -1 790 308)" fill="white"></circle>
</svg>
<div id="mask"><svg viewBox="0 0 1028 385" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 77H234.226L307.006 24H790" stroke="#f25d8e" stroke-width="20"></path>
<path d="M0 140H233.035L329.72 71H1028" stroke="#f25d8e" stroke-width="20"></path>
<path d="M1 255H234.226L307.006 307H790" stroke="#f25d8e" stroke-width="20"></path>
<path d="M0 305H233.035L329.72 375H1028" stroke="#f25d8e" stroke-width="20"></path>
<rect y="186" width="236" height="24" fill="#f25d8e"></rect>
<ellipse cx="790" cy="25.5" rx="25" ry="25.5" fill="#f25d8e"></ellipse>
<circle r="14" transform="matrix(1 0 0 -1 790 25)" fill="white"></circle>
<ellipse cx="790" cy="307.5" rx="25" ry="25.5" fill="#f25d8e"></ellipse>
<circle r="14" transform="matrix(1 0 0 -1 790 308)" fill="white"></circle>
</svg></div>
<div id="orange-mask"><svg viewBox="0 0 1028 385" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 77H234.226L307.006 24H790" stroke="#ffd52b" stroke-width="20"></path>
<path d="M0 140H233.035L329.72 71H1028" stroke="#ffd52b" stroke-width="20"></path>
<path d="M1 255H234.226L307.006 307H790" stroke="#ffd52b" stroke-width="20"></path>
<path d="M0 305H233.035L329.72 375H1028" stroke="#ffd52b" stroke-width="20"></path>
<rect y="186" width="236" height="24" fill="#ffd52b"></rect>
<ellipse cx="790" cy="25.5" rx="25" ry="25.5" fill="#ffd52b"></ellipse>
<circle r="14" transform="matrix(1 0 0 -1 790 25)" fill="white"></circle>
<ellipse cx="790" cy="307.5" rx="25" ry="25.5" fill="#ffd52b"></ellipse>
<circle r="14" transform="matrix(1 0 0 -1 790 308)" fill="white"></circle>
</svg></div>
<!-- <p id="people">共<b>29</b>人</p> -->
</div>
</div>
<div class="reward-list-all" th:if="${not #lists.isEmpty(theme.config.aboutReward.reward_list)}"
@ -820,8 +821,7 @@
<div class="reward-list-item-name">[[${authorReward.name}]]</div>
<div class="reward-list-bottom-group">
<div th:if="${authorReward.sign == 'N'}" class="reward-list-item-money">¥
[[${authorReward.amount}]]
</div>
[[${authorReward.amount}]]</div>
<div th:if="${authorReward.sign == 'Y'}" class="reward-list-item-money"
style="background: var(--heo-vip);">¥ [[${authorReward.amount}]]
</div>

View File

@ -400,10 +400,22 @@ var heo = {
return arr[0]
},
// 显示打赏中控台
rewardShowConsole: function () {
$('.console-card-group-reward').attr('style', 'display: flex');
$('.console-card-group').attr('style', 'display: none');
document.querySelector("#console").classList.add("show");
},
//显示中控台
showConsole: function () {
$('.console-card-group-reward').attr('style', 'display: none');
$('.console-card-group').attr('style', 'display: flex');
document.querySelector("#console").classList.add("show");
},
//隐藏中控台
@ -447,5 +459,6 @@ var heo = {
$htmlDom.contains('hide-aside')
? document.querySelector("#consoleHideAside").classList.add("on")
: document.querySelector("#consoleHideAside").classList.remove("on")
}
},
}

View File

@ -4,9 +4,9 @@ var commentBarrageConfig = {
//弹幕显示间隔时间ms
barrageTime: 4000,
//twikoo部署地址腾讯云的为环境ID
twikooUrl: "https://twikoo.yzczi.com/",
twikooUrl: "xxxx",
//token获取见上方
accessToken: "a0b1120dcbdd45579833ceab6ec112f7",
accessToken: "xxxx",
pageUrl: window.location.pathname,
barrageTimer: [],
barrageList: [],

View File

@ -7025,6 +7025,20 @@ a.console_switchbutton {
transition: 0s;
}
/* 导航栏名称样式 */
#nav #site-name {
color: var(--heo-fontcolor);
padding: 0 8px;
transition: 0.3s;
display: flex;
height: 35px;
/* width: 75px; */
justify-content: center;
align-items: center;
text-shadow: none;
border-radius: 40px;
}
/* 搜索 */
#search-button > a > span {
display: none;
@ -9064,7 +9078,7 @@ li {
margin: 10px 16px 0px 5px;
width: fit-content;
line-height: 1;
background: rgba(48,52,63,0.75);
background: var(--heo-main);
color: #fff;
border-radius: 6px;
-webkit-user-select: none;
@ -9079,7 +9093,7 @@ li {
cursor: pointer;
}
.ai-btn-item:hover {
background: var(--heo-main);
background: var(--heo-theme);
}
.ai-recommend {
display: -webkit-box;
@ -9170,7 +9184,7 @@ li {
.ai-title {
display: flex;
color: var(--heo-lighttext);
color: var(--font-color);
border-radius: 8px;
align-items: center;
padding: 0 12px;
@ -12095,9 +12109,9 @@ blockquote p {
position: absolute;
right: 22px;
top: -77px;
content: "\e00d";
content: "\f25e";
font-size: 180px;
font-family: "heofont";
font-family: "Font Awesome 5 Brands";
color: var(--heo-fontcolor);
opacity: 0.1;
filter: blur(7px);
@ -15819,6 +15833,272 @@ span.hexo-douban-pagenum {
transform: rotate(20deg);
}
.about-reward {
position: absolute;
top: 1rem;
right: 2rem
}
@media screen and (max-width: 768px) {
.reward .about-reward #con {
width:170px
}
.reward #tube-con {
display: none
}
}
.reward #con {
width: 350px;
height: 85px;
position: relative;
border-radius: 4px
}
.reward #TA-con {
width: 157px;
height: 50px;
background-color: #f25d8e;
-webkit-box-shadow: 0 4px 4px rgba(255,112,159,.3);
box-shadow: 0 4px 4px rgba(255,112,159,.3);
position: absolute;
top: 50%;
left: 10%;
-webkit-transform: translateY(-50%);
-moz-transform: translateY(-50%);
-o-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
border-radius: 4px;
cursor: pointer
}
@media screen and (max-width: 768px) {
.reward #TA-con {
width:125px;
left: 54px
}
}
.reward #TA-con:hover {
background-color: #ff6b9a
}
.reward #text-con {
width: 100px;
height: 100%;
margin: 0 auto;
position: relative
}
.reward #linght {
width: 0;
height: 0;
position: absolute;
top: 36%;
left: 4px;
border-color: transparent;
border-style: solid;
border-width: 10px;
border-top: 10px solid #fff;
border-radius: 4px;
-webkit-transform: rotate(-55deg);
-moz-transform: rotate(-55deg);
-o-transform: rotate(-55deg);
-ms-transform: rotate(-55deg);
transform: rotate(-55deg)
}
.reward #linght::after {
position: absolute;
top: -13px;
left: -11px;
content: "";
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
border-width: 10px;
border-top: 10px solid #fff;
-webkit-transform: rotate(180deg);
-moz-transform: rotate(180deg);
-o-transform: rotate(180deg);
-ms-transform: rotate(180deg);
transform: rotate(180deg);
border-radius: 4px
}
.reward #TA {
float: right;
line-height: 50px;
font-size: 15px;
color: #fff
}
.reward #tube-con {
width: 157px;
height: 55px;
position: absolute;
right: -5px;
top: 15px
}
.reward svg {
width: 100%;
height: 100%
}
.reward #mask {
width: 0;
height: 100%;
overflow: hidden;
position: absolute;
top: 0;
left: 0;
-webkit-transition: all .5s;
-moz-transition: all .5s;
-o-transition: all .5s;
-ms-transition: all .5s;
transition: all .5s
}
.reward #mask svg {
width: 157px;
height: 55px
}
.reward #TA-con:hover+#tube-con>#mask {
width: 157px
}
.reward #TA-con:hover+#tube-con>#orange-mask {
-webkit-animation: move1 .5s linear .2s infinite;
-moz-animation: move1 .5s linear .2s infinite;
-o-animation: move1 .5s linear .2s infinite;
-ms-animation: move1 .5s linear .2s infinite;
animation: move1 .5s linear .2s infinite
}
.reward #TA-con:hover+#tube-con>#orange-mask svg {
-webkit-animation: movetwo .5s linear .2s infinite;
-moz-animation: movetwo .5s linear .2s infinite;
-o-animation: movetwo .5s linear .2s infinite;
-ms-animation: movetwo .5s linear .2s infinite;
animation: movetwo .5s linear .2s infinite
}
.reward #orange-mask {
width: 18px;
height: 100%;
overflow: hidden;
position: absolute;
left: -15px;
top: 0
}
.reward #orange-mask svg {
position: absolute;
top: 0;
left: 15px;
width: 157px;
height: 55px
}
.reward #people {
position: absolute;
right: 10px;
top: 4px;
font-size: 12px;
font-family: "雅黑";
color: #aaa
}
.reward #people>b {
color: #777
}
@-moz-keyframes move1 {
0% {
left: -15px
}
100% {
left: 140px
}
}
@-webkit-keyframes move1 {
0% {
left: -15px
}
100% {
left: 140px
}
}
@-o-keyframes move1 {
0% {
left: -15px
}
100% {
left: 140px
}
}
@keyframes move1 {
0% {
left: -15px
}
100% {
left: 140px
}
}
@-moz-keyframes movetwo {
0% {
left: 15px
}
100% {
left: -140px
}
}
@-webkit-keyframes movetwo {
0% {
left: 15px
}
100% {
left: -140px
}
}
@-o-keyframes movetwo {
0% {
left: 15px
}
100% {
left: -140px
}
}
@keyframes movetwo {
0% {
left: 15px
}
100% {
left: -140px
}
}
/* 关于页面打招呼信息 */
#about-page .myInfoAndSayHello {
@ -16889,6 +17169,7 @@ span.hexo-douban-pagenum {
}
}
@media screen and (max-width: 768px) {
#console .console-card-group {
display: none;
@ -16897,8 +17178,10 @@ span.hexo-douban-pagenum {
#consoleHideAside {
display: none;
}
}
@media screen and (max-height: 800px) {
#console .console-card-group {
display: none;
@ -16913,6 +17196,30 @@ span.hexo-douban-pagenum {
}
}
@media screen and (max-width: 867px) {
#console .close-btn {
display:none
}
#console .console-card-group {
display: none
}
#consoleHideAside {
display: none
}
.console-card-group-reward .reward-all .reward-item img {
width: 130px;
height: 130px
}
#console #consoleKeyboard {
display: none
}
}
#console .console-card {
background: var(--heo-maskbg);
border-radius: 12px;
@ -16922,6 +17229,11 @@ span.hexo-douban-pagenum {
padding: 40px;
}
.console-card-group-reward .reward-all .reward-item img {
width: 230px;
height: 230px
}
#console .console-card.tags {
height: calc(100% - 172px);
}
@ -17193,6 +17505,21 @@ span.hexo-douban-pagenum {
font-size: 1rem;
}
#console .console-card-group-reward .reward-all {
display: flex;
align-items: center;
justify-content: center
}
#console .console-card-group-reward .reward-all .reward-item {
display: flex;
flex-direction: column;
align-items: center;
margin: .625rem;
}
/* 快捷键窗口 */
#keyboard-tips {
position: fixed;
@ -17334,19 +17661,6 @@ a.toc-link {
}
}
/* 导航栏名称样式 */
#nav #site-name {
color: var(--heo-fontcolor);
padding: 0 8px;
transition: 0.3s;
display: flex;
height: 35px;
/*width: 75px;*/
justify-content: center;
align-items: center;
text-shadow: none;
border-radius: 40px;
}

File diff suppressed because one or more lines are too long

View File

@ -125,6 +125,36 @@
<script>
!function(p) {
"use strict";
!function(t) {
var s = window
, e = document
, i = p
, c = "".concat("https:" === e.location.protocol ? "https://" : "http://", "sdk.51.la/js-sdk-pro.min.js")
, n = e.createElement("script")
, r = e.getElementsByTagName("script")[0];
n.type = "text/javascript",
n.setAttribute("charset", "UTF-8"),
n.async = !0,
n.src = c,
n.id = "LA_COLLECT",
i.d = n;
var o = function() {
s.LA.ids.push(i)
};
s.LA ? s.LA.ids && o() : (s.LA = p,
s.LA.ids = [],
o()),
r.parentNode.insertBefore(n, r)
}()
}({
id: "[[${theme.config.about.LingQueMonitorID}]]",
ck: "[[${theme.config.about.LingQueMonitorID}]]",
hashMode: true
});
</script>
<script >

View File

@ -39,7 +39,7 @@
th:href="@{${post.status.permalink}}"
th:text="${post.spec.title}">
</a>
<div class="content" th:text="${post.status.excerpt}"></div>
<!-- <div class="content" th:text="${post.status.excerpt}"></div> -->
</div>

View File

@ -0,0 +1,377 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<!-- 文章ai摘要 -->
<script data-pjax th:fragment="postHeadAiDescription" th:if="${theme.config.aiDescription.enable}">
(function () {
let ai = "[[${post.status.excerpt}]]"
let randomNum = [[${theme.config.aiDescription.randomNum}]] //按钮最大的随机次数,也就是一篇文章最大随机出来几种
let basicWordCount = [[${theme.config.aiDescription.basicWordCount}]] // 最低获取字符数, 最小1000, 最大1999
let btnLink = "[[${theme.config.aiDescription.btnLink}]]"
let gptName = "[[${theme.config.aiDescription.gptName}]]"
let modeName = "[[${theme.config.aiDescription.modeName}]]" //默认模式 可选值: tianli/local
let switchBtn = [[${theme.config.aiDescription.switchBtn}]] //# 可以配置是否显示切换按钮 以切换tianli/local
let keys = "[[${theme.config.aiDescription.key}]]"
let Referers = "[[${theme.config.aiDescription.Referer}]]"
// 当前随机到的ai摘要到index
let lastAiRandomIndex = -1;
let animationRunning = true; // 标志变量,控制动画函数的运行
// 当前gpt模式
let mode = modeName
// 刷新点击次数
let refreshNum = 0
// 记录上一次传递给aiAbstract的参数
let prevParam;
const aiTitleRefreshIcon = document.querySelector(".ai-title .anzhiyufont.anzhiyu-icon-arrow-rotate-right")
const explanation = document.querySelector(".ai-explanation");
const post_ai = document.querySelector(".post-ai");
let ai_str = "";
let ai_str_length = "";
let delay_init = 600;
let i = 0;
let j = 0;
let sto = [];
let elapsed = 0;
const animate = timestamp => {
if (!animationRunning) {
return; // 动画函数停止运行
}
if (!animate.start) animate.start = timestamp;
elapsed = timestamp - animate.start;
if (elapsed >= 20) {
animate.start = timestamp;
if (i < ai_str_length - 1) {
let char = ai_str.charAt(i + 1);
let delay = /[,.,。!?]/.test(char) ? 150 : 20;
if (explanation.firstElementChild) {
explanation.removeChild(explanation.firstElementChild);
}
explanation.innerHTML += char;
let div = document.createElement("div");
div.className = "ai-cursor";
explanation.appendChild(div);
i++;
if (delay === 150) {
document.querySelector(".ai-explanation .ai-cursor").style.opacity = "0";
}
if (i === ai_str_length - 1) {
observer.disconnect(); // 暂停监听
explanation.removeChild(explanation.firstElementChild);
}
sto[0] = setTimeout(() => {
requestAnimationFrame(animate);
}, delay);
}
} else {
requestAnimationFrame(animate);
}
};
const observer = new IntersectionObserver(
entries => {
let isVisible = entries[0].isIntersecting;
animationRunning = isVisible; // 标志变量更新
if (animationRunning) {
delay_init = i === 0 ? 200 : 20;
sto[1] = setTimeout(() => {
if (j) {
i = 0;
j = 0;
}
if (i === 0) {
explanation.innerHTML = ai_str.charAt(0);
}
requestAnimationFrame(animate);
}, delay_init);
}
},
{ threshold: 0 }
);
function clearSTO() {
if (sto.length) {
sto.forEach(item => {
if (item) {
clearTimeout(item);
}
});
}
}
function startAI(str, df = true) {
i = 0; //重置计数器
j = 1;
clearSTO();
animationRunning = false;
elapsed = 0;
observer.disconnect(); // 暂停上一次监听
explanation.innerHTML = df ? "生成中. . ." : "请等待. . .";
ai_str = str;
ai_str_length = ai_str.length;
observer.observe(post_ai); //启动新监听
}
async function aiAbstract(num = basicWordCount) {
i = 0; //重置计数器
j = 1;
clearSTO();
animationRunning = false;
elapsed = 0;
observer.disconnect(); // 暂停上一次监听
if (mode === "tianli") {
num = Math.max(10, Math.min(2000, num));
const options = {
key: keys,
Referer: Referers
};
const truncateDescription = getTitleAndContent(num);
const queryParams = `key=${options.key}&content=${truncateDescription}`;
const requestOptions = {
method: "GET",
headers: {
"Content-Type": "application/json",
Referer: options.Referer
},
};
try {
let animationInterval = null
if (animationInterval) clearInterval(animationInterval);
animationInterval = setInterval(() => {
const animationText = "生成中" + ".".repeat(j);
explanation.innerHTML = animationText;
j = (j % 3) + 1; // 在 1、2、3 之间循环
}, 500);
const response = await fetch(`https://summary.tianli0.top/?${queryParams}`, requestOptions);
const result = await response.json();
const summary = result.summary.trim();
setTimeout(() => {
aiTitleRefreshIcon.style.opacity = "1";
}, 300)
startAI(summary);
clearInterval(animationInterval)
} catch (error) {
console.error(error);
}
} else {
const strArr = ai.split(",").map(item => item.trim()); // 将字符串转换为数组,去除每个字符串前后的空格
if (strArr.length !== 1) {
let randomIndex = Math.floor(Math.random() * strArr.length); // 随机生成一个索引
while (randomIndex === lastAiRandomIndex) { // 如果随机到了上次的索引
randomIndex = Math.floor(Math.random() * strArr.length); // 再次随机
}
lastAiRandomIndex = randomIndex; // 更新上次随机到的索引
startAI(strArr[randomIndex]);
} else {
startAI(strArr[0])
}
setTimeout(() => {
aiTitleRefreshIcon.style.opacity = "1";
}, 600)
}
}
function aiRecommend() {
i = 0; //重置计数器
j = 1;
clearSTO();
animationRunning = false;
elapsed = 0;
explanation.innerHTML = "生成中. . .";
ai_str = "";
ai_str_length = "";
observer.disconnect(); // 暂停上一次监听
sto[2] = setTimeout(() => {
explanation.innerHTML = recommendList();
}, 600);
}
function aiGoHome() {
startAI("正在前往博客主页...", false);
sto[2] = setTimeout(() => {
pjax.loadUrl("/");
}, 1000);
}
const ai_btn_item = document.querySelectorAll(".ai-btn-item");
function Introduce() {
if (mode == "tianli") {
startAI("我是文章辅助AI: TianliGPT点击下方的按钮让我生成本文简介、推荐相关文章等。")
} else {
startAI("我是文章辅助AI: " + gptName + " GPT点击下方的按钮让我生成本文简介、推荐相关文章等。")
}
}
function aiTitleRefreshIconClick() {
aiTitleRefreshIcon.click()
}
const aiFunctions = [Introduce, aiTitleRefreshIconClick, aiRecommend, aiGoHome];
ai_btn_item.forEach((item, index) => {
item.addEventListener("click", () => {
aiFunctions[index]();
});
});
function recommendList() {
let thumbnail = document.querySelectorAll('.relatedPosts-list a');
if (!thumbnail.length) {
const cardRecentPost = document.querySelector('.card-widget.card-recent-post');
if (!cardRecentPost) return '';
thumbnail = cardRecentPost.querySelectorAll('.aside-list-item a');
let list = '';
for (let i = 0; i < thumbnail.length; i++) {
const item = thumbnail[i];
list += `<div class="ai-recommend-item"><span class="index">${i + 1}</span><a href="javascript:;" onclick="pjax.loadUrl('${item.href}')" title="${item.title}" data-pjax-state="">${item.title}</a></div>`;
}
return `很抱歉,无法找到类似的文章,你也可以看看本站最新发布的文章:<br /><div class="ai-recommend">${list}</div>`;
}
let list = '';
for (let i = 0; i < thumbnail.length; i++) {
const item = thumbnail[i];
list += `<div class="ai-recommend-item"><span>推荐${i + 1}</span><a href="javascript:;" onclick="pjax.loadUrl('${item.href}')" title="${item.title}" data-pjax-state="">${item.title}</a></div>`;
}
return `推荐文章:<br /><div class="ai-recommend">${list}</div>`;
}
function changeShowMode() {
if (mode === "tianli") {
mode = "local";
document.getElementById("ai-tag").innerHTML = gptName + " GPT";
aiAbstract(basicWordCount);
} else {
mode = "tianli";
document.getElementById("ai-tag").innerHTML = "Tianli GPT";
const truncateDescription = getTitleAndContent(basicWordCount);
let value = Math.floor(Math.random() * randomNum) + basicWordCount;
while (value === prevParam || truncateDescription.length - value === prevParam) {
value = Math.floor(Math.random() * randomNum) + basicWordCount;
}
aiTitleRefreshIcon.style.opacity = "0.2";
aiTitleRefreshIcon.style.transitionDuration = "0.3s";
aiTitleRefreshIcon.style.transform = "rotate(" + 360 * refreshNum + "deg)";
if (truncateDescription.length <= 1000) {
let param = truncateDescription.length - Math.floor(Math.random() * randomNum);
while (param === prevParam) {
param = truncateDescription.length - Math.floor(Math.random() * randomNum);
}
aiAbstract(param);
prevParam = param;
} else {
aiAbstract(value);
prevParam = value;
}
refreshNum++;
}
}
//- 监听tag点击事件
document.getElementById("ai-tag").addEventListener("click", () => {
if (mode === "tianli") {
document.querySelectorAll(".ai-btn-item").forEach(item => item.style.display = "none");
document.getElementById("go-tianli-blog").style.display = "block";
startAI("你好我是Tianli开发的摘要生成助理TianliGPT是一个基于GPT-4的生成式AI。我在这里只负责摘要的预生成和显示你无法与我直接沟通如果你也需要一个这样的AI摘要接口可以在下方购买。暂未开放购买敬请期待")
} else {
document.getElementById("go-tianli-blog").style.display = "none";
startAI("你好,我是本站摘要生成助理" + gptName + " GPT是一个基于GPT-4的生成式AI。我在这里只负责摘要的预生成和显示你无法与我直接沟通。")
}
});
aiTitleRefreshIcon.addEventListener("click", () => {
const truncateDescription = getTitleAndContent(basicWordCount);
let value = Math.floor(Math.random() * randomNum) + basicWordCount;
while (value === prevParam || truncateDescription.length - value === prevParam) {
value = Math.floor(Math.random() * randomNum) + basicWordCount;
}
aiTitleRefreshIcon.style.opacity = "0.2";
aiTitleRefreshIcon.style.transitionDuration = "0.3s";
aiTitleRefreshIcon.style.transform = "rotate(" + 360 * refreshNum + "deg)";
if (truncateDescription.length <= 1000) {
let param = truncateDescription.length - Math.floor(Math.random() * randomNum);
while (param === prevParam) {
param = truncateDescription.length - Math.floor(Math.random() * randomNum);
}
aiAbstract(param);
prevParam = param;
} else {
aiAbstract(value);
prevParam = value;
}
showAiBtn();
refreshNum++;
});
document.getElementById("go-tianli-blog").addEventListener("click", () => {
window.open(btnLink, "_blank");
});
if (switchBtn) {
document.getElementById("ai-Toggle").addEventListener("click", () => {
changeShowMode()
});
}
function showAiBtn() {
document.querySelectorAll(".ai-btn-item").forEach(item => {
if (item.id !== "go-tianli-blog") {
item.style.display = "block";
}
if (item.id === "go-tianli-blog") {
item.style.display = "none";
}
});
}
//读取文章中的所有文本
function getTitleAndContent(basicWordCount) {
try {
const title = document.title;
const container = document.querySelector('#post #article-container');
if (!container) {
console.warn('TianliGPT找不到文章容器。请尝试将引入的代码放入到文章容器之后。如果本身没有打算使用摘要功能可以忽略此提示。');
return '';
}
const paragraphs = container.getElementsByTagName('p');
const headings = container.querySelectorAll('h1, h2, h3, h4, h5');
let content = '';
for (let h of headings) {
content += h.innerText + ' ';
}
for (let p of paragraphs) {
// 移除包含'http'的链接
const filteredText = p.innerText.replace(/https?:\/\/[^\s]+/g, '');
content += filteredText;
}
const combinedText = title + ' ' + content;
let wordLimit = 1000;
if (basicWordCount !== "undefined") {
wordLimit = basicWordCount;
}
const truncatedText = combinedText.slice(0, wordLimit);
return truncatedText;
} catch (e) {
console.error('TianliGPT错误可能由于一个或多个错误导致没有正常运行原因出在获取文章容器中的内容失败或者可能是在文章转换过程中失败。', e);
return '';
}
}
aiAbstract();
showAiBtn()
})()
</script>
</html>

View File

@ -36,8 +36,7 @@
<ul class="card-archive-list" th:with="archives = ${postFinder.archives(1,1000)}">
<th:block th:each="archive : ${archives.items}">
<li class="card-archive-list-item" th:each="month,monthStat : ${archive.months}">
<a class="card-archive-list-link"
th:href="@{'/archives/'+${archive.year}+'/'+${month.month}}"
<a class="card-archive-list-link" th:href="@{'/archives/'+${archive.year}+'/'+${month.month}}"
data-pjax-state="load"><span
class="card-archive-list-date">[[${archive.year}]]-[[${month.month}]]</span>
<div class="card-archive-list-count-group"><span
@ -51,19 +50,33 @@
</div>
</div>
</div>
<div class="console-card-group-reward" th:if="${theme.config.aboutReward.reward.enable_reward}">
<ul class="reward-all console-card">
<li class="reward-item"><a th:href="@{${theme.config.aboutReward.reward.wxPay}}"
rel="external nofollow noreferrer" target="_blank" draggable="false"><img
class=" entered loaded" alt="微信"
th:src="${theme.config.aboutReward.reward.wxPay}"></a>
<div class="post-qr-code-desc">微信</div>
</li>
<li class="reward-item"><a th:href="@{${theme.config.aboutReward.reward.alipay}}"
rel="external nofollow noreferrer" target="_blank" draggable="false"><img
class=" entered loaded" alt="支付宝"
th:src="${theme.config.aboutReward.reward.alipay}"></a>
<div class="post-qr-code-desc">支付宝</div>
</li>
</ul>
</div>
<div class="button-group">
<div class="console-btn-item">
<!-- 用到了 rightmenu.js 的功能,还需要调整 -->
<a class="darkmode_switchbutton" href="javascript:void(0);" onclick="rm.switchDarkMode()"
rel="external nofollow"
<a class="darkmode_switchbutton" href="javascript:void(0);" onclick="rm.switchDarkMode()" rel="external nofollow"
title="显示模式切换"><i class="iconfont icon-moon" style="font-size:1rem"></i>
</a>
</div>
<div class="console-btn-item" id="consoleHideAside" onclick="heo.hideAsideBtn()" title="边栏显示控制"><a
class="asideSwitch" data-pjax-state=""><i class="anzhiyufont anzhiyu-icon-arrows-left-right"></i></a>
</div>
<div class="console-btn-item on" id="consoleCommentBarrage" onclick="heo.switchCommentBarrage()"
title="热评开关"><a
class="asideSwitch" data-pjax-state=""><i class="anzhiyufont anzhiyu-icon-arrows-left-right"></i></a></div>
<div class="console-btn-item on" id="consoleCommentBarrage" onclick="heo.switchCommentBarrage()" title="热评开关"><a
class="commentBarrage" data-pjax-state=""><i class="anzhiyufont anzhiyu-icon-message"></i></a></div>
<!--<div class="console-btn-item" id="consoleKeyboard" onclick="heo.keyboardToggle()" title="快捷键开关"><a-->

View File

@ -97,18 +97,15 @@
<main class="layout" id="content-inner" th:classappend="${theme.config.sidebar.location}">
<div id="post">
<!-- <link rel="stylesheet" href="https://cdn1.tianli0.top/gh/zhheo/Post-Abstract-AI@0.7/tianli_gpt.css">
<script>
let tianliGPT_postSelector = '#post #article-container';
let tianliGPT_key = 'QokJo3m2LZ53uAqICeLO';
</script>
<script src="https://blog.zhheo.com/js/heo_gpt.js"></script> -->
<!-- <div class="post-ai">
<!-- 文章ai摘要 -->
<div class="post-ai" th:if="${theme.config.aiDescription.enable}">
<div class="ai-title"><i class="anzhiyufont anzhiyu-icon-bilibili"></i>
<div class="ai-title-text">AI-摘要</div><i
class="anzhiyufont anzhiyu-icon-arrow-rotate-right"></i>
<div class="ai-tag" id="ai-tag">Tianli GPT</div>
<div class="ai-title-text">AI-摘要</div>
<div th:if="${theme.config.aiDescription.switchBtn}" id="ai-Toggle">切换</div>
<i class="anzhiyufont anzhiyu-icon-arrow-rotate-right"></i>
<div class="ai-tag" id="ai-tag">[[${theme.config.aiDescription.gptName}]] GPT</div>
</div>
<div class="ai-explanation" style="display: block;">AI初始化中...</div>
<div class="ai-btn-box">
@ -118,334 +115,22 @@
<div class="ai-btn-item">前往主页</div>
<div class="ai-btn-item" id="go-tianli-blog">前往tianli博客</div>
</div>
<script data-pjax>(function () {
// 当前随机到的ai摘要到index
let lastAiRandomIndex = -1;
let animationRunning = true; // 标志变量,控制动画函数的运行
// 当前gpt模式
let mode = "tianli"
// 刷新点击次数
let refreshNum = 0
// 记录上一次传递给aiAbstract的参数
let prevParam;
const aiTitleRefreshIcon = document.querySelector(".ai-title .anzhiyufont.anzhiyu-icon-arrow-rotate-right")
const explanation = document.querySelector(".ai-explanation");
const post_ai = document.querySelector(".post-ai");
let ai_str = "";
let ai_str_length = "";
let delay_init = 600;
let i = 0;
let j = 0;
let sto = [];
let elapsed = 0;
const animate = timestamp => {
if (!animationRunning) {
return; // 动画函数停止运行
}
if (!animate.start) animate.start = timestamp;
elapsed = timestamp - animate.start;
if (elapsed >= 20) {
animate.start = timestamp;
if (i < ai_str_length - 1) {
let char = ai_str.charAt(i + 1);
let delay = /[,.,。!?]/.test(char) ? 150 : 20;
if (explanation.firstElementChild) {
explanation.removeChild(explanation.firstElementChild);
}
explanation.innerHTML += char;
let div = document.createElement("div");
div.className = "ai-cursor";
explanation.appendChild(div);
i++;
if (delay === 150) {
document.querySelector(".ai-explanation .ai-cursor").style.opacity = "0";
}
if (i === ai_str_length - 1) {
observer.disconnect(); // 暂停监听
explanation.removeChild(explanation.firstElementChild);
}
sto[0] = setTimeout(() => {
requestAnimationFrame(animate);
}, delay);
}
} else {
requestAnimationFrame(animate);
}
};
const observer = new IntersectionObserver(
entries => {
let isVisible = entries[0].isIntersecting;
animationRunning = isVisible; // 标志变量更新
if (animationRunning) {
delay_init = i === 0 ? 200 : 20;
sto[1] = setTimeout(() => {
if (j) {
i = 0;
j = 0;
}
if (i === 0) {
explanation.innerHTML = ai_str.charAt(0);
}
requestAnimationFrame(animate);
}, delay_init);
}
},
{ threshold: 0 }
);
function clearSTO() {
if (sto.length) {
sto.forEach(item => {
if (item) {
clearTimeout(item);
}
});
}
}
function startAI(str, df = true) {
i = 0; //重置计数器
j = 1;
clearSTO();
animationRunning = false;
elapsed = 0;
observer.disconnect(); // 暂停上一次监听
explanation.innerHTML = df ? "生成中. . ." : "请等待. . .";
ai_str = str;
ai_str_length = ai_str.length;
observer.observe(post_ai); //启动新监听
}
</div>
async function aiAbstract(num = 1000) {
i = 0; //重置计数器
j = 1;
clearSTO();
animationRunning = false;
elapsed = 0;
observer.disconnect(); // 暂停上一次监听
if (mode === "tianli") {
num = Math.max(10, Math.min(2000, num));
const options = {
key: "QokJo3m2LZ53uAqICeLO",
Referer: "https://0206.ink/"
};
const truncateDescription = ("Docker Swarm常用命令" + "查看集群节点, Token相关, 创建nginx服务, 查看swarm集群中的服务, kill其中一个容器, 修改服务实例数量为3, 删除nginx服务, 删除swarm节点, docker swarm 常用命令, docker node 常用命令, docker service 常用命令查看集群节点相关查看加入的命令查看加入的命令重置的仅打印创建服务下载私有仓库镜像创建个容器为私有仓库查看集群中的服务其中一个容器等会自动启动一个新的容器修改服务实例数量为删除服务删除节点常用命令初始化集群查看工作节点的查看管理节点的加入集群中常用命令查看所有集群节点删除某个节点强制删除查看节点详情节点降级由管理节点降级为工作节点节点升级由工作节点升级为管理节点更新节点查看节点中的任务常用命令部署服务查看服务详情产看某个服务日志查看所有服务详情删除某个服务强制删除设置某个服务个数更新某个服务").trim().substring(0, num)
const queryParams = `key=${options.key}&content=${truncateDescription}`;
const requestOptions = {
method: "GET",
headers: {
"Content-Type": "application/json",
Referer: options.Referer
},
};
try {
let animationInterval = null
if (animationInterval) clearInterval(animationInterval);
animationInterval = setInterval(() => {
const animationText = "生成中" + ".".repeat(j);
explanation.innerHTML = animationText;
j = (j % 3) + 1; // 在 1、2、3 之间循环
}, 500);
const response = await fetch(`https://summary.tianli0.top/?${queryParams}`, requestOptions);
console.log(response)
const result = await response.json();
const summary = result.summary.trim();
setTimeout(() => {
aiTitleRefreshIcon.style.opacity = "1";
}, 300)
startAI(summary);
clearInterval(animationInterval)
} catch (error) {
console.error(error);
}
} else {
const strArr = "true".split(",").map(item => item.trim()); // 将字符串转换为数组,去除每个字符串前后的空格
if (strArr.length !== 1) {
let randomIndex = Math.floor(Math.random() * strArr.length); // 随机生成一个索引
while (randomIndex === lastAiRandomIndex) { // 如果随机到了上次的索引
randomIndex = Math.floor(Math.random() * strArr.length); // 再次随机
}
lastAiRandomIndex = randomIndex; // 更新上次随机到的索引
startAI(strArr[randomIndex]);
} else {
startAI(strArr[0])
}
setTimeout(() => {
aiTitleRefreshIcon.style.opacity = "1";
}, 600)
}
}
function aiRecommend() {
i = 0; //重置计数器
j = 1;
clearSTO();
animationRunning = false;
elapsed = 0;
explanation.innerHTML = "生成中. . .";
ai_str = "";
ai_str_length = "";
observer.disconnect(); // 暂停上一次监听
sto[2] = setTimeout(() => {
explanation.innerHTML = recommendList();
}, 600);
}
function aiGoHome() {
startAI("正在前往博客主页...", false);
sto[2] = setTimeout(() => {
pjax.loadUrl("/");
}, 1000);
}
const ai_btn_item = document.querySelectorAll(".ai-btn-item");
function Introduce() {
if (mode == "tianli") {
startAI("我是文章辅助AI: TianliGPT点击下方的按钮让我生成本文简介、推荐相关文章等。")
} else {
startAI("我是文章辅助AI: KunKunYu GPT点击下方的按钮让我生成本文简介、推荐相关文章等。")
}
}
function aiTitleRefreshIconClick() {
aiTitleRefreshIcon.click()
}
const aiFunctions = [Introduce, aiTitleRefreshIconClick, aiRecommend, aiGoHome];
ai_btn_item.forEach((item, index) => {
item.addEventListener("click", () => {
aiFunctions[index]();
});
});
function recommendList() {
let thumbnail = document.querySelectorAll('.relatedPosts-list a');
if (!thumbnail.length) {
const cardRecentPost = document.querySelector('.card-widget.card-recent-post');
if (!cardRecentPost) return '';
thumbnail = cardRecentPost.querySelectorAll('.aside-list-item a');
let list = '';
for (let i = 0; i < thumbnail.length; i++) {
const item = thumbnail[i];
list += `<div class="ai-recommend-item"><span class="index">${i + 1}</span><a href="javascript:;" onclick="pjax.loadUrl('${item.href}')" title="${item.title}" data-pjax-state="">${item.title}</a></div>`;
}
return `很抱歉,无法找到类似的文章,你也可以看看本站最新发布的文章:<br /><div class="ai-recommend">${list}</div>`;
}
let list = '';
for (let i = 0; i < thumbnail.length; i++) {
const item = thumbnail[i];
list += `<div class="ai-recommend-item"><span>推荐${i + 1}</span><a href="javascript:;" onclick="pjax.loadUrl('${item.href}')" title="${item.title}" data-pjax-state="">${item.title}</a></div>`;
}
return `推荐文章:<br /><div class="ai-recommend">${list}</div>`;
}
function changeShowMode() {
if (mode === "tianli") {
mode = "local";
document.getElementById("ai-tag").innerHTML = "KunKunYu GPT";
aiAbstract(1000);
} else {
mode = "tianli";
document.getElementById("ai-tag").innerHTML = "Tianli GPT";
const truncateDescription = ("" + "查看集群节点, Token相关, 创建nginx服务, 查看swarm集群中的服务, kill其中一个容器, 修改服务实例数量为3, 删除nginx服务, 删除swarm节点, docker swarm 常用命令, docker node 常用命令, docker service 常用命令查看集群节点相关查看加入的命令查看加入的命令重置的仅打印创建服务下载私有仓库镜像创建个容器为私有仓库查看集群中的服务其中一个容器等会自动启动一个新的容器修改服务实例数量为删除服务删除节点常用命令初始化集群查看工作节点的查看管理节点的加入集群中常用命令查看所有集群节点删除某个节点强制删除查看节点详情节点降级由管理节点降级为工作节点节点升级由工作节点升级为管理节点更新节点查看节点中的任务常用命令部署服务查看服务详情产看某个服务日志查看所有服务详情删除某个服务强制删除设置某个服务个数更新某个服务").trim().substring(0, 1000);
let value = Math.floor(Math.random() * 3) + 1000;
while (value === prevParam || truncateDescription.length - value === prevParam) {
value = Math.floor(Math.random() * 3) + 1000;
}
aiTitleRefreshIcon.style.opacity = "0.2";
aiTitleRefreshIcon.style.transitionDuration = "0.3s";
aiTitleRefreshIcon.style.transform = "rotate(" + 360 * refreshNum + "deg)";
if (truncateDescription.length <= 1000) {
let param = truncateDescription.length - Math.floor(Math.random() * 3);
while (param === prevParam) {
param = truncateDescription.length - Math.floor(Math.random() * 3);
}
aiAbstract(param);
prevParam = param;
} else {
aiAbstract(value);
prevParam = value;
}
refreshNum++;
}
}
//- 监听tag点击事件
document.getElementById("ai-tag").addEventListener("click", () => {
if (mode === "tianli") {
document.querySelectorAll(".ai-btn-item").forEach(item => item.style.display = "none");
document.getElementById("go-tianli-blog").style.display = "block";
startAI("你好我是Tianli开发的摘要生成助理TianliGPT是一个基于GPT-4的生成式AI。我在这里只负责摘要的预生成和显示你无法与我直接沟通如果你也需要一个这样的AI摘要接口可以在下方购买。暂未开放购买敬请期待")
} else {
document.getElementById("go-tianli-blog").style.display = "none";
startAI("你好我是本站摘要生成助理KunKunYu GPT是一个基于GPT-4的生成式AI。我在这里只负责摘要的预生成和显示你无法与我直接沟通。")
}
});
aiTitleRefreshIcon.addEventListener("click", () => {
const truncateDescription = ("" + "查看集群节点, Token相关, 创建nginx服务, 查看swarm集群中的服务, kill其中一个容器, 修改服务实例数量为3, 删除nginx服务, 删除swarm节点, docker swarm 常用命令, docker node 常用命令, docker service 常用命令查看集群节点相关查看加入的命令查看加入的命令重置的仅打印创建服务下载私有仓库镜像创建个容器为私有仓库查看集群中的服务其中一个容器等会自动启动一个新的容器修改服务实例数量为删除服务删除节点常用命令初始化集群查看工作节点的查看管理节点的加入集群中常用命令查看所有集群节点删除某个节点强制删除查看节点详情节点降级由管理节点降级为工作节点节点升级由工作节点升级为管理节点更新节点查看节点中的任务常用命令部署服务查看服务详情产看某个服务日志查看所有服务详情删除某个服务强制删除设置某个服务个数更新某个服务").trim().substring(0, 1000);
let value = Math.floor(Math.random() * 3) + 1000;
while (value === prevParam || truncateDescription.length - value === prevParam) {
value = Math.floor(Math.random() * 3) + 1000;
}
aiTitleRefreshIcon.style.opacity = "0.2";
aiTitleRefreshIcon.style.transitionDuration = "0.3s";
aiTitleRefreshIcon.style.transform = "rotate(" + 360 * refreshNum + "deg)";
if (truncateDescription.length <= 1000) {
let param = truncateDescription.length - Math.floor(Math.random() * 3);
while (param === prevParam) {
param = truncateDescription.length - Math.floor(Math.random() * 3);
}
aiAbstract(param);
prevParam = param;
} else {
aiAbstract(value);
prevParam = value;
}
showAiBtn();
refreshNum++;
});
document.getElementById("go-tianli-blog").addEventListener("click", () => {
window.open("https://afdian.net/item/886a79d4db6711eda42a52540025c377", "_blank");
});
if (false) {
document.getElementById("ai-Toggle").addEventListener("click", () => {
changeShowMode()
});
}
function showAiBtn() {
document.querySelectorAll(".ai-btn-item").forEach(item => {
if (item.id !== "go-tianli-blog") {
item.style.display = "block";
}
if (item.id === "go-tianli-blog") {
item.style.display = "none";
}
});
}
aiAbstract();
showAiBtn()
})()</script>
</div> -->
<!-- 文章内容 -->
<article class="post-content line-numbers" id="article-container" th:utext="${post.content.content}">
</article>
<!-- 文章ai摘要 -->
<script th:replace="~{modules/postHeadAiDescription :: postHeadAiDescription}"></script>
<div class="post-tools" id="post-tools">
<div class="post-tools-left">
<!-- 打赏 -->
<div th:if="${theme.config.post.reward.enable_reward && (not #strings.isEmpty(theme.config.post.reward.wxPay) || not #strings.isEmpty(theme.config.post.reward.alipay))}"
<div th:if="${theme.config.aboutReward.reward.enable_reward_wz}"
class="post-reward" onclick="AddRewardMask()">
<div class="reward-button button&#45;&#45;animated" title="赞赏作者"><i
class="fas fa-hamburger"></i>
@ -454,19 +139,19 @@
<div class="reward-main">
<ul class="reward-all"><span class="reward-title">感谢你赐予我前进的力量</span>
<ul class="reward-group">
<li class="reward-item"><a th:href="@{${theme.config.post.reward.wxPay}}"
<li class="reward-item"><a th:href="@{${theme.config.aboutReward.reward.wxPay}}"
target="_blank">
<img alt="微信" class="post-qr-code-img"
th:src="${theme.config.post.reward.wxPay}"></a>
th:src="${theme.config.aboutReward.reward.wxPay}"></a>
<div class="post-qr-code-desc">微信</div>
</li>
<li class="reward-item"><a th:href="@{${theme.config.post.reward.alipay}}"
<li class="reward-item"><a th:href="@{${theme.config.aboutReward.reward.alipay}}"
target="_blank"><img alt="支付宝" class="post-qr-code-img"
th:src="${theme.config.post.reward.alipay}"></a>
th:src="${theme.config.aboutReward.reward.alipay}"></a>
<div class="post-qr-code-desc">支付宝</div>
</li>
</ul>
<a class="reward-main-btn" th:href="@{${theme.config.post.reward.reward_md_url}}"
<a class="reward-main-btn" th:href="@{${theme.config.aboutReward.reward.reward_md_url}}"
target="_blank">
<div class="reward-text">赞赏者名单</div>
<div class="reward-dec">因为你们的支持让我意识到写文章的价值🙏</div>