15 changed files with 992 additions and 729 deletions
|
Before Width: | Height: | Size: 133 KiB After Width: | Height: | Size: 32 KiB |
@ -1,35 +0,0 @@ |
|||
<template> |
|||
<div class='img-box'> |
|||
<img :src="url" style="width: 100%;height: 100%;cursor: pointer;" /> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: "headImage", |
|||
data() { |
|||
return {} |
|||
}, |
|||
props: { |
|||
size: { |
|||
type: Number, |
|||
default: 50 |
|||
}, |
|||
url:{ |
|||
type: String, |
|||
default: '../assets/default_head.png' |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.img-box { |
|||
width: 100%; |
|||
height: 100%; |
|||
display: inline-block; |
|||
border-radius: 3px; |
|||
background-color: #c0c4cc; |
|||
overflow: hidden; |
|||
} |
|||
</style> |
|||
@ -1,165 +1,165 @@ |
|||
<template> |
|||
|
|||
<div class="item" :class="active ? 'active' : ''"> |
|||
<div class="left"> |
|||
<head-image :url="chat.headImage" :size="40"> |
|||
|
|||
</head-image> |
|||
<div v-show="chat.unreadCount>0" class="unread-text">{{chat.unreadCount}}</div> |
|||
</div> |
|||
<div class="mid"> |
|||
<div>{{ chat.showName}}</div> |
|||
<div class="msg-text">{{chat.lastContent}}</div> |
|||
</div> |
|||
<div class="right "> |
|||
<div @click.stop="onClickClose()"><i class="el-icon-close close" style="border: none; font-size: 20px;color: black;" title="关闭"></i></div> |
|||
|
|||
<div class="msg-time"> |
|||
<chat-time :time="chat.lastSendTime"></chat-time> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
</template> |
|||
|
|||
<script> |
|||
import ChatTime from "./ChatTime.vue"; |
|||
import HeadImage from './HeadImage.vue'; |
|||
|
|||
export default { |
|||
name: "chatItem", |
|||
components: { |
|||
ChatTime, |
|||
HeadImage |
|||
}, |
|||
data() { |
|||
return {} |
|||
}, |
|||
props: { |
|||
chat: { |
|||
type: Object |
|||
}, |
|||
active: { |
|||
type: Boolean |
|||
}, |
|||
index: { |
|||
type: Number |
|||
} |
|||
}, |
|||
methods: { |
|||
|
|||
onClickClose(){ |
|||
this.$emit("del"); |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scode lang="scss"> |
|||
.item { |
|||
height: 65px; |
|||
display: flex; |
|||
margin-bottom: 1px; |
|||
position: relative; |
|||
padding-left: 15px; |
|||
align-items: center; |
|||
padding-right: 5px; |
|||
background-color: #eeeeee; |
|||
|
|||
&:hover { |
|||
background-color: #dddddd; |
|||
} |
|||
|
|||
&.active { |
|||
background-color: #cccccc; |
|||
} |
|||
|
|||
|
|||
&:hover { |
|||
.close { |
|||
display: block !important; |
|||
} |
|||
} |
|||
|
|||
.left { |
|||
position: relative; |
|||
display: flex; |
|||
width: 45px; |
|||
height: 45px; |
|||
|
|||
.unread-text { |
|||
position: absolute; |
|||
background-color: #f56c6c; |
|||
right: -8px; |
|||
top: -8px; |
|||
color: white; |
|||
border-radius: 30px; |
|||
padding: 0 5px; |
|||
font-size: 10px; |
|||
text-align: center; |
|||
white-space: nowrap; |
|||
border: 1px solid #f1e5e5; |
|||
} |
|||
} |
|||
|
|||
|
|||
.mid { |
|||
margin-left: 15px; |
|||
flex: 3; |
|||
display: flex; |
|||
flex-direction: column; |
|||
height: 100%; |
|||
flex-shrink: 0; |
|||
overflow: hidden; |
|||
|
|||
&>div { |
|||
display: flex; |
|||
justify-content: flex-start; |
|||
align-items: center; |
|||
flex: 1; |
|||
} |
|||
|
|||
.msg-text { |
|||
font-size: 14px; |
|||
color: #888888; |
|||
white-space: nowrap; |
|||
} |
|||
} |
|||
|
|||
.right { |
|||
flex: 1; |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: flex-end; |
|||
height: 100%; |
|||
flex-shrink: 0; |
|||
overflow: hidden; |
|||
|
|||
&>div { |
|||
display: flex; |
|||
justify-content: flex-start; |
|||
align-items: center; |
|||
flex: 1; |
|||
} |
|||
|
|||
.close { |
|||
width: 1.5rem; |
|||
height: 1.5rem; |
|||
right: 0; |
|||
top: 1rem; |
|||
cursor: pointer; |
|||
display: none; |
|||
} |
|||
|
|||
.msg-time { |
|||
font-size: 14px; |
|||
color: #888888; |
|||
white-space: nowrap; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.active { |
|||
background-color: #eeeeee; |
|||
} |
|||
</style> |
|||
<template> |
|||
|
|||
<div class="item" :class="active ? 'active' : ''"> |
|||
<div class="left"> |
|||
<head-image :url="chat.headImage" :size="40"> |
|||
|
|||
</head-image> |
|||
<div v-show="chat.unreadCount>0" class="unread-text">{{chat.unreadCount}}</div> |
|||
</div> |
|||
<div class="mid"> |
|||
<div>{{ chat.showName}}</div> |
|||
<div class="msg-text">{{chat.lastContent}}</div> |
|||
</div> |
|||
<div class="right "> |
|||
<div @click.stop="onClickClose()"><i class="el-icon-close close" style="border: none; font-size: 20px;color: black;" title="关闭"></i></div> |
|||
|
|||
<div class="msg-time"> |
|||
<chat-time :time="chat.lastSendTime"></chat-time> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
</template> |
|||
|
|||
<script> |
|||
import ChatTime from "./ChatTime.vue"; |
|||
import HeadImage from '../common/HeadImage.vue'; |
|||
|
|||
export default { |
|||
name: "chatItem", |
|||
components: { |
|||
ChatTime, |
|||
HeadImage |
|||
}, |
|||
data() { |
|||
return {} |
|||
}, |
|||
props: { |
|||
chat: { |
|||
type: Object |
|||
}, |
|||
active: { |
|||
type: Boolean |
|||
}, |
|||
index: { |
|||
type: Number |
|||
} |
|||
}, |
|||
methods: { |
|||
|
|||
onClickClose(){ |
|||
this.$emit("del"); |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scode lang="scss"> |
|||
.item { |
|||
height: 65px; |
|||
display: flex; |
|||
margin-bottom: 1px; |
|||
position: relative; |
|||
padding-left: 15px; |
|||
align-items: center; |
|||
padding-right: 5px; |
|||
background-color: #eeeeee; |
|||
|
|||
&:hover { |
|||
background-color: #dddddd; |
|||
} |
|||
|
|||
&.active { |
|||
background-color: #cccccc; |
|||
} |
|||
|
|||
|
|||
&:hover { |
|||
.close { |
|||
display: block !important; |
|||
} |
|||
} |
|||
|
|||
.left { |
|||
position: relative; |
|||
display: flex; |
|||
width: 45px; |
|||
height: 45px; |
|||
|
|||
.unread-text { |
|||
position: absolute; |
|||
background-color: #f56c6c; |
|||
right: -8px; |
|||
top: -8px; |
|||
color: white; |
|||
border-radius: 30px; |
|||
padding: 0 5px; |
|||
font-size: 10px; |
|||
text-align: center; |
|||
white-space: nowrap; |
|||
border: 1px solid #f1e5e5; |
|||
} |
|||
} |
|||
|
|||
|
|||
.mid { |
|||
margin-left: 15px; |
|||
flex: 3; |
|||
display: flex; |
|||
flex-direction: column; |
|||
height: 100%; |
|||
flex-shrink: 0; |
|||
overflow: hidden; |
|||
|
|||
&>div { |
|||
display: flex; |
|||
justify-content: flex-start; |
|||
align-items: center; |
|||
flex: 1; |
|||
} |
|||
|
|||
.msg-text { |
|||
font-size: 14px; |
|||
color: #888888; |
|||
white-space: nowrap; |
|||
} |
|||
} |
|||
|
|||
.right { |
|||
flex: 1; |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: flex-end; |
|||
height: 100%; |
|||
flex-shrink: 0; |
|||
overflow: hidden; |
|||
|
|||
&>div { |
|||
display: flex; |
|||
justify-content: flex-start; |
|||
align-items: center; |
|||
flex: 1; |
|||
} |
|||
|
|||
.close { |
|||
width: 1.5rem; |
|||
height: 1.5rem; |
|||
right: 0; |
|||
top: 1rem; |
|||
cursor: pointer; |
|||
display: none; |
|||
} |
|||
|
|||
.msg-time { |
|||
font-size: 14px; |
|||
color: #888888; |
|||
white-space: nowrap; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.active { |
|||
background-color: #eeeeee; |
|||
} |
|||
</style> |
|||
@ -1,43 +1,41 @@ |
|||
<template> |
|||
<span>{{formatDate}}</span> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: "chatTime", |
|||
data() { |
|||
return {} |
|||
}, |
|||
props: { |
|||
time: { |
|||
type: Number |
|||
} |
|||
}, |
|||
computed:{ |
|||
formatDate(){ |
|||
console.log(this.time); |
|||
let time = new Date(this.time); |
|||
let strtime = ""; |
|||
let curTime = new Date(); |
|||
let dayDiff =curTime.getDate() - time.getDate() ; |
|||
if (time.getDate() === new Date().getDate()) { |
|||
strtime = time.getHours() <= 9 ? "0" + time.getHours() : time.getHours(); |
|||
strtime += ":" |
|||
strtime += time.getMinutes() <= 9 ? "0" + time.getMinutes() : time.getMinutes(); |
|||
} else if (dayDiff === 1) { |
|||
strtime = "昨天"; |
|||
} else if (dayDiff < 7) { |
|||
strtime = `${dayDiff}天前`; |
|||
} else { |
|||
strtime = time.getMonth()+1+"月"+time.getDate()+"日"; |
|||
} |
|||
|
|||
console.log(strtime); |
|||
return strtime; |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style> |
|||
</style> |
|||
<template> |
|||
<span>{{formatDate}}</span> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: "chatTime", |
|||
data() { |
|||
return {} |
|||
}, |
|||
props: { |
|||
time: { |
|||
type: Number |
|||
} |
|||
}, |
|||
computed:{ |
|||
formatDate(){ |
|||
let time = new Date(this.time); |
|||
let strtime = ""; |
|||
let curTime = new Date(); |
|||
let dayDiff =curTime.getDate() - time.getDate() ; |
|||
if (time.getDate() === new Date().getDate()) { |
|||
strtime = time.getHours() <= 9 ? "0" + time.getHours() : time.getHours(); |
|||
strtime += ":" |
|||
strtime += time.getMinutes() <= 9 ? "0" + time.getMinutes() : time.getMinutes(); |
|||
} else if (dayDiff === 1) { |
|||
strtime = "昨天"; |
|||
} else if (dayDiff < 7) { |
|||
strtime = `${dayDiff}天前`; |
|||
} else { |
|||
strtime = time.getMonth()+1+"月"+time.getDate()+"日"; |
|||
} |
|||
|
|||
return strtime; |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style> |
|||
</style> |
|||
@ -0,0 +1,209 @@ |
|||
<template> |
|||
<div class="im-msg-item" :class="{'im-chat-mine':mine}"> |
|||
<div class="head-image"> |
|||
<head-image :url="headImage"></head-image> |
|||
</div> |
|||
<div class="im-msg-content"> |
|||
<div class="im-msg-top"> |
|||
<span>{{showName}}</span> |
|||
<chat-time :time="msgInfo.sendTime"></chat-time> |
|||
</div> |
|||
<div class="im-msg-bottom"> |
|||
<span class="im-msg-text" v-if="msgInfo.type==0" >{{msgInfo.content}}</span> |
|||
<div class="im-msg-image" v-if="msgInfo.type==1"> |
|||
<div class="img-load-box" v-loading="loading" |
|||
element-loading-text="上传中.." |
|||
element-loading-background="rgba(0, 0, 0, 0.4)"> |
|||
<img class="send-image" :src="JSON.parse(msgInfo.content).thumbUrl"/> |
|||
</div> |
|||
<span title="发送失败" v-show="loadFail" @click="handleSendFail" class="send-fail el-icon-warning"></span> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import ChatTime from "./ChatTime.vue"; |
|||
import HeadImage from "../common/HeadImage.vue"; |
|||
|
|||
export default { |
|||
name: "messageItem", |
|||
components: { |
|||
ChatTime, |
|||
HeadImage |
|||
}, |
|||
props: { |
|||
mine:{ |
|||
type:Boolean, |
|||
required: true |
|||
}, |
|||
headImage: { |
|||
type: String, |
|||
required: true |
|||
}, |
|||
showName: { |
|||
type: String, |
|||
required: true |
|||
}, |
|||
msgInfo: { |
|||
type: Object, |
|||
required: true |
|||
} |
|||
}, |
|||
methods:{ |
|||
handleSendFail(){ |
|||
this.$message.error("该文件已上传失败,目前不支持自动重新发送,建议手动重新发送") |
|||
} |
|||
}, |
|||
computed:{ |
|||
loading(){ |
|||
return this.msgInfo.loadStatus && this.msgInfo.loadStatus === "loadding"; |
|||
}, |
|||
loadFail(){ |
|||
return this.msgInfo.loadStatus && this.msgInfo.loadStatus === "fail"; |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.im-msg-item { |
|||
position: relative; |
|||
font-size: 0; |
|||
margin-bottom: 10px; |
|||
padding-left: 60px; |
|||
min-height: 68px; |
|||
|
|||
.head-image { |
|||
position: absolute; |
|||
width: 40px; |
|||
height: 40px; |
|||
top: 0; |
|||
left: 0; |
|||
} |
|||
|
|||
.im-msg-content { |
|||
display: flex; |
|||
flex-direction: column; |
|||
|
|||
.im-msg-top { |
|||
display: flex; |
|||
flex-wrap: nowrap; |
|||
color: #333; |
|||
font-size: 14px; |
|||
line-height: 20px; |
|||
|
|||
span { |
|||
margin-right: 12px; |
|||
} |
|||
} |
|||
|
|||
.im-msg-bottom { |
|||
text-align: left; |
|||
|
|||
.im-msg-text { |
|||
position: relative; |
|||
line-height: 22px; |
|||
margin-top: 10px; |
|||
padding: 10px; |
|||
background-color: #eeeeee; |
|||
border-radius: 3px; |
|||
color: #333; |
|||
display: inline-block; |
|||
font-size: 14px; |
|||
|
|||
&:after { |
|||
content: ""; |
|||
position: absolute; |
|||
left: -10px; |
|||
top: 13px; |
|||
width: 0; |
|||
height: 0; |
|||
border-style: solid dashed dashed; |
|||
border-color: #eeeeee transparent transparent; |
|||
overflow: hidden; |
|||
border-width: 10px; |
|||
} |
|||
} |
|||
|
|||
.im-msg-image{ |
|||
display: flex; |
|||
flex-wrap: nowrap; |
|||
flex-direction: row; |
|||
align-items: center; |
|||
|
|||
|
|||
.send-image{ |
|||
min-width: 300px; |
|||
min-height: 200px; |
|||
max-width: 600px; |
|||
max-height: 400px; |
|||
border: #dddddd solid 1px; |
|||
cursor: pointer; |
|||
} |
|||
|
|||
.send-fail{ |
|||
color: red; |
|||
font-size: 30px; |
|||
cursor: pointer; |
|||
margin: 0 20px; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
&.im-chat-mine { |
|||
text-align: right; |
|||
padding-left: 0; |
|||
padding-right: 60px; |
|||
|
|||
.head-image { |
|||
left: auto; |
|||
right: 0; |
|||
} |
|||
|
|||
.im-msg-content { |
|||
|
|||
.im-msg-top { |
|||
flex-direction: row-reverse; |
|||
|
|||
span { |
|||
margin-left: 12px; |
|||
margin-right: 0; |
|||
} |
|||
} |
|||
|
|||
.im-msg-bottom { |
|||
text-align: right; |
|||
|
|||
.im-msg-text { |
|||
margin-left: 10px; |
|||
background-color: #5fb878; |
|||
color: #fff; |
|||
display: inline-block; |
|||
vertical-align: top; |
|||
font-size: 14px; |
|||
|
|||
&:after { |
|||
left: auto; |
|||
right: -10px; |
|||
border-top-color: #5fb878; |
|||
} |
|||
} |
|||
|
|||
.im-msg-image { |
|||
flex-direction: row-reverse; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.message-info { |
|||
right: 60px !important; |
|||
display: inline-block; |
|||
} |
|||
} |
|||
|
|||
} |
|||
</style> |
|||
@ -0,0 +1,87 @@ |
|||
<template> |
|||
<el-upload :action="action" :accept="fileTypes.join(',')" :show-file-list="false" :on-success="handleSuccess" |
|||
:before-upload="beforeUpload"> |
|||
<slot></slot> |
|||
</el-upload> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: "fileUpload", |
|||
data() { |
|||
return { |
|||
loading: null |
|||
} |
|||
}, |
|||
props: { |
|||
action: { |
|||
type: String, |
|||
required: true |
|||
}, |
|||
fileTypes: { |
|||
type: Array, |
|||
default: null |
|||
}, |
|||
maxSize: { |
|||
type: Number, |
|||
default: null |
|||
}, |
|||
showLoading: { |
|||
type: Boolean, |
|||
default: false |
|||
} |
|||
}, |
|||
methods: { |
|||
handleSuccess(res, file) { |
|||
this.loading && this.loading.close(); |
|||
if (res.code == 200) { |
|||
this.$emit("success", res, file); |
|||
}else{ |
|||
this.$message.error(res.message); |
|||
this.$emit("fail", res, file); |
|||
} |
|||
}, |
|||
beforeUpload(file) { |
|||
// 校验文件类型 |
|||
let fileType = file.type; |
|||
let t = this.fileTypes.find((t) => t.toLowerCase() === fileType); |
|||
console.log(t); |
|||
if (t === undefined) { |
|||
this.$message.error(`文件格式错误,请上传以下格式的文件:${this.fileTypes.join("、")}`); |
|||
return false; |
|||
} |
|||
// 校验大小 |
|||
let size = file.size; |
|||
if (size > this.maxSize) { |
|||
this.$message.error(`文件大小不能超过 ${this.fileSizeStr}!`); |
|||
return false; |
|||
} |
|||
|
|||
if (this.showLoading) { |
|||
this.loading = this.$loading({ |
|||
lock: true, |
|||
text: '正在上传...', |
|||
spinner: 'el-icon-loading', |
|||
background: 'rgba(0, 0, 0, 0.7)' |
|||
}); |
|||
} |
|||
this.$emit("before", file); |
|||
return true; |
|||
} |
|||
}, |
|||
computed: { |
|||
fileSizeStr() { |
|||
if (this.maxSize > 1024 * 1024) { |
|||
return (this.maxSize / 1024 / 1024) + "M"; |
|||
} |
|||
if (this.maxSize > 1024) { |
|||
return (this.maxSize / 1024) + "KB"; |
|||
} |
|||
return this.maxSize + "B"; |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style> |
|||
</style> |
|||
@ -0,0 +1,54 @@ |
|||
<template> |
|||
<div class='img-box'> |
|||
<img :src="url" |
|||
style="width: 100%;height: 100%;cursor: pointer;" /> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: "headImage", |
|||
data() { |
|||
return { |
|||
} |
|||
}, |
|||
methods:{ |
|||
}, |
|||
props: { |
|||
size: { |
|||
type: Number, |
|||
default: 50 |
|||
}, |
|||
url:{ |
|||
type: String |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped lang="scss"> |
|||
.img-box { |
|||
width: 100%; |
|||
height: 100%; |
|||
display: inline-block; |
|||
border-radius: 3px; |
|||
background-color: #c0c4cc; |
|||
overflow: hidden; |
|||
|
|||
img { |
|||
position: relative; |
|||
} |
|||
|
|||
img:before { |
|||
|
|||
content: ''; |
|||
display: block; |
|||
width: 100%; |
|||
height: 100%; |
|||
background:url('../../assets/default_head.png') no-repeat 0 0; |
|||
background-size: 100%; |
|||
|
|||
|
|||
} |
|||
} |
|||
</style> |
|||
@ -1,119 +1,119 @@ |
|||
<template> |
|||
<el-dialog title="添加好友" :visible.sync="dialogVisible" width="350px" :before-close="onClose"> |
|||
<el-input width="200px" placeholder="搜索好友" class="input-with-select" v-model="searchText" @keyup.enter.native="onSearch()"> |
|||
<el-button slot="append" icon="el-icon-search" @click="onSearch()"></el-button> |
|||
</el-input> |
|||
<el-scrollbar style="height:400px"> |
|||
<div v-for="(userInfo) in users" :key="userInfo.id"> |
|||
<div class="item"> |
|||
<div class="avatar"> |
|||
<head-image :url="userInfo.headImage"></head-image> |
|||
</div> |
|||
<div class="add-friend-text"> |
|||
<div>{{userInfo.nickName}}</div> |
|||
<div :class="userInfo.online ? 'online-status online':'online-status'">{{ userInfo.online?"[在线]":"[离线]"}}</div> |
|||
</div> |
|||
<el-button type="success" v-show="!isFriend(userInfo.id)" plain @click="onAddFriends(userInfo)">添加</el-button> |
|||
<el-button type="info" v-show="isFriend(userInfo.id)" plain disabled>已添加</el-button> |
|||
</div> |
|||
</div> |
|||
</el-scrollbar> |
|||
</el-dialog> |
|||
</template> |
|||
|
|||
<script> |
|||
import HeadImage from './HeadImage.vue' |
|||
|
|||
|
|||
export default { |
|||
name: "addFriends", |
|||
components:{HeadImage}, |
|||
data() { |
|||
return { |
|||
users: [], |
|||
searchText: "" |
|||
} |
|||
}, |
|||
props: { |
|||
dialogVisible: { |
|||
type: Boolean |
|||
} |
|||
}, |
|||
methods: { |
|||
onClose() { |
|||
this.$emit("close"); |
|||
}, |
|||
onSearch() { |
|||
this.$http({ |
|||
url: "/api/user/findByNickName", |
|||
method: "get", |
|||
params: { |
|||
nickName: this.searchText |
|||
} |
|||
}).then((data) => { |
|||
this.users = data; |
|||
}) |
|||
}, |
|||
onAddFriends(userInfo){ |
|||
this.$http({ |
|||
url: "/api/friends/add", |
|||
method: "post", |
|||
params: { |
|||
friendId: userInfo.id |
|||
} |
|||
}).then((data) => { |
|||
this.$store.commit("") |
|||
this.$message.success("添加成功,对方已成为您的好友"); |
|||
let friendsInfo = { |
|||
friendId:userInfo.id, |
|||
friendNickName: userInfo.nickName, |
|||
friendHeadImage: userInfo.headImage, |
|||
online: userInfo.online |
|||
} |
|||
this.$store.commit("addFriends",friendsInfo); |
|||
|
|||
}) |
|||
}, |
|||
isFriend(userId){ |
|||
let friendList = this.$store.state.friendsStore.friendsList; |
|||
let friend = friendList.find((f)=> f.friendId==userId); |
|||
return friend != undefined; |
|||
} |
|||
}, |
|||
|
|||
mounted() { |
|||
this.onSearch(); |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped lang="scss"> |
|||
|
|||
.item { |
|||
height: 80px; |
|||
display: flex; |
|||
position: relative; |
|||
padding-left: 15px; |
|||
align-items: center; |
|||
padding-right: 25px; |
|||
|
|||
.add-friend-text { |
|||
margin-left: 15px; |
|||
line-height: 80px; |
|||
flex: 3; |
|||
display: flex; |
|||
flex-direction: row; |
|||
height: 100%; |
|||
flex-shrink: 0; |
|||
overflow: hidden; |
|||
|
|||
.online-status{ |
|||
font-size: 12px; |
|||
font-weight: 600; |
|||
&.online{ |
|||
color: #5fb878; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
<template> |
|||
<el-dialog title="添加好友" :visible.sync="dialogVisible" width="350px" :before-close="onClose"> |
|||
<el-input width="200px" placeholder="搜索好友" class="input-with-select" v-model="searchText" @keyup.enter.native="onSearch()"> |
|||
<el-button slot="append" icon="el-icon-search" @click="onSearch()"></el-button> |
|||
</el-input> |
|||
<el-scrollbar style="height:400px"> |
|||
<div v-for="(userInfo) in users" :key="userInfo.id"> |
|||
<div class="item"> |
|||
<div class="avatar"> |
|||
<head-image :url="userInfo.headImage"></head-image> |
|||
</div> |
|||
<div class="add-friend-text"> |
|||
<div>{{userInfo.nickName}}</div> |
|||
<div :class="userInfo.online ? 'online-status online':'online-status'">{{ userInfo.online?"[在线]":"[离线]"}}</div> |
|||
</div> |
|||
<el-button type="success" v-show="!isFriend(userInfo.id)" plain @click="onAddFriends(userInfo)">添加</el-button> |
|||
<el-button type="info" v-show="isFriend(userInfo.id)" plain disabled>已添加</el-button> |
|||
</div> |
|||
</div> |
|||
</el-scrollbar> |
|||
</el-dialog> |
|||
</template> |
|||
|
|||
<script> |
|||
import HeadImage from '../common/HeadImage.vue' |
|||
|
|||
|
|||
export default { |
|||
name: "addFriends", |
|||
components:{HeadImage}, |
|||
data() { |
|||
return { |
|||
users: [], |
|||
searchText: "" |
|||
} |
|||
}, |
|||
props: { |
|||
dialogVisible: { |
|||
type: Boolean |
|||
} |
|||
}, |
|||
methods: { |
|||
onClose() { |
|||
this.$emit("close"); |
|||
}, |
|||
onSearch() { |
|||
this.$http({ |
|||
url: "/api/user/findByNickName", |
|||
method: "get", |
|||
params: { |
|||
nickName: this.searchText |
|||
} |
|||
}).then((data) => { |
|||
this.users = data; |
|||
}) |
|||
}, |
|||
onAddFriends(userInfo){ |
|||
this.$http({ |
|||
url: "/api/friends/add", |
|||
method: "post", |
|||
params: { |
|||
friendId: userInfo.id |
|||
} |
|||
}).then((data) => { |
|||
this.$store.commit("") |
|||
this.$message.success("添加成功,对方已成为您的好友"); |
|||
let friendsInfo = { |
|||
friendId:userInfo.id, |
|||
friendNickName: userInfo.nickName, |
|||
friendHeadImage: userInfo.headImage, |
|||
online: userInfo.online |
|||
} |
|||
this.$store.commit("addFriends",friendsInfo); |
|||
|
|||
}) |
|||
}, |
|||
isFriend(userId){ |
|||
let friendList = this.$store.state.friendsStore.friendsList; |
|||
let friend = friendList.find((f)=> f.friendId==userId); |
|||
return friend != undefined; |
|||
} |
|||
}, |
|||
|
|||
mounted() { |
|||
this.onSearch(); |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped lang="scss"> |
|||
|
|||
.item { |
|||
height: 80px; |
|||
display: flex; |
|||
position: relative; |
|||
padding-left: 15px; |
|||
align-items: center; |
|||
padding-right: 25px; |
|||
|
|||
.add-friend-text { |
|||
margin-left: 15px; |
|||
line-height: 80px; |
|||
flex: 3; |
|||
display: flex; |
|||
flex-direction: row; |
|||
height: 100%; |
|||
flex-shrink: 0; |
|||
overflow: hidden; |
|||
|
|||
.online-status{ |
|||
font-size: 12px; |
|||
font-weight: 600; |
|||
&.online{ |
|||
color: #5fb878; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -1,114 +1,114 @@ |
|||
<template> |
|||
<div class="item" :class="active ? 'active' : ''"> |
|||
<div class="avatar"> |
|||
<head-image :url="friendsInfo.friendHeadImage" > </head-image> |
|||
</div> |
|||
<div class="text"> |
|||
<div>{{ friendsInfo.friendNickName}}</div> |
|||
<div :class="online ? 'online-status online':'online-status'">{{ online?"[在线]":"[离线]"}}</div> |
|||
</div> |
|||
<div class="close" @click.stop="$emit('del',friendsInfo,index)"> |
|||
<i class="el-icon-close" style="border: none; font-size: 20px;color: black;" title="添加好友"></i> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import HeadImage from './HeadImage.vue'; |
|||
|
|||
export default { |
|||
name: "frinedsItem", |
|||
components: {HeadImage}, |
|||
data() { |
|||
return { |
|||
} |
|||
}, |
|||
props: { |
|||
friendsInfo: { |
|||
type: Object |
|||
}, |
|||
active:{ |
|||
type: Boolean |
|||
}, |
|||
index:{ |
|||
type: Number |
|||
} |
|||
}, |
|||
computed:{ |
|||
online(){ |
|||
return this.$store.state.friendsStore.friendsList[this.index].online; |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scope lang="scss"> |
|||
.item { |
|||
height: 65px; |
|||
display: flex; |
|||
margin-bottom: 1px; |
|||
position: relative; |
|||
padding-left: 15px; |
|||
align-items: center; |
|||
padding-right: 5px; |
|||
background-color: #eeeeee; |
|||
&:hover { |
|||
background-color: #dddddd; |
|||
} |
|||
|
|||
&.active{ |
|||
background-color: #cccccc; |
|||
} |
|||
|
|||
|
|||
.close { |
|||
width: 1.5rem; |
|||
height: 1.5rem; |
|||
right: 10px; |
|||
top: 1.825rem; |
|||
cursor: pointer; |
|||
display: none; |
|||
} |
|||
|
|||
&:hover { |
|||
.close { |
|||
display: block; |
|||
} |
|||
} |
|||
|
|||
.avatar { |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
width: 45px; |
|||
height: 45px; |
|||
} |
|||
|
|||
.text { |
|||
margin-left: 15px; |
|||
flex: 3; |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: space-around; |
|||
height: 100%; |
|||
flex-shrink: 0; |
|||
overflow: hidden; |
|||
&>div { |
|||
display: flex; |
|||
justify-content: flex-start; |
|||
} |
|||
|
|||
.online-status{ |
|||
font-size: 12px; |
|||
font-weight: 600; |
|||
&.online{ |
|||
color: #5fb878; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
.active { |
|||
background-color: #eeeeee; |
|||
} |
|||
</style> |
|||
<template> |
|||
<div class="item" :class="active ? 'active' : ''"> |
|||
<div class="avatar"> |
|||
<head-image :url="friendsInfo.friendHeadImage" > </head-image> |
|||
</div> |
|||
<div class="text"> |
|||
<div>{{ friendsInfo.friendNickName}}</div> |
|||
<div :class="online ? 'online-status online':'online-status'">{{ online?"[在线]":"[离线]"}}</div> |
|||
</div> |
|||
<div class="close" @click.stop="$emit('del',friendsInfo,index)"> |
|||
<i class="el-icon-close" style="border: none; font-size: 20px;color: black;" title="添加好友"></i> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import HeadImage from '../common/HeadImage.vue'; |
|||
|
|||
export default { |
|||
name: "frinedsItem", |
|||
components: {HeadImage}, |
|||
data() { |
|||
return { |
|||
} |
|||
}, |
|||
props: { |
|||
friendsInfo: { |
|||
type: Object |
|||
}, |
|||
active:{ |
|||
type: Boolean |
|||
}, |
|||
index:{ |
|||
type: Number |
|||
} |
|||
}, |
|||
computed:{ |
|||
online(){ |
|||
return this.$store.state.friendsStore.friendsList[this.index].online; |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scope lang="scss"> |
|||
.item { |
|||
height: 65px; |
|||
display: flex; |
|||
margin-bottom: 1px; |
|||
position: relative; |
|||
padding-left: 15px; |
|||
align-items: center; |
|||
padding-right: 5px; |
|||
background-color: #eeeeee; |
|||
&:hover { |
|||
background-color: #dddddd; |
|||
} |
|||
|
|||
&.active{ |
|||
background-color: #cccccc; |
|||
} |
|||
|
|||
|
|||
.close { |
|||
width: 1.5rem; |
|||
height: 1.5rem; |
|||
right: 10px; |
|||
top: 1.825rem; |
|||
cursor: pointer; |
|||
display: none; |
|||
} |
|||
|
|||
&:hover { |
|||
.close { |
|||
display: block; |
|||
} |
|||
} |
|||
|
|||
.avatar { |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
width: 45px; |
|||
height: 45px; |
|||
} |
|||
|
|||
.text { |
|||
margin-left: 15px; |
|||
flex: 3; |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: space-around; |
|||
height: 100%; |
|||
flex-shrink: 0; |
|||
overflow: hidden; |
|||
&>div { |
|||
display: flex; |
|||
justify-content: flex-start; |
|||
} |
|||
|
|||
.online-status{ |
|||
font-size: 12px; |
|||
font-weight: 600; |
|||
&.online{ |
|||
color: #5fb878; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
.active { |
|||
background-color: #eeeeee; |
|||
} |
|||
</style> |
|||
Loading…
Reference in new issue