修改昵称

This commit is contained in:
username 2024-06-16 17:45:01 +08:00
parent 952447ec70
commit 5415e64853
8 changed files with 283 additions and 123 deletions

View File

@ -1,5 +1,6 @@
import request from '../utils/request' import request from '../utils/request'
// 登录接口
export function login (data) { export function login (data) {
return request({ return request({
url: '/login', url: '/login',
@ -8,6 +9,7 @@ export function login (data) {
}) })
} }
// 自动登录接口
export function autoLogin (token) { export function autoLogin (token) {
return request({ return request({
url: '/auto-login', url: '/auto-login',
@ -15,3 +17,21 @@ export function autoLogin (token) {
data: { token } data: { token }
}) })
} }
// 修改用户信息
export function updateUserInfo (data) {
return request({
url: '/update-user-info',
method: 'put',
data
})
}
// 获取用户信息接口
export function getUserInfo (username) {
return request({
url: '/user-info',
method: 'get',
params: { username }
})
}

10
src/api/personal.js Normal file
View File

@ -0,0 +1,10 @@
import request from '../utils/request'
// 修改
export function updateUse (data) {
return request({
url: '/updateUser',
method: 'put',
data
})
}

View File

@ -9,22 +9,34 @@
<router-link to="/" exact-active-class="active">首页</router-link> <router-link to="/" exact-active-class="active">首页</router-link>
</li> </li>
<li> <li>
<router-link to="/labelpage" exact-active-class="active">标签</router-link> <router-link to="/labelpage" exact-active-class="active"
>标签</router-link
>
</li> </li>
<li> <li>
<router-link to="/listPage" exact-active-class="active">专题</router-link> <router-link to="/listPage" exact-active-class="active"
>专题</router-link
>
</li> </li>
<li> <li>
<router-link to="/messageboard" exact-active-class="active">留言板</router-link> <router-link to="/messageboard" exact-active-class="active"
>留言板</router-link
>
</li> </li>
<li> <li>
<router-link to="/photoGallery" exact-active-class="active">照片集</router-link> <router-link to="/photoGallery" exact-active-class="active"
>照片集</router-link
>
</li> </li>
<li> <li>
<router-link to="/interlinkage" exact-active-class="active">友情链接</router-link> <router-link to="/interlinkage" exact-active-class="active"
>友情链接</router-link
>
</li> </li>
<li> <li>
<router-link to="/about" exact-active-class="active">个人中心</router-link> <router-link to="/about" exact-active-class="active"
>个人中心</router-link
>
</li> </li>
</ul> </ul>
<div class="search" @click.stop> <div class="search" @click.stop>
@ -35,9 +47,13 @@
style="width: 230px; margin-right: 10px" style="width: 230px; margin-right: 10px"
@keyup.enter="performSearch" @keyup.enter="performSearch"
></el-input> ></el-input>
<el-button icon="el-icon-search" circle @click="performSearch"></el-button> <el-button
icon="el-icon-search"
circle
@click="performSearch"
></el-button>
<el-avatar style="margin-left: 10px; position: absolute; top: 10px"> <el-avatar style="margin-left: 10px; position: absolute; top: 10px">
<router-link to="/about">user</router-link> <router-link to="/about"> {{ lastCharacterOfUsername }}</router-link>
</el-avatar> </el-avatar>
<div class="out" @click="handleOut">退出</div> <div class="out" @click="handleOut">退出</div>
<div v-if="resultsVisible" class="search-results" @click.stop> <div v-if="resultsVisible" class="search-results" @click.stop>
@ -46,7 +62,7 @@
<router-link :to="result.link">{{ result.title }}</router-link> <router-link :to="result.link">{{ result.title }}</router-link>
</li> </li>
</ul> </ul>
<p v-else >暂无内容</p> <p v-else>暂无内容</p>
</div> </div>
</div> </div>
</div> </div>
@ -54,18 +70,31 @@
</template> </template>
<script> <script>
import { mapState, mapGetters, mapActions } from 'vuex'
export default { export default {
data () { data () {
return { return {
input: '',
searchResults: [],
isFixed: false, // isFixed: false, //
input: '', //
searchResults: [], //
resultsVisible: false // / resultsVisible: false // /
} }
}, },
computed: {
...mapState(['username']),
...mapGetters(['getUsername']),
lastCharacterOfUsername () {
if (this.username) {
return this.username.slice(-1) //
}
return '' //
}
},
mounted () { mounted () {
window.addEventListener('scroll', this.handleScroll) window.addEventListener('scroll', this.handleScroll)
document.addEventListener('click', this.hideResults) document.addEventListener('click', this.hideResults)
this.loadUsername() //
}, },
beforeDestroy () { beforeDestroy () {
window.removeEventListener('scroll', this.handleScroll) window.removeEventListener('scroll', this.handleScroll)
@ -76,6 +105,15 @@ export default {
const scrollTop = window.scrollY || document.documentElement.scrollTop const scrollTop = window.scrollY || document.documentElement.scrollTop
this.isFixed = scrollTop > 60 this.isFixed = scrollTop > 60
}, },
loadUsername () {
const username = localStorage.getItem('username')
if (username) {
// localStorage Vuex store
this.$store.commit('setUsername', username)
console.log('从 localStorage 中加载用户名:', username)
}
},
...mapActions(['updateUsername']),
// //
performSearch () { performSearch () {
if (!this.input.trim()) { if (!this.input.trim()) {
@ -100,9 +138,18 @@ export default {
) )
this.resultsVisible = true this.resultsVisible = true
}, },
//
loginSuccess (username) {
// Vuex store
this.updateUsername(username) // Vuex action
console.log('登录成功,用户名已设置为:', username)
},
// 退 // 退
handleOut () { handleOut () {
localStorage.removeItem('token') localStorage.removeItem('token')
// Vuex store
this.$store.commit('setUsername', '')
localStorage.removeItem('username') // localStorage
this.$router.push('/login') this.$router.push('/login')
this.$message({ this.$message({
message: '您已退出', message: '您已退出',

View File

@ -1,4 +1,3 @@
// src/store/index.js
import Vue from 'vue' import Vue from 'vue'
import Vuex from 'vuex' import Vuex from 'vuex'
@ -6,11 +5,15 @@ Vue.use(Vuex)
export default new Vuex.Store({ export default new Vuex.Store({
state: { state: {
isAuthenticated: false isAuthenticated: false,
username: ''
}, },
mutations: { mutations: {
setAuthenticated (state, status) { setAuthenticated (state, status) {
state.isAuthenticated = status state.isAuthenticated = status
},
setUsername (state, username) {
state.username = username
} }
}, },
actions: { actions: {
@ -19,9 +22,23 @@ export default new Vuex.Store({
}, },
logout ({ commit }) { logout ({ commit }) {
commit('setAuthenticated', false) commit('setAuthenticated', false)
},
updateUsername ({ commit }, username) {
// 更新 Vuex 中的用户名
commit('setUsername', username)
// 更新 localStorage 中的用户名
localStorage.setItem('username', username)
},
loadUsernameFromLocalStorage ({ commit }) {
// 从 localStorage 加载用户名
const savedUsername = localStorage.getItem('username')
if (savedUsername) {
commit('setUsername', savedUsername)
}
} }
}, },
getters: { getters: {
isAuthenticated: state => state.isAuthenticated isAuthenticated: state => state.isAuthenticated,
username: state => state.username
} }
}) })

View File

@ -4,7 +4,7 @@ import router from '../router'
// 创建一个 axios 实例 // 创建一个 axios 实例
const service = axios.create({ const service = axios.create({
baseURL: 'http://localhost:5000/', // API 基础 URL baseURL: 'http://localhost:5000', // API 基础 URL
timeout: 5000 // 请求超时时间 timeout: 5000 // 请求超时时间
}) })

View File

@ -6,16 +6,11 @@
<el-tab-pane label="个人信息"> <el-tab-pane label="个人信息">
<div class="AboutUs-left"> <div class="AboutUs-left">
<div class="AboutUs-img"> <div class="AboutUs-img">
<img src="../assets/images/sub.jpg" alt="用户头像" /> <img :src="avatar" alt="用户头像" />
</div> </div>
<div class="user-info"> <div class="user-info">
<div <div class="user-item">
v-for="(item, index) in users" <p class="user-name">{{ username }}</p>
:key="index"
class="user-item"
>
<p class="user-name">{{ item.name }}</p>
<p class="user-date">{{ item.date }}</p>
</div> </div>
</div> </div>
</div> </div>
@ -50,75 +45,63 @@
<el-tab-pane label="基本设置"> <el-tab-pane label="基本设置">
<div class="basic-settings"> <div class="basic-settings">
<!-- 左边内容 -->
<div class="left-section"> <div class="left-section">
<!-- 昵称 --> <form :model="form">
<div class="form-item">
<label for="username">昵称</label>
<input
type="text"
id="username"
v-model="form.username"
placeholder="请输入修改的昵称"
/>
</div>
<div class="form-item">
<label for="intro">介绍</label>
<input id="intro" v-model="form.intro" placeholder="请输入介绍" />
</div>
<div class="form-item">
<label>性别</label>
<input type="radio" v-model="form.gender" value="male" />
<input
type="radio"
v-model="form.gender"
value="female"
style="margin-left: 10px"
/>
</div>
<div class="form-item">
<label for="birthday">生日</label>
<input type="date" id="birthday" v-model="form.birthday" />
</div>
<div class="form-item">
<label for="region">地区</label>
<select id="region" v-model="form.region">
<option value="region1">地区1</option>
<option value="region2">地区2</option>
<option value="region3">地区3</option>
</select>
<select id="city" v-model="form.city" style="margin-left: 10px">
<option value="city1">城市1</option>
<option value="city2">城市2</option>
<option value="city3">城市3</option>
</select>
</div>
</form>
<div class="form-item"> <div class="form-item">
<label for="nickname">昵称</label> <button class="save-btn" @click="saveUserInfo">修改</button>
<input
type="text"
id="nickname"
v-model="nickname"
placeholder="请输入昵称"
/>
</div>
<!-- 介绍 -->
<div class="form-item">
<label for="intro">介绍</label>
<input id="intro" v-model="intro" placeholder="请输入介绍" />
</div>
<!-- 性别 -->
<div class="form-item">
<label>性别</label>
<input type="radio" v-model="gender" value="male" />
<input
type="radio"
v-model="gender"
value="female"
style="margin-left: 10px"
/>
</div>
<!-- 生日 -->
<div class="form-item">
<label for="birthday">生日</label>
<input type="date" id="birthday" v-model="birthday" />
</div>
<!-- 地区选择 -->
<div class="form-item">
<label for="region">地区</label>
<select id="region" v-model="region">
<option value="region1">地区1</option>
<option value="region2">地区2</option>
<option value="region3">地区3</option>
</select>
<select id="region" v-model="city" style="margin-left: 10px">
<option value="city1">地区1</option>
<option value="city2">地区2</option>
<option value="city3">地区3</option>
</select>
</div>
<!-- 保存按钮 -->
<div class="form-item">
<button class="save-btn" @click="saveUserInfo">保存</button>
</div> </div>
</div> </div>
<!-- 右边内容 -->
<div class="right-section"> <div class="right-section">
<div class="avatar-section"> <div class="avatar-section">
<!-- 头像显示 -->
<img :src="avatar" alt="用户头像" class="avatar" /> <img :src="avatar" alt="用户头像" class="avatar" />
<!-- 更换头像按钮 --> <span class="change-avatar-btn" @click="changeAvatar">更换头像</span>
<span class="change-avatar-btn" @click="changeAvatar"
>更换头像</span
>
</div> </div>
</div> </div>
</div> </div>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
<!-- 头像上传 -->
<el-dialog title="更换头像" :visible.sync="dialogVisible" width="30%"> <el-dialog title="更换头像" :visible.sync="dialogVisible" width="30%">
<el-upload <el-upload
class="avatar-uploader" class="avatar-uploader"
@ -131,10 +114,8 @@
<i v-else class="el-icon-plus avatar-uploader-icon"></i> <i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload> </el-upload>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button> <el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="handleAddAvatar" <el-button type="primary" @click="handleAddAvatar">确定</el-button>
> </el-button
>
</span> </span>
</el-dialog> </el-dialog>
</div> </div>
@ -146,44 +127,105 @@
<script> <script>
import navigationBar from '@/components/navigationBar.vue' import navigationBar from '@/components/navigationBar.vue'
import trigger from '@/components/trigger.vue' import trigger from '@/components/trigger.vue'
import { getUserInfo, updateUserInfo } from '@/api/login'
import { mapState, mapActions } from 'vuex'
export default { export default {
data () { data () {
return { return {
isShow: false, isShow: false,
nickname: '', form: {
intro: '', username: '',
gender: '', intro: '',
birthday: '', gender: '',
region: '', birthday: '',
city: '', region: '',
city: ''
},
dialogVisible: false, dialogVisible: false,
imageUrl: '', imageUrl: '',
avatar: require('@/assets/images/789.jpg'), // name: '',
users: [ avatar: require('@/assets/images/sub.jpg'), // Define the avatar property
{
name: '当前用户名',
date: '2024-01-01'
}
],
newTodo: '', newTodo: '',
todos: [], // todos: [],
selectedTodoIndex: null // selectedTodoIndex: null
} }
}, },
components: { components: {
navigationBar, navigationBar,
trigger trigger
}, },
computed: {
...mapState({
username: state => state.username
})
},
created () {
this.$store.dispatch('loadUsernameFromLocalStorage')
const savedUsername = localStorage.getItem('name')
if (savedUsername) {
this.fetchUserInfo(savedUsername)
}
},
methods: { methods: {
fetchUserInfo (username) {
getUserInfo(username)
.then((res) => {
if (res && res.data) {
const userInfo = res.data
this.form.username = userInfo.username
this.form.intro = userInfo.intro
this.form.gender = userInfo.gender
this.form.birthday = userInfo.birthday
this.form.region = userInfo.region
this.form.city = userInfo.city
this.avatar = userInfo.avatar || this.avatar
localStorage.setItem('userInfo', JSON.stringify(userInfo))
}
})
.catch((error) => {
console.error('获取用户信息失败:', error)
})
},
toggleBackground () { toggleBackground () {
this.isShow = true this.isShow = true
}, },
...mapActions(['updateUsername']),
saveUserInfo () { saveUserInfo () {
// const currentUsername = localStorage.getItem('username') //
this.$message.success('保存成功')
const updatedUserInfo = {
currentUsername,
username: this.form.username, //
intro: this.form.intro,
gender: this.form.gender,
birthday: this.form.birthday,
region: this.form.region,
city: this.form.city,
avatar: this.form.avatar
}
this.$store.dispatch('updateUsername', this.form.username) // 使
updateUserInfo(updatedUserInfo)
.then((res) => {
if (res && res.status === 200) {
this.$message.success('用户信息更新成功')
//
this.fetchUserInfo(this.form.username)
} else {
this.$message.error('用户信息更新失败')
}
})
.catch((error) => {
console.error('用户信息更新失败:', error)
this.$message.error('用户信息更新失败')
})
console.log(updatedUserInfo)
}, },
//
handleAdd () { handleAdd () {
if (this.newTodo.trim() !== '') { if (this.newTodo.trim() !== '') {
this.todos.push(this.newTodo.trim()) this.todos.push(this.newTodo.trim())
@ -193,11 +235,9 @@ export default {
this.$message.error('请输入待办事项') this.$message.error('请输入待办事项')
} }
}, },
//
selectTodo (index) { selectTodo (index) {
this.selectedTodoIndex = index this.selectedTodoIndex = index
}, },
//
handleDelete () { handleDelete () {
if (this.selectedTodoIndex !== null) { if (this.selectedTodoIndex !== null) {
this.todos.splice(this.selectedTodoIndex, 1) this.todos.splice(this.selectedTodoIndex, 1)
@ -208,7 +248,6 @@ export default {
} }
}, },
changeAvatar () { changeAvatar () {
//
this.dialogVisible = true this.dialogVisible = true
}, },
handleAvatarSuccess (res, file) { handleAvatarSuccess (res, file) {
@ -402,7 +441,7 @@ hr {
.form-item { .form-item {
margin-bottom: 20px; margin-bottom: 20px;
#nickname { #username {
width: 250px; width: 250px;
padding: 5px; padding: 5px;
outline: none; outline: none;

View File

@ -57,6 +57,7 @@
<script> <script>
import { login, autoLogin } from '@/api/login' import { login, autoLogin } from '@/api/login'
import store from '@/store'
import dayjs from 'dayjs' import dayjs from 'dayjs'
export default { export default {
@ -114,7 +115,6 @@ export default {
}, },
autoLogin (token) { autoLogin (token) {
autoLogin(token).then(response => { autoLogin(token).then(response => {
console.log(response)
if (this.$route.path !== '/') { if (this.$route.path !== '/') {
this.$router.push('/') this.$router.push('/')
} }
@ -142,7 +142,6 @@ export default {
// //
if (!this.create) { if (!this.create) {
login({ ...this.form }).then(response => { login({ ...this.form }).then(response => {
console.log(response)
localStorage.setItem('token', response.data.token) localStorage.setItem('token', response.data.token)
if (this.checked) { if (this.checked) {
localStorage.setItem('rememberedUsername', this.form.username) localStorage.setItem('rememberedUsername', this.form.username)
@ -160,6 +159,10 @@ export default {
message: '登陆成功', message: '登陆成功',
type: 'success' type: 'success'
}) })
// Vuex store
store.commit('setUsername', response.data.username)
// LocalStorage
localStorage.setItem('username', response.data.username)
}).catch(error => { }).catch(error => {
console.error('登录失败:', error) console.error('登录失败:', error)
if (error.response && error.response.status === 401) { if (error.response && error.response.status === 401) {

View File

@ -3,15 +3,24 @@
<main class="main-content"> <main class="main-content">
<div class="kecheng"> <div class="kecheng">
<div class="empty" v-if="!detailContent.length">暂无内容</div> <div class="empty" v-if="!detailContent.length">暂无内容</div>
<div class="con" v-for="(item, index) in detailContent" :key="index"> <div class="con" v-for="(item, index) in paginatedContent" :key="index">
<div class="title" @click="pushDetailPage">{{ item.title }}</div> <div class="title" @click="pushDetailPage(item)">
{{ item.title }}
</div>
<div class="content" v-html="item.content"></div> <div class="content" v-html="item.content"></div>
</div> </div>
</div> </div>
<el-pagination
background
layout="prev, pager, next"
:total="total"
:hide-on-single-page="conceal"
@current-change="handlePageChange"
style="margin: 20px 0 20px 500px;"
>
</el-pagination>
</main> </main>
<div class="fortter"> <div class="fortter"></div>
</div>
</div> </div>
</template> </template>
@ -22,35 +31,50 @@ export default {
name: 'liSt', name: 'liSt',
data () { data () {
return { return {
detailContent: '' // detailContent: [], //
conceal: true, //
currentPage: 1, //
pageSize: 10, //
total: 0 //
} }
}, },
created () { created () {
this.fetchContent() // this.fetchContent() //
}, },
methods: { methods: {
fetchContent () { fetchContent () {
const id = this.$route.params.id // const id = this.$route.params.id //
// //
getlist(id) getlist(id, (this.currentPage - 1) * this.pageSize, this.pageSize)
.then((response) => { .then((response) => {
//
this.detailContent = response.data this.detailContent = response.data
this.total = response.data.length this.total = response.data.length
// console.log(response)
}) })
.catch((error) => { .catch((error) => {
console.error('Error fetching content:', error) console.error('获取内容时出错:', error)
}) })
}, },
pushDetailPage () { pushDetailPage (item) {
// // id
this.$router.push({ this.$router.push({
name: 'detailPage', name: 'detailPage',
params: { params: {
id: this.$route.params.id id: item.id // id
} }
}) })
},
handlePageChange (newPage) {
//
this.currentPage = newPage
this.fetchContent() //
}
},
computed: {
paginatedContent () {
// currentPage pageSize
const startIndex = (this.currentPage - 1) * this.pageSize
const endIndex = startIndex + this.pageSize
return this.detailContent.slice(startIndex, endIndex)
} }
} }
} }