6.14
This commit is contained in:
parent
f255121dff
commit
952447ec70
@ -5,7 +5,7 @@
|
|||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
<title>墨思留痕</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<noscript>
|
<noscript>
|
||||||
|
26
src/App.vue
26
src/App.vue
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<main>
|
<main>
|
||||||
<router-view />
|
<router-view />
|
||||||
<trigger></trigger>
|
<trigger></trigger>
|
||||||
</main>
|
</main>
|
||||||
@ -13,8 +13,13 @@
|
|||||||
<script>
|
<script>
|
||||||
import trigger from '@/components/trigger.vue'
|
import trigger from '@/components/trigger.vue'
|
||||||
import basePage from './components/base.vue'
|
import basePage from './components/base.vue'
|
||||||
export default {
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
components: {
|
components: {
|
||||||
trigger,
|
trigger,
|
||||||
basePage
|
basePage
|
||||||
@ -23,22 +28,5 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
*{
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
/* 针对 WebKit 浏览器 */
|
|
||||||
::-webkit-scrollbar {
|
|
||||||
width: 5px; /* 滚动条宽度 */
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb {
|
|
||||||
background: #2ee600; /* 滑块颜色 */
|
|
||||||
border-radius: 10px; /* 滑块圆角 */
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar-track {
|
|
||||||
background: #f1f1f1ef; /* 轨道颜色 */
|
|
||||||
border-radius: 10px; /* 轨道圆角 */
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
9
src/api/interlinkage.js
Normal file
9
src/api/interlinkage.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import request from '../utils/request'
|
||||||
|
|
||||||
|
export function interList (data) {
|
||||||
|
return request({
|
||||||
|
url: '/interList',
|
||||||
|
method: 'get',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
@ -7,3 +7,11 @@ export function login (data) {
|
|||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function autoLogin (token) {
|
||||||
|
return request({
|
||||||
|
url: '/auto-login',
|
||||||
|
method: 'post',
|
||||||
|
data: { token }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 18 KiB |
@ -1,14 +1,35 @@
|
|||||||
*{
|
* {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
}
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
body{
|
|
||||||
background-color: #eeeeee;
|
/* 针对 WebKit 浏览器 */
|
||||||
}
|
::-webkit-scrollbar {
|
||||||
|
width: 5px;
|
||||||
a {
|
/* 滚动条宽度 */
|
||||||
text-decoration: inherit;
|
}
|
||||||
color: inherit;
|
|
||||||
}
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: #2ee600;
|
||||||
|
/* 滑块颜色 */
|
||||||
|
border-radius: 10px;
|
||||||
|
/* 滑块圆角 */
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background: #f1f1f1ef;
|
||||||
|
/* 轨道颜色 */
|
||||||
|
border-radius: 10px;
|
||||||
|
/* 轨道圆角 */
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: #eeeeee;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: inherit;
|
||||||
|
color: inherit;
|
||||||
|
}
|
@ -80,6 +80,13 @@ export default {
|
|||||||
return this.playlist[this.currentSongIndex]
|
return this.playlist[this.currentSongIndex]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
mounted () {
|
||||||
|
// 检查 localStorage 中的锁定状态
|
||||||
|
const savedLockState = localStorage.getItem('isLocked')
|
||||||
|
if (savedLockState !== null) {
|
||||||
|
this.isLocked = JSON.parse(savedLockState)
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
searchMusic () {
|
searchMusic () {
|
||||||
// 实现音乐搜索功能
|
// 实现音乐搜索功能
|
||||||
@ -93,8 +100,7 @@ export default {
|
|||||||
},
|
},
|
||||||
prevSong () {
|
prevSong () {
|
||||||
this.currentSongIndex =
|
this.currentSongIndex =
|
||||||
(this.currentSongIndex - 1 + this.playlist.length) %
|
(this.currentSongIndex - 1 + this.playlist.length) % this.playlist.length
|
||||||
this.playlist.length
|
|
||||||
this.isPlaying = true // 切换歌曲时自动播放
|
this.isPlaying = true // 切换歌曲时自动播放
|
||||||
},
|
},
|
||||||
nextSong () {
|
nextSong () {
|
||||||
@ -104,6 +110,8 @@ export default {
|
|||||||
},
|
},
|
||||||
toggleLock () {
|
toggleLock () {
|
||||||
this.isLocked = !this.isLocked
|
this.isLocked = !this.isLocked
|
||||||
|
// 将锁定状态保存到 localStorage
|
||||||
|
localStorage.setItem('isLocked', JSON.stringify(this.isLocked))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,9 +102,10 @@ export default {
|
|||||||
},
|
},
|
||||||
// 退出
|
// 退出
|
||||||
handleOut () {
|
handleOut () {
|
||||||
this.$router.push({ path: '/login' })
|
localStorage.removeItem('token')
|
||||||
|
this.$router.push('/login')
|
||||||
this.$message({
|
this.$message({
|
||||||
message: '退出成功',
|
message: '您已退出',
|
||||||
type: 'success'
|
type: 'success'
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
0
src/components/quillEditor.vue
Normal file
0
src/components/quillEditor.vue
Normal file
@ -12,6 +12,8 @@ Vue.use(ElementUI)
|
|||||||
Vue.component('navigationBar', navigationBar)
|
Vue.component('navigationBar', navigationBar)
|
||||||
Vue.component('musIc', music)
|
Vue.component('musIc', music)
|
||||||
|
|
||||||
|
document.title = '墨思留痕'
|
||||||
|
|
||||||
Vue.config.productionTip = false
|
Vue.config.productionTip = false
|
||||||
|
|
||||||
new Vue({
|
new Vue({
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
import { Message } from 'element-ui'
|
||||||
|
import router from '../router'
|
||||||
|
|
||||||
// 创建一个 axios 实例
|
// 创建一个 axios 实例
|
||||||
const service = axios.create({
|
const service = axios.create({
|
||||||
@ -9,27 +11,29 @@ const service = axios.create({
|
|||||||
// 请求拦截器
|
// 请求拦截器
|
||||||
service.interceptors.request.use(
|
service.interceptors.request.use(
|
||||||
config => {
|
config => {
|
||||||
// 从 localStorage 中获取 token
|
const token = localStorage.getItem('token')
|
||||||
const token = localStorage.getItem('user-token')
|
|
||||||
if (token) {
|
if (token) {
|
||||||
// 将 token 添加到请求头中
|
|
||||||
config.headers.Authorization = `Bearer ${token}`
|
config.headers.Authorization = `Bearer ${token}`
|
||||||
}
|
}
|
||||||
return config
|
return config
|
||||||
},
|
},
|
||||||
error => {
|
error => {
|
||||||
// 对请求错误做些什么
|
|
||||||
return Promise.reject(error)
|
return Promise.reject(error)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// 响应拦截器
|
|
||||||
service.interceptors.response.use(
|
service.interceptors.response.use(
|
||||||
response => {
|
response => {
|
||||||
// 对响应数据做点什么
|
|
||||||
return response
|
return response
|
||||||
},
|
},
|
||||||
error => {
|
error => {
|
||||||
|
if (error.response && error.response.status === 401) {
|
||||||
|
Message.error('认证已过期,请重新登录')
|
||||||
|
localStorage.removeItem('token')
|
||||||
|
router.push('/login')
|
||||||
|
} else {
|
||||||
|
Message.error(error.message)
|
||||||
|
}
|
||||||
return Promise.reject(error)
|
return Promise.reject(error)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
<navigationBar />
|
<navigationBar />
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<el-tabs type="border-card">
|
<el-tabs type="border-card">
|
||||||
|
|
||||||
<el-tab-pane label="个人信息">
|
<el-tab-pane label="个人信息">
|
||||||
<div class="AboutUs-left">
|
<div class="AboutUs-left">
|
||||||
<div class="AboutUs-img">
|
<div class="AboutUs-img">
|
||||||
@ -117,8 +116,27 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
|
|
||||||
|
<!-- 头像上传 -->
|
||||||
|
<el-dialog title="更换头像" :visible.sync="dialogVisible" width="30%">
|
||||||
|
<el-upload
|
||||||
|
class="avatar-uploader"
|
||||||
|
action="https://jsonplaceholder.typicode.com/posts/"
|
||||||
|
:show-file-list="false"
|
||||||
|
:on-success="handleAvatarSuccess"
|
||||||
|
:before-upload="beforeAvatarUpload"
|
||||||
|
>
|
||||||
|
<img v-if="imageUrl" :src="imageUrl" class="avatar" />
|
||||||
|
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
|
||||||
|
</el-upload>
|
||||||
|
<span slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
<el-button type="primary" @click="handleAddAvatar"
|
||||||
|
>确 定</el-button
|
||||||
|
>
|
||||||
|
</span>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<musIc />
|
<musIc />
|
||||||
@ -139,6 +157,8 @@ export default {
|
|||||||
birthday: '',
|
birthday: '',
|
||||||
region: '',
|
region: '',
|
||||||
city: '',
|
city: '',
|
||||||
|
dialogVisible: false,
|
||||||
|
imageUrl: '',
|
||||||
avatar: require('@/assets/images/789.jpg'), // 默认头像地址
|
avatar: require('@/assets/images/789.jpg'), // 默认头像地址
|
||||||
users: [
|
users: [
|
||||||
{
|
{
|
||||||
@ -163,10 +183,6 @@ export default {
|
|||||||
// 保存用户信息的逻辑
|
// 保存用户信息的逻辑
|
||||||
this.$message.success('保存成功')
|
this.$message.success('保存成功')
|
||||||
},
|
},
|
||||||
changeAvatar () {
|
|
||||||
// 更换头像的逻辑
|
|
||||||
this.$message.success('更换成功')
|
|
||||||
},
|
|
||||||
// 添加按钮
|
// 添加按钮
|
||||||
handleAdd () {
|
handleAdd () {
|
||||||
if (this.newTodo.trim() !== '') {
|
if (this.newTodo.trim() !== '') {
|
||||||
@ -190,6 +206,32 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
this.$message.error('请选择要删除的待办事项')
|
this.$message.error('请选择要删除的待办事项')
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
changeAvatar () {
|
||||||
|
// 更换头像的逻辑
|
||||||
|
this.dialogVisible = true
|
||||||
|
},
|
||||||
|
handleAvatarSuccess (res, file) {
|
||||||
|
this.imageUrl = URL.createObjectURL(file.raw)
|
||||||
|
},
|
||||||
|
beforeAvatarUpload (file) {
|
||||||
|
const isJPG = file.type === 'image/jpeg'
|
||||||
|
const isLt2M = file.size / 1024 / 1024 < 2
|
||||||
|
|
||||||
|
if (!isJPG) {
|
||||||
|
this.$message.error('上传头像图片只能是 JPG 格式!')
|
||||||
|
}
|
||||||
|
if (!isLt2M) {
|
||||||
|
this.$message.error('上传头像图片大小不能超过 2MB!')
|
||||||
|
}
|
||||||
|
return isJPG && isLt2M
|
||||||
|
},
|
||||||
|
handleAddAvatar () {
|
||||||
|
this.$message({
|
||||||
|
message: '上传成功',
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
this.dialogVisible = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -197,7 +239,7 @@ export default {
|
|||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.wtbDone {
|
.wtbDone {
|
||||||
width: 400px;
|
width: 700px;
|
||||||
height: 500px;
|
height: 500px;
|
||||||
border: 1px solid black;
|
border: 1px solid black;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
@ -207,7 +249,7 @@ export default {
|
|||||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
|
||||||
input {
|
input {
|
||||||
width: 300px;
|
width: 550px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
@ -219,61 +261,61 @@ export default {
|
|||||||
border: 1px solid #007bff;
|
border: 1px solid #007bff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
width: 350px;
|
width: 600px;
|
||||||
height: 310px;
|
height: 310px;
|
||||||
margin: 20px auto;
|
margin: 20px auto;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
border: 1px solid #ddd;
|
border: 1px solid #ddd;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
|
||||||
li {
|
li {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 40px;
|
|
||||||
line-height: 40px;
|
|
||||||
text-align: center;
|
|
||||||
background-color: #f5f5f5;
|
|
||||||
border-bottom: 1px solid #ddd;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: background-color 0.3s;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: #e6e6e6;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.selected {
|
|
||||||
background-color: #d3e5ff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.wtbDone-footer {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
margin-top: 20px;
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
width: 70px;
|
|
||||||
height: 40px;
|
height: 40px;
|
||||||
background-color: #007bff;
|
line-height: 40px;
|
||||||
color: #fff;
|
text-align: center;
|
||||||
border: none;
|
background-color: #f5f5f5;
|
||||||
border-radius: 4px;
|
border-bottom: 1px solid #ddd;
|
||||||
margin-left: 5px;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: background-color 0.3s;
|
transition: background-color 0.3s;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: #0056b3;
|
background-color: #e6e6e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.selected {
|
||||||
|
background-color: #d3e5ff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.wtbDone-footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 20px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
width: 120px;
|
||||||
|
height: 40px;
|
||||||
|
background-color: #007bff;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-left: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.box {
|
.box {
|
||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
@ -445,4 +487,28 @@ hr {
|
|||||||
background-color: #218838;
|
background-color: #218838;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.avatar-uploader .el-upload {
|
||||||
|
border: 1px dashed #d9d9d9;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.avatar-uploader .el-upload:hover {
|
||||||
|
border-color: #409eff;
|
||||||
|
}
|
||||||
|
.avatar-uploader-icon {
|
||||||
|
font-size: 28px;
|
||||||
|
color: #8c939d;
|
||||||
|
width: 178px;
|
||||||
|
height: 178px;
|
||||||
|
line-height: 178px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.avatar {
|
||||||
|
width: 178px;
|
||||||
|
height: 178px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -17,65 +17,23 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { interList } from '@/api/interlinkage'
|
||||||
export default {
|
export default {
|
||||||
name: 'interLinkage',
|
name: 'interLinkage',
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
contentList: [
|
contentList: []
|
||||||
{
|
|
||||||
img: require('@/assets/images/kecheng/C.jpg'),
|
|
||||||
name: '百度一下,你就知道',
|
|
||||||
url: 'http://www.baidu.com'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: require('@/assets/images/kecheng/C.jpg'),
|
|
||||||
name: '4399小游戏',
|
|
||||||
url: 'http://www.4399.com'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: require('@/assets/images/kecheng/C.jpg'),
|
|
||||||
name: '百度一下,你就知道',
|
|
||||||
url: 'http://www.baidu.com'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: require('@/assets/images/kecheng/C.jpg'),
|
|
||||||
name: '4399小游戏',
|
|
||||||
url: 'http://www.4399.com'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: require('@/assets/images/kecheng/C.jpg'),
|
|
||||||
name: '百度一下,你就知道',
|
|
||||||
url: 'http://www.baidu.com'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: require('@/assets/images/kecheng/C.jpg'),
|
|
||||||
name: '4399小游戏',
|
|
||||||
url: 'http://www.4399.com'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: require('@/assets/images/kecheng/C.jpg'),
|
|
||||||
name: '百度一下,你就知道',
|
|
||||||
url: 'http://www.baidu.com'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: require('@/assets/images/kecheng/C.jpg'),
|
|
||||||
name: '4399小游戏',
|
|
||||||
url: 'http://www.4399.com'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: require('@/assets/images/kecheng/C.jpg'),
|
|
||||||
name: '百度一下,你就知道',
|
|
||||||
url: 'http://www.baidu.com'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: require('@/assets/images/kecheng/C.jpg'),
|
|
||||||
name: '4399小游戏',
|
|
||||||
url: 'http://www.4399.com'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
created () {
|
||||||
|
this.getList()
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
getList () {
|
||||||
|
interList().then(res => {
|
||||||
|
this.contentList = res.data
|
||||||
|
})
|
||||||
|
},
|
||||||
goLink (url) {
|
goLink (url) {
|
||||||
window.open(url)
|
window.open(url)
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,9 @@
|
|||||||
</header>
|
</header>
|
||||||
<div class="box-bd">
|
<div class="box-bd">
|
||||||
<ul class="clearfix">
|
<ul class="clearfix">
|
||||||
<li v-for="(item, index) in items" :key="index" >
|
<li v-for="(item, index) in items" :key="index">
|
||||||
<router-link :to="`/paiListPage/${index + 1}`"> <!-- 这里的index + 1对应着表的序号 -->
|
<router-link :to="`/paiListPage/${index + 1}`">
|
||||||
|
<!-- 这里的index + 1对应着表的序号 -->
|
||||||
<img :src="item.url" :alt="item.title" />
|
<img :src="item.url" :alt="item.title" />
|
||||||
<h4>{{ item.title }}</h4>
|
<h4>{{ item.title }}</h4>
|
||||||
</router-link>
|
</router-link>
|
||||||
@ -25,7 +26,19 @@
|
|||||||
<button @click="openDialog">添加笔记</button>
|
<button @click="openDialog">添加笔记</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 其他代码 -->
|
<!-- 添加笔记弹窗 -->
|
||||||
|
<el-dialog title="提示" :visible.sync="dialogVisible" width="30%">
|
||||||
|
<el-form ref="form" :model="form" label-width="80px" :rules="rules">
|
||||||
|
<el-form-item label="笔记标题" prop="addContent">
|
||||||
|
<el-input v-model="form.addContent"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<span slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
<el-button type="primary" @click="handleAdd">确 定</el-button>
|
||||||
|
</span>
|
||||||
|
</el-dialog>
|
||||||
<musIc />
|
<musIc />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -35,14 +48,11 @@ import { getTags } from '@/api/tags'
|
|||||||
export default {
|
export default {
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
items: [
|
items: [],
|
||||||
|
|
||||||
],
|
|
||||||
drawer: false,
|
|
||||||
direction: 'ltr',
|
|
||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
form: {},
|
form: {
|
||||||
addContent: '',
|
addContent: ''
|
||||||
|
},
|
||||||
rules: {
|
rules: {
|
||||||
addContent: [
|
addContent: [
|
||||||
{ required: true, message: '请输入标题', trigger: 'blur' }
|
{ required: true, message: '请输入标题', trigger: 'blur' }
|
||||||
@ -55,7 +65,7 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
fetchTags () {
|
fetchTags () {
|
||||||
getTags().then(res => {
|
getTags().then((res) => {
|
||||||
this.items = res.data
|
this.items = res.data
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@ -63,17 +73,12 @@ export default {
|
|||||||
this.dialogVisible = true
|
this.dialogVisible = true
|
||||||
},
|
},
|
||||||
handleAdd () {
|
handleAdd () {
|
||||||
this.$refs.form.validate((valid) => {
|
this.dialogVisible = false
|
||||||
if (valid) {
|
this.$message({
|
||||||
this.$message({
|
message: '添加成功',
|
||||||
message: '添加成功',
|
type: 'success'
|
||||||
type: 'success'
|
|
||||||
})
|
|
||||||
this.dialogVisible = false
|
|
||||||
} else {
|
|
||||||
this.$message.error('请检查输入项')
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
this.form.addContent = ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="tool">
|
<div class="tool">
|
||||||
<div>
|
<div>
|
||||||
<el-checkbox v-model="checked" @change="remenber" v-if="!create"
|
<el-checkbox v-model="checked" @change="remember" v-if="!create"
|
||||||
>记住密码</el-checkbox
|
>记住密码</el-checkbox
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@ -56,7 +56,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { login } from '@/api/login' // 导入登录请求的方法
|
import { login, autoLogin } from '@/api/login'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -91,33 +91,110 @@ export default {
|
|||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
this.postDate = dayjs().format('HH : mm : ss')
|
this.postDate = dayjs().format('HH : mm : ss')
|
||||||
}, 1000)
|
}, 1000)
|
||||||
|
|
||||||
|
this.loadRememberedCredentials()
|
||||||
|
|
||||||
|
// 尝试自动登录
|
||||||
|
const token = localStorage.getItem('token')
|
||||||
|
if (token) {
|
||||||
|
this.autoLogin(token)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
login () {
|
loadRememberedCredentials () {
|
||||||
// 调用后端登录接口
|
const rememberedUsername = localStorage.getItem('rememberedUsername')
|
||||||
login(this.form).then(response => {
|
const rememberedPassword = localStorage.getItem('rememberedPassword')
|
||||||
// 登录成功的处理逻辑
|
const rememberMeChecked = localStorage.getItem('rememberMeChecked')
|
||||||
console.log(response) // 假设登录成功后返回的数据中包含用户信息
|
|
||||||
this.$router.push('/')
|
if (rememberedUsername && rememberedPassword && rememberMeChecked) {
|
||||||
|
this.form.username = rememberedUsername
|
||||||
|
this.form.password = rememberedPassword
|
||||||
|
this.checked = JSON.parse(rememberMeChecked)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
autoLogin (token) {
|
||||||
|
autoLogin(token).then(response => {
|
||||||
|
console.log(response)
|
||||||
|
if (this.$route.path !== '/') {
|
||||||
|
this.$router.push('/')
|
||||||
|
}
|
||||||
this.$message({
|
this.$message({
|
||||||
message: '登陆成功',
|
message: '自动登录成功',
|
||||||
type: 'success'
|
type: 'success'
|
||||||
})
|
})
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
// 登录失败的处理逻辑
|
console.error('自动登录失败:', error)
|
||||||
console.error('登录失败:', error)
|
localStorage.removeItem('token')
|
||||||
this.$message({
|
this.$message({
|
||||||
message: '登录失败,请检查账号或密码',
|
message: '自动登录失败,请重新登录',
|
||||||
type: 'error'
|
type: 'error'
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
remenber (data) {
|
login () {
|
||||||
this.checked = data
|
if (this.form.username === '' || this.form.password === '') {
|
||||||
if (this.checked) {
|
this.$message({
|
||||||
localStorage.setItem('news', JSON.stringify(this.form))
|
message: '账号或密码不能为空',
|
||||||
|
type: 'error'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 登录验证
|
||||||
|
if (!this.create) {
|
||||||
|
login({ ...this.form }).then(response => {
|
||||||
|
console.log(response)
|
||||||
|
localStorage.setItem('token', response.data.token)
|
||||||
|
if (this.checked) {
|
||||||
|
localStorage.setItem('rememberedUsername', this.form.username)
|
||||||
|
localStorage.setItem('rememberedPassword', this.form.password)
|
||||||
|
localStorage.setItem('rememberMeChecked', true)
|
||||||
|
} else {
|
||||||
|
localStorage.removeItem('rememberedUsername')
|
||||||
|
localStorage.removeItem('rememberedPassword')
|
||||||
|
localStorage.removeItem('rememberMeChecked')
|
||||||
|
}
|
||||||
|
if (this.$route.path !== '/') {
|
||||||
|
this.$router.push('/')
|
||||||
|
}
|
||||||
|
this.$message({
|
||||||
|
message: '登陆成功',
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('登录失败:', error)
|
||||||
|
if (error.response && error.response.status === 401) {
|
||||||
|
this.$message({
|
||||||
|
message: '账号或密码错误',
|
||||||
|
type: 'error'
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.$message({
|
||||||
|
message: '服务器错误,请稍后再试',
|
||||||
|
type: 'error'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
localStorage.removeItem('news')
|
this.$message({
|
||||||
|
message: '暂未开放注册,请联系管理员',
|
||||||
|
type: 'warning'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
remember () {
|
||||||
|
if (this.checked) {
|
||||||
|
this.$message({
|
||||||
|
message: '将会记住您的登录信息',
|
||||||
|
type: 'info'
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
localStorage.removeItem('rememberedUsername')
|
||||||
|
localStorage.removeItem('rememberedPassword')
|
||||||
|
localStorage.removeItem('rememberMeChecked')
|
||||||
|
this.$message({
|
||||||
|
message: '已取消记住密码',
|
||||||
|
type: 'info'
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
forgetpas () {
|
forgetpas () {
|
||||||
@ -128,22 +205,19 @@ export default {
|
|||||||
},
|
},
|
||||||
register () {
|
register () {
|
||||||
if (this.create) {
|
if (this.create) {
|
||||||
window.location.reload()
|
// 从注册页面返回登录页面时保留内容
|
||||||
} else if (
|
this.create = false
|
||||||
this.form.username ||
|
this.loadRememberedCredentials()
|
||||||
this.form.password ||
|
} else {
|
||||||
this.form.repassword
|
// 从登录页面进入注册页面时清空内容
|
||||||
) {
|
this.create = true
|
||||||
// 从登录切换到注册清空表单内容
|
|
||||||
this.form.username = ''
|
this.form.username = ''
|
||||||
this.form.password = ''
|
this.form.password = ''
|
||||||
this.form.repassword = ''
|
this.form.repassword = ''
|
||||||
|
this.$refs.form.clearValidate('username')
|
||||||
|
this.$refs.form.clearValidate('password')
|
||||||
|
this.$refs.form.clearValidate('repassword')
|
||||||
}
|
}
|
||||||
this.create = !this.create
|
|
||||||
// 清除字段的验证错误
|
|
||||||
this.$refs.form.clearValidate('username')
|
|
||||||
this.$refs.form.clearValidate('password')
|
|
||||||
this.$refs.form.clearValidate('repassword')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -180,7 +254,7 @@ export default {
|
|||||||
/* 左侧阴影 */ 5px -5px 10px rgba(0, 0, 0, 0.1),
|
/* 左侧阴影 */ 5px -5px 10px rgba(0, 0, 0, 0.1),
|
||||||
/* 下部阴影 */ -5px -5px 10px rgba(0, 0, 0, 0.1); /* 上部阴影 */
|
/* 下部阴影 */ -5px -5px 10px rgba(0, 0, 0, 0.1); /* 上部阴影 */
|
||||||
width: 400px;
|
width: 400px;
|
||||||
height: 300px;
|
height: 350px;
|
||||||
padding: 30px;
|
padding: 30px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
transform: translate(-50%);
|
transform: translate(-50%);
|
||||||
|
@ -23,16 +23,26 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="gallery">
|
<div class="gallery">
|
||||||
|
<div class="pointer" :style="pointerStyle"></div>
|
||||||
<div
|
<div
|
||||||
class="gallery-item"
|
class="gallery-item"
|
||||||
v-for="(item, index) in photos"
|
v-for="(item, index) in photos"
|
||||||
:key="index"
|
:key="index"
|
||||||
:class="item.sizeClass"
|
:class="item.sizeClass"
|
||||||
|
@mouseover="onMouseOver($event, item.sizeClass)"
|
||||||
|
@mouseleave="onMouseLeave"
|
||||||
|
@click="openImageViewer(item.src)"
|
||||||
ref="photoItems"
|
ref="photoItems"
|
||||||
>
|
>
|
||||||
<img :data-src="item.src" :alt="item.alt" class="lazy" />
|
<img :data-src="item.src" :alt="item.alt" class="lazy" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="showImageViewer" class="image-viewer" @click.self="closeImageViewer">
|
||||||
|
<div class="image-viewer-content">
|
||||||
|
<span class="close" @click="closeImageViewer">×</span>
|
||||||
|
<img :src="currentImage" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<musIc />
|
<musIc />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -42,6 +52,7 @@ export default {
|
|||||||
name: 'photoGallery',
|
name: 'photoGallery',
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
// 初始照片列表
|
||||||
photos: [
|
photos: [
|
||||||
{ src: require('@/assets/images/789.jpg'), alt: 'Photo 1', sizeClass: 'medium' },
|
{ src: require('@/assets/images/789.jpg'), alt: 'Photo 1', sizeClass: 'medium' },
|
||||||
{ src: require('@/assets/images/789.jpg'), alt: 'Photo 2', sizeClass: 'large' },
|
{ src: require('@/assets/images/789.jpg'), alt: 'Photo 2', sizeClass: 'large' },
|
||||||
@ -72,42 +83,56 @@ export default {
|
|||||||
{ src: require('@/assets/images/789.jpg'), alt: 'Photo 27', sizeClass: 'small' }
|
{ src: require('@/assets/images/789.jpg'), alt: 'Photo 27', sizeClass: 'small' }
|
||||||
],
|
],
|
||||||
newPhoto: {
|
newPhoto: {
|
||||||
src: '',
|
src: '', // 新照片的URL
|
||||||
alt: ''
|
alt: '' // 新照片的描述
|
||||||
},
|
},
|
||||||
newPhotoFile: null,
|
newPhotoFile: null, // 新照片的文件对象
|
||||||
showModal: false
|
showModal: false, // 控制上传照片模态框的显示
|
||||||
|
showImageViewer: false, // 控制图片查看器的显示
|
||||||
|
currentImage: '', // 当前显示的大图的URL
|
||||||
|
pointerStyle: {
|
||||||
|
display: 'none', // 控制边框指示器的显示
|
||||||
|
top: '0px',
|
||||||
|
left: '0px',
|
||||||
|
width: '0px',
|
||||||
|
height: '0px',
|
||||||
|
borderColor: '' // 边框指示器的颜色
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
// 加载图片方法
|
||||||
loadImages () {
|
loadImages () {
|
||||||
const images = this.$refs.photoItems
|
const images = this.$refs.photoItems // 获取所有照片项的引用
|
||||||
const options = {
|
const options = {
|
||||||
root: null,
|
root: null,
|
||||||
rootMargin: '0px',
|
rootMargin: '0px',
|
||||||
threshold: 0.1
|
threshold: 0.1 // 触发观察器的阈值
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 创建IntersectionObserver对象
|
||||||
const observer = new IntersectionObserver((entries, observer) => {
|
const observer = new IntersectionObserver((entries, observer) => {
|
||||||
entries.forEach(entry => {
|
entries.forEach(entry => {
|
||||||
if (entry.isIntersecting) {
|
if (entry.isIntersecting) {
|
||||||
const img = entry.target.querySelector('img')
|
const img = entry.target.querySelector('img')
|
||||||
img.src = img.getAttribute('data-src')
|
img.src = img.getAttribute('data-src') // 加载图片
|
||||||
observer.unobserve(entry.target)
|
observer.unobserve(entry.target) // 停止观察已加载的图片
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}, options)
|
}, options)
|
||||||
|
|
||||||
images.forEach(image => {
|
images.forEach(image => {
|
||||||
observer.observe(image)
|
observer.observe(image) // 观察每个图片项
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
// 处理文件变化
|
||||||
onFileChange (e) {
|
onFileChange (e) {
|
||||||
const file = e.target.files[0]
|
const file = e.target.files[0]
|
||||||
if (file) {
|
if (file) {
|
||||||
this.newPhotoFile = URL.createObjectURL(file)
|
this.newPhotoFile = URL.createObjectURL(file) // 创建文件的临时URL
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// 添加新照片
|
||||||
addPhoto () {
|
addPhoto () {
|
||||||
if (this.newPhotoFile && this.newPhoto.alt) {
|
if (this.newPhotoFile && this.newPhoto.alt) {
|
||||||
const sizeClasses = ['small', 'medium', 'large']
|
const sizeClasses = ['small', 'medium', 'large']
|
||||||
@ -117,24 +142,61 @@ export default {
|
|||||||
alt: this.newPhoto.alt,
|
alt: this.newPhoto.alt,
|
||||||
sizeClass: sizeClass
|
sizeClass: sizeClass
|
||||||
})
|
})
|
||||||
this.newPhotoFile = null
|
this.newPhotoFile = null // 清空文件对象
|
||||||
this.newPhoto.alt = ''
|
this.newPhoto.alt = '' // 清空描述
|
||||||
this.showModal = false
|
this.showModal = false // 关闭模态框
|
||||||
document.body.classList.remove('no-scroll')
|
document.body.classList.remove('no-scroll') // 恢复页面滚动
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.loadImages()
|
this.loadImages() // 重新加载图片
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// 打开模态框
|
||||||
openModal () {
|
openModal () {
|
||||||
this.showModal = true
|
this.showModal = true
|
||||||
document.body.classList.add('no-scroll')
|
document.body.classList.add('no-scroll') // 禁用页面滚动
|
||||||
},
|
},
|
||||||
|
// 关闭模态框
|
||||||
closeModal () {
|
closeModal () {
|
||||||
this.showModal = false
|
this.showModal = false
|
||||||
document.body.classList.remove('no-scroll')
|
document.body.classList.remove('no-scroll') // 恢复页面滚动
|
||||||
|
},
|
||||||
|
// 打开图片查看器
|
||||||
|
openImageViewer (src) {
|
||||||
|
this.currentImage = src
|
||||||
|
this.showImageViewer = true
|
||||||
|
document.body.classList.add('no-scroll') // 禁用页面滚动
|
||||||
|
},
|
||||||
|
// 关闭图片查看器
|
||||||
|
closeImageViewer () {
|
||||||
|
this.showImageViewer = false
|
||||||
|
document.body.classList.remove('no-scroll') // 恢复页面滚动
|
||||||
|
},
|
||||||
|
// 鼠标悬停时显示边框指示器
|
||||||
|
onMouseOver (event, sizeClass) {
|
||||||
|
const galleryItem = event.currentTarget
|
||||||
|
const rect = galleryItem.getBoundingClientRect()
|
||||||
|
const scrollTop = window.pageYOffset || document.documentElement.scrollTop
|
||||||
|
const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft
|
||||||
|
|
||||||
|
// 生成随机颜色
|
||||||
|
const randomColor = '#' + Math.floor(Math.random() * 16777215).toString(16)
|
||||||
|
|
||||||
|
this.pointerStyle = {
|
||||||
|
display: 'block',
|
||||||
|
top: `${rect.top + scrollTop - 85}px`,
|
||||||
|
left: `${rect.left + scrollLeft - 205}px`,
|
||||||
|
width: `${rect.width + 30}px`,
|
||||||
|
height: `${rect.height + 30}px`,
|
||||||
|
borderColor: randomColor // 设置随机颜色
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 鼠标离开时隐藏边框指示器
|
||||||
|
onMouseLeave () {
|
||||||
|
this.pointerStyle.display = 'none'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// 组件挂载后加载图片
|
||||||
mounted () {
|
mounted () {
|
||||||
this.loadImages()
|
this.loadImages()
|
||||||
}
|
}
|
||||||
@ -184,6 +246,7 @@ header {
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
z-index: 10000; /* Ensure modal is on top */
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-content {
|
.modal-content {
|
||||||
@ -194,6 +257,7 @@ header {
|
|||||||
width: 400px;
|
width: 400px;
|
||||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||||
animation: fadeIn 0.3s;
|
animation: fadeIn 0.3s;
|
||||||
|
z-index: 10001; /* Ensure modal content is on top */
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes fadeIn {
|
@keyframes fadeIn {
|
||||||
@ -257,6 +321,12 @@ button:hover {
|
|||||||
.gallery {
|
.gallery {
|
||||||
column-count: 4;
|
column-count: 4;
|
||||||
column-gap: 16px;
|
column-gap: 16px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pointer {
|
||||||
|
position: absolute;
|
||||||
|
border: 2px solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gallery-item {
|
.gallery-item {
|
||||||
@ -270,7 +340,7 @@ button:hover {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.gallery-item:hover {
|
.gallery-item:hover {
|
||||||
transform: translateY(-5px);
|
transform: scale(1.05);
|
||||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,4 +361,39 @@ button:hover {
|
|||||||
.gallery-item.large img {
|
.gallery-item.large img {
|
||||||
height: 250px;
|
height: 250px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.image-viewer {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: rgba(0, 0, 0, 0.8);
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
z-index: 10000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-viewer-content {
|
||||||
|
position: relative;
|
||||||
|
max-width: 95%;
|
||||||
|
max-height: 95%;
|
||||||
|
z-index: 10001;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-viewer img {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-viewer .close {
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
right: 10px;
|
||||||
|
font-size: 20px;
|
||||||
|
color: white;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -9,9 +9,7 @@
|
|||||||
</path>
|
</path>
|
||||||
</svg>
|
</svg>
|
||||||
<div class="ana">
|
<div class="ana">
|
||||||
<p>
|
<p>{{ user }}</p>
|
||||||
{{ user }}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="article" v-for="(item, index) in articleS" :key="index">
|
<div class="article" v-for="(item, index) in articleS" :key="index">
|
||||||
@ -27,15 +25,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-pagination
|
<el-pagination
|
||||||
background
|
background
|
||||||
layout="prev, pager, next"
|
layout="prev, pager, next"
|
||||||
:total="total"
|
:total="total"
|
||||||
style="margin: 10px auto; width: 80%; text-align: center"
|
style="margin: 10px auto; width: 80%; text-align: center"
|
||||||
prev-text="上一页"
|
prev-text="上一页"
|
||||||
next-text="下一页"
|
next-text="下一页"
|
||||||
hide-on-single-page
|
hide-on-single-page
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<musIc />
|
<musIc />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -45,40 +42,66 @@ import { getSubject } from '@/api/subject'
|
|||||||
import { fetchUser } from '@/api/dailySentence'
|
import { fetchUser } from '@/api/dailySentence'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'subJect',
|
name: 'Subject',
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
articleS: [],
|
articleS: [],
|
||||||
total: 0,
|
total: 0,
|
||||||
user: ''
|
user: '',
|
||||||
|
lastUpdateTime: localStorage.getItem('lastUpdateTime') || null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created () {
|
created () {
|
||||||
this.getList()
|
this.checkAndFetchUser() // 检查并获取用户内容
|
||||||
// 页面加载时,从本地存储获取用户内容
|
this.getList() // 获取文章列表
|
||||||
this.user = localStorage.getItem('userContent') || ''
|
|
||||||
// 每天早上8点获取用户内容
|
// 每天早上8点获取用户内容
|
||||||
setInterval(() => {
|
const now = new Date()
|
||||||
this.fetchUser()
|
const nextUpdate = new Date()
|
||||||
}, 1000 * 60 * 60 * 24) // 每24小时重复执行一次
|
nextUpdate.setHours(8, 0, 0, 0) // 设置到今天8点
|
||||||
|
if (now > nextUpdate) {
|
||||||
|
nextUpdate.setDate(nextUpdate.getDate() + 1) // 如果现在已经过了8点,设置到明天8点
|
||||||
|
}
|
||||||
|
const timeToNextUpdate = nextUpdate - now
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
this.fetchUser() // 立即获取一次用户内容
|
||||||
|
setInterval(() => {
|
||||||
|
this.fetchUser()
|
||||||
|
}, 1000 * 60 * 60 * 24) // 每24小时重复执行一次
|
||||||
|
}, timeToNextUpdate)
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getList () {
|
getList () {
|
||||||
getSubject().then(res => {
|
getSubject().then(res => {
|
||||||
this.articleS = res.data
|
this.articleS = res.data
|
||||||
this.total = res.data.length
|
this.total = res.data.length
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('获取文章列表失败:', error)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
fetchUser () {
|
fetchUser () {
|
||||||
fetchUser()
|
fetchUser()
|
||||||
.then(response => {
|
.then(response => {
|
||||||
this.user = response.data.result.content
|
this.user = response.data.result.content
|
||||||
// 将用户内容存储在本地存储中
|
// 将用户内容和更新时间存储在本地存储中
|
||||||
localStorage.setItem('userContent', this.user)
|
localStorage.setItem('userContent', this.user)
|
||||||
|
localStorage.setItem('lastUpdateTime', new Date().toISOString())
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.log(error)
|
console.error('获取用户内容失败:', error)
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
checkAndFetchUser () {
|
||||||
|
const lastUpdate = new Date(this.lastUpdateTime)
|
||||||
|
const now = new Date()
|
||||||
|
const oneDay = 1000 * 60 * 60 * 24
|
||||||
|
|
||||||
|
if (!this.lastUpdateTime || (now - lastUpdate > oneDay)) {
|
||||||
|
this.fetchUser()
|
||||||
|
} else {
|
||||||
|
this.user = localStorage.getItem('userContent') || ''
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -130,10 +153,10 @@ export default {
|
|||||||
background-color: #e5e5f7;
|
background-color: #e5e5f7;
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
background-image: linear-gradient(-45deg,
|
background-image: linear-gradient(-45deg,
|
||||||
#e5e5f7,
|
#e5e5f7,
|
||||||
#e5e5f7 50%,
|
#e5e5f7 50%,
|
||||||
#d6d7e5 50%,
|
#d6d7e5 50%,
|
||||||
#d6d7e5);
|
#d6d7e5);
|
||||||
background-size: 8px 8px;
|
background-size: 8px 8px;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
@ -186,7 +209,7 @@ export default {
|
|||||||
color: rgb(143, 143, 143);
|
color: rgb(143, 143, 143);
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
|
|
||||||
.content{
|
.content {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-family: Cambria, Cochin, Georgia, Times, "Times New Roman", serif;
|
font-family: Cambria, Cochin, Georgia, Times, "Times New Roman", serif;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user