Browse Source

ui美化

master
xsx 2 years ago
parent
commit
de6e5a9ac7
  1. 66
      im-ui/src/api/date.js
  2. 10
      im-ui/src/api/wssocket.js
  3. 169
      im-ui/src/components/chat/ChatItem.vue
  4. 20
      im-ui/src/components/chat/ChatMessageItem.vue
  5. 43
      im-ui/src/components/chat/ChatTime.vue
  6. 2
      im-ui/src/components/common/HeadImage.vue
  7. 38
      im-ui/src/components/common/RightMenu.vue
  8. 106
      im-ui/src/components/friend/FriendItem.vue
  9. 31
      im-ui/src/components/group/GroupItem.vue
  10. 3
      im-ui/src/main.js
  11. 6
      im-ui/src/store/chatStore.js
  12. 12
      im-ui/src/view/Chat.vue
  13. 52
      im-ui/src/view/Friend.vue
  14. 46
      im-ui/src/view/Group.vue
  15. 66
      im-uniapp/common/date.js
  16. 53
      im-uniapp/components/chat-item/chat-item.vue
  17. 12
      im-uniapp/components/chat-message-item/chat-message-item.vue
  18. 45
      im-uniapp/components/chat-time/chat-time.vue
  19. 33
      im-uniapp/components/friend-item/friend-item.vue
  20. 21
      im-uniapp/components/group-item/group-item.vue
  21. 14
      im-uniapp/components/pop-menu/pop-menu.vue
  22. 2
      im-uniapp/main.js
  23. 33
      im-uniapp/pages/group/group-info.vue

66
im-ui/src/api/date.js

@ -0,0 +1,66 @@
let toTimeText = (timeStamp, simple) => {
var dateTime = new Date(timeStamp)
var currentTime = Date.parse(new Date()); //当前时间
var timeDiff = currentTime - dateTime; //与当前时间误差
var timeText = '';
if (timeDiff <= 60000) { //一分钟内
timeText = '刚刚';
} else if (timeDiff > 60000 && timeDiff < 3600000) {
//1小时内
timeText = Math.floor(timeDiff / 60000) + '分钟前';
} else if (timeDiff >= 3600000 && timeDiff < 86400000 && !isYestday(dateTime)) {
//今日
timeText = formatDateTime(dateTime).substr(11, 5);
} else if (isYestday(dateTime)) {
//昨天
timeText = '昨天' + formatDateTime(dateTime).substr(11, 5);
} else if (isYear(dateTime)) {
//今年
timeText = formatDateTime(dateTime).substr(5, simple ? 5 : 14);
} else {
//不属于今年
timeText = formatDateTime(dateTime);
if(simple){
timeText = timeText.substring(2,5);
}
}
return timeText;
}
let isYestday = (date) => {
var yesterday = new Date(new Date() - 1000 * 60 * 60 * 24);
return yesterday.getYear() === date.getYear() &&
yesterday.getMonth() === date.getMonth() &&
yesterday.getDate() === date.getDate();
}
let isYear = (date) => {
return date.getYear() === new Date().getYear();
}
let formatDateTime = (date) => {
if (date === '' || !date) {
return ''
}
var dateObject = new Date(date)
var y = dateObject.getFullYear()
var m = dateObject.getMonth() + 1
m = m < 10 ? ('0' + m) : m
var d = dateObject.getDate()
d = d < 10 ? ('0' + d) : d
var h = dateObject.getHours()
h = h < 10 ? ('0' + h) : h
var minute = dateObject.getMinutes()
minute = minute < 10 ? ('0' + minute) : minute
var second = dateObject.getSeconds()
second = second < 10 ? ('0' + second) : second
return y + '/' + m + '/' + d + ' ' + h + ':' + minute + ':' + second
}
export{
toTimeText,
isYestday,
isYear,
formatDateTime
}

10
im-ui/src/api/wssocket.js

