Compare commits

...

110 Commits

Author SHA1 Message Date
c1d8c639a3 upgrade 2021-11-20 00:04:14 +08:00
8c3bb44cf8 修复刷新后下移的问题 2021-10-19 17:01:48 +08:00
1cef9e1dbf 修复刷新后下移的问题 2021-10-19 15:41:49 +08:00
d7ab590958 修复刷新后下移的问题 2021-10-19 15:17:23 +08:00
62763af8ff link 2021-08-11 12:37:33 +08:00
e41cccd4cc lint 2021-08-11 12:35:15 +08:00
6e9a818d10 upgrade package 2021-08-04 17:01:23 +08:00
bc6327c556 upgrade package 2021-08-04 16:49:01 +08:00
e5ca37faed upgrade package 2021-08-04 16:48:25 +08:00
58821bef70 upgrade package 2021-08-04 16:03:32 +08:00
dc4681c032 添加备案号 2021-07-07 12:58:48 +08:00
184347c4f9 解决CDN异常 2020-12-19 22:15:26 +08:00
1449524d4e fix top and articel list 2020-11-14 14:25:43 +08:00
76de2e555f 添加版权声明 2020-11-10 21:53:33 +08:00
995f875616 解决google ad警告 2020-09-26 19:15:12 +08:00
fc08315bf8 修改友链 2020-09-26 19:06:53 +08:00
0e2e8ca254 修改友链 2020-09-26 19:03:34 +08:00
dbebc68cb0 添加提醒功能 2020-09-20 16:57:04 +08:00
26cdfd79b2 添加设置功能 2020-09-19 14:32:07 +08:00
4c6ad37f3a 添加设置功能 2020-09-17 21:07:07 +08:00
24a603c755 添加草稿功能 2020-09-16 23:35:24 +08:00
35e5523b93 修改友链 2020-08-31 12:04:07 +08:00
93f32fc016 添加设置前端 2020-08-21 21:12:37 +08:00
295d959e6e android 2020-07-23 17:18:00 +08:00
8851dd8c47 添加qq登录 2020-07-23 15:04:46 +08:00
c0d2f24c65 添加qq登录 2020-07-23 14:37:59 +08:00
8520e5567a 添加微博登录 2020-07-23 14:28:58 +08:00
ea90eac506 完善微信登录 2020-07-23 09:33:15 +08:00
912d48bf71 添加微信登录 2020-07-23 08:37:04 +08:00
dd89e298b9 添加微信登录 2020-07-23 08:35:25 +08:00
f4da5d9455 添加微信登录 2020-07-23 08:31:38 +08:00
20345ae9ce 添加微信登录 2020-07-23 08:25:24 +08:00
39be6a3439 添加微信登录 2020-07-22 23:54:22 +08:00
0b02bf7838 添加微信登录 2020-07-22 23:53:37 +08:00
209d25f204 添加微信登录 2020-07-22 22:48:29 +08:00
687f5c5c68 添加微信登录 2020-07-22 19:30:42 +08:00
fa69d02bc6 添加微信登录 2020-07-22 18:02:37 +08:00
78ff669765 添加微信登录 2020-07-22 14:07:07 +08:00
dd78f3af82 添加微信登录 2020-07-21 23:47:38 +08:00
ca2ec55a72 解决切换页面后编辑器异常 2020-07-21 15:39:59 +08:00
719e716c6f 博客-文章页meta完善 2020-07-20 21:30:22 +08:00
5d744b5e84 xml解析 2020-07-20 18:28:58 +08:00
868fc81fd1 添加编辑器粘贴功能 2020-07-20 00:13:27 +08:00
ada4718146 添加评论展示功能 2020-07-19 21:28:10 +08:00
af2b675052 调整样式 2020-07-19 21:18:44 +08:00
4030b22f41 添加图片预览功能 2020-07-19 20:13:07 +08:00
befa2e1679 完善后台评论管理 2020-07-19 01:03:30 +08:00
41875a39e8 解决内容为空的问题 2020-07-18 22:38:11 +08:00
f85dddf4b8 解决内容为空的问题 2020-07-18 17:46:34 +08:00
9add042253 添加评论功能 2020-07-17 18:10:55 +08:00
b0c6b81951 添加评论功能 2020-07-17 14:00:01 +08:00
4241d13d33 添加评论功能 2020-07-17 12:04:14 +08:00
3121a2bdb5 添加评论功能 2020-07-17 10:56:02 +08:00
ac0bc41842 添加评论功能 2020-07-17 10:41:02 +08:00
c618c83f9b 添加评论功能 2020-07-17 10:32:06 +08:00
54a1633884 解决搜索问题 2020-07-17 00:25:15 +08:00
d385062f5f 解决搜索问题 2020-07-17 00:02:48 +08:00
321dd05d97 添加评论功能 2020-07-16 23:38:24 +08:00
4d05c1a1a5 添加评论功能 2020-07-16 23:14:41 +08:00
280e58e058 添加登录 2020-07-16 22:51:18 +08:00
a82d2fb4ca fix: 修复手机看的时候,点开左边侧边栏,点空白的地方不会隐藏的bug 2020-07-15 15:44:25 +08:00
47fad8167a fix: 修复手机看的时候,点开左边侧边栏,点空白的地方不会隐藏的bug 2020-07-15 14:44:27 +08:00
3f8396a254 添加github登陆功能 2020-07-15 01:22:34 +08:00
7e61d738cf 修复CSS问题 2020-07-12 16:32:48 +08:00
6ad10cd450 添加评论 2020-07-10 18:01:41 +08:00
2507d7bff7 添加评论 2020-07-10 18:01:08 +08:00
80192652ed 添加评论 2020-07-10 17:49:51 +08:00
0cbd50eeda 添加上传能力 2020-07-10 14:32:56 +08:00
9b455e6f25 添加上传接口 2020-07-10 12:04:37 +08:00
221cd42fb3 add: 讨论 2020-07-10 10:03:49 +08:00
ee4be3a0b9 add: 讨论 2020-07-09 18:16:27 +08:00
1d26c243be add: 回复显示 2020-07-09 00:01:48 +08:00
cac01d8aa1 add: 编辑器 2020-07-08 23:44:33 +08:00
7c5509ec53 add: 编辑器 2020-07-08 22:36:46 +08:00
2403d74ce9 add: 讨论 2020-07-08 18:13:20 +08:00
f248fa1d11 add: 评论功能 2020-07-06 18:13:28 +08:00
3bba510ae0 fix: 热门排序异常 2020-06-12 23:38:29 +08:00
88e4f4ec78 add: rss 2020-06-10 21:28:34 +08:00
9662f26fe1 add: rss 2020-06-10 21:25:02 +08:00
981d6f2de9 add: 友链 2020-05-31 18:54:06 +08:00
5f7f6574d7 update: 添加友链 2020-05-18 00:46:12 +08:00
50e6926b7c update: 添加友链 2020-05-17 16:28:21 +08:00
560b9e083c add: LFhacks友链 2020-05-15 13:20:34 +08:00
13f1674167 update: 更新友链 2020-05-10 20:41:43 +08:00
0b4674293b update: 更新友链 2020-05-10 20:41:04 +08:00
e0f4f55ea9 update: 更新标题 2020-05-10 19:41:39 +08:00
4c8e4f353f 更新标题 2020-05-10 19:39:05 +08:00
44e07da6d4 fix: 移除某些联系方式 2020-05-05 10:22:09 +08:00
528d7616fb fix: 更新依赖项 2020-05-04 20:23:51 +08:00
fd3f622e53 fix: 更新依赖项 2020-05-04 20:19:09 +08:00
dba182cf1b update: 根据要求修改网站名称 2020-05-04 18:15:35 +08:00
ad86083b87 @ 2020-03-02 21:07:13 +08:00
bf1263e67b 修改名称 2020-03-02 19:43:47 +08:00
2ab312e001 添加友链 2020-02-24 18:18:11 +08:00
dadcad783a 添加友链 2020-02-24 18:13:54 +08:00
56da7e7aad 增加赞赏码 2020-02-22 16:00:05 +08:00
046b10ad1b update 2019-12-17 20:25:37 +08:00
6b75e98c6f update 2019-12-17 20:19:29 +08:00
c57cbc7950 update 2019-12-16 22:54:21 +08:00
9c9efe6120 update 2019-12-16 22:53:01 +08:00
f820cc24e1 update 2019-12-16 22:51:27 +08:00
34965b8b3b 添加提示 2019-12-14 12:59:22 +08:00
a197ca80ce 优化广告展示 2019-12-14 12:14:37 +08:00
036abef98d add ADs 2019-12-14 12:06:07 +08:00
94a0f24b32 add ADs 2019-12-14 11:07:44 +08:00
703f411ee7 upgrade 2019-12-13 11:46:15 +08:00
eaf48b86c3 update 2019-12-07 19:36:12 +08:00
d8e32c2221 Merge branch 'master' of github.com:yi-ge/blog-client 2019-07-07 21:00:45 +08:00
143756be8b 修改测试地址 2019-07-07 21:00:36 +08:00
6880d329ce 修改头像 2019-07-07 20:53:45 +08:00
40 changed files with 7496 additions and 4811 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

View File

@ -5,13 +5,13 @@ module.exports = {
node: true
},
parserOptions: {
parser: 'babel-eslint'
parser: "babel-eslint"
},
extends: [
'@nuxtjs'
],
// add your custom rules here
extends: ["@nuxtjs"],
rules: {
'no-console': 'off'
"no-console": "off"
},
globals: {
"_": true
}
}
};

23
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,23 @@
{
"cSpell.words": [
"Fhacks",
"Weibo",
"Weixin",
"autorestart",
"categorys",
"consola",
"eslintignore",
"fontawesome",
"fortawesome",
"gotop",
"hljs",
"navication",
"nuxt",
"nuxtjs",
"styl",
"vditor",
"viewerjs",
"vmodal",
"wangeditor"
]
}

14
app.html Normal file
View File

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html {{ HTML_ATTRS }}>
<head {{ HEAD_ATTRS }}>
{{ HEAD }}
<script src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js" async
data-ad-client="ca-pub-2143583075951360"></script>
</head>
<body {{ BODY_ATTRS }}>
{{ APP }}
</body>
</html>

View File

@ -1,11 +1,18 @@
<template lang="pug">
footer
a#gotop.scroll-top(href='javascript:;', style='display: none;')
Icon(:icon="['fas', 'angle-double-up']")
#mobileToc.mobileToc(style='display: none;')
a#gotop.scroll-top(href='javascript:;', style='display: none')
Icon(:icon='["fas", "angle-double-up"]')
#mobileToc.mobileToc(style='display: none')
| 目录
.footer
| Copyright © 2018 WangYi.
| Copyright © 2009-2020 WangYi.
br
| All Rights Reserved. 浙ICP备14013313号-2
| All Rights Reserved.
a(
href='https://beian.miit.gov.cn',
target='_blank',
rel='external nofollow',
style='color: #ccc; margin-left: 5px'
)
| 浙ICP备14013313号-2
</template>

View File

