1.0版本

This commit is contained in:
Xubx 2024-10-29 11:21:42 +08:00
parent 0ff621b43d
commit 91d459b673
12 changed files with 1164 additions and 85 deletions

603
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -8,6 +8,7 @@
"lint": "vue-cli-service lint" "lint": "vue-cli-service lint"
}, },
"dependencies": { "dependencies": {
"ant-design-vue": "^1.7.8",
"arale-qrcode": "^3.0.5", "arale-qrcode": "^3.0.5",
"axios": "^1.6.0", "axios": "^1.6.0",
"core-js": "^3.8.3", "core-js": "^3.8.3",

View File

@ -1,10 +1,10 @@
<template> <template>
<div> <div>
<div class="menu"> <div class="menu">
<div class="brand"> <router-link to="/" class="brand">
<h3 class="red">BIG</h3> <h3 class="red">BIG</h3>
<h3 class="white">DATA</h3> <h3 class="white">DATA</h3>
</div> </router-link>
<div class="main-nav"> <div class="main-nav">
<router-link to="/" type="primary" class="button-container"> <router-link to="/" type="primary" class="button-container">
<h2>主页</h2> <h2>主页</h2>
@ -15,39 +15,51 @@
<router-link to="/add" type="success" class="button-container"> <router-link to="/add" type="success" class="button-container">
<h2>发布博客</h2> <h2>发布博客</h2>
</router-link> </router-link>
<router-link to="/chat" type="success" class="button-container">
<h2>聊天室</h2>
</router-link>
</div> </div>
<div class="right-nav"> <div class="right-nav">
<el-dropdown @command="handleCommand" class="el-dropdown-link"> <el-badge is-dot :hidden=isSignVisible>
<span> <el-dropdown @command="handleCommand" class="el-dropdown-link">
<el-avatar v-if="imageUrl" :src="imageUrl" style="width: 50px; height: 50px;" <span>
class="avatar flip animated"></el-avatar> <el-avatar v-if="imageUrl" :src="imageUrl" style="width: 50px; height: 50px;"
<i v-else class="el-icon-plus avatar-uploader-icon"></i> class="avatar flip animated"></el-avatar>
</span> <i v-else class="el-icon-plus avatar-uploader-icon"></i>
<el-dropdown-menu slot="dropdown"> </span>
<p>{{ this.username }}</p> <el-dropdown-menu slot="dropdown">
<el-upload action="http://124.71.135.249:8081/uploadAvatar/" :show-file-list="false" <p>{{ this.username }}</p>
:on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload"> <a @click="friendRequestVisible = true">
<el-dropdown-item divided icon="el-icon-picture-outline-round">更换头像</el-dropdown-item> <el-dropdown-item divided icon="el-icon-user-solid">
</el-upload> <el-badge is-dot :hidden=isSignVisible>好友申请</el-badge>
<a @click="nameChangeVisible = true"> </el-dropdown-item>
<el-dropdown-item divided icon="el-icon-user">
修改昵称 </a>
</el-dropdown-item> <el-upload action="http://62.234.217.137:8088/user/uploadAvatar" :headers="uploadHeaders" :show-file-list="false"
</a> :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
<a @click="passwordChangeVisible = true"> <el-dropdown-item divided icon="el-icon-picture-outline-round">更换头像</el-dropdown-item>
<el-dropdown-item divided icon="el-icon-edit-outline"> </el-upload>
修改密码 <a @click="nameChangeVisible = true">
</el-dropdown-item> <el-dropdown-item divided icon="el-icon-user">
</a> 修改昵称
<router-link to="/login" class="right-nav"> </el-dropdown-item>
<el-dropdown-item divided icon="el-icon-switch-button">退出登录</el-dropdown-item> </a>
</router-link> <a @click="passwordChangeVisible = true">
</el-dropdown-menu> <el-dropdown-item divided icon="el-icon-edit-outline">
</el-dropdown> 修改密码
</el-dropdown-item>
</a>
<router-link to="/login" class="right-nav">
<el-dropdown-item divided icon="el-icon-switch-button">退出登录</el-dropdown-item>
</router-link>
</el-dropdown-menu>
</el-dropdown>
</el-badge>
</div> </div>
</div> </div>
<el-dialog title="修改昵称" :visible="nameChangeVisible" width="400px" @close="nameChangeVisible = false"> <el-dialog title="修改昵称" :modal="false" :visible="nameChangeVisible" width="400px"
@close="nameChangeVisible = false">
<el-form :model="usernameForm" :rules="usernameRules"> <el-form :model="usernameForm" :rules="usernameRules">
<el-form-item label="请输入昵称" :label-width="200" prop="usernameChange"> <el-form-item label="请输入昵称" :label-width="200" prop="usernameChange">
<el-input v-model="usernameForm.usernameChange" style="width: 350px;"></el-input> <el-input v-model="usernameForm.usernameChange" style="width: 350px;"></el-input>
@ -58,7 +70,7 @@
<el-button type="primary" @click="usernameChange()"> </el-button> <el-button type="primary" @click="usernameChange()"> </el-button>
</span> </span>
</el-dialog> </el-dialog>
<el-dialog title="修改密码" :destroy-on-close="true" :visible="passwordChangeVisible" width="550px" <el-dialog title="修改密码" :modal="false" :destroy-on-close="true" :visible="passwordChangeVisible" width="550px"
@close="passwordChangeVisible = false"> @close="passwordChangeVisible = false">
<el-form :model="passwordForm" label-width="100px" :rules="passwordRules"> <el-form :model="passwordForm" label-width="100px" :rules="passwordRules">
<el-form-item label="原密码" prop="oldPassword"> <el-form-item label="原密码" prop="oldPassword">
@ -76,6 +88,25 @@
<el-button type="primary" @click="passwordChange()"> </el-button> <el-button type="primary" @click="passwordChange()"> </el-button>
</span> </span>
</el-dialog> </el-dialog>
<el-dialog title="好友申请" :visible="friendRequestVisible" :modal="false" width="400px"
@close="friendRequestVisible = false">
<div v-for="friendRequest in friendRequests" :key="friendRequest.id" style="margin-top: 10px;">
<el-card>
<div style="display: flex; justify-content: space-between; align-items: center;">
<div style="display: flex; align-items: center;">
<el-avatar :src="friendRequest.avatar" style="width: 50px; height: 50px;"></el-avatar>
<el-tag style="font-size: 17px; margin: 10px;">{{ friendRequest.initiator }}</el-tag>
</div>
<div>
<el-button size="small" type="success"
@click="agreeFriendRequest(friendRequest.username, friendRequest.friend)">同意</el-button>
<el-button size="small" type="danger"
@click="refuseFriendRequest(friendRequest.username, friendRequest.friend)">拒绝</el-button>
</div>
</div>
</el-card>
</div>
</el-dialog>
</div> </div>
</template> </template>
<script> <script>
@ -102,10 +133,21 @@ export default {
} }
}; };
return { return {
Url: {
getAvatar: '/user/getAvatar',
getUsername: '/user/getUsername',
usernameChange: '/user/usernameChange',
passwordChange: '/user/passwordChange',
haveFriendRequest: '/user/checkFriendRequest',
acceptRequest: '/relationship/acceptRequest',
refuseRequest: '/relationship/refuseRequest',
},
imageUrl: '', imageUrl: '',
username: '', username: '',
nameChangeVisible: false, nameChangeVisible: false,//
passwordChangeVisible: false, passwordChangeVisible: false,//
friendRequestVisible: false,//
friendRequests: [],//
usernameForm: { usernameForm: {
usernameChange: '' usernameChange: ''
}, },
@ -114,6 +156,7 @@ export default {
newPassword: '', newPassword: '',
configurePassword: '' configurePassword: ''
}, },
isSignVisible: true,//
passwordRules: { passwordRules: {
oldPassword: [ oldPassword: [
{ required: true, message: '请输入原密码', trigger: 'blur' }, { required: true, message: '请输入原密码', trigger: 'blur' },
@ -129,9 +172,18 @@ export default {
usernameChange: [ usernameChange: [
{ validator: validateUsername, trigger: 'blur' }, //trigger: 'blur' { validator: validateUsername, trigger: 'blur' }, //trigger: 'blur'
], ],
} },
}; };
}, },
computed: {
uploadHeaders() {
// localStoragetoken
const token = window.localStorage.getItem("token");
return {
Authorization: token ? token : ''
};
}
},
methods: { methods: {
handleAvatarSuccess(res, file) { handleAvatarSuccess(res, file) {
this.imageUrl = URL.createObjectURL(file.raw); this.imageUrl = URL.createObjectURL(file.raw);
@ -152,19 +204,19 @@ export default {
return isJPG && isLt2M; return isJPG && isLt2M;
}, },
getAvatar() { getAvatar() {
axios.get("/getAvatar").then((res) => { axios.get(this.Url.getAvatar).then((res) => {
this.imageUrl = 'http://124.71.135.249:8081' + res.data; this.imageUrl = 'http://62.234.217.137:8088' + res.data;
console.log("接收的url" + this.imageUrl) console.log("接收的url" + this.imageUrl)
}) })
}, },
getUsername() { getUsername() {
axios.get("/getUsername").then((res) => { axios.get(this.Url.getUsername).then((res) => {
this.username = res.data; this.username = res.data;
console.log(this.username); console.log(this.username);
}) })
}, },
usernameChange() { usernameChange() {
axios.get("/usernameChange", { axios.get(this.Url.usernameChange, {
params: { params: {
username: this.usernameForm.usernameChange username: this.usernameForm.usernameChange
} }
@ -181,7 +233,7 @@ export default {
}) })
}, },
passwordChange() { passwordChange() {
axios.get("/passwordChange", { axios.get(this.Url.passwordChange, {
params: { params: {
oldPassword: this.passwordForm.oldPassword, oldPassword: this.passwordForm.oldPassword,
newPassword: this.passwordForm.newPassword, newPassword: this.passwordForm.newPassword,
@ -200,10 +252,73 @@ export default {
}) })
}, },
//
haveFriendRequest() {
axios.get(this.Url.haveFriendRequest).then((res) => {
this.friendRequests = res.data.friendRequests;
for (let i = 0; i < this.friendRequests.length; i++) {
if (this.friendRequests[i].avatar == null || this.friendRequests[i].avatar == '') {
//
this.friendRequests[i].avatar = 'http://62.234.217.137:8088' + '/images/avatar/default.jpg'
} else {
this.friendRequests[i].avatar = 'http://62.234.217.137:8088' + this.friendRequests[i].avatar
}
}
if (this.friendRequests.length > 0) {
this.isSignVisible = false;//
} else {
this.isSignVisible = true;
}
})
},
//
agreeFriendRequest(initiator, friend) {
axios.post(this.Url.acceptRequest, {
username: initiator,
friend: friend
}).then((res) => {
const result = res.data;
if (result.code === 200) {
this.haveFriendRequest();
this.$message({
message: result.message,
type: 'success'
});
} else {
this.$message({
message: result.message,
type: 'error'
});
}
})
},
//
refuseFriendRequest(initiator, friend) {
axios.post(this.Url.refuseRequest, {
username: initiator,
friend: friend
}).then((res) => {
const result = res.data;
if (result.code === 200) {
this.haveFriendRequest();
this.$message({
message: result.message,
type: 'success'
});
} else {
this.$message({
message: result.message,
type: 'error'
});
}
})
},
}, },
created() { created() {
this.getAvatar(); this.getAvatar();
this.getUsername(); this.getUsername();
this.haveFriendRequest();
}, },
name: "MenuView", name: "MenuView",
@ -357,7 +472,7 @@ export default {
/* position: absolute; /* position: absolute;
background-color: transparent; */ background-color: transparent; */
width: 100%; width: 100%;
position: fixed; /* position: fixed; */
height: 70px; height: 70px;
background-color: transparent; background-color: transparent;
display: flex; display: flex;

View File

@ -3,6 +3,7 @@ import App from './App.vue'
import router from './router' import router from './router'
import store from './store' import store from './store'
import axios from 'axios' import axios from 'axios'
import "./css/common.css" import "./css/common.css"
Vue.config.productionTip = false Vue.config.productionTip = false
@ -11,13 +12,31 @@ import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css'; import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI); Vue.use(ElementUI);
//导入mavon-editor用户Markdown编辑器 //导入mavon-editor用户Markdown编辑器
import mavonEditor from 'mavon-editor' import mavonEditor from 'mavon-editor'
//解决Markdown编辑器的图标不出现问题 //解决Markdown编辑器的图标不出现问题
import "mavon-editor/dist/css/index.css" import "mavon-editor/dist/css/index.css"
Vue.use(mavonEditor) Vue.use(mavonEditor)
axios.defaults.baseURL="http://localhost:8081" axios.defaults.baseURL = "http://62.234.217.137:8088"
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
// 判断是否存在token,如果存在将每个请求header添加token
const excludedPaths = ['/login', '/register'];
console.log(config.headers, window.localStorage.getItem("token"));
if (!excludedPaths.includes(config.url) && window.localStorage.getItem("token")) {
config.headers.Authorization = window.localStorage.getItem("token");
console.log(config.headers.Authorization);
}
return config;
}, function (error) {
router.push('/login');
return Promise.reject(error);
});
//修改标题 //修改标题
router.beforeEach((to, from, next) => { router.beforeEach((to, from, next) => {

View File

@ -9,6 +9,7 @@ import jwt_decode from "jwt-decode";
import BlogTime from '../views/BlogTimeView.vue' import BlogTime from '../views/BlogTimeView.vue'
import ProjectWall from '../views/ProjectWallView.vue' import ProjectWall from '../views/ProjectWallView.vue'
import MobileLogin from '../views/MobileLoginView.vue' import MobileLogin from '../views/MobileLoginView.vue'
import ChatRoom from '../views/ChatRoomView.vue'
import store from "../store/index.js" import store from "../store/index.js"
@ -64,6 +65,14 @@ const routes = [
title: 'Xubx的博客' title: 'Xubx的博客'
} }
}, },
{
path: '/chat',
name: 'ChatRoom',
component: ChatRoom,
meta: {
title: 'Xubx的博客'
}
},
{ {
path: '/test', path: '/test',
name: 'ProjectWall', name: 'ProjectWall',
@ -102,7 +111,6 @@ router.beforeEach((to, from, next) => {
} }
next(); next();
} }
}) })

View File

@ -73,7 +73,7 @@ export default {
this.$refs[formName].validate((valid) => { this.$refs[formName].validate((valid) => {
if (valid) { if (valid) {
// //
axios.post('/addBlog', { axios.post('/blog/addBlog', {
// id: this.ruleForm.id, // id: this.ruleForm.id,
title: this.ruleForm.title, title: this.ruleForm.title,
description: this.ruleForm.description, description: this.ruleForm.description,

View File

@ -4,7 +4,10 @@
<Header></Header> <Header></Header>
<div style="text-align: left;padding-left: 40px; width: 96%;" class="mblog"> <div style="text-align: left;padding-left: 40px; width: 96%;" class="mblog">
<br> <br>
<h2>{{ blog.title }}</h2> <div>
<h2>{{ blog.title }}</h2>
<span style="font-size: 13px;">发布时间: {{ formatDate(blog.created) }}</span>
</div>
<br> <br>
<div> <div>
<el-link icon="el-icon-edit"> <el-link icon="el-icon-edit">
@ -67,6 +70,8 @@
v-if="(commentReply.parent_id == comment.comment_id) && isClickId === comment.comment_id"> v-if="(commentReply.parent_id == comment.comment_id) && isClickId === comment.comment_id">
<div class="comment-reply"> <div class="comment-reply">
<div class="comment-top"> <div class="comment-top">
<el-avatar class="comment-avatar" shape="circle" size="medium"
:src="commentReply.avatar" />
<el-tag class="comment-username" style="font-size: 17px;">{{ <el-tag class="comment-username" style="font-size: 17px;">{{
commentReply.username }} 回复 @{{ commentReply.username }} 回复 @{{
commentReply.parent_name }}</el-tag> commentReply.parent_name }}</el-tag>
@ -136,6 +141,10 @@ export default {
} }
}, },
methods: { methods: {
formatDate(dateString) {
const options = { year: 'numeric', month: 'long', day: 'numeric' };
return new Date(dateString).toLocaleString('zh-CN', options);
},
viewReplys(comment) { viewReplys(comment) {
this.isClickId = comment.comment_id this.isClickId = comment.comment_id
const commentReplyAdd = [] const commentReplyAdd = []
@ -219,7 +228,7 @@ export default {
commentGet() { commentGet() {
this.commentVisible = true this.commentVisible = true
// //
axios.get('/getComment', { axios.get('/comment/getComment', {
params: { params: {
blogId: this.blog.id blogId: this.blog.id
} }
@ -227,11 +236,11 @@ export default {
console.log(res.data) console.log(res.data)
this.comments = res.data this.comments = res.data
for (let i = 0; i < this.comments.length; i++) { for (let i = 0; i < this.comments.length; i++) {
if (this.comments[i].avatar == null) { if (this.comments[i].avatar == null || this.comments[i].avatar == '') {
// //
this.comments[i].avatar = 'http://124.71.135.249:8081' + '/images/avatar/default.jpg' this.comments[i].avatar = 'http://62.234.217.137:8088' + '/images/avatar/default.jpg'
} else { } else {
this.comments[i].avatar = 'http://124.71.135.249:8081' + this.comments[i].avatar this.comments[i].avatar = 'http://62.234.217.137:8088' + this.comments[i].avatar
} }
console.log("this.comments[i].parent_id" + this.comments[i].parent_id + "this.comments[i].username" + this.comments[i].username) console.log("this.comments[i].parent_id" + this.comments[i].parent_id + "this.comments[i].username" + this.comments[i].username)
} }
@ -250,7 +259,7 @@ export default {
this.commentForm.created = created this.commentForm.created = created
console.log(this.commentForm) console.log(this.commentForm)
// //
axios.post('/addComment', { axios.post('/comment/addComment', {
article_id: this.commentForm.id, article_id: this.commentForm.id,
parent_id: this.replyComent.comment_id, parent_id: this.replyComent.comment_id,
parent_name: this.replyComent.replyName, parent_name: this.replyComent.replyName,
@ -275,7 +284,7 @@ export default {
created() { created() {
const blogId = this.$route.params.blogId const blogId = this.$route.params.blogId
const that = this const that = this
axios.get('/getBlogDetail', { axios.get('/blog/getBlogDetail', {
params: { params: {
blogId: blogId blogId: blogId
} }

View File

@ -114,7 +114,7 @@ export default {
const that = this const that = this
if (blogId !== undefined && blogId !== null && blogId !== '') { if (blogId !== undefined && blogId !== null && blogId !== '') {
console.log(blogId) console.log(blogId)
axios.get('/getBlogDetail', { axios.get('/blog/getBlogDetail', {
params: { params: {
blogId: blogId blogId: blogId
} }

View File

@ -114,7 +114,7 @@ export default {
methods: { methods: {
getBlogs() { getBlogs() {
const that = this; const that = this;
axios.get("/getBlogs").then((response) => { axios.get("/blog/getBlogs").then((response) => {
that.blogs = response.data; that.blogs = response.data;
for (let index in that.blogs) { for (let index in that.blogs) {
that.blogs[index].imageUrl = this.imageUrls[index % 8]; that.blogs[index].imageUrl = this.imageUrls[index % 8];
@ -227,7 +227,7 @@ export default {
}; };
</script> </script>
<style> <style scoped>
/*base code*/ /*base code*/
.animated { .animated {
-webkit-animation-duration: 1s; -webkit-animation-duration: 1s;

View File

@ -19,7 +19,7 @@
</el-card> </el-card>
</eltimeline-item> </eltimeline-item>
<br> <br>
<el-timeline-item :timestamp="new Date(blog.created)" placement="top" v-for="blog in pagedBlogs" <el-timeline-item :timestamp="formatDate(blog.created)" placement="top" v-for="blog in pagedBlogs"
:key="blog.title"> :key="blog.title">
<el-card> <el-card>
<!-- 路由跳转 --> <!-- 路由跳转 -->
@ -80,9 +80,13 @@ export default {
}, },
methods: { methods: {
formatDate(dateString) {
const options = { year: 'numeric', month: 'long', day: 'numeric' };
return new Date(dateString).toLocaleString('zh-CN', options);
},
getBlogs() { getBlogs() {
const that = this; const that = this;
axios.get("/getBlogs").then((response) => { axios.get("/blog/getBlogs").then((response) => {
that.blogs = response.data; that.blogs = response.data;
that.total = that.blogs.length; // that.total = that.blogs.length; //
that.handleCurrentChange(that.currentPage); // that.handleCurrentChange(that.currentPage); //

357
src/views/ChatRoomView.vue Normal file
View File

@ -0,0 +1,357 @@
<template>
<div class="container">
<Menu></Menu>
<br>
<div class="room">
<el-row gutter="24">
<el-col :span="6">
<el-card class="left">
<div slot="header">
<span style="font-weight: bold; font-size: 20px; padding-left: 30px;">好友列表</span>
<el-button @click="addFriends()" style="float: right;" type="text">添加好友</el-button>
</div>
<div style="margin-top: 10px;">
<!-- 好友列表 -->
<div v-for="friend in friends" :key="friend.id" class="friends"
@click="chat(friend.username)"
:class="{ 'selected-friend': friend.username === currentUsername }">
<div style="display: flex; justify-content: space-between; align-items: center;">
<el-badge v-if="friend.unreadCount != 0" :value=friend.unreadCount>
<div style="display: flex; align-items: center;">
<el-avatar :src="friend.avatar"
style="width: 50px; height: 50px;"></el-avatar>
<el-tag style="font-size: 17px; margin: 10px;">{{ friend.username
}}</el-tag>
</div>
</el-badge>
<div v-else>
<div style="display: flex; align-items: center;">
<el-avatar :src="friend.avatar"
style="width: 50px; height: 50px;"></el-avatar>
<el-tag style="font-size: 17px; margin: 10px;">{{ friend.username
}}</el-tag>
</div>
</div>
</div>
</div>
</div>
</el-card>
</el-col>
<el-col :span="18">
<el-card class="right">
<!-- 好友名称 -->
<div slot="header" style="display: flex;">
<span style="font-size: 20px;">{{ currentUsername }}</span>
</div>
<!-- 聊天内容 -->
<div class="chat-box" ref="ChatBox">
<br>
<div v-for="message in messages" :key="message.id">
<div v-if="message.sender === currentUsername"
style="display:flex; text-align: left; margin: 4px;">
<el-avatar shape="square" :src="message.avatar"
style="width: 40px; height: 40px;"></el-avatar>
<div style="margin-left: 10px; display: flex; flex-direction: column;">
<span style="font-size: 14px; margin-top: -10px;">{{ message.sender }}</span>
<el-tag
style="background-color: white; color: black; height: 40px; line-height: 40px; font-size: 14px; margin-top: 5px; margin-bottom: 5px;">
{{ message.content }}
</el-tag>
</div>
</div>
<div v-else
style="display: flex; justify-content: flex-end; flex-direction: row; margin: 4px;">
<div style="margin-right: 10px; display: flex; flex-direction: column;">
<span style="font-size: 14px; margin-top: -10px; text-align: right;">{{
message.sender }}</span>
<el-tag
style="background-color: #95ec69; color: black; height: 40px; line-height: 40px; font-size: 14px; margin-top: 5px; margin-bottom: 5px;">
{{ message.content }}
</el-tag>
</div>
<el-avatar shape="square" :src="message.avatar"
style="width: 40px; height: 40px;"></el-avatar>
</div>
</div>
</div>
<el-divider></el-divider>
<!-- 输入框 -->
<div v-if="currentUsername != ''" class="InputBox">
<el-input type="textarea" :rows="5" resize="none" placeholder="请输入内容"
@keyup.enter.native="sendMessages" v-model="inputArea">
</el-input>
<el-button style="margin-top: 10px; float: right; color: #07c160;"
@click="sendMessages()">发送</el-button>
</div>
</el-card>
</el-col>
</el-row>
<el-dialog title="添加好友" :visible.sync="addFriendsVisible" width="30%" :before-close="handleClose">
<div style="display: flex; ">
<el-input v-model="username" placeholder="请输入用户名"></el-input>
<el-button style="margin-left:10px; " type="primary" @click="queryUser()"> </el-button>
</div>
<div style="margin-top: 10px; max-height: 400px; overflow-y: auto;">
<div v-for="user in users" :key="user.id" style="margin-top: 10px;">
<div style="display: flex; justify-content: space-between; align-items: center;">
<div style="display: flex; align-items: center;">
<el-avatar :src="user.avatar" style="width: 50px; height: 50px;"></el-avatar>
<el-tag style="font-size: 17px; margin: 10px;">{{ user.username }}</el-tag>
</div>
<el-button type="success" @click="requestFriend(user.username)">添加</el-button>
</div>
</div>
</div>
</el-dialog>
</div>
<br>
<Footer></Footer>
</div>
</template>
<script>
import Footer from "../components/Footer";
import Menu from "../components/Menu";
import axios from "axios";
let ws;
export default {
components: { Menu, Footer },
beforeRouteEnter(to, from, next) {
//
window.scrollTo(0, 0);
next();
},
data() {
return {
Url: {
queryUser: '/relationship/queryUser',
addRequest: '/relationship/addRequest',
getFriends: '/relationship/getFriends',
sendMessages: '/messages/sendMessages',
getMessages: '/messages/getMessages',
getUsername: '/user/getUsername'
},
addFriendsVisible: false,
users: [],
username: '',
friends: [],
currentUsername: '',//
loginUsername: '',
inputArea: '',
messages: [],//
};
},
methods: {
//
addFriends() {
this.users = [];//
this.username = '';//
this.addFriendsVisible = true;
},
//
queryUser() {
this.users = [];//
axios.get(this.Url.queryUser, {
params: {
username: this.username
}
}).then((res) => {
this.users = res.data;
for (let i = 0; i < this.users.length; i++) {
if (this.users[i].avatar == null || this.users[i].avatar == '') {
//
this.users[i].avatar = 'http://62.234.217.137:8088' + '/images/avatar/default.jpg'
} else {
this.users[i].avatar = 'http://62.234.217.137:8088' + this.users[i].avatar
}
}
if (res.data.length == 0) {
this.$message({
message: '未找到该用户',
type: 'warning'
});
}
});
},
//
requestFriend(friendId) {
axios.get(this.Url.addRequest, {
params: {
username: friendId
}
}).then((res) => {
const result = res.data;
if (result.code === 200) {
this.$message({
message: result.message,
type: 'success'
});
} else {
this.$message({
message: result.message,
type: 'error'
});
}
}).catch((error) => {
this.$message({
message: '请求发送失败: ' + error.message,
type: 'error'
});
});
this.addFriendsVisible = false;
},
//
getFriends() {
axios.get(this.Url.getFriends).then((res) => {
console.log(res.data, '好友列表')
this.friends = res.data;
for (let i = 0; i < this.friends.length; i++) {
if (this.friends[i].avatar == null || this.friends[i].avatar == '') {
//
this.friends[i].avatar = 'http://62.234.217.137:8088' + '/images/avatar/default.jpg'
} else {
this.friends[i].avatar = 'http://62.234.217.137:8088' + this.friends[i].avatar
}
}
});
},
//
chat(currentUsername) {
this.currentUsername = currentUsername;//
axios.get(this.Url.getMessages, {
params: {
recipient: currentUsername
}
}).then((res) => {
let result = res.data.result;
this.messages = result.data;
for (let i = 0; i < this.messages.length; i++) {
if (this.messages[i].avatar == null || this.messages[i].avatar == '') {
//
this.messages[i].avatar = 'http://62.234.217.137:8088' + '/images/avatar/default.jpg'
} else {
this.messages[i].avatar = 'http://62.234.217.137:8088' + this.messages[i].avatar
}
}
this.getFriends();//
this.$nextTick(() => {
this.scrollToBottom();
});
});
},
sendMessages() {
if (this.inputArea == '') {
this.$message({
message: '发送内容不能为空',
type: 'warning'
});
return;
}
let message = {
sender: this.loginUsername,
recipient: this.currentUsername,
content: this.inputArea
};
ws.send(JSON.stringify(message));
this.inputArea = '';//
this.chat(this.currentUsername);//
this.$nextTick(() => {
this.scrollToBottom();
});
},
scrollToBottom() {
this.$nextTick(() => {
const chatBox = this.$refs.ChatBox;
chatBox.scrollTop = chatBox.scrollHeight;
});
},
getUsername() {
axios.get(this.Url.getUsername).then((res) => {
this.loginUsername = res.data;
}).then(() => {
this.WebSocket();
});
},
WebSocket() {
console.log('WebSocket',)
// WebSocket
ws = new WebSocket('ws://62.234.217.137:8088/ws/' + this.loginUsername);
ws.onopen = () => {
console.log('WebSocket连接成功');
};
ws.onmessage = (e) => {
this.chat(this.currentUsername);//
this.$nextTick(() => {
this.scrollToBottom();
});
console.log('收到消息:', e.data);
};
//
window.addEventListener('beforeunload', () => {
// WebSocket
if (ws && ws.readyState === WebSocket.OPEN) {
ws.send("closeWebsocket");
console.log("关闭WebSocket连接")
}
});
// ws.onclose = () => {
// console.log('WebSocket');
// };
},
},
created() {
this.getFriends();
this.getUsername();
}
}
</script>
<style scoped>
.container {
/* 居中显示 */
margin: 0 auto;
z-index: 10;
background: #c7d1d5;
}
.room {
padding-left: 20px;
padding-right: 20px;
}
.left {
height: 620px;
/* background: #e5e4e4; */
}
.right {
height: 620px;
}
.chat-box {
height: 320px;
overflow-y: auto
}
.InputBox {
max-height: 100px;
}
.friends {
cursor: pointer;
padding: 10px;
border-bottom: 1px solid #e5e4e4;
}
/* 仅当 .friends 没有被选中时,鼠标悬停样式才生效 */
.friends:not(.selected-friend):hover {
background: #ebeae8;
}
.selected-friend {
background: #d6d3d2;
}
</style>

View File

@ -137,15 +137,18 @@ export default {
submitLoginForm() { submitLoginForm() {
const that = this const that = this
axios.post("/login", { axios.post("/user/login", {
username: this.loginForm.username, username: this.loginForm.username,
password: this.loginForm.password password: this.loginForm.password
}).then(res => { }).then(res => {
var jsonObject = res.data; var jsonObject = res.data;
var jsonString = JSON.stringify(jsonObject) var jsonString = JSON.stringify(jsonObject)
if (jsonString !== "false") { if (jsonString !== "false") {
window.localStorage.removeItem("token");
window.localStorage.setItem("token", jsonString); window.localStorage.setItem("token", jsonString);
that.setToken({ token: jsonString }) that.setToken({ token: jsonString })
//token
axios.defaults.headers.common['Authorization'] = jsonString;
this.$router.push({ path: "/" }) this.$router.push({ path: "/" })
this.$message.success("登陆成功!") this.$message.success("登陆成功!")
} else { } else {
@ -154,23 +157,23 @@ export default {
}) })
}, },
submitRegisterForm() { submitRegisterForm() {
axios.post("/register", { axios.post("/user/register", {
username: this.registerForm.username, username: this.registerForm.username,
password: this.registerForm.password, password: this.registerForm.password,
}).then(res => { }).then(res => {
if (res.data === "注册成功") { if (res.status === 201) {
this.$message.success(res.data) this.$message.success('注册成功')
} else if (res.status === 409) {
this.$message.error('用户已经存在')
} else { } else {
this.$message.error(res.data) this.$message.error('注册失败,服务器内部错误')
} }
}).catch(err => {
this.$message.error(err.response.data)
console.log(err)
}) })
}, },
}, },
//token
created() {
const that = this
that.delToken({ token: "123" })
},
name: "LoginView", name: "LoginView",
} }