@ -86,7 +86,7 @@ let close = () => {
//心跳设置 //心跳设置
var heartCheck = { let heartCheck = {
timeout: 5000, //每段时间发送一次心跳包 这里设置为20s timeout: 5000, //每段时间发送一次心跳包 这里设置为20s
timeoutObj: null, //延时发送消息对象(启动心跳新建这个对象,收到消息后重置对象) timeoutObj: null, //延时发送消息对象(启动心跳新建这个对象,收到消息后重置对象)
start: function() { start: function() {
@ -112,7 +112,7 @@ var heartCheck = {
// 实际调用的方法 // 实际调用的方法
function sendMessage(agentData) { let sendMessage = (agentData) => {
// console.log(globalCallback) // console.log(globalCallback)
if (websock.readyState === websock.OPEN) { if (websock.readyState === websock.OPEN) {
// 若是ws开启状态 // 若是ws开启状态
@ -131,16 +131,16 @@ function sendMessage(agentData) {
} }
function onMessage(callback) { let onMessage = (callback) => {
messageCallBack = callback; messageCallBack = callback;
} }
function onOpen(callback) { let onOpen = (callback) => {
openCallBack = callback; openCallBack = callback;
} }
function onClose(callback) { let onClose = (callback) => {
closeCallBack = callback; closeCallBack = callback;
} }
// 将方法暴露出去 // 将方法暴露出去

169
im-ui/src/components/chat/ChatItem.vue

@ -1,36 +1,53 @@
<template> <template>
<div class="chat-item" :class="active ? 'active' : ''" @contextmenu.prevent="showRightMenu($event)">
<div class="chat-item" :class="active ? 'active' : ''"> <div class="chat-left">
<div class="left"> <head-image :url="chat.headImage" :size="50" :id="chat.type=='PRIVATE'?chat.targetId:0"></head-image>
<head-image :url="chat.headImage" :size="40" :id="chat.type=='PRIVATE'?chat.targetId:0"></head-image>
<div v-show="chat.unreadCount>0" class="unread-text">{{chat.unreadCount}}</div> <div v-show="chat.unreadCount>0" class="unread-text">{{chat.unreadCount}}</div>
</div> </div>
<div class="mid"> <div class="chat-right">
<div>{{ chat.showName}}</div> <div class="chat-name">
<div class="msg-text" v-html="$emo.transform(chat.lastContent)"></div> {{ chat.showName}}
</div> </div>
<div class="right "> <div class="chat-content">
<div @click.stop="onClickClose()"><i class="el-icon-close close" style="border: none; font-size: 20px;color: black;" title="关闭"></i></div> <div class="chat-content-text" v-html="$emo.transform(chat.lastContent)"></div>
<div class="msg-time"> <div class="chat-time">{{showTime}}</div>
<chat-time :time="chat.lastSendTime"></chat-time>
</div> </div>
</div> </div>
<right-menu v-show="rightMenu.show" :pos="rightMenu.pos" :items="rightMenu.items"
@close="rightMenu.show=false" @select="handleSelectMenu"></right-menu>
</div> </div>
</template> </template>
<script> <script>
import ChatTime from "./ChatTime.vue";
import HeadImage from '../common/HeadImage.vue'; import HeadImage from '../common/HeadImage.vue';
import RightMenu from '../common/RightMenu.vue';
export default { export default {
name: "chatItem", name: "chatItem",
components: { components: {
ChatTime, HeadImage,
HeadImage RightMenu
}, },
data() { data() {
return {} return {
rightMenu: {
show: false,
pos: {
x: 0,
y: 0
},
items: [{
key: 'TOP',
name: '置顶',
icon: 'el-icon-top'
}, {
key: 'DELETE',
name: '删除',
icon: 'el-icon-delete'
}]
}
}
}, },
props: { props: {
chat: { chat: {
@ -44,55 +61,61 @@
} }
}, },
methods: { methods: {
showRightMenu(e) {
onClickClose(){ this.rightMenu.pos = {
this.$emit("del"); x: e.x,
y: e.y
};
this.rightMenu.show = "true";
},
handleSelectMenu(item) {
this.$emit(item.key.toLowerCase(), this.msgInfo);
}
},
computed: {
showTime() {
return this.$date.toTimeText(this.chat.lastSendTime, true)
} }
} }
} }
</script> </script>
<style lang="scss"> <style lang="scss">
.chat-item { .chat-item {
height: 65px; height: 65px;
display: flex; display: flex;
margin-bottom: 1px; margin-bottom: 1px;
position: relative; position: relative;
padding-left: 15px; padding-left: 10px;
align-items: center; align-items: center;
padding-right: 5px; padding-right: 5px;
background-color: #fafafa; background-color: #fafafa;
white-space: nowrap; white-space: nowrap;
color: black;
cursor: pointer;
&:hover { &:hover {
background-color: #eeeeee; background-color: #eeeeee;
} }
&.active { &.active {
background-color: #dddddd; background-color: #e8e8f0;
}
&:hover {
.close {
display: block !important;
}
} }
.left { .chat-left {
position: relative; position: relative;
display: flex; display: flex;
width: 45px; width: 50px;
height: 45px; height: 50px;
.unread-text { .unread-text {
position: absolute; position: absolute;
background-color: #f56c6c; background-color: #f56c6c;
right: -8px; right: -5px;
top: -8px; top: -5px;
color: white; color: white;
border-radius: 30px; border-radius: 30px;
padding: 0 5px; padding: 1px 5px;
font-size: 10px; font-size: 10px;
text-align: center; text-align: center;
white-space: nowrap; white-space: nowrap;
@ -101,65 +124,45 @@
} }
.mid { .chat-right {
margin-left: 15px; flex: 1;
flex: 2;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%; padding-left: 10px;
flex-shrink: 0; text-align: left;
overflow: hidden;
&>div {
display: flex;
justify-content: flex-start;
align-items: center;
flex: 1;
}
.msg-text { .chat-name {
font-size: 16px; font-size: 16px;
color: #888888; font-weight: 600;
line-height: 30px;
white-space: nowrap; white-space: nowrap;
overflow: hidden;
img{
width: 30px !important;
height: 30px !important;
}
} }
}
.right {
flex: 1;
display: flex;
flex-direction: column;
align-items: flex-end;
height: 100%;
flex-shrink: 0;
overflow: hidden;
&>div { .chat-content {
display: flex; display: flex;
justify-content: flex-start;
align-items: center;
flex: 1;
}
.close { .chat-content-text {
width: 1.5rem; flex: 2;
height: 1.5rem; font-size: 14px;
right: 0; white-space: nowrap;
top: 1rem; overflow: hidden;
cursor: pointer;
display: none;
}
.msg-time { img {
font-size: 14px; width: 30px !important;
color: #888888; height: 30px !important;
white-space: nowrap; }
}
.chat-time {
flex: 1;
font-size: 13px;
text-align: right;
color: #888888;
white-space: nowrap;
overflow: hidden;
}
} }
} }
} }
</style> </style>

20
im-ui/src/components/chat/ChatMessageItem.vue

@ -8,7 +8,7 @@
<div class="chat-msg-content"> <div class="chat-msg-content">
<div class="chat-msg-top"> <div class="chat-msg-top">
<span>{{showName}}</span> <span>{{showName}}</span>
<chat-time :time="msgInfo.sendTime"></chat-time> <span>{{$date.toTimeText(msgInfo.sendTime)}}</span>
</div> </div>
<div class="chat-msg-bottom" @contextmenu.prevent="showRightMenu($event)"> <div class="chat-msg-bottom" @contextmenu.prevent="showRightMenu($event)">
<span class="chat-msg-text" v-if="msgInfo.type==$enums.MESSAGE_TYPE.TEXT" <span class="chat-msg-text" v-if="msgInfo.type==$enums.MESSAGE_TYPE.TEXT"
@ -50,14 +50,12 @@
</template> </template>
<script> <script>
import ChatTime from "./ChatTime.vue";
import HeadImage from "../common/HeadImage.vue"; import HeadImage from "../common/HeadImage.vue";
import RightMenu from '../common/RightMenu.vue'; import RightMenu from '../common/RightMenu.vue';
export default { export default {
name: "messageItem", name: "messageItem",
components: { components: {
ChatTime,
HeadImage, HeadImage,
RightMenu RightMenu
}, },
@ -214,10 +212,10 @@
position: relative; position: relative;
line-height: 35px; line-height: 35px;
margin-top: 10px; margin-top: 10px;
padding: 10px; padding: 14px;
background-color: #eeeeee; background-color: rgb(235,235,245);
border-radius: 3px; border-radius: 10px;
color: #333; color: black;
display: block; display: block;
font-size: 17px; font-size: 17px;
text-align: left; text-align: left;
@ -232,9 +230,9 @@
width: 0; width: 0;
height: 0; height: 0;
border-style: solid dashed dashed; border-style: solid dashed dashed;
border-color: #eeeeee transparent transparent; border-color: rgb(235,235,245) transparent transparent;
overflow: hidden; overflow: hidden;
border-width: 10px; border-width: 13px;
} }
} }
@ -348,14 +346,14 @@
.chat-msg-text { .chat-msg-text {
margin-left: 10px; margin-left: 10px;
background-color: #5fb878; background-color: rgb(88, 127, 240);
color: #fff; color: #fff;
vertical-align: top; vertical-align: top;
&:after { &:after {
left: auto; left: auto;
right: -10px; right: -10px;
border-top-color: #5fb878; border-top-color: rgb(88, 127, 240);
} }
} }

43
im-ui/src/components/chat/ChatTime.vue

@ -1,43 +0,0 @@
<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 todayTime = new Date();
todayTime.setHours(0,0,0,0)
let dayDiff = Math.floor((todayTime.getTime() - time.getTime())/(24*3600*1000)) ;
if (time.getTime() > todayTime.getTime()) {
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+1}天前`;
} else {
strtime = time.getMonth()+1+"月"+time.getDate()+"日";
}
return strtime;
}
}
}
</script>
<style>
</style>

2
im-ui/src/components/common/HeadImage.vue

@ -46,7 +46,7 @@
img { img {
position: relative; position: relative;
overflow: hidden; overflow: hidden;
border-radius: 5%; border-radius: 10%;
} }
img:before { img:before {

38
im-ui/src/components/common/RightMenu.vue

@ -1,10 +1,12 @@
<template> <template>
<div class="right-menu-mask" @click="close()" @contextmenu.prevent="close()"> <div class="right-menu-mask" @click="close()" @contextmenu.prevent="close()">
<div class="right-menu" :style="{'left':pos.x+'px','top':pos.y+'px'}"> <div class="right-menu" :style="{'left':pos.x+'px','top':pos.y+'px'}">
<el-menu background-color="#f5f5f5" text-color="#333333"> <el-menu text-color="#333333">
<el-menu-item v-for="(item) in items" :key="item.key" :title="item.name" @click="handleSelectMenu(item)"> <el-menu-item v-for="(item) in items" :key="item.key" :title="item.name"
<i :class="item.icon"></i> @click="handleSelectMenu(item)">
<span :class="item.icon"></span>
<span>{{item.name}}</span> <span>{{item.name}}</span>
</el-menu-item> </el-menu-item>
</el-menu> </el-menu>
</div> </div>
@ -21,16 +23,16 @@
pos: { pos: {
type: Object type: Object
}, },
items:{ items: {
type: Array type: Array
} }
}, },
methods:{ methods: {
close(){ close() {
this.$emit("close"); this.$emit("close");
}, },
handleSelectMenu(item){ handleSelectMenu(item) {
this.$emit("select",item); this.$emit("select", item);
} }
} }
} }
@ -50,13 +52,21 @@
.right-menu { .right-menu {
position: fixed; position: fixed;
box-shadow: 0px 0px 10px #ccc;
.el-menu {
border: 1px solid #b4b4b4;
border-radius: 7px;
overflow: hidden;
.el-menu-item { .el-menu-item {
height: 40px; height: 40px;
line-height: 40px; line-height: 40px;
span {
font-weight: 600;
}
border-bottom: 1px solid #d0d0d0;
i {
color: #333333;
} }
} }
} }

106
im-ui/src/components/friend/FriendItem.vue

@ -1,34 +1,58 @@
<template> <template>
<div class="friend-item" :class="active ? 'active' : ''"> <div class="friend-item" :class="active ? 'active' : ''" @contextmenu.prevent="showRightMenu($event)">
<div class="avatar"> <div class="friend-avatar">
<head-image :url="friend.headImage"> </head-image> <head-image :url="friend.headImage"> </head-image>
</div> </div>
<div class="text"> <div class="friend-info">
<div>{{ friend.nickName}}</div> <div class="friend-name">{{ friend.nickName}}</div>
<div :class="online ? 'online-status online':'online-status'">{{ online?"[在线]":"[离线]"}}</div> <div class="friend-online" :class="friend.online ? 'online':''">{{ friend.online?"[在线]":"[离线]"}}</div>
</div>
<div v-if="showDelete" class="close" @click.stop="handleDel()">
<i class="el-icon-close" style="border: none; font-size: 20px;color: black;" title="添加好友"></i>
</div> </div>
<right-menu v-show="menu && rightMenu.show" :pos="rightMenu.pos" :items="rightMenu.items"
@close="rightMenu.show=false" @select="handleSelectMenu"></right-menu>
<slot></slot> <slot></slot>
</div> </div>
</template> </template>
<script> <script>
import HeadImage from '../common/HeadImage.vue'; import HeadImage from '../common/HeadImage.vue';
import RightMenu from "../common/RightMenu.vue";
export default { export default {
name: "frinedItem", name: "frinedItem",
components: { components: {
HeadImage HeadImage,
RightMenu
}, },
data() { data() {
return {} return {
rightMenu: {
show: false,
pos: {
x: 0,
y: 0
},
items: [{
key: 'CHAT',
name: '发送消息',
icon: 'el-icon-chat-dot-round'
}, {
key: 'DELETE',
name: '删除好友',
icon: 'el-icon-delete'
}]
}
}
}, },
methods:{ methods: {
handleDel(){ showRightMenu(e) {
console.log("11111111111111111111") this.rightMenu.pos = {
this.$emit('del',this.friend,this.index) x: e.x,
y: e.y
};
this.rightMenu.show = "true";
},
handleSelectMenu(item) {
this.$emit(item.key.toLowerCase(), this.msgInfo);
} }
}, },
props: { props: {
@ -41,16 +65,12 @@
index: { index: {
type: Number type: Number
}, },
showDelete:{ menu: {
type: Boolean, type: Boolean,
default: true default: true
} }
},
computed: {
online() {
return this.$store.state.friendStore.friends[this.index].online;
}
} }
} }
</script> </script>
@ -60,11 +80,12 @@
display: flex; display: flex;
margin-bottom: 1px; margin-bottom: 1px;
position: relative; position: relative;
padding-left: 15px; padding-left: 10px;
align-items: center; align-items: center;
padding-right: 5px; padding-right: 5px;
background-color: #fafafa; background-color: #fafafa;
white-space: nowrap; white-space: nowrap;
&:hover { &:hover {
background-color: #eeeeee; background-color: #eeeeee;
} }
@ -73,48 +94,31 @@
background-color: #dddddd; background-color: #dddddd;
} }
.friend-avatar {
.close {
width: 1.5rem;
height: 1.5rem;
right: 10px;
top: 1.825rem;
cursor: pointer;
display: none;
}
&:hover {
.close {
display: block;
}
}
.avatar {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
width: 45px; width: 50px;
height: 45px; height: 50px;
} }
.text { .friend-info {
margin-left: 15px;
flex: 1; flex: 1;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-around; padding-left: 10px;
height: 100%; text-align: left;
flex-shrink: 0;
overflow: hidden;
&>div { .friend-name {
display: flex; font-size: 16px;
justify-content: flex-start; font-weight: 600;
line-height: 30px;
white-space: nowrap;
overflow: hidden;
} }
.online-status { .friend-online {
font-size: 12px; font-size: 12px;
font-weight: 600;
&.online { &.online {
color: #5fb878; color: #5fb878;

31
im-ui/src/components/group/GroupItem.vue

@ -1,9 +1,9 @@
<template> <template>
<div class="item" :class="active ? 'active' : ''"> <div class="group-item" :class="active ? 'active' : ''">
<div class="avatar"> <div class="group-avatar">
<head-image :url="group.headImage"> </head-image> <head-image :url="group.headImage"> </head-image>
</div> </div>
<div class="text"> <div class="group-name">
<div>{{group.remark}}</div> <div>{{group.remark}}</div>
</div> </div>
</div> </div>
@ -33,12 +33,12 @@
</script> </script>
<style lang="scss" > <style lang="scss" >
.item { .group-item {
height: 65px; height: 65px;
display: flex; display: flex;
margin-bottom: 1px; margin-bottom: 1px;
position: relative; position: relative;
padding-left: 15px; padding-left: 10px;
align-items: center; align-items: center;
padding-right: 5px; padding-right: 5px;
background-color: #fafafa; background-color: #fafafa;
@ -51,21 +51,20 @@
background-color: #dddddd; background-color: #dddddd;
} }
.avatar { .group-avatar {
width: 45px; width: 50px;
height: 45px; height: 50px;
} }
.text { .group-name {
display: flex; padding-left: 10px;
flex-direction: column;
justify-content: space-around;
flex: 1;
margin-left: 15px;
height: 100%; height: 100%;
flex-shrink: 0;
overflow: hidden;
text-align: left; text-align: left;
line-height: 65px;
white-space: nowrap;
overflow: hidden;
font-size: 16px;
font-weight: 600;
} }
} }
</style> </style>

3
im-ui/src/main.js

@ -10,12 +10,13 @@ import emotion from './api/emotion.js';
import element from './api/element.js'; import element from './api/element.js';
import store from './store'; import store from './store';
import * as enums from './api/enums.js'; import * as enums from './api/enums.js';
import * as date from './api/date.js';
import './utils/directive/dialogDrag'; import './utils/directive/dialogDrag';
Vue.use(ElementUI); Vue.use(ElementUI);
// 挂载全局 // 挂载全局
Vue.prototype.$wsApi = socketApi; Vue.prototype.$wsApi = socketApi;
Vue.prototype.$date = date;
Vue.prototype.$http = httpRequest // http请求方法 Vue.prototype.$http = httpRequest // http请求方法
Vue.prototype.$emo = emotion; // emo表情 Vue.prototype.$emo = emotion; // emo表情
Vue.prototype.$elm = element; // 元素操作 Vue.prototype.$elm = element; // 元素操作

6
im-ui/src/store/chatStore.js

@ -57,6 +57,12 @@ export default {
state.activeIndex = state.chats.length - 1; state.activeIndex = state.chats.length - 1;
} }
}, },
moveTop(state,idx){
let chat = state.chats[idx];
// 放置头部
state.chats.splice(idx, 1);
state.chats.unshift(chat);
},
removeGroupChat(state, groupId) { removeGroupChat(state, groupId) {
for (let idx in state.chats) { for (let idx in state.chats) {
if (state.chats[idx].type == 'GROUP' && if (state.chats[idx].type == 'GROUP' &&

12
im-ui/src/view/Chat.vue

@ -8,7 +8,10 @@
</div> </div>
<el-scrollbar class="l-chat-list" > <el-scrollbar class="l-chat-list" >
<div v-for="(chat,index) in chatStore.chats" :key="index"> <div v-for="(chat,index) in chatStore.chats" :key="index">
<chat-item :chat="chat" :index="index" @click.native="handleActiveItem(index)" @del="handleDelItem(chat,index)" <chat-item :chat="chat" :index="index"
@click.native="handleActiveItem(index)"
@delete="handleDelItem(index)"
@top="handleTop(index)"
:active="index === chatStore.activeIndex"></chat-item> :active="index === chatStore.activeIndex"></chat-item>
</div> </div>
</el-scrollbar> </el-scrollbar>
@ -41,9 +44,12 @@
handleActiveItem(index) { handleActiveItem(index) {
this.$store.commit("activeChat", index); this.$store.commit("activeChat", index);
}, },
handleDelItem(chat, index) { handleDelItem(index) {
this.$store.commit("removeChat", index); this.$store.commit("removeChat", index);
} },
handleTop(chatIdx) {
this.$store.commit("moveTop", chatIdx);
},
}, },
computed: { computed: {
chatStore() { chatStore() {

52
im-ui/src/view/Friend.vue

@ -7,15 +7,16 @@
<el-button slot="append" icon="el-icon-search"></el-button> <el-button slot="append" icon="el-icon-search"></el-button>
</el-input> </el-input>
</div> </div>
<el-button plain icon="el-icon-plus" style="border: none; padding:12px; font-size: 20px;color: black;" title="添加好友" <el-button plain icon="el-icon-plus" style="border: none; padding:12px; font-size: 20px;color: black;"
@click="handleShowAddFriend()"></el-button> title="添加好友" @click="handleShowAddFriend()"></el-button>
<add-friend :dialogVisible="showAddFriend" @close="handleCloseAddFriend"> <add-friend :dialogVisible="showAddFriend" @close="handleCloseAddFriend">
</add-friend> </add-friend>
</div> </div>
<el-scrollbar class="l-friend-list" > <el-scrollbar class="l-friend-list">
<div v-for="(friend,index) in $store.state.friendStore.friends" :key="index"> <div v-for="(friend,index) in $store.state.friendStore.friends" :key="index">
<friend-item v-show="friend.nickName.startsWith(searchText)" :friend="friend" :index="index" :active="index === $store.state.friendStore.activeIndex" <friend-item v-show="friend.nickName.startsWith(searchText)" :friend="friend" :index="index"
@del="handleDelItem(friend,index)" @click.native="handleActiveItem(friend,index)"> :active="index === $store.state.friendStore.activeIndex" @chat="handleSendMessage(friend)"
@delete="handleDelItem(friend,index)" @click.native="handleActiveItem(friend,index)">
</friend-item> </friend-item>
</div> </div>
</el-scrollbar> </el-scrollbar>
@ -26,8 +27,8 @@
</div> </div>
<div v-show="userInfo.id"> <div v-show="userInfo.id">
<div class="user-detail"> <div class="user-detail">
<head-image class="detail-head-image" :size="200" <head-image class="detail-head-image" :size="200" :url="userInfo.headImage"
:url="userInfo.headImage" @click.native="showFullImage()"></head-image> @click.native="showFullImage()"></head-image>
<div class="info-item"> <div class="info-item">
<el-descriptions title="好友信息" class="description" :column="1"> <el-descriptions title="好友信息" class="description" :column="1">
<el-descriptions-item label="用户名">{{ userInfo.userName }} <el-descriptions-item label="用户名">{{ userInfo.userName }}
@ -40,7 +41,7 @@
</div> </div>
</div> </div>
<div class="btn-group"> <div class="btn-group">
<el-button class="send-btn" @click="handleSendMessage()">发消息</el-button> <el-button class="send-btn" @click="handleSendMessage(userInfo)">消息</el-button>
</div> </div>
</div> </div>
</el-container> </el-container>
@ -58,6 +59,7 @@
FriendItem, FriendItem,
AddFriend, AddFriend,
HeadImage HeadImage
}, },
data() { data() {
return { return {
@ -75,7 +77,7 @@
}, },
handleActiveItem(friend, index) { handleActiveItem(friend, index) {
this.$store.commit("activeFriend", index); this.$store.commit("activeFriend", index);
this.loadUserInfo(friend,index); this.loadUserInfo(friend, index);
}, },
handleDelItem(friend, index) { handleDelItem(friend, index) {
this.$confirm(`确认要解除与 '${friend.nickName}'的好友关系吗?`, '确认解除?', { this.$confirm(`确认要解除与 '${friend.nickName}'的好友关系吗?`, '确认解除?', {
@ -93,8 +95,7 @@
}) })
}) })
}, },
handleSendMessage() { handleSendMessage(user) {
let user = this.userInfo;
let chat = { let chat = {
type: 'PRIVATE', type: 'PRIVATE',
targetId: user.id, targetId: user.id,
@ -105,9 +106,9 @@
this.$store.commit("activeChat", 0); this.$store.commit("activeChat", 0);
this.$router.push("/home/chat"); this.$router.push("/home/chat");
}, },
showFullImage(){ showFullImage() {
if(this.userInfo.headImage){ if (this.userInfo.headImage) {
this.$store.commit('showFullImageBox',this.userInfo.headImage); this.$store.commit('showFullImageBox', this.userInfo.headImage);
} }
}, },
@ -125,7 +126,7 @@
this.$store.commit("updateChatFromFriend", user); this.$store.commit("updateChatFromFriend", user);
}) })
}, },
loadUserInfo(friend,index){ loadUserInfo(friend, index) {
this.$http({ this.$http({
url: `/user/find/${friend.id}`, url: `/user/find/${friend.id}`,
method: 'get' method: 'get'
@ -139,15 +140,15 @@
}) })
} }
}, },
computed:{ computed: {
friendStore(){ friendStore() {
return this.$store.state.friendStore; return this.$store.state.friendStore;
} }
}, },
mounted() { mounted() {
if(this.friendStore.activeIndex>=0){ if (this.friendStore.activeIndex >= 0) {
let friend = this.friendStore.friends[this.friendStore.activeIndex]; let friend = this.friendStore.friends[this.friendStore.activeIndex];
this.loadUserInfo(friend,this.friendStore.activeIndex); this.loadUserInfo(friend, this.friendStore.activeIndex);
} }
} }
@ -161,6 +162,7 @@
flex-direction: column; flex-direction: column;
border: #dddddd solid 1px; border: #dddddd solid 1px;
background: white; background: white;
.l-friend-header { .l-friend-header {
height: 50px; height: 50px;
display: flex; display: flex;
@ -173,7 +175,7 @@
} }
} }
.l-friend-ist{ .l-friend-ist {
flex: 1; flex: 1;
} }
} }
@ -182,6 +184,7 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
border: #dddddd solid 1px; border: #dddddd solid 1px;
.r-friend-header { .r-friend-header {
width: 100%; width: 100%;
height: 50px; height: 50px;
@ -196,24 +199,23 @@
} }
.user-detail { .user-detail {
width: 100%;
display: flex; display: flex;
padding: 50px 10px 10px 50px; padding: 50px 80px 20px 80px;
text-align: center; text-align: center;
.info-item { .info-item {
width: 400px;
height: 200px;
margin-left: 20px; margin-left: 20px;
background-color: #ffffff; background-color: #ffffff;
} }
.description { .description {
padding: 20px 20px 0px 20px; padding: 20px 20px 0px 20px;
} }
} }
.btn-group { .btn-group {
text-align: left !important; text-align: left !important;
padding-left: 100px; padding-left: 120px;
} }
} }
} }

46
im-ui/src/view/Group.vue

@ -7,13 +7,13 @@
<el-button slot="append" icon="el-icon-search"></el-button> <el-button slot="append" icon="el-icon-search"></el-button>
</el-input> </el-input>
</div> </div>
<el-button plain icon="el-icon-plus" style="border: none; padding: 12px; font-size: 20px;color: black;" title="创建群聊" <el-button plain icon="el-icon-plus" style="border: none; padding: 12px; font-size: 20px;color: black;"
@click="handleCreateGroup()"></el-button> title="创建群聊" @click="handleCreateGroup()"></el-button>
</div> </div>
<el-scrollbar class="l-group-list"> <el-scrollbar class="l-group-list">
<div v-for="(group,index) in groupStore.groups" :key="index"> <div v-for="(group,index) in groupStore.groups" :key="index">
<group-item v-show="group.remark.startsWith(searchText)" :group="group" :active="index === groupStore.activeIndex" <group-item v-show="group.remark.startsWith(searchText)" :group="group"
@click.native="handleActiveItem(group,index)"> :active="index === groupStore.activeIndex" @click.native="handleActiveItem(group,index)">
</group-item> </group-item>
</div> </div>
</el-scrollbar> </el-scrollbar>
@ -26,14 +26,16 @@
<div v-show="activeGroup.id"> <div v-show="activeGroup.id">
<div class="r-group-info"> <div class="r-group-info">
<div> <div>
<file-upload class="avatar-uploader" :action="imageAction" :disabled="!isOwner" :showLoading="true" <file-upload class="avatar-uploader" :action="imageAction" :disabled="!isOwner"
:maxSize="maxSize" @success="handleUploadSuccess" :fileTypes="['image/jpeg', 'image/png', 'image/jpg','image/webp']"> :showLoading="true" :maxSize="maxSize" @success="handleUploadSuccess"
:fileTypes="['image/jpeg', 'image/png', 'image/jpg','image/webp']">
<img v-if="activeGroup.headImage" :src="activeGroup.headImage" class="avatar"> <img v-if="activeGroup.headImage" :src="activeGroup.headImage" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i> <i v-else class="el-icon-plus avatar-uploader-icon"></i>
</file-upload> </file-upload>
<el-button class="send-btn" @click="handleSendMessage()">发送消息</el-button> <el-button class="send-btn" @click="handleSendMessage()">发送消息</el-button>
</div> </div>
<el-form class="r-group-form" label-width="130px" :model="activeGroup" :rules="rules" ref="groupForm"> <el-form class="r-group-form" label-width="130px" :model="activeGroup" :rules="rules"
ref="groupForm">
<el-form-item label="群聊名称" prop="name"> <el-form-item label="群聊名称" prop="name">
<el-input v-model="activeGroup.name" :disabled="!isOwner" maxlength="20"></el-input> <el-input v-model="activeGroup.name" :disabled="!isOwner" maxlength="20"></el-input>
</el-form-item> </el-form-item>
@ -41,13 +43,15 @@
<el-input :value="ownerName" disabled></el-input> <el-input :value="ownerName" disabled></el-input>
</el-form-item> </el-form-item>
<el-form-item label="备注"> <el-form-item label="备注">
<el-input v-model="activeGroup.remark" placeholder="群聊的备注仅自己可见" maxlength="20"></el-input> <el-input v-model="activeGroup.remark" placeholder="群聊的备注仅自己可见"
maxlength="20"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="我在本群的昵称"> <el-form-item label="我在本群的昵称">
<el-input v-model="activeGroup.aliasName" placeholder="" maxlength="20"></el-input> <el-input v-model="activeGroup.aliasName" placeholder="" maxlength="20"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="群公告"> <el-form-item label="群公告">
<el-input v-model="activeGroup.notice" :disabled="!isOwner" type="textarea" maxlength="1024" placeholder="群主未设置"></el-input> <el-input v-model="activeGroup.notice" :disabled="!isOwner" type="textarea"
maxlength="1024" placeholder="群主未设置"></el-input>
</el-form-item> </el-form-item>
<div class="btn-group"> <div class="btn-group">
<el-button type="success" @click="handleSaveGroup()">提交</el-button> <el-button type="success" @click="handleSaveGroup()">提交</el-button>
@ -60,16 +64,18 @@
<el-scrollbar style="height:400px;"> <el-scrollbar style="height:400px;">
<div class="r-group-member-list"> <div class="r-group-member-list">
<div v-for="(member) in groupMembers" :key="member.id"> <div v-for="(member) in groupMembers" :key="member.id">
<group-member v-show="!member.quit" class="r-group-member" :member="member" :showDel="isOwner&&member.userId!=activeGroup.ownerId" <group-member v-show="!member.quit" class="r-group-member" :member="member"
@del="handleKick"></group-member> :showDel="isOwner&&member.userId!=activeGroup.ownerId"
@del="handleKick"></group-member>
</div> </div>
<div class="r-group-invite"> <div class="r-group-invite">
<div class="invite-member-btn" title="邀请好友进群聊" @click="handleInviteMember()"> <div class="invite-member-btn" title="邀请好友进群聊" @click="handleInviteMember()">
<i class="el-icon-plus"></i> <i class="el-icon-plus"></i>
</div> </div>
<div class="invite-member-text">邀请</div> <div class="invite-member-text">邀请</div>
<add-group-member :visible="showAddGroupMember" :groupId="activeGroup.id" :members="groupMembers" @reload="loadGroupMembers" <add-group-member :visible="showAddGroupMember" :groupId="activeGroup.id"
@close="handleCloseAddGroupMember"></add-group-member> :members="groupMembers" @reload="loadGroupMembers"
@close="handleCloseAddGroupMember"></add-group-member>
</div> </div>
</div> </div>
</el-scrollbar> </el-scrollbar>
@ -119,12 +125,12 @@
inputErrorMessage: '请输入群聊名称' inputErrorMessage: '请输入群聊名称'
}).then((o) => { }).then((o) => {
let userInfo = this.$store.state.userStore.userInfo; let userInfo = this.$store.state.userStore.userInfo;
let data= { let data = {
name: o.value, name: o.value,
remark: o.value, remark: o.value,
aliasName: userInfo.name, aliasName: userInfo.name,
headImage: userInfo.headImage, headImage: userInfo.headImage,
headImageThumb: userInfo.headImageThumb, headImageThumb: userInfo.headImageThumb,
ownerId: userInfo.id ownerId: userInfo.id
} }
this.$http({ this.$http({
@ -182,7 +188,7 @@
this.$store.commit("removeGroup", this.activeGroup.id); this.$store.commit("removeGroup", this.activeGroup.id);
this.$store.commit("activeGroup", -1); this.$store.commit("activeGroup", -1);
this.$store.commit("removeGroupChat", this.activeGroup.id); this.$store.commit("removeGroupChat", this.activeGroup.id);
this.activeGroup= {}; this.activeGroup = {};
}); });
}) })
@ -254,7 +260,7 @@
isOwner() { isOwner() {
return this.activeGroup.ownerId == this.$store.state.userStore.userInfo.id; return this.activeGroup.ownerId == this.$store.state.userStore.userInfo.id;
}, },
imageAction(){ imageAction() {
return `${process.env.VUE_APP_BASE_API}/image/upload`; return `${process.env.VUE_APP_BASE_API}/image/upload`;
} }
}, },
@ -290,7 +296,7 @@
} }
} }
.l-group-ist{ .l-group-ist {
flex: 1; flex: 1;
} }
} }
@ -314,7 +320,7 @@
} }
.r-group-container { .r-group-container {
padding: 20px; padding: 50px;
.r-group-info { .r-group-info {
display: flex; display: flex;
@ -358,7 +364,7 @@
} }
.send-btn { .send-btn {
margin-top: 10px; margin-top: 20px;
} }
} }

66
im-uniapp/common/date.js

@ -0,0 +1,66 @@
let toTimeText = (timeStamp, simple) => {
var dateTime = new Date(timeStamp)
var currentTime = Date.parse(new Date()); //当前时间
var timeDiff = currentTime - dateTime; //与当前时间误差
var timeText = '';
if (timeDiff <= 60000) { //一分钟内
timeText = '刚刚';
} else if (timeDiff > 60000 && timeDiff < 3600000) {
//1小时内
timeText = Math.floor(timeDiff / 60000) + '分钟前';
} else if (timeDiff >= 3600000 && timeDiff < 86400000 && !isYestday(dateTime)) {
//今日
timeText = formatDateTime(dateTime).substr(11, 5);
} else if (isYestday(dateTime)) {
//昨天
timeText = '昨天' + formatDateTime(dateTime).substr(11, 5);
} else if (isYear(dateTime)) {
//今年
timeText = formatDateTime(dateTime).substr(5, simple ? 5 : 14);
} else {
//不属于今年
timeText = formatDateTime(dateTime);
if(simple){
timeText = timeText.substring(2,5);
}
}
return timeText;
}
let isYestday = (date) => {
var yesterday = new Date(new Date() - 1000 * 60 * 60 * 24);
return yesterday.getYear() === date.getYear() &&
yesterday.getMonth() === date.getMonth() &&
yesterday.getDate() === date.getDate();
}
let isYear = (date) => {
return date.getYear() === new Date().getYear();
}
let formatDateTime = (date) => {
if (date === '' || !date) {
return ''
}
var dateObject = new Date(date)
var y = dateObject.getFullYear()
var m = dateObject.getMonth() + 1
m = m < 10 ? ('0' + m) : m
var d = dateObject.getDate()
d = d < 10 ? ('0' + d) : d
var h = dateObject.getHours()
h = h < 10 ? ('0' + h) : h
var minute = dateObject.getMinutes()
minute = minute < 10 ? ('0' + minute) : minute
var second = dateObject.getSeconds()
second = second < 10 ? ('0' + second) : second
return y + '/' + m + '/' + d + ' ' + h + ':' + minute + ':' + second
}
export{
toTimeText,
isYestday,
isYear,
formatDateTime
}

53
im-uniapp/components/chat-item/chat-item.vue

@ -4,15 +4,14 @@
<image class="head-image" :src="chat.headImage" mode="aspectFill" lazy-load="true" ></image> <image class="head-image" :src="chat.headImage" mode="aspectFill" lazy-load="true" ></image>
<view v-show="chat.unreadCount>0" class="unread-text">{{chat.unreadCount}}</view> <view v-show="chat.unreadCount>0" class="unread-text">{{chat.unreadCount}}</view>
</view> </view>
<view class="mid"> <view class="chat-right">
<view class="show-name">{{ chat.showName}}</view> <view class="chat-name">
<view class="msg-text" v-html="$emo.transform(chat.lastContent)"></view> {{ chat.showName}}
</view> </view>
<view class="right "> <view class="chat-content">
<view class="msg-time"> <view class="chat-content-text" v-html="$emo.transform(chat.lastContent)"></view>
<chat-time :time="chat.lastSendTime"></chat-time> <view class="chat-time">{{$date.toTimeText(chat.lastSendTime)}}</view>
</view> </view>
<view></view>
</view> </view>
</view> </view>
</template> </template>
@ -41,7 +40,7 @@
} }
</script> </script>
<style lang="scss" scode> <style scoped lang="scss">
.chat-item { .chat-item {
height: 120rpx; height: 120rpx;
display: flex; display: flex;
@ -85,6 +84,42 @@
} }
} }
.chat-right {
flex: 1;
display: flex;
flex-direction: column;
padding-left: 20rpx;
text-align: left;
.chat-name {
font-size: 30rpx;
font-weight: 600;
line-height: 60rpx;
white-space: nowrap;
overflow: hidden;
}
.chat-content {
display: flex;
.chat-content-text {
flex: 2;
font-size: 28rpx;
white-space: nowrap;
overflow: hidden;
line-height: 50rpx;
}
.chat-time {
flex: 1;
font-size: 26rpx;
text-align: right;
color: #888888;
white-space: nowrap;
overflow: hidden;
}
}
}
.mid { .mid {
margin-left: 20rpx; margin-left: 20rpx;

12
im-uniapp/components/chat-message-item/chat-message-item.vue

@ -11,7 +11,7 @@
<view class="chat-msg-content" @longpress="onShowMenu($event)"> <view class="chat-msg-content" @longpress="onShowMenu($event)">
<view class="chat-msg-top"> <view class="chat-msg-top">
<text>{{showName}}</text> <text>{{showName}}</text>
<chat-time :time="msgInfo.sendTime"></chat-time> <text>{{$date.toTimeText(msgInfo.sendTime)}}</text>
</view> </view>
<view class="chat-msg-bottom"> <view class="chat-msg-bottom">
@ -216,7 +216,7 @@
.head-image { .head-image {
width: 100%; width: 100%;
height: 100%; height: 100%;
border-radius: 5%; border-radius: 10%;
} }
} }
@ -245,7 +245,7 @@
line-height: 30px; line-height: 30px;
margin-top: 10px; margin-top: 10px;
padding: 10px; padding: 10px;
background-color: #eeeeee; background-color: rgb(235,235,245);
border-radius: 3px; border-radius: 3px;
color: #333; color: #333;
font-size: 16px; font-size: 16px;
@ -262,7 +262,7 @@
width: 0; width: 0;
height: 0; height: 0;
border-style: solid dashed dashed; border-style: solid dashed dashed;
border-color: #eeeeee transparent transparent; border-color: rgb(235,235,245) transparent transparent;
overflow: hidden; overflow: hidden;
border-width: 10px; border-width: 10px;
} }
@ -384,13 +384,13 @@
padding-right: 0; padding-right: 0;
.chat-msg-text { .chat-msg-text {
margin-left: 10px; margin-left: 10px;
background-color: #45ab62; background-color: rgb(88, 127, 240);
color: #fff; color: #fff;
&:after { &:after {
left: auto; left: auto;
right: -10px; right: -10px;
border-top-color: #45ab62; border-top-color: rgb(88, 127, 240);
} }
} }

45
im-uniapp/components/chat-time/chat-time.vue

@ -1,45 +0,0 @@
<template>
<view>
<text>{{formatDate}}</text>
</view>
</template>
<script>
export default {
name: "chat-time",
data() {
return {}
},
props: {
time: {
type: Number
}
},
computed: {
formatDate() {
let time = new Date(this.time);
let strtime = "";
let todayTime = new Date();
todayTime.setHours(0, 0, 0, 0)
let dayDiff = Math.floor((todayTime.getTime() - time.getTime()) / (24 * 3600 * 1000));
if (time.getTime() > todayTime.getTime()) {
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+1}天前`;
} else {
strtime = time.getMonth() + 1 + "月" + time.getDate() + "日";
}
return strtime;
}
}
}
</script>
<style>
</style>

33
im-uniapp/components/friend-item/friend-item.vue

@ -1,11 +1,14 @@
<template> <template>
<view class="friend-item" @click="showFriendInfo()"> <view class="friend-item" @click="showFriendInfo()">
<view class="avatar"> <view class="friend-avatar">
<image class="head-image" :src="friend.headImage" lazy-load="true" mode="aspectFill"></image> <image class="head-image" :src="friend.headImage" lazy-load="true" mode="aspectFill"></image>
</view> </view>
<view class="text"> <view class="friend-info">
<view>{{ friend.nickName}}</view> <view class="friend-name">{{ friend.nickName}}</view>
<view :class="friend.online ? 'online-status online':'online-status'">{{ friend.online?"[在线]":"[离线]"}}</view> <view class="friend-online"
:class="friend.online ? 'online':''">
{{ friend.online?"[在线]":"[离线]"}}
</view>
</view> </view>
</view> </view>
</template> </template>
@ -46,7 +49,7 @@
background-color: #eeeeee; background-color: #eeeeee;
} }
.avatar { .friend-avatar {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
@ -61,21 +64,23 @@
} }
} }
.text { .friend-info {
font-size: 36rpx;
margin-left: 30rpx;
flex: 1; flex: 1;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-around; padding-left: 20rpx;
height: 100%; text-align: left;
flex-shrink: 0;
overflow: hidden;
.friend-name {
font-size: 30rpx;
font-weight: 600;
line-height: 60rpx;
white-space: nowrap;
overflow: hidden;
}
.online-status { .friend-online {
font-size: 28rpx; font-size: 28rpx;
font-weight: 600;
&.online { &.online {
color: #5fb878; color: #5fb878;

21
im-uniapp/components/group-item/group-item.vue

@ -1,9 +1,9 @@
<template> <template>
<view class="group-item" @click="showGroupInfo()"> <view class="group-item" @click="showGroupInfo()">
<view class="avatar"> <view class="group-avatar">
<image class="head-image" :src="group.headImage" lazy-load="true" mode="aspectFill"></image> <image class="head-image" :src="group.headImage" lazy-load="true" mode="aspectFill"></image>
</view> </view>
<view class="text"> <view class="group-name">
<view>{{ group.remark}}</view> <view>{{ group.remark}}</view>
</view> </view>
</view> </view>
@ -45,7 +45,7 @@
background-color: #eeeeee; background-color: #eeeeee;
} }
.avatar { .group-avatar {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
@ -60,15 +60,12 @@
} }
} }
.text { .group-name {
font-size: 36rpx; font-size: 32rpx;
margin-left: 30rpx; padding-left: 20rpx;
flex: 1; font-weight: 600;
display: flex; text-align: left;
flex-direction: column; white-space: nowrap;
justify-content: space-around;
height: 100%;
flex-shrink: 0;
overflow: hidden; overflow: hidden;
} }
} }

14
im-uniapp/components/pop-menu/pop-menu.vue

@ -49,18 +49,20 @@
.menu { .menu {
position: fixed; position: fixed;
border: 1px solid #d0d0d0; border: 1px solid #b4b4b4;
box-shadow: 0 0 20rpx gray; border-radius: 7px;
overflow: hidden;
box-shadow: 0px 0px 10px #ccc;
background-color: #eeeeee; background-color: #eeeeee;
.menu-item { .menu-item {
height: 30px; height: 25px;
line-height: 30px; line-height: 25px;
font-size: 20px; font-size: 18px;
display: flex; display: flex;
padding: 10px; padding: 10px;
align-items: center; align-items: center;
border-bottom: 1px solid #d0d0d0; border-bottom: 1px solid #d0d0d8;
} }
} }
</style> </style>

2
im-uniapp/main.js

@ -2,6 +2,7 @@ import App from './App'
import request from './common/request'; import request from './common/request';
import emotion from './common/emotion.js'; import emotion from './common/emotion.js';
import * as enums from './common/enums.js'; import * as enums from './common/enums.js';
import * as date from './common/date';
import * as socketApi from './common/wssocket'; import * as socketApi from './common/wssocket';
import store from './store'; import store from './store';
@ -14,6 +15,7 @@ export function createApp() {
app.config.globalProperties.$wsApi = socketApi; app.config.globalProperties.$wsApi = socketApi;
app.config.globalProperties.$emo = emotion; app.config.globalProperties.$emo = emotion;
app.config.globalProperties.$enums = enums; app.config.globalProperties.$enums = enums;
app.config.globalProperties.$date = date;
return { return {
app app
} }

33
im-uniapp/pages/group/group-info.vue

@ -4,10 +4,10 @@
<view class="member-items"> <view class="member-items">
<view v-for="(member,idx) in groupMembers" :key="idx"> <view v-for="(member,idx) in groupMembers" :key="idx">
<view class="member-item" v-if="idx<9" @click="onShowUserInfo(member.userId)"> <view class="member-item" v-if="idx<9" @click="onShowUserInfo(member.userId)">
<view class="avatar"> <view class="member-avatar">
<image class="head-image" :src="member.headImage" mode="aspectFill"> </image> <image class="head-image" :src="member.headImage" mode="aspectFill"> </image>
</view> </view>
<view class="text"> <view class="member-name">
<text>{{member.aliasName}}</text> <text>{{member.aliasName}}</text>
</view> </view>
</view> </view>
@ -19,28 +19,28 @@
<view class="member-more" @click="onShowMoreMmeber()">查看更多群成员 ></view> <view class="member-more" @click="onShowMoreMmeber()">查看更多群成员 ></view>
</view> </view>
<view class="group-detail"> <view class="group-detail">
<uni-section title="群聊名称:" titleFontSize="12px"> <uni-section title="群聊名称:" titleFontSize="14px">
<template v-slot:right> <template v-slot:right>
<text>{{group.name}}</text> <text class="detail-text">{{group.name}}</text>
</template> </template>
</uni-section> </uni-section>
<uni-section title="群主:" titleFontSize="12px"> <uni-section title="群主:" titleFontSize="14px">
<template v-slot:right> <template v-slot:right>
<text>{{ownerName}}</text> <text class="detail-text">{{ownerName}}</text>
</template> </template>
</uni-section> </uni-section>
<uni-section title="群聊备注:" titleFontSize="12px"> <uni-section title="群聊备注:" titleFontSize="14px">
<template v-slot:right> <template v-slot:right>
<text> {{group.remark}}</text> <text class="detail-text"> {{group.remark}}</text>
</template> </template>
</uni-section> </uni-section>
<uni-section title="我在本群的昵称:" titleFontSize="12px"> <uni-section title="我在本群的昵称:" titleFontSize="14px">
<template v-slot:right> <template v-slot:right>
<text> {{group.aliasName}}</text> <text class="detail-text"> {{group.aliasName}}</text>
</template> </template>
</uni-section> </uni-section>
<uni-section title="群公告:" titleFontSize="12px"> <uni-section title="群公告:" titleFontSize="14px">
<uni-notice-bar :text="group.notice" /> <uni-notice-bar :text="group.notice" />
</uni-section> </uni-section>
<view class="group-edit" @click="onEditGroup()">修改群聊资料 > </view> <view class="group-edit" @click="onEditGroup()">修改群聊资料 > </view>
@ -221,7 +221,7 @@
background-color: #fafafa; background-color: #fafafa;
white-space: nowrap; white-space: nowrap;
.avatar { .member-avatar {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
@ -236,7 +236,7 @@
} }
} }
.text { .member-name {
width: 100%; width: 100%;
flex: 1; flex: 1;
font-size: 14px; font-size: 14px;
@ -271,11 +271,14 @@
padding: 30rpx; padding: 30rpx;
background: white; background: white;
.detail-text{
font-size: 28rpx;
font-weight: 600;
}
.group-edit { .group-edit {
padding: 20rpx; padding: 20rpx;
text-align: center; text-align: center;
font-size: 16px; font-size: 30rpx;
} }
} }

Loading…
Cancel
Save