@ -3,39 +3,42 @@
#wrap
#leftMain
h1.title
nuxt-link(to='/') 轶哥博客
nuxt-link(to='/') 轶哥
.widget.avatar
.widgetTitle
label 关于作者
img(src='https://cdn.wyr.me/avatar.png')
img(src='https://data.sercretcore.cn/new_avatar.jpeg')
p.aboutMe
| 妄图改变世界的全栈程序员
.social
ul
li
a(href='https://github.com/yi-ge', target='_blank')
Icon(:icon="['fab', 'github']")
a(
href='https://github.com/yi-ge',
target='_blank',
rel='external nofollow'
)
Icon(:icon='["fab", "github"]')
li
Icon(:icon="['fab', 'qq']" @click="info('qq')")
Icon(:icon='["fab", "qq"]', @click='info("qq")')
li
Icon(:icon="['fab', 'weixin']" @click="info('weixin')")
Icon(:icon='["fab", "weixin"]', @click='info("weixin")')
li
a(href='http://weibo.com/syxj', target='_blank')
Icon(:icon="['fab', 'weibo']")
a(
href='http://weibo.com/syxj',
target='_blank',
rel='external nofollow'
)
Icon(:icon='["fab", "weibo"]')
li
a(href='https://twitter.com/FYTencel', target='_blank')
Icon(:icon="['fab', 'twitter']")
Icon(:icon='["fas", "envelope"]', @click='info("email")')
li
a(href='https://www.facebook.com/cnyige', target='_blank')
Icon(:icon="['fab', 'facebook']")
li
a(href='https://plus.google.com/u/0/101716298673782941484', target='_blank')
Icon(:icon="['fab', 'google-plus']")
li
a(href='https://t.me/cnyige', target='_blank')
Icon(:icon="['fab', 'telegram']")
li
Icon(:icon="['fas', 'envelope']" @click="info('email')")
a(
href='https://www.wyr.me/rss.xml',
target='_blank',
rel='external nofollow'
)
Icon(:icon='["fas", "rss"]')
.social-info-box(v-if='socialInfo')
| {{ socialInfo }}
#navication.widget.navication
@ -44,61 +47,101 @@
ul
li
nuxt-link(to='/') 主页
li(v-for='(categorys, index) in $store.state.categorys', :key='index', v-show="categorys.name !== '未分类'")
nuxt-link(:to="'/' + categorys.slug") {{ categorys.name }}
li(
v-for='(categorys, index) in $store.state.categorys',
:key='index',
v-show='categorys.name !== \'未分类\''
)
nuxt-link(:to='"/" + categorys.slug') {{ categorys.name }}
li
a(:href="'https://driver.wyr.me/'" target="_blank") MAC N卡驱动更新提示
a(:href='"https://driver.wyr.me/"', target='_blank') MAC N卡驱动更新提示
.search-box
input.search(type='text', placeholder='搜索', v-model='searchVal', @keyup.enter='search')
Icon(:icon="['fas', 'search']" @click="search")
input.search(
type='text',
placeholder='搜索',
v-model='searchVal',
@keyup.enter='search'
)
Icon(:icon='["fas", "search"]', @click='search')
.widget.comment
.widgetTitle
label 最新评论
ul
li(v-for='(newComment, index) in $store.state.newComments', :key='index')
li(
v-for='(newComment, index) in $store.state.newComments',
:key='index'
)
strong {{ newComment.comment_author }}
span
nuxt-link(:to="'/post/' + newComment.post.ID + '#comments'") {{ newComment.comment_content }}
nuxt-link(
:to='"/post/" + newComment.post.ID + "#comments"',
v-html='newComment.comment_content_html'
)
.meta
span
Icon(:icon="['far', 'clock']")
Icon(:icon='["far", "clock"]')
| &nbsp; {{ newComment.comment_date }}
span
|
nuxt-link(:to="'/post/' + newComment.post.ID") {{ newComment.post.post_title }}
nuxt-link(:to='"/post/" + newComment.post.ID') {{ newComment.post.post_title }}
.widget.posts
.widgetTitle
label 热门文章
ul
li(v-for='(hotArticle, index) in $store.state.hotArticle', :key='index')
.thumbnail
img(width='150', :src="hotArticle.postimages[0].guid + '?x-oss-process=image/resize,m_lfit,h_150,w_150'")
.detail
nuxt-link(:to="'/post/' + hotArticle.ID", :title='hotArticle.post_title') {{ hotArticle.post_title }}
li(
v-for='(hotArticle, index) in $store.state.hotArticle',
:key='index'
)
.thumbnail(
v-if='hotArticle && hotArticle.postimages && hotArticle.postimages[0]'
)
img(
width='150',
:src='hotArticle.postimages[0].guid + "?x-oss-process=image/resize,m_lfit,h_150,w_150"'
)
.detail(
:style='hotArticle && hotArticle.postimages && hotArticle.postimages[0] ? "margin-left: 70px" : "margin-left: 0"'
)
nuxt-link(
:to='"/post/" + hotArticle.ID',
:title='hotArticle.post_title'
) {{ hotArticle.post_title }}
.meta {{ hotArticle.post_modified }}
.widget.links(v-if="$route.path === '/'")
.widget.links(v-if='$route.path === "/"')
.widgetTitle
label 友情链接
.links
a(href="https://johnsonlee.site/" target="_blank") Johnson Blog
ul
li
a(href='https://wintc.top/', target='_blank') 沐码小站
li
a(href='https://johnsonlee.site/', target='_blank') Johnson Blog
li
a(href='https://www.lfhacks.com/', target='_blank') LFhacks
li
nuxt-link(to='/links', title='更多友链') 更多友链
#tags.widget.tags
.widgetTitle
label 标签
.tagcloud
nuxt-link(:to="'/tag/' + tag.slug", :title='tag.name', v-for='tag in $store.state.tags', :key='tag.term_id') {{ tag.name }}
nuxt-link(
:to='"/tag/" + tag.slug',
:title='tag.name',
v-for='tag in $store.state.tags',
:key='tag.term_id'
) {{ tag.name }}
</template>
<script>
export default {
data() {
data () {
return {
socialInfo: false,
searchVal: ''
}
},
methods: {
info(type) {
info (type) {
if (type === 'qq') {
this.socialInfo = 'QQ: 373226722'
} else if (type === 'weixin') {
@ -111,8 +154,8 @@ export default {
this.socialInfo = false
}, 3000)
},
search() {
if (this.searchVal !== '') this.$router.push({ path: 'search?q=' + this.searchVal })
search () {
if (this.searchVal !== '') { this.$router.push({ path: '/search?q=' + this.searchVal }) }
}
}
}

View File

@ -1,414 +0,0 @@
<template>
<div
class="swiper-container"
@touchmove="fn"
>
<div
class="default-swiper-box"
:class="box"
@transitionend="transitionend"
@touchstart="s"
@touchmove="m"
@touchend="e"
@mousedown="s"
@mousemove="m"
@mouseup="e"
>
<slot />
</div>
<slot name="pagination">
<!-- 默认提供了一个 pagination -->
<div
v-if="pagination"
class="swiper-pagination"
>
<div
v-for="(value, key) in reallySlidesNumber"
:key="key"
class="swiper-dot"
:class="{'swiper-dot-active': currentSlide === key}"
/>
</div>
</slot>
<!-- 这两个就不默认提供了 -->
<slot name="arrowLeft" />
<slot name="arrowRight" />
<!-- 当你需要在全局的内容里面加一些玩意的时候 -->
<slot name="g" />
</div>
</template>
<script>
function toArray(arraylike) {
return Array.prototype.slice.call(arraylike)
}
export default {
name: 'Swiper',
props: {
/* 一次滑动的默认时间 */
duration: {
type: Number,
default: 500
},
/* 两次滑动的间隔时间 */
interval: {
type: Number,
default: 2500
},
/* 是否自动播放 */
autoplay: {
type: Boolean,
default: true
},
/* 用户滑动多少距离, 翻页 */
therehold: {
type: Number,
default: 110
},
defaultSlide: {
type: Number,
default: 0
},
pagination: {
type: Boolean,
default: true
},
/* 有时候全屏滚动, 的确想要禁用垂直方向的滚动的时候 */
vLock: {
type: Boolean,
default: false
}
},
data() {
return {
swiper: null,
swiperWidth: 0,
slides: null,
slidesNumber: 0,
reallySlidesNumber: 0,
currentSlide: 0,
timer: null,
userDuration: 200,
pos: {
startX: 0,
moveX: 0,
endX: 0,
local: 0,
distance: 0
},
moving: false,
unlock: false,
activeId: '',
mousedown: false,
box: '',
isOnly: false
}
},
mounted() {
this.box = 'swiper-box-' + Math.random().toFixed(2) * 1000
setTimeout(() => {
/* 初始化的时候, 拿到所有的 DOM 元素以及相关属性 */
this.initElement()
if (this.isOnly) {
return
}
/* 克隆两个节点, 用来实现 loop 效果 */
this.cloneSlide()
/* 克隆结束之后, 需要设置默认显示的slide */
this.setDefaultSlide()
/*
## start
设置默认slide之后, 就需要开始设置定时器, 自动轮播
*/
if (this.autoplay) {
this.play()
}
}, 100)
},
methods: {
/* 阻止容器的上下滚动, 并且只有在水平方向上面滚动超过 10px 才可以阻止 */
fn(e) {
if (this.vLock || Math.abs(this.pos.startX - this.pos.moveX) > 10) {
e.preventDefault()
}
},
/* 滑动到指定的页面 */
slideTo(index) {
if (!this.moving) {
const currentSlide = Math.round(Math.abs(this.left()) / this.swiperWidth)
/* 如果索引值不合法 或者和目前的值相等 */
if (index > this.slidesNumber - 2 - 1 || index < 0 || currentSlide === index + 1) {
return
}
this.moving = true
clearTimeout(this.timer)
/*
说明要往右边滑动
注意这里不管需要滑动多少个, duration 都是 300, 这个如果需要, 可以
自己根据起点/终点计算出一个合适的值.
*/
this.transitionDuration(300)
this.translateX(-this.swiperWidth * (index + 1))
}
},
next() {
if (!this.moving) {
clearTimeout(this.timer)
this.moving = true
this.transitionDuration(this.userDuration)
this.translateX(this.left() - this.swiperWidth)
}
},
previous() {
if (!this.moving) {
clearTimeout(this.timer)
this.moving = true
this.transitionDuration(this.userDuration)
this.translateX(this.left() + this.swiperWidth)
}
},
initElement() {
/* 因为传递过来的是个字符串, 所以要手动加点 */
this.swiper = document.querySelector('.' + this.box)
this.swiperWidth = this.swiper.clientWidth
this.slides = toArray(this.swiper.children)
this.slidesNumber = this.slides.length
/* 实际的 slide 个数, 因为 slidesNumber 会在后面重新赋值 */
this.reallySlidesNumber = this.slides.length
/* 如果就仅仅只有一个 slide, 那么不克隆, 不绑定, 就纯展示就可以了 */
if (this.reallySlidesNumber === 1) {
this.isOnly = true
}
},
cloneSlide() {
const head = this.slides[0].cloneNode(this.slides[0], true)
const tail = this.slides[this.slidesNumber - 1].cloneNode(this.slides[this.slidesNumber - 1], true)
this.swiper.appendChild(head)
this.swiper.insertBefore(tail, this.slides[0])
/* 克隆节点之后, 需要重置一些属性 */
this.slides = toArray(this.swiper.children)
this.slidesNumber = this.slides.length
},
/* 根据用户给定的 defaultSlide 设置 init slide 的值 */
setDefaultSlide() {
/*
一切用户给定的值, 都是从 0 - x 开始, 比如用户数据里面有 6个数据
那么给定的就是 0 - 5
但是我们内部运算的时候, 实际上我们的索引能到 0 - 7
0 是实际的 5 的拷贝, 7 实际上是实际的0的拷贝
所以当用户给定的 defaultSlide =0, 我们实际上是要让展示内部索引为 1 的元素
*/
/* 如果用户设置了一个非法值, 直接抛出异常 */
if (this.defaultSlide < 0 || this.defaultSlide > this.slidesNumber - 2 - 1) {
throw new Error('[swiper:Error]: You have set a wrong defaultSlide value with defaultSlide = ' + this.defaultSlide)
}
this.translateX(-this.swiperWidth * (this.defaultSlide + 1))
//
// this.currentSlide = this.defaultSlide;
},
/*
## start
*/
play() {
this.timer = setTimeout(() => {
clearTimeout(this.timer)
this.moving = true
this.unlock = false
this.transitionDuration(this.duration)
this.translateX(-(this.swiperWidth + Math.abs(this.left())))
}, this.interval)
},
transitionend() {
this.transitionDuration(0)
/*
一次滑动结束之后, 通过计算, 实际上我们可以拿到当前处于内部索引的第几个 slide
拿到这个 currentSlide 我们就知道当前是不是滚动到最后一个了
*/
const currentSlide = Math.round(Math.abs(this.left()) / this.swiperWidth)
this.currentSlide = currentSlide - 1
/* 如果滚动到最后一个, 那么就要瞬间跳转一下, 到外部看起来的第一个, 内部的 */
if (currentSlide === this.slidesNumber - 1) {
this.translateX(-this.swiperWidth)
this.currentSlide = 0
}
if (currentSlide === 0) {
this.translateX(-this.swiperWidth * (this.slidesNumber - 2))
this.currentSlide = this.slidesNumber - 3
}
this.$emit('transitionend', this.currentSlide)
/*
防止极限操作, 用户在滑动结束之后事件还没发送出去又滑动导致计算
结果错误, 所以等事件发出去之后再解开
*/
this.moving = false
/*
##start
*/
if (this.autoplay) {
this.play()
}
},
/* toushstart handler */
s(e) {
if (this.isOnly) {
return
}
if (e.type === 'mousedown' && !this.moving) {
this.mousedown = true
this.pos.startX = e.pageX
this.pos.local = this.left()
clearTimeout(this.timer)
this.transitionDuration(0)
} else {
this.activeId = toArray(e.changedTouches)[0].identifier
if (!this.moving) {
const active = e.touches.length - 1
clearTimeout(this.timer)
this.transitionDuration(0)
this.unlock = true
this.pos.startX = e.touches[active].clientX
/* 一次 touch 的 起始local 点, 是固定的 */
this.pos.local = this.left()
}
}
},
/* toushmove handler */
m(e) {
if (this.isOnly) {
return
}
if (e.type === 'mousemove' && this.mousedown && !this.moving) {
this.pos.moveX = e.pageX
this.pos.distance = this.pos.moveX - this.pos.startX
this.translateX(this.pos.local + this.pos.distance)
} else if (!this.moving && this.unlock) {
const active = e.touches.length - 1
this.pos.moveX = e.touches[active].clientX
this.pos.distance = this.pos.moveX - this.pos.startX
this.translateX(this.pos.local + this.pos.distance)
}
},
/* toushend handler */
e(e) {
if (this.isOnly) {
return
}
if (e.type === 'mouseup' && this.mousedown && !this.moving) {
this.mousedown = false
this.pos.endX = e.pageX
this.pos.distance = this.pos.endX - this.pos.startX
this.recover()
} else {
const curId = toArray(e.changedTouches)[0].identifier
if (!this.moving && this.unlock && (curId === this.activeId)) {
this.unlock = false
this.pos.endX = e.changedTouches[0].clientX
this.pos.distance = this.pos.endX - this.pos.startX
this.recover()
}
}
},
/* 响应用户滚动行为 */
recover() {
this.transitionDuration(this.userDuration)
const distance = Math.abs(this.left()) % this.swiperWidth
let point = []
let direction = ''
/*
主要是为了拿到当前状态下面, swiper 距离正常状态的, 左右移动的距离分别是多少.
*/
if (this.left() > 0) {
point = [distance, this.swiperWidth - distance]
} else {
point = [this.swiperWidth - distance, distance]
}
if (this.pos.distance > 0) {
direction = 'to-right'
} else if (this.pos.distance < 0) {
direction = 'to-left'
} else {
direction = 'none'
}
if (direction === 'none') {
if (this.autoplay) {
this.play()
}
}
if (direction === 'to-right') {
this.moving = true
/* 说明需要向右边移动 */
if (point[0] > this.therehold) {
this.translateX(this.left() + point[1])
const next = (this.left() + point[1]) / this.swiperWidth
if (Math.abs(next) === 0) {
this.unlock = false
}
} else {
this.translateX(this.left() - point[0])
}
}
if (direction === 'to-left') {
this.moving = true
if (point[1] > this.therehold) {
this.translateX(this.left() - point[0])
const next = (this.left() - point[0]) / this.swiperWidth
if (Math.abs(next) === this.slidesNumber - 1) {
this.unlock = false
}
} else {
this.translateX(this.left() + point[1])
}
}
},
translateX(value) {
this.swiper.style.transform = 'translate3d(' + value + 'px, 0, 0)'
},
transitionDuration(ms) {
this.swiper.style.transitionDuration = ms + 'ms'
},
left() {
return this.swiper.getBoundingClientRect().left
}
}
}
</script>
<style lang="stylus">
.swiper-container
position relative
width 100%
overflow hidden
.default-swiper-box
height 100%
width 100%
display flex
// 分页
.swiper-pagination
position absolute
bottom 10px
height 18px
width 100%
background transparent
display flex
align-items center
justify-content center
.swiper-dot
height 8px
width 8px
background #000
opacity 0.2
margin 0 5px
border-radius 50%
.swiper-dot-active
opacity 1
background #3498db
</style>

16
ecosystem.config.js Normal file
View File

@ -0,0 +1,16 @@
module.exports = {
apps: [{
name: 'blog-client',
script: './server/index.js',
watch: false,
max_memory_restart: '3G', // 超过多大内存自动重启,仅防止内存泄露有意义,需要根据自己的业务设置
env: {
NODE_ENV: 'production',
HOST: '0.0.0.0',
PORT: 8080
},
exec_mode: 'cluster', // 开启多线程模式,用于负载均衡
instances: 'max', // 启用多少个实例,可用于负载均衡
autorestart: true // 程序崩溃后自动重启
}]
}

12
layouts/auth.vue Normal file
View File

@ -0,0 +1,12 @@
<template lang="pug">
.content
#loading.allSpinner
.spinner
.bounce1
.bounce2
.bounce3
.container
.page-container
nuxt
v-dialog
</template>

View File

@ -2,6 +2,12 @@
margin 0
padding 0
html
overflow hidden
body
overflow auto
body, html
color #2e2f30
letter-spacing 0.5px
@ -12,7 +18,6 @@ body, html
#__nuxt, .content
width 100%
height 100%
max-width 1040px
margin 0 auto
position relative
@ -87,7 +92,7 @@ footer
position fixed
right 8px
bottom 8px
z-index 999
z-index 998
padding 4px
i
@ -113,7 +118,7 @@ footer
.btn-footer
margin-top 50px
font-size 12px
color #cccccc
color #333
float left
i
@ -124,6 +129,8 @@ footer
.btn-disable
color #dfdede !important
user-select none
cursor not-allowed
footer .footer
color #a2a2a2
@ -150,6 +157,7 @@ footer .footer
height 100%
width 295px
float left
box-shadow 8px 0px 11px 0px #fff
#rightContent
margin-left 300px
@ -206,6 +214,10 @@ input:-moz-placeholder
.links
margin-bottom 20px
font-weight 300
li
margin-top 5px
.widgetTitle
font-size 18px
@ -355,6 +367,9 @@ input:-moz-placeholder
white-space nowrap
text-overflow ellipsis
img
width 100%
.posts
margin-bottom 40px
@ -406,9 +421,11 @@ input:-moz-placeholder
//
.pageList
.articleList:not(:first-child)
margin-top 30px
.articleList
background-color #fff
margin-top 30px
.articleImgs
width 100%
@ -500,14 +517,14 @@ input:-moz-placeholder
color #ffffff
position fixed
right 8px
bottom 38px
bottom 42px
z-index 999
padding 4px
@media (max-width: 768px)
@media (max-width 768px)
.header
position fixed
z-index 999999
z-index 99999
width 100%
display block
box-sizing border-box
@ -531,7 +548,7 @@ input:-moz-placeholder
padding-top 6px
cursor pointer
#leftBackgroundColor, #LeftMenu
#LeftMenu
display none
#rightContent
@ -556,3 +573,6 @@ blockquote
.articelContent
a
color #de8787
.toasted-container
z-index 9999999 !important

View File

@ -15,13 +15,14 @@
path(d='M192 674l640 0 0 64-640 0 0-64Z')
nuxt-link(to='/')
h1.title
| 轶哥博客
| 轶哥
.page-container
#LeftMenu(:style="'display: '+ showLeftMenuValue + ';' + isPhone")
LeftContent
#rightContent
#rightContent(@click='hiddenLeftMenu')
nuxt
Footer
v-dialog
</template>
<script>
@ -33,13 +34,13 @@ export default {
LeftContent,
Footer
},
data() {
data () {
return {
showLeftMenuValue: 'block',
isPhone: ''
}
},
mounted() {
mounted () {
const phoneStyle = 'height: 100%; position: fixed; top: 70px; background-color: #fff; z-index:9999; overflow: scroll; overflow-x: hidden; -webkit-overflow-scrolling: touch;'
if (document.body.clientWidth > 768) {
this.showLeftMenuValue = 'block'
@ -60,10 +61,15 @@ export default {
}
},
methods: {
showLeftMenu() {
if (this.showLeftMenuValue !== 'block') {
this.showLeftMenuValue = 'block'
showLeftMenu () {
if (this.showLeftMenuValue === 'block') {
this.showLeftMenuValue = 'none'
} else {
this.showLeftMenuValue = 'block'
}
},
hiddenLeftMenu () {
if (document.body.clientWidth < 768) {
this.showLeftMenuValue = 'none'
}
}

View File

@ -8,6 +8,7 @@ section.container
nuxt-link(to='/', v-if='error.statusCode === 404')
.button
| 返回首页
v-dialog
</template>
<script>

View File

@ -5,5 +5,6 @@
nuxt
footer
.footer
| Copyright © 2018 WangYi. All Rights Reserved.
| Copyright © 2020 WangYi. All Rights Reserved.
v-dialog
</template>

View File

@ -1,8 +1,8 @@
const pkg = require('./package')
// const DevBaseUrl = 'http://127.0.0.1:65534'
const DevBaseUrl = 'https://api.wyr.me'
const DevBaseUrl = 'http://127.0.0.1:65534'
const ProdBashUrl = 'https://api.wyr.me'
const ProdServerBashUrl = 'http://127.0.0.1:65534'
module.exports = {
mode: 'universal',
@ -11,7 +11,7 @@ module.exports = {
** Headers of the page
*/
head: {
title: '轶哥博客',
title: '轶哥 - 火星人',
htmlAttrs: {
lang: 'zh-cn'
},
@ -78,7 +78,10 @@ module.exports = {
{
src: '~/plugins/browser.js',
ssr: false
}
},
{ src: '~/plugins/vue-js-modal', mode: 'client' },
{ src: '~/plugins/vue-toasted', mode: 'client' },
{ src: '~/plugins/v-viewer', mode: 'client' }
],
/*
@ -93,7 +96,19 @@ module.exports = {
*/
axios: {
// See https://github.com/nuxt-community/axios-module#options
baseURL: process.env.NODE_ENV === 'development' ? DevBaseUrl : ProdBashUrl // 配置API接口地址
baseURL: process.env.NODE_ENV === 'development' ? DevBaseUrl : ProdServerBashUrl // 配置API接口地址
},
publicRuntimeConfig: {
axios: {
browserBaseURL: process.env.NODE_ENV === 'development' ? DevBaseUrl : ProdBashUrl
}
},
privateRuntimeConfig: {
axios: {
baseURL: process.env.NODE_ENV === 'development' ? DevBaseUrl : ProdServerBashUrl
}
},
/*
@ -103,7 +118,7 @@ module.exports = {
/*
** You can extend webpack config here
*/
extend(config, ctx) {
extend (config, ctx) {
// Run ESLint on save
if (ctx.isDev && ctx.isClient) {
config.module.rules.push({
@ -114,9 +129,21 @@ module.exports = {
})
}
},
vendor: ['moment']
vendor: ['moment'],
babel: {
plugins: [
[
'component',
{
libraryName: 'element-ui',
styleLibraryName: 'theme-chalk'
}
]
]
}
},
env: {
version: pkg.version
version: pkg.version,
baseURL: process.env.NODE_ENV === 'development' ? DevBaseUrl : ProdBashUrl
}
}

View File

@ -1,46 +1,55 @@
{
"name": "blog-client",
"version": "1.0.0",
"version": "1.0.1",
"description": "My Blog Client",
"author": "yi-ge",
"private": true,
"scripts": {
"dev": "cross-env NODE_ENV=development nodemon server/index.js --watch server",
"build": "nuxt build",
"start": "cross-env NODE_ENV=production HOST=0.0.0.0 PORT=80 node server/index.js",
"start": "cross-env NODE_ENV=production HOST=0.0.0.0 PORT=8080 node server/index.js",
"generate": "nuxt generate",
"lint": "eslint --ext .js,.vue --ignore-path .gitignore --ignore-path .eslintignore .",
"precommit": "npm run lint"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.15",
"@fortawesome/free-brands-svg-icons": "^5.7.2",
"@fortawesome/free-regular-svg-icons": "^5.7.2",
"@fortawesome/free-solid-svg-icons": "^5.7.2",
"@fortawesome/vue-fontawesome": "^0.1.5",
"@nuxtjs/axios": "^5.4.0",
"cross-env": "^5.2.0",
"highlight.js": "^9.15.6",
"koa": "^2.7.0",
"moment": "^2.24.0",
"nuxt": "^2.4.5"
"@fortawesome/fontawesome-svg-core": "^1.2.35",
"@fortawesome/free-brands-svg-icons": "^5.15.3",
"@fortawesome/free-regular-svg-icons": "^5.15.3",
"@fortawesome/free-solid-svg-icons": "^5.15.3",
"@fortawesome/vue-fontawesome": "^2.0.2",
"@nuxtjs/axios": "^5.13.6",
"cross-env": "^7.0.3",
"element-ui": "^2.15.4",
"highlight.js": "^11.2.0",
"koa": "^2.13.1",
"moment": "^2.29.1",
"nuxt": "^2.15.7",
"remark": "12.0.1",
"strip-markdown": "^4.1.0",
"v-viewer": "^1.6.4",
"vditor": "^3.8.6",
"vue-js-modal": "^2.0.1",
"vue-toasted": "^1.1.28"
},
"devDependencies": {
"@nuxtjs/eslint-config": "^0.0.1",
"babel-eslint": "^10.0.1",
"eslint": "^5.15.0",
"eslint-config-standard": ">=12.0.0",
"eslint-loader": "^2.1.2",
"eslint-plugin-import": ">=2.16.0",
"eslint-plugin-jest": "^22.3.0",
"eslint-plugin-node": ">=8.0.1",
"eslint-plugin-promise": ">=4.0.1",
"eslint-plugin-standard": ">=4.0.0",
"eslint-plugin-vue": "^5.2.2",
"nodemon": "^1.18.10",
"pug": "^2.0.3",
"pug-plain-loader": "^1.0.0",
"stylus": "^0.54.5",
"stylus-loader": "^3.0.2"
"@nuxtjs/eslint-config": "^6.0.1",
"babel-eslint": "^10.0.3",
"babel-plugin-component": "^1.1.1",
"eslint": "^7.32.0",
"eslint-config-standard": ">=16.0.3",
"eslint-loader": "^4.0.2",
"eslint-plugin-html": "^6.1.2",
"eslint-plugin-import": ">=2.23.4",
"eslint-plugin-jest": "^24.4.0",
"eslint-plugin-node": ">=10.0.0",
"eslint-plugin-promise": ">=5.1.0",
"eslint-plugin-standard": ">=5.0.0",
"eslint-plugin-vue": "^7.15.1",
"nodemon": "^2.0.12",
"pug": "^3.0.2",
"pug-plain-loader": "^1.1.0",
"stylus": "^0.54.8",
"stylus-loader": "3.0.2"
}
}
}

View File

@ -2,44 +2,55 @@
.pageList
.articleContent(ref='articleImgs', v-if='Articels')
article.articleList(v-for='(post, index) in Articels', :key='index')
.articleImgs(v-if='post.postImages.length')
nuxt-link(:to="'/post/' + post.ID")
Swiper(:style="'height: ' + imageHeight + 'px'")
Slide(v-for="(imgUrl, inx) in post.postImages" :key="inx")
img(:src='imgUrl')
.articleAbstract
nuxt-link(:to="'/post/' + post.ID")
nuxt-link(:to='"/post/" + post.ID')
.articleTitle(v-html='post.post_title')
.articalMeta
ul
li
Icon(:icon="['far', 'calendar-alt']")
Icon(:icon='["far", "calendar-alt"]')
| &nbsp; {{ post.post_date }}
li
Icon(:icon="['far', 'bookmark']")
nuxt-link(v-for='(relationships, idx) in post.term_relationships', :key='idx', v-if='relationships.term_taxonomy', :to="'/' + relationships.term_taxonomy.term.slug")
Icon(:icon='["far", "bookmark"]')
nuxt-link(
v-for='(relationships, idx) in post.term_relationships',
:key='idx',
v-if='relationships.term_taxonomy',
:to='"/" + relationships.term_taxonomy.term.slug'
)
span
| &nbsp; {{ relationships.term_taxonomy.term.name }}
li(v-if='post.postmetum.meta_value !== 0')
Icon(:icon="['fas', 'thermometer-' + post.hotValue]")
Icon(:icon='["fas", "thermometer-" + post.hotValue]')
| &nbsp; {{ post.postmetum.meta_value }}
.articelAbstractContent(v-html='post.post_excerpt || post.post_content')
.articelAbstractContent(
v-html='post.post_excerpt || post.post_content'
)
.readMore
nuxt-link.readMoreBtn(:to="'/post/' + post.ID")
nuxt-link.readMoreBtn(:to='"/post/" + post.ID')
| READ MORE
.Info(v-if='Info')
| {{ Info }}
nuxt-link(:to="nowPage > 2 ? nowPath + '/page/' + (nowPage - 1) : nowPath + '/'", :class="nowPage > 1 ? 'btn-footer btn-prev ' : 'btn-footer btn-prev btn-disable'")
Icon(:icon="['fas', 'chevron-left']")
nuxt-link(
:to='nowPage > 2 ? nowPath + "/page/" + (nowPage - 1) : nowPath + "/"',
:class='nowPage > 1 ? "btn-footer btn-prev " : "btn-footer btn-prev btn-disable"'
)
Icon(:icon='["fas", "chevron-left"]')
| &nbsp; 上一页
nuxt-link(:to="(nowPage + 1) <= Math.ceil(ArticelsCount / 8) ? nowPath + '/page/' + (nowPage + 1) : '#'", :class="(nowPage + 1) <= Math.ceil(ArticelsCount / 8) ? 'btn-footer btn-next' : 'btn-footer btn-next btn-disable'")
nuxt-link(
:to='nowPage + 1 <= Math.ceil(ArticelsCount / 8) ? nowPath + "/page/" + (nowPage + 1) : "#"',
:class='nowPage + 1 <= Math.ceil(ArticelsCount / 8) ? "btn-footer btn-next" : "btn-footer btn-next btn-disable"'
)
| 下一页 &nbsp;
Icon(:icon="['fas', 'chevron-right']")
Icon(:icon='["fas", "chevron-right"]')
</template>
<script>
export default {
async asyncData({ app, params, $axios }) {
validate ({ params }) {
return (params && params.terms) !== '404'
},
async asyncData ({ app, params, $axios }) {
let Info = null
let Articels = []
const nowPage = params.page ? parseInt(params.page) : 1
@ -64,11 +75,11 @@ export default {
Articels[n].postmetum = {}
Articels[n].postmetum.meta_value = 0
}
Articels[n].postImages = []
}
} else if (data.status === 404) {
Info = '未找到文章。'
// redirect('/404')
// return
}
return {
@ -80,27 +91,8 @@ export default {
nowPath: params.terms ? '/' + params.terms : ''
}
},
mounted() {
mounted () {
this.$finishLoad()
this.analyseImages()
},
methods: {
async analyseImages() { // 图片大小分析及处理
const articleImgsWidth = this.$refs.articleImgs.getBoundingClientRect().width
this.imageHeight = articleImgsWidth * 0.5625
for (const n in this.Articels) {
if (this.Articels[n].postimages.length !== 0) {
for (const i in this.Articels[n].postimages) {
const data = await this.$axios.$get(this.Articels[n].postimages[i].guid + '?x-oss-process=image/info')
const widthValue = data.ImageWidth.value
const heightValue = data.ImageHeight.value
if (widthValue > articleImgsWidth && (articleImgsWidth * heightValue / widthValue > this.imageHeight) && this.Articels[n].postImages.length < 10) {
this.Articels[n].postImages.push(this.Articels[n].postimages[i].guid + '?x-oss-process=image/resize,m_lfit,w_' + articleImgsWidth)
}
}
}
}
}
}
}
</script>

View File

@ -2,44 +2,52 @@
.pageList
.articleContent(ref='articleImgs', v-if='Articels')
article.articleList(v-for='(post, index) in Articels', :key='index')
.articleImgs(v-if='post.postImages.length')
nuxt-link(:to="'/post/' + post.ID")
Swiper(:style="'height: ' + imageHeight + 'px'")
Slide(v-for="(imgUrl, inx) in post.postImages" :key="inx")
img(:src='imgUrl')
.articleAbstract
nuxt-link(:to="'/post/' + post.ID")
nuxt-link(:to='"/post/" + post.ID')
.articleTitle(v-html='post.post_title')
.articalMeta
ul
li
Icon(:icon="['far', 'calendar-alt']")
Icon(:icon='["far", "calendar-alt"]')
| &nbsp; {{ post.post_date }}
li
Icon(:icon="['far', 'bookmark']")
nuxt-link(v-for='(relationships, idx) in post.term_relationships', :key='idx', v-if='relationships.term_taxonomy', :to="'/' + relationships.term_taxonomy.term.slug")
Icon(:icon='["far", "bookmark"]')
nuxt-link(
v-for='(relationships, idx) in post.term_relationships',
:key='idx',
v-if='relationships.term_taxonomy',
:to='"/" + relationships.term_taxonomy.term.slug'
)
span
| &nbsp; {{ relationships.term_taxonomy.term.name }}
li(v-if='post.postmetum.meta_value !== 0')
Icon(:icon="['fas', 'thermometer-' + post.hotValue]")
Icon(:icon='["fas", "thermometer-" + post.hotValue]')
| &nbsp; {{ post.postmetum.meta_value }}
.articelAbstractContent(v-html='post.post_excerpt || post.post_content')
.articelAbstractContent(
v-html='post.post_excerpt || post.post_content'
)
.readMore
nuxt-link.readMoreBtn(:to="'/post/' + post.ID")
nuxt-link.readMoreBtn(:to='"/post/" + post.ID')
| READ MORE
.Info(v-if='Info')
| {{ Info }}
nuxt-link(:to="nowPage > 2 ? nowPath + '/page/' + (nowPage - 1) : nowPath + '/'", :class="nowPage > 1 ? 'btn-footer btn-prev' : 'btn-footer btn-prev btn-disable'")
Icon(:icon="['fas', 'chevron-left']")
nuxt-link(
:to='nowPage > 2 ? nowPath + "/page/" + (nowPage - 1) : nowPath + "/"',
:class='nowPage > 1 ? "btn-footer btn-prev" : "btn-footer btn-prev btn-disable"'
)
Icon(:icon='["fas", "chevron-left"]')
| &nbsp; 上一页
nuxt-link(:to="(nowPage + 1) <= Math.ceil(ArticelsCount / 8) ? nowPath + '/page/' + (nowPage + 1) : ''", :class="(nowPage + 1) <= Math.ceil(ArticelsCount / 8) ? 'btn-footer btn-next' : 'btn-footer btn-next btn-disable'")
nuxt-link(
:to='nowPage + 1 <= Math.ceil(ArticelsCount / 8) ? nowPath + "/page/" + (nowPage + 1) : ""',
:class='nowPage + 1 <= Math.ceil(ArticelsCount / 8) ? "btn-footer btn-next" : "btn-footer btn-next btn-disable"'
)
| 下一页 &nbsp;
Icon(:icon="['fas', 'chevron-right']")
Icon(:icon='["fas", "chevron-right"]')
</template>
<script>
export default {
async asyncData({ app, params, $axios }) {
async asyncData ({ app, params, $axios }) {
let Info = null
let Articels = []
const nowPage = params.page ? parseInt(params.page) : 1
@ -64,11 +72,11 @@ export default {
Articels[n].postmetum = {}
Articels[n].postmetum.meta_value = 0
}
Articels[n].postImages = []
}
} else if (data.status === 404) {
Info = '未找到文章。'
// redirect('/404')
// return
}
return {
@ -80,27 +88,8 @@ export default {
nowPath: params.terms ? '/' + params.terms : ''
}
},
mounted() {
mounted () {
this.$finishLoad()
this.analyseImages()
},
methods: {
async analyseImages() { // 图片大小分析及处理
const articleImgsWidth = this.$refs.articleImgs.getBoundingClientRect().width
this.imageHeight = articleImgsWidth * 0.5625
for (const n in this.Articels) {
if (this.Articels[n].postimages.length !== 0) {
for (const i in this.Articels[n].postimages) {
const data = await this.$axios.$get(this.Articels[n].postimages[i].guid + '?x-oss-process=image/info')
const widthValue = data.ImageWidth.value
const heightValue = data.ImageHeight.value
if (widthValue > articleImgsWidth && (articleImgsWidth * heightValue / widthValue > this.imageHeight) && this.Articels[n].postImages.length < 10) {
this.Articels[n].postImages.push(this.Articels[n].postimages[i].guid + '?x-oss-process=image/resize,m_lfit,w_' + articleImgsWidth)
}
}
}
}
}
}
}
</script>

92
pages/auth.vue Normal file
View File

@ -0,0 +1,92 @@
<template lang="pug">
.auth(v-html="notice")
</template>
<script>
export default {
layout: 'auth',
data () {
return {
notice: 'Loading...'
}
},
async mounted () {
const code = this.$route.query.code
const type = this.$route.query.type
const state = this.$route.query.state.split('-')
if (!code) { this.notice = '<p style="color: #999">非法访问,缺少授权参数"code"。<p><br><br> <a href="https://www.wyr.me" target="_blank">返回首页<a>'; this.$finishLoad(); return }
if (type === 'weixin') {
const { data } = await this.$axios.post(`${process.env.baseURL}/visitor/user/weixin`, {
code,
app: 'wx9d5e677f533d1e84'
})
if (data.status !== 1) {
this.$toasted.show('微信登录失败,请重试或换用其它登录方式。', {
position: 'top-center'
})
this.$finishLoad()
return
} else {
try {
window.localStorage.visitorToken = data.result.token
window.localStorage.visitorInfo = JSON.stringify(data.result.visitorInfo)
window.location.href = 'https://www.wyr.me/post/' + state[1] + '?hash=comment'
} catch (_) { }
}
return
}
if (state[0] === 'weibo' || state[0] === 'qq') {
const { data } = await this.$axios.post(`${process.env.baseURL}/visitor/user/` + state[0], {
code
})
if (data.status !== 1) {
this.$toasted.show((state[0] === 'weibo' ? '微博' : 'QQ') + '登录失败,请重试或换用其它登录方式。', {
position: 'top-center'
})
this.$finishLoad()
return
} else {
try {
window.localStorage.visitorToken = data.result.token
window.localStorage.visitorInfo = JSON.stringify(data.result.visitorInfo)
window.location.href = 'https://www.wyr.me/post/' + state[1] + '?hash=comment'
} catch (_) { }
}
return
}
const { data } = await this.$axios.post('/visitor/user/auth', {
type: 'github',
code
})
if (data.status !== 1) {
this.notice = '<p style="color: #999">授权失败,请关闭页面从登陆入口再试一次。<p><br><br> <a href="https://www.wyr.me" target="_blank">返回首页<a>'
this.$finishLoad()
return
}
window.opener.authSuccess(data)
window.close()
this.$finishLoad()
},
methods: {
}
}
</script>
<style lang="stylus" scoped>
.auth
width 100%
height 100%
padding 50px
</style>

View File

@ -2,44 +2,52 @@
.pageList
.articleContent(ref='articleImgs', v-if='Articels')
article.articleList(v-for='(post, index) in Articels', :key='index')
.articleImgs(v-if='post.postImages.length')
nuxt-link(:to="'/post/' + post.ID")
Swiper(:style="'height: ' + imageHeight + 'px'")
Slide(v-for="(imgUrl, inx) in post.postImages" :key="inx")
img(:src='imgUrl')
.articleAbstract
nuxt-link(:to="'/post/' + post.ID")
nuxt-link(:to='"/post/" + post.ID')
.articleTitle(v-html='post.post_title')
.articalMeta
ul
li
Icon(:icon="['far', 'calendar-alt']")
Icon(:icon='["far", "calendar-alt"]')
| &nbsp; {{ post.post_date }}
li
Icon(:icon="['far', 'bookmark']")
nuxt-link(v-for='(relationships, idx) in post.term_relationships', :key='idx', v-if='relationships.term_taxonomy', :to="'/' + relationships.term_taxonomy.term.slug")
Icon(:icon='["far", "bookmark"]')
nuxt-link(
v-for='(relationships, idx) in post.term_relationships',
:key='idx',
v-if='relationships.term_taxonomy',
:to='"/" + relationships.term_taxonomy.term.slug'
)
span
| &nbsp; {{ relationships.term_taxonomy.term.name }}
li(v-if='post.postmetum.meta_value !== 0')
Icon(:icon="['fas', 'thermometer-' + post.hotValue]")
Icon(:icon='["fas", "thermometer-" + post.hotValue]')
| &nbsp; {{ post.postmetum.meta_value }}
.articelAbstractContent(v-html='post.post_excerpt || post.post_content')
.articelAbstractContent(
v-html='post.post_excerpt || post.post_content'
)
.readMore
nuxt-link.readMoreBtn(:to="'/post/' + post.ID")
nuxt-link.readMoreBtn(:to='"/post/" + post.ID')
| READ MORE
.Info(v-if='Info')
| {{ Info }}
nuxt-link(:to="nowPage > 2 ? nowPath + '/page/' + (nowPage - 1) : nowPath + '/'", :class="nowPage > 1 ? 'btn-footer btn-prev ' : 'btn-footer btn-prev btn-disable'")
Icon(:icon="['fas', 'chevron-left']")
nuxt-link(
:to='nowPage > 2 ? nowPath + "/page/" + (nowPage - 1) : nowPath + "/"',
:class='nowPage > 1 ? "btn-footer btn-prev " : "btn-footer btn-prev btn-disable"'
)
Icon(:icon='["fas", "chevron-left"]')
| &nbsp; 上一页
nuxt-link(:to="(nowPage + 1) <= Math.ceil(ArticelsCount / 8) ? nowPath + '/page/' + (nowPage + 1) : '#'", :class="(nowPage + 1) <= Math.ceil(ArticelsCount / 8) ? 'btn-footer btn-next' : 'btn-footer btn-next btn-disable'")
nuxt-link(
:to='nowPage + 1 <= Math.ceil(ArticelsCount / 8) ? nowPath + "/page/" + (nowPage + 1) : "#"',
:class='nowPage + 1 <= Math.ceil(ArticelsCount / 8) ? "btn-footer btn-next" : "btn-footer btn-next btn-disable"'
)
| 下一页 &nbsp;
Icon(:icon="['fas', 'chevron-right']")
Icon(:icon='["fas", "chevron-right"]')
</template>
<script>
export default {
async asyncData(inject) {
async asyncData (inject) {
const { app, params, $axios } = inject
let Info = null
let Articels = []
@ -65,11 +73,11 @@ export default {
Articels[n].postmetum = {}
Articels[n].postmetum.meta_value = 0
}
Articels[n].postImages = []
}
} else if (data.status === 404) {
Info = '未找到文章。'
// redirect('/404')
// return
}
return {
@ -81,27 +89,8 @@ export default {
nowPath: params.terms ? '/' + params.terms : ''
}
},
mounted() {
mounted () {
this.$finishLoad()
this.analyseImages()
},
methods: {
async analyseImages() { // 图片大小分析及处理
const articleImgsWidth = this.$refs.articleImgs.getBoundingClientRect().width
this.imageHeight = articleImgsWidth * 0.5625
for (const n in this.Articels) {
if (this.Articels[n].postimages.length !== 0) {
for (const i in this.Articels[n].postimages) {
const data = await this.$axios.$get(this.Articels[n].postimages[i].guid + '?x-oss-process=image/info')
const widthValue = data.ImageWidth.value
const heightValue = data.ImageHeight.value
if (widthValue > articleImgsWidth && (articleImgsWidth * heightValue / widthValue > this.imageHeight) && this.Articels[n].postImages.length < 10) {
this.Articels[n].postImages.push(this.Articels[n].postimages[i].guid + '?x-oss-process=image/resize,m_lfit,w_' + articleImgsWidth)
}
}
}
}
}
}
}
</script>

63
pages/links.vue Normal file
View File

@ -0,0 +1,63 @@
<template lang="pug">
.links
.Info(v-if='Info')
| {{ Info }}
h1.title
| 首页友链
ul
li
a(href='https://wintc.top/', target='_blank') 沐码小站
li
a(href='https://johnsonlee.site/', target='_blank') Johnson Blog
li
a(href='https://www.lfhacks.com/', target='_blank') LFhacks
h1.title
| 内页友链
ul
li
a(href='http://www.zzfly.net/', target='_blank') 烟花易冷
h1.title
| 暂时取消的友链
ul
li
| 前端视角 网站无法访问
li
| 会打篮球的程序猿 网站无法访问
li
| 西秦公子 友链长期缺失
h1.title
| 友链说明
p
| 本站友链遵循对等原则即您的友链放置于首页我的友链也放置于首页
p
| 交换友链请通过左侧头像下方的联系方式与我联系只要网站/博客能正常打开不定时更新原创文章即可
</template>
<script>
export default {
asyncData ({ app, params, $axios }) {
return {
Info: ''
}
},
mounted () {
this.$finishLoad()
}
}
</script>
<style lang="stylus" scoped>
.links
width 100%
height 100%
padding 50px
.title
margin-top 60px
margin-bottom 20px
font-weight 500
</style>

47
pages/p.vue Normal file
View File

@ -0,0 +1,47 @@
<template lang="pug">
.pClass
Form(ref='form', :model='form', label-width='120px')
FormItem(label='请输入文章编号')
Input(v-model='form.no', size='small', @keyup.enter='onSubmit')
FormItem
Button(type='primary', size='small', @click='onSubmit')
| 确定
</template>
<script>
import { Form, FormItem, Input, Switch, Button } from 'element-ui'
export default {
components: {
Form, FormItem, Input, VueSwitch: Switch, Button
},
layout: 'auth',
data () {
return {
form: {
no: ''
}
}
},
mounted () {
this.$finishLoad()
},
methods: {
onSubmit () {
if (!this.form.no) {
alert('请输入文章编号')
return
}
this.$router.push('/post/' + this.form.no + '#comment')
}
}
}
</script>
<style lang="stylus" scoped>
.pClass
width 100%
height 100%
padding 50px 20px
box-sizing border-box
</style>

View File

@ -2,44 +2,52 @@
.pageList
.articleContent(ref='articleImgs', v-if='Articels')
article.articleList(v-for='(post, index) in Articels', :key='index')
.articleImgs(v-if='post.postImages.length')
nuxt-link(:to="'/post/' + post.ID")
Swiper(:style="'height: ' + imageHeight + 'px'")
Slide(v-for="(imgUrl, inx) in post.postImages" :key="inx")
img(:src='imgUrl')
.articleAbstract
nuxt-link(:to="'/post/' + post.ID")
nuxt-link(:to='"/post/" + post.ID')
.articleTitle(v-html='post.post_title')
.articalMeta
ul
li
Icon(:icon="['far', 'calendar-alt']")
Icon(:icon='["far", "calendar-alt"]')
| &nbsp; {{ post.post_date }}
li
Icon(:icon="['far', 'bookmark']")
nuxt-link(v-for='(relationships, idx) in post.term_relationships', :key='idx', v-if='relationships.term_taxonomy', :to="'/' + relationships.term_taxonomy.term.slug")
Icon(:icon='["far", "bookmark"]')
nuxt-link(
v-for='(relationships, idx) in post.term_relationships',
:key='idx',
v-if='relationships.term_taxonomy',
:to='"/" + relationships.term_taxonomy.term.slug'
)
span
| &nbsp; {{ relationships.term_taxonomy.term.name }}
li(v-if='post.postmetum.meta_value !== 0')
Icon(:icon="['fas', 'thermometer-' + post.hotValue]")
Icon(:icon='["fas", "thermometer-" + post.hotValue]')
| &nbsp; {{ post.postmetum.meta_value }}
.articelAbstractContent(v-html='post.post_excerpt || post.post_content')
.articelAbstractContent(
v-html='post.post_excerpt || post.post_content'
)
.readMore
nuxt-link.readMoreBtn(:to="'/post/' + post.ID")
nuxt-link.readMoreBtn(:to='"/post/" + post.ID')
| READ MORE
.Info(v-if='Info')
| {{ Info }}
nuxt-link(:to="nowPage > 2 ? nowPath + '/page/' + (nowPage - 1) : nowPath + '/'", :class="nowPage > 1 ? 'btn-footer btn-prev ' : 'btn-footer btn-prev btn-disable'")
Icon(:icon="['fas', 'chevron-left']")
nuxt-link(
:to='nowPage > 2 ? nowPath + "/page/" + (nowPage - 1) : nowPath + "/"',
:class='nowPage > 1 ? "btn-footer btn-prev " : "btn-footer btn-prev btn-disable"'
)
Icon(:icon='["fas", "chevron-left"]')
| &nbsp; 上一页
nuxt-link(:to="(nowPage + 1) <= Math.ceil(ArticelsCount / 8) ? nowPath + '/page/' + (nowPage + 1) : '#'", :class="(nowPage + 1) <= Math.ceil(ArticelsCount / 8) ? 'btn-footer btn-next' : 'btn-footer btn-next btn-disable'")
nuxt-link(
:to='nowPage + 1 <= Math.ceil(ArticelsCount / 8) ? nowPath + "/page/" + (nowPage + 1) : "#"',
:class='nowPage + 1 <= Math.ceil(ArticelsCount / 8) ? "btn-footer btn-next" : "btn-footer btn-next btn-disable"'
)
| 下一页 &nbsp;
Icon(:icon="['fas', 'chevron-right']")
Icon(:icon='["fas", "chevron-right"]')
</template>
<script>
export default {
async asyncData({ app, params, $axios }) {
async asyncData ({ app, params, $axios }) {
let Info = null
let Articels = []
const nowPage = params.page ? parseInt(params.page) : 1
@ -64,11 +72,11 @@ export default {
Articels[n].postmetum = {}
Articels[n].postmetum.meta_value = 0
}
Articels[n].postImages = []
}
} else if (data.status === 404) {
Info = '未找到文章。'
// redirect('/404')
// return
}
return {
@ -80,27 +88,8 @@ export default {
nowPath: params.terms ? '/' + params.terms : ''
}
},
mounted() {
mounted () {
this.$finishLoad()
this.analyseImages()
},
methods: {
async analyseImages() { // 图片大小分析及处理
const articleImgsWidth = this.$refs.articleImgs.getBoundingClientRect().width
this.imageHeight = articleImgsWidth * 0.5625
for (const n in this.Articels) {
if (this.Articels[n].postimages.length !== 0) {
for (const i in this.Articels[n].postimages) {
const data = await this.$axios.$get(this.Articels[n].postimages[i].guid + '?x-oss-process=image/info')
const widthValue = data.ImageWidth.value
const heightValue = data.ImageHeight.value
if (widthValue > articleImgsWidth && (articleImgsWidth * heightValue / widthValue > this.imageHeight) && this.Articels[n].postImages.length < 10) {
this.Articels[n].postImages.push(this.Articels[n].postimages[i].guid + '?x-oss-process=image/resize,m_lfit,w_' + articleImgsWidth)
}
}
}
}
}
}
}
</script>

File diff suppressed because it is too large Load Diff

47
pages/post/p.vue Normal file
View File

@ -0,0 +1,47 @@
<template lang="pug">
.pClass
Form(ref='form', :model='form', label-width='120px')
FormItem(label='请输入文章编号')
Input(v-model='form.no', size='small', @keyup.enter='onSubmit')
FormItem
Button(type='primary', size='small', @click='onSubmit')
| 确定
</template>
<script>
import { Form, FormItem, Input, Switch, Button } from 'element-ui'
export default {
components: {
Form, FormItem, Input, VueSwitch: Switch, Button
},
layout: 'auth',
data () {
return {
form: {
no: ''
}
}
},
mounted () {
this.$finishLoad()
},
methods: {
onSubmit () {
if (!this.form.no) {
alert('请输入文章编号')
return
}
this.$router.push('/post/' + this.form.no + '#comment')
}
}
}
</script>
<style lang="stylus" scoped>
.pClass
width 100%
height 100%
padding 50px 20px
box-sizing border-box
</style>

View File

@ -2,44 +2,52 @@
.pageList
.articleContent(ref='articleImgs', v-if='Articels')
article.articleList(v-for='(post, index) in Articels', :key='index')
.articleImgs(v-if='post.postImages.length')
nuxt-link(:to="'/post/' + post.ID")
Swiper(:style="'height: ' + imageHeight + 'px'")
Slide(v-for="(imgUrl, inx) in post.postImages" :key="inx")
img(:src='imgUrl')
.articleAbstract
nuxt-link(:to="'/post/' + post.ID")
nuxt-link(:to='"/post/" + post.ID')
.articleTitle(v-html='post.post_title')
.articalMeta
ul
li
Icon(:icon="['far', 'calendar-alt']")
Icon(:icon='["far", "calendar-alt"]')
| &nbsp; {{ post.post_date }}
li
Icon(:icon="['far', 'bookmark']")
nuxt-link(v-for='(relationships, idx) in post.term_relationships', :key='idx', v-if='relationships.term_taxonomy', :to="'/' + relationships.term_taxonomy.term.slug")
Icon(:icon='["far", "bookmark"]')
nuxt-link(
v-for='(relationships, idx) in post.term_relationships',
:key='idx',
v-if='relationships.term_taxonomy',
:to='"/" + relationships.term_taxonomy.term.slug'
)
span
| &nbsp; {{ relationships.term_taxonomy.term.name }}
li(v-if='post.postmetum.meta_value !== 0')
Icon(:icon="['fas', 'thermometer-' + post.hotValue]")
Icon(:icon='["fas", "thermometer-" + post.hotValue]')
| &nbsp; {{ post.postmetum.meta_value }}
.articelAbstractContent(v-html='post.post_excerpt || post.post_content')
.articelAbstractContent(
v-html='post.post_excerpt || post.post_content'
)
.readMore
nuxt-link.readMoreBtn(:to="'/post/' + post.ID")
nuxt-link.readMoreBtn(:to='"/post/" + post.ID')
| READ MORE
.Info(v-if='Info')
| {{ Info }}
nuxt-link(:to="nowPage > 2 ? nowPath + '/page/' + (nowPage - 1) : nowPath + '/'", :class="nowPage > 1 ? 'btn-footer btn-prev ' : 'btn-footer btn-prev btn-disable'")
Icon(:icon="['fas', 'chevron-left']")
nuxt-link(
:to='nowPage > 2 ? nowPath + "/page/" + (nowPage - 1) : nowPath + "/"',
:class='nowPage > 1 ? "btn-footer btn-prev " : "btn-footer btn-prev btn-disable"'
)
Icon(:icon='["fas", "chevron-left"]')
| &nbsp; 上一页
nuxt-link(:to="(nowPage + 1) <= Math.ceil(ArticelsCount / 8) ? nowPath + '/page/' + (nowPage + 1) : '#'", :class="(nowPage + 1) <= Math.ceil(ArticelsCount / 8) ? 'btn-footer btn-next' : 'btn-footer btn-next btn-disable'")
nuxt-link(
:to='nowPage + 1 <= Math.ceil(ArticelsCount / 8) ? nowPath + "/page/" + (nowPage + 1) : "#"',
:class='nowPage + 1 <= Math.ceil(ArticelsCount / 8) ? "btn-footer btn-next" : "btn-footer btn-next btn-disable"'
)
| 下一页 &nbsp;
Icon(:icon="['fas', 'chevron-right']")
Icon(:icon='["fas", "chevron-right"]')
</template>
<script>
export default {
async asyncData({ app, params, query, $axios }) {
async asyncData ({ app, params, query, $axios, redirect }) {
let Info = null
let Articels = []
const nowPage = params.page ? parseInt(params.page) : 1
@ -69,6 +77,8 @@ export default {
}
} else if (data.status === 404) {
Info = '未找到文章。'
// redirect('/404')
// return
}
return {
@ -80,27 +90,8 @@ export default {
nowPath: params.terms ? '/' + params.terms : ''
}
},
mounted() {
mounted () {
this.$finishLoad()
this.analyseImages()
},
methods: {
async analyseImages() { // 图片大小分析及处理
const articleImgsWidth = this.$refs.articleImgs.getBoundingClientRect().width
this.imageHeight = articleImgsWidth * 0.5625
for (const n in this.Articels) {
if (this.Articels[n].postimages.length !== 0) {
for (const i in this.Articels[n].postimages) {
const data = await this.$axios.$get(this.Articels[n].postimages[i].guid + '?x-oss-process=image/info')
const widthValue = data.ImageWidth.value
const heightValue = data.ImageHeight.value
if (widthValue > articleImgsWidth && (articleImgsWidth * heightValue / widthValue > this.imageHeight) && this.Articels[n].postImages.length < 10) {
this.Articels[n].postImages.push(this.Articels[n].postimages[i].guid + '?x-oss-process=image/resize,m_lfit,w_' + articleImgsWidth)
}
}
}
}
}
}
}
</script>

View File

@ -2,44 +2,52 @@
.pageList
.articleContent(ref='articleImgs', v-if='Articels')
article.articleList(v-for='(post, index) in Articels', :key='index')
.articleImgs(v-if='post.postImages.length')
nuxt-link(:to="'/post/' + post.ID")
Swiper(:style="'height: ' + imageHeight + 'px'")
Slide(v-for="(imgUrl, inx) in post.postImages" :key="inx")
img(:src='imgUrl')
.articleAbstract
nuxt-link(:to="'/post/' + post.ID")
nuxt-link(:to='"/post/" + post.ID')
.articleTitle(v-html='post.post_title')
.articalMeta
ul
li
Icon(:icon="['far', 'calendar-alt']")
Icon(:icon='["far", "calendar-alt"]')
| &nbsp; {{ post.post_date }}
li
Icon(:icon="['far', 'bookmark']")
nuxt-link(v-for='(relationships, idx) in post.term_relationships', :key='idx', v-if='relationships.term_taxonomy', :to="'/' + relationships.term_taxonomy.term.slug")
Icon(:icon='["far", "bookmark"]')
nuxt-link(
v-for='(relationships, idx) in post.term_relationships',
:key='idx',
v-if='relationships.term_taxonomy',
:to='"/" + relationships.term_taxonomy.term.slug'
)
span
| &nbsp; {{ relationships.term_taxonomy.term.name }}
li(v-if='post.postmetum.meta_value !== 0')
Icon(:icon="['fas', 'thermometer-' + post.hotValue]")
Icon(:icon='["fas", "thermometer-" + post.hotValue]')
| &nbsp; {{ post.postmetum.meta_value }}
.articelAbstractContent(v-html='post.post_excerpt || post.post_content')
.articelAbstractContent(
v-html='post.post_excerpt || post.post_content'
)
.readMore
nuxt-link.readMoreBtn(:to="'/post/' + post.ID")
nuxt-link.readMoreBtn(:to='"/post/" + post.ID')
| READ MORE
.Info(v-if='Info')
| {{ Info }}
nuxt-link(:to="nowPage > 2 ? nowPath + '/page/' + (nowPage - 1) : nowPath + '/'", :class="nowPage > 1 ? 'btn-footer btn-prev ' : 'btn-footer btn-prev btn-disable'")
Icon(:icon="['fas', 'chevron-left']")
nuxt-link(
:to='nowPage > 2 ? nowPath + "/page/" + (nowPage - 1) : nowPath + "/"',
:class='nowPage > 1 ? "btn-footer btn-prev " : "btn-footer btn-prev btn-disable"'
)
Icon(:icon='["fas", "chevron-left"]')
| &nbsp; 上一页
nuxt-link(:to="(nowPage + 1) <= Math.ceil(ArticelsCount / 8) ? nowPath + '/page/' + (nowPage + 1) : '#'", :class="(nowPage + 1) <= Math.ceil(ArticelsCount / 8) ? 'btn-footer btn-next' : 'btn-footer btn-next btn-disable'")
nuxt-link(
:to='nowPage + 1 <= Math.ceil(ArticelsCount / 8) ? nowPath + "/page/" + (nowPage + 1) : "#"',
:class='nowPage + 1 <= Math.ceil(ArticelsCount / 8) ? "btn-footer btn-next" : "btn-footer btn-next btn-disable"'
)
| 下一页 &nbsp;
Icon(:icon="['fas', 'chevron-right']")
Icon(:icon='["fas", "chevron-right"]')
</template>
<script>
export default {
async asyncData({ app, params, $axios }) {
async asyncData ({ app, params, $axios }) {
let Info = null
let Articels = []
const nowPage = params.page ? parseInt(params.page) : 1
@ -64,11 +72,11 @@ export default {
Articels[n].postmetum = {}
Articels[n].postmetum.meta_value = 0
}
Articels[n].postImages = []
}
} else if (data.status === 404) {
Info = '未找到文章。'
// redirect('/404')
// return
}
return {
@ -80,27 +88,8 @@ export default {
nowPath: params.terms ? '/' + params.terms : ''
}
},
mounted() {
mounted () {
this.$finishLoad()
this.analyseImages()
},
methods: {
async analyseImages() { // 图片大小分析及处理
const articleImgsWidth = this.$refs.articleImgs.getBoundingClientRect().width
this.imageHeight = articleImgsWidth * 0.5625
for (const n in this.Articels) {
if (this.Articels[n].postimages.length !== 0) {
for (const i in this.Articels[n].postimages) {
const data = await this.$axios.$get(this.Articels[n].postimages[i].guid + '?x-oss-process=image/info')
const widthValue = data.ImageWidth.value
const heightValue = data.ImageHeight.value
if (widthValue > articleImgsWidth && (articleImgsWidth * heightValue / widthValue > this.imageHeight) && this.Articels[n].postImages.length < 10) {
this.Articels[n].postImages.push(this.Articels[n].postimages[i].guid + '?x-oss-process=image/resize,m_lfit,w_' + articleImgsWidth)
}
}
}
}
}
}
}
</script>

View File

@ -2,44 +2,52 @@
.pageList
.articleContent(ref='articleImgs', v-if='Articels')
article.articleList(v-for='(post, index) in Articels', :key='index')
.articleImgs(v-if='post.postImages.length')
nuxt-link(:to="'/post/' + post.ID")
Swiper(:style="'height: ' + imageHeight + 'px'")
Slide(v-for="(imgUrl, inx) in post.postImages" :key="inx")
img(:src='imgUrl')
.articleAbstract
nuxt-link(:to="'/post/' + post.ID")
nuxt-link(:to='"/post/" + post.ID')
.articleTitle(v-html='post.post_title')
.articalMeta
ul
li
Icon(:icon="['far', 'calendar-alt']")
Icon(:icon='["far", "calendar-alt"]')
| &nbsp; {{ post.post_date }}
li
Icon(:icon="['far', 'bookmark']")
nuxt-link(v-for='(relationships, idx) in post.term_relationships', :key='idx', v-if='relationships.term_taxonomy', :to="'/' + relationships.term_taxonomy.term.slug")
Icon(:icon='["far", "bookmark"]')
nuxt-link(
v-for='(relationships, idx) in post.term_relationships',
:key='idx',
v-if='relationships.term_taxonomy',
:to='"/" + relationships.term_taxonomy.term.slug'
)
span
| &nbsp; {{ relationships.term_taxonomy.term.name }}
li(v-if='post.postmetum.meta_value !== 0')
Icon(:icon="['fas', 'thermometer-' + post.hotValue]")
Icon(:icon='["fas", "thermometer-" + post.hotValue]')
| &nbsp; {{ post.postmetum.meta_value }}
.articelAbstractContent(v-html='post.post_excerpt || post.post_content')
.articelAbstractContent(
v-html='post.post_excerpt || post.post_content'
)
.readMore
nuxt-link.readMoreBtn(:to="'/post/' + post.ID")
nuxt-link.readMoreBtn(:to='"/post/" + post.ID')
| READ MORE
.Info(v-if='Info')
| {{ Info }}
nuxt-link(:to="nowPage > 2 ? nowPath + '/page/' + (nowPage - 1) : nowPath + '/'", :class="nowPage > 1 ? 'btn-footer btn-prev ' : 'btn-footer btn-prev btn-disable'")
Icon(:icon="['fas', 'chevron-left']")
nuxt-link(
:to='nowPage > 2 ? nowPath + "/page/" + (nowPage - 1) : nowPath + "/"',
:class='nowPage > 1 ? "btn-footer btn-prev " : "btn-footer btn-prev btn-disable"'
)
Icon(:icon='["fas", "chevron-left"]')
| &nbsp; 上一页
nuxt-link(:to="(nowPage + 1) <= Math.ceil(ArticelsCount / 8) ? nowPath + '/page/' + (nowPage + 1) : '#'", :class="(nowPage + 1) <= Math.ceil(ArticelsCount / 8) ? 'btn-footer btn-next' : 'btn-footer btn-next btn-disable'")
nuxt-link(
:to='nowPage + 1 <= Math.ceil(ArticelsCount / 8) ? nowPath + "/page/" + (nowPage + 1) : "#"',
:class='nowPage + 1 <= Math.ceil(ArticelsCount / 8) ? "btn-footer btn-next" : "btn-footer btn-next btn-disable"'
)
| 下一页 &nbsp;
Icon(:icon="['fas', 'chevron-right']")
Icon(:icon='["fas", "chevron-right"]')
</template>
<script>
export default {
async asyncData({ app, params, $axios }) {
async asyncData ({ app, params, $axios }) {
let Info = null
let Articels = []
const nowPage = params.page ? parseInt(params.page) : 1
@ -69,6 +77,8 @@ export default {
}
} else if (data.status === 404) {
Info = '未找到文章。'
// redirect('/404')
// return
}
return {
@ -80,27 +90,8 @@ export default {
nowPath: params.terms ? '/' + params.terms : ''
}
},
mounted() {
mounted () {
this.$finishLoad()
this.analyseImages()
},
methods: {
async analyseImages() { // 图片大小分析及处理
const articleImgsWidth = this.$refs.articleImgs.getBoundingClientRect().width
this.imageHeight = articleImgsWidth * 0.5625
for (const n in this.Articels) {
if (this.Articels[n].postimages.length !== 0) {
for (const i in this.Articels[n].postimages) {
const data = await this.$axios.$get(this.Articels[n].postimages[i].guid + '?x-oss-process=image/info')
const widthValue = data.ImageWidth.value
const heightValue = data.ImageHeight.value
if (widthValue > articleImgsWidth && (articleImgsWidth * heightValue / widthValue > this.imageHeight) && this.Articels[n].postImages.length < 10) {
this.Articels[n].postImages.push(this.Articels[n].postimages[i].guid + '?x-oss-process=image/resize,m_lfit,w_' + articleImgsWidth)
}
}
}
}
}
}
}
</script>

View File

@ -1,9 +1,14 @@
import '~/layouts/common.styl'
import vditor from 'vditor'
import 'vditor/dist/index.css'
const $tags = document.getElementById('tags')
const floatTop = $tags.offsetTop + $tags.scrollHeight + 30
let floatTop = null
if ($tags) {
floatTop = $tags.offsetTop + $tags.scrollHeight + 30
}
function addEvent(obj, type, fn) {
function addEvent (obj, type, fn) {
if (obj.attachEvent) {
obj.attachEvent('on' + type, function () {
fn.call(obj)
@ -17,35 +22,37 @@ window.addEvent = addEvent
window.onload = function () {
if (navigator.appName === 'Microsoft Internet Explorer' && parseInt(navigator.appVersion.split(';')[1].replace(/[ ]/g, '').replace('MSIE', '')) <= 9) {
alert('您的浏览器版本过低,继续访问将会出现问题,请升级浏览器版本!')
alert('您的浏览器版本过低,继续访问将会出现问题,请升级浏览器版本!') // eslint-disable-line
}
// 底部返回顶部按钮
const top = document.getElementById('gotop')
// 滚动一屏幕时显示回到顶部
addEvent(window, 'scroll', function () {
const currentPosition = document.documentElement.scrollTop || document.body.scrollTop
currentPosition > window.screen.availHeight ? top.style.display = 'block' : top.style.display = 'none'
if (top) {
// 滚动一屏幕时显示回到顶部
addEvent(window, 'scroll', function () {
const currentPosition = document.documentElement.scrollTop || document.body.scrollTop
currentPosition > window.screen.availHeight ? top.style.display = 'block' : top.style.display = 'none'
// 左部导航自动浮动
if (currentPosition > floatTop) {
document.getElementById('navication').style.position = 'fixed'
} else {
document.getElementById('navication').style.position = 'static'
}
})
top.onclick = function () {
var timer = setInterval(function () { // eslint-disable-line
let currentPosition = document.documentElement.scrollTop || document.body.scrollTop
currentPosition -= 100
if (currentPosition > 0) {
window.scrollTo(0, currentPosition)
// 左部导航自动浮动
if (currentPosition > floatTop && document.body.clientWidth > 768) {
document.getElementById('navication').style.position = 'fixed'
} else {
window.scrollTo(0, 0)
clearInterval(timer)
document.getElementById('navication').style.position = 'static'
}
}, 10)
})
top.onclick = function () {
var timer = setInterval(function () { // eslint-disable-line
let currentPosition = document.documentElement.scrollTop || document.body.scrollTop
currentPosition -= 100
if (currentPosition > 0) {
window.scrollTo(0, currentPosition)
} else {
window.scrollTo(0, 0)
clearInterval(timer)
}
}, 10)
}
}
let _hmt = _hmt || [] // eslint-disable-line
@ -54,3 +61,13 @@ window.onload = function () {
const s = document.getElementsByTagName('script')[0]
s.parentNode.insertBefore(hm, s)
}
window.Vditor = vditor
window.authSuccess = (data) => { // eslint-disable-line
if (data.status === 1) {
try {
if (window.setAuthToken) { window.setAuthToken(data.result.token, data.result.visitorInfo) }
} catch (_) { }
}
}

5
plugins/v-viewer.js Normal file
View File

@ -0,0 +1,5 @@
import 'viewerjs/dist/viewer.css'
import Viewer from 'v-viewer'
import Vue from 'vue'
Vue.use(Viewer)

5
plugins/vue-js-modal.js Normal file
View File

@ -0,0 +1,5 @@
import Vue from 'vue'
import VModal from 'vue-js-modal/dist/ssr.nocss'
import 'vue-js-modal/dist/styles.css'
Vue.use(VModal, { dialog: true })

4
plugins/vue-toasted.js Normal file
View File

@ -0,0 +1,4 @@
import Vue from 'vue'
import Toasted from 'vue-toasted'
Vue.use(Toasted)

View File

@ -1,18 +1,66 @@
import Vue from 'vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faGithub, faQq, faWeixin, faWeibo, faTwitter, faFacebook, faGooglePlus, faTelegram } from '@fortawesome/free-brands-svg-icons'
import { faEnvelope, faSearch, faThermometerEmpty, faThermometerQuarter, faThermometerHalf, faThermometerThreeQuarters, faThermometerFull, faAngleDoubleUp, faChevronLeft, faChevronRight } from '@fortawesome/free-solid-svg-icons'
import { faClock, faCalendarAlt, faBookmark } from '@fortawesome/free-regular-svg-icons'
import {
faGithub,
faQq,
faWeixin,
faWeibo,
faTwitter,
faFacebook,
faGooglePlus,
faTelegram
} from '@fortawesome/free-brands-svg-icons'
import {
faEnvelope,
faSearch,
faThermometerEmpty,
faThermometerQuarter,
faThermometerHalf,
faThermometerThreeQuarters,
faThermometerFull,
faAngleDoubleUp,
faChevronLeft,
faChevronRight,
faRss
} from '@fortawesome/free-solid-svg-icons'
import {
faClock,
faCalendarAlt,
faBookmark
} from '@fortawesome/free-regular-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import hljs from 'highlight.js'
import Swiper from '../components/Swiper'
import { Loading } from 'element-ui'
import Slide from '../components/Slide'
library.add(faGithub, faQq, faWeixin, faWeibo, faTwitter, faFacebook, faGooglePlus, faTelegram, faEnvelope, faSearch, faClock, faCalendarAlt, faBookmark, faThermometerEmpty, faThermometerQuarter, faThermometerHalf, faThermometerThreeQuarters, faThermometerFull, faAngleDoubleUp, faChevronLeft, faChevronRight)
library.add(
faGithub,
faQq,
faWeixin,
faWeibo,
faTwitter,
faFacebook,
faGooglePlus,
faTelegram,
faEnvelope,
faRss,
faSearch,
faClock,
faCalendarAlt,
faBookmark,
faThermometerEmpty,
faThermometerQuarter,
faThermometerHalf,
faThermometerThreeQuarters,
faThermometerFull,
faAngleDoubleUp,
faChevronLeft,
faChevronRight
)
Vue.component('Icon', FontAwesomeIcon)
Vue.component('Swiper', Vue.extend(Swiper))
Vue.component('Slide', Vue.extend(Slide))
Vue.use(Loading.directive)
export default function (ctx, inject) {
inject('getHatValue', (count, hotConst = 1000) => {
@ -34,7 +82,10 @@ export default function (ctx, inject) {
})
inject('finishLoad', () => {
Array.prototype.forEach.call(document.querySelectorAll('pre code'), hljs.highlightBlock) // 代码高亮
Array.prototype.forEach.call(
document.querySelectorAll('pre code'),
hljs.highlightBlock
) // 代码高亮
document.getElementById('loading').style.display = 'none' // 隐藏Loading
})
}

View File

@ -1,3 +1,11 @@
#!/bin/bash
export NODE_OPTIONS=--openssl-legacy-provider
yarn run build
rsync -avr --delete-after --exclude ".git" . root@139.129.130.191:/root/site/blog-client && ssh root@139.129.130.191 'docker restart blog-client && docker restart blog-client1 && docker restart blog-client2 && docker restart blog-client3'
rsync -avr --delete-after --exclude ".git" --exclude "node_modules" . root@manage.wyr.me:/root/blog-client
ssh -t -t root@manage.wyr.me << remotessh
source /root/.bashrc
cd /root/blog-client
yarn && pm2 restart blog-client && exit
remotessh

View File

@ -8,12 +8,12 @@ const app = new Koa()
const config = require('../nuxt.config.js')
config.dev = !(app.env === 'production')
async function start() {
async function start () {
// Instantiate nuxt.js
const nuxt = new Nuxt(config)
const {
host = process.env.HOST || '127.0.0.1',
host = process.env.HOST || '0.0.0.0',
port = process.env.PORT || 3000
} = nuxt.options.server

BIN
static/.DS_Store vendored Normal file

Binary file not shown.

1
static/ads.txt Normal file
View File

@ -0,0 +1 @@
google.com, pub-2143583075951360, DIRECT, f08c47fec0942fa0

View File

@ -1 +1 @@
.allSpinner{position:fixed;top:0;left:0;z-index:999999;width:100%;height:100%;background-color:#fff}.spinner{position:fixed;top:50%;left:50%;z-index:9999999;margin:75pt auto 0;margin-top:-1pc;margin-left:-75px;width:150px;text-align:center}.spinner>div{display:inline-block;width:30px;height:30px;border-radius:100%;background-color:#67cf22;-webkit-animation:bouncedelay 1.4s infinite ease-in-out;animation:bouncedelay 1.4s infinite ease-in-out;-webkit-animation-fill-mode:both;animation-fill-mode:both}.spinner .bounce1{-webkit-animation-delay:-.32s;animation-delay:-.32s}.spinner .bounce2{-webkit-animation-delay:-.16s;animation-delay:-.16s}@-webkit-keyframes bouncedelay{0%,80%,to{-webkit-transform:scale(0)}40%{-webkit-transform:scale(1)}}@keyframes bouncedelay{0%,80%,to{-webkit-transform:scale(0);transform:scale(0)}40%{-webkit-transform:scale(1);transform:scale(1)}}
.allSpinner{position:fixed;top:0;left:0;z-index:999999;width:100%;height:100%;background-color:#fff}.spinner{position:fixed;top:50%;left:50%;z-index:9999999;margin:75pt auto 0;margin-top:-1pc;margin-left:-75px;width:150px;text-align:center}.spinner>div{display:inline-block;width:30px;height:30px;border-radius:100%;background-color:#272727;-webkit-animation:bouncedelay 1.4s infinite ease-in-out;animation:bouncedelay 1.4s infinite ease-in-out;-webkit-animation-fill-mode:both;animation-fill-mode:both}.spinner .bounce1{-webkit-animation-delay:-.32s;animation-delay:-.32s}.spinner .bounce2{-webkit-animation-delay:-.16s;animation-delay:-.16s}@-webkit-keyframes bouncedelay{0%,80%,to{-webkit-transform:scale(0)}40%{-webkit-transform:scale(1)}}@keyframes bouncedelay{0%,80%,to{-webkit-transform:scale(0);transform:scale(0)}40%{-webkit-transform:scale(1);transform:scale(1)}}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 42 KiB

View File

@ -7,10 +7,10 @@ export const state = () => ({
})
export const mutations = {
increment(state) {
increment (state) {
state.counter++
},
setLeftDatas(state, data) {
setLeftDatas (state, data) {
const NewComments = data[0]
const HotArticle = data[1]
const terms = data[2]
@ -41,7 +41,7 @@ export const mutations = {
}
export const actions = {
async nuxtServerInit({ state, commit }, { $axios }) {
async nuxtServerInit ({ state, commit }, { $axios }) {
if (state.tags.length === 0) {
try {
const datas = await Promise.all([

9237
yarn.lock

File diff suppressed because it is too large Load Diff