Browse Source

样式细节优化

master
xsx 7 months ago
parent
commit
af5368d0dd
  1. 1
      im-platform/src/main/java/com/bx/implatform/dto/RegisterDTO.java
  2. 5
      im-platform/src/main/java/com/bx/implatform/service/impl/UserServiceImpl.java
  3. 28
      im-web/src/assets/style/element.scss
  4. 12
      im-web/src/assets/style/im.scss
  5. 2
      im-web/src/components/chat/ChatBox.vue
  6. 22
      im-web/src/components/chat/ChatItem.vue
  7. 24
      im-web/src/components/chat/ChatMessageItem.vue
  8. 19
      im-web/src/components/common/FullImage.vue
  9. 2
      im-web/src/components/friend/AddFriend.vue
  10. 4
      im-web/src/components/friend/FriendItem.vue
  11. 6
      im-web/src/components/group/GroupItem.vue
  12. 14
      im-web/src/components/group/GroupMemberItem.vue
  13. 4
      im-web/src/store/configStore.js
  14. 16
      im-web/src/view/Chat.vue
  15. 11
      im-web/src/view/Friend.vue
  16. 11
      im-web/src/view/Group.vue
  17. 25
      im-web/src/view/Home.vue

1
im-platform/src/main/java/com/bx/implatform/dto/RegisterDTO.java

@ -20,7 +20,6 @@ public class RegisterDTO {
private String password; private String password;
@Length(max = 20, message = "昵称不能大于20字符") @Length(max = 20, message = "昵称不能大于20字符")
@NotEmpty(message = "用户昵称不可为空")
@Schema(description = "用户昵称") @Schema(description = "用户昵称")
private String nickName; private String nickName;

5
im-platform/src/main/java/com/bx/implatform/service/impl/UserServiceImpl.java

@ -1,5 +1,6 @@
package com.bx.implatform.service.impl; package com.bx.implatform.service.impl;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
@ -109,6 +110,10 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
@Override @Override
public void register(RegisterDTO dto) { public void register(RegisterDTO dto) {
// 昵称默认跟用户名保持一致
if(StrUtil.isEmpty(dto.getNickName())){
dto.setUserName(dto.getUserName());
}
User user = this.findUserByUserName(dto.getUserName()); User user = this.findUserByUserName(dto.getUserName());
if(!dto.getUserName().equals(sensitiveFilterUtil.filter(dto.getUserName()))){ if(!dto.getUserName().equals(sensitiveFilterUtil.filter(dto.getUserName()))){
throw new GlobalException("用户名包含敏感字符"); throw new GlobalException("用户名包含敏感字符");

28
im-web/src/assets/style/element.scss

@ -104,9 +104,27 @@ $--font-family: Microsoft YaHei, 'Avenir', Helvetica, Arial, sans-serif;
font-family: $--font-family; font-family: $--font-family;
} }
.el-tag--mini {
height: 18px; .el-tag {
padding: 0 2px; font-size: 10px;
height: 16px;
line-height: 16px; line-height: 16px;
border-radius: 2px; text-align: center;
} border-radius: 5px;
border: 0;
margin-left: 3px;
padding: 0 3px !important;
color: white !important;
&.el-tag--primary {
background: var(--im-color-primary-light-4);
}
&.el-tag--warning {
background: var(--im-color-warning);
}
&.el-tag--danger {
background: var(--im-color-danger);
}
}

12
im-web/src/assets/style/im.scss

@ -44,9 +44,9 @@
--im-box-shadow-dark: 0px 16px 48px 16px rgba(0, 0, 0, .08), 0px 12px 32px rgba(0, 0, 0, .12), 0px 8px 16px -8px rgba(0, 0, 0, .16); --im-box-shadow-dark: 0px 16px 48px 16px rgba(0, 0, 0, .08), 0px 12px 32px rgba(0, 0, 0, .12), 0px 8px 16px -8px rgba(0, 0, 0, .16);
// 背景色 // 背景色
--im-background: #F3F3F3; --im-background: white;
--im-background-active: #F1F1F1; --im-background-active: #f4f4fc;
--im-background-active-dark: #E9E9E9; --im-background-active-dark: var(--im-color-primary-light-9);
} }
html { html {
@ -83,6 +83,12 @@ section {
border-radius: 4px; border-radius: 4px;
} }
.el-scrollbar__thumb {
border-radius: 4px;
background: var(--im-color-primary-light-9) !important;
}
.search-input { .search-input {
.el-input__inner { .el-input__inner {
border: unset !important; border: unset !important;

2
im-web/src/components/chat/ChatBox.vue

@ -883,7 +883,7 @@ export default {
.im-chat-main { .im-chat-main {
padding: 0; padding: 0;
background-color: #fff; background-color: #f4f5f6;
.im-chat-box { .im-chat-box {
>ul { >ul {

22
im-web/src/components/chat/ChatItem.vue

@ -9,7 +9,7 @@
<div class="chat-name"> <div class="chat-name">
<div class="chat-name-text"> <div class="chat-name-text">
<div>{{ chat.showName }}</div> <div>{{ chat.showName }}</div>
<el-tag v-if="chat.type == 'GROUP'" size="mini"></el-tag> <el-tag v-if="chat.type == 'GROUP'" type="primary" size="mini"></el-tag>
</div> </div>
<div class="chat-time-text">{{ showTime }}</div> <div class="chat-time-text">{{ showTime }}</div>
</div> </div>
@ -117,14 +117,16 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.chat-item { .chat-item {
height: 50px; height: 56px;
display: flex; display: flex;
position: relative; position: relative;
padding: 5px 10px; margin: 0 3px;
padding: 5px 8px;
align-items: center; align-items: center;
background-color: var(--im-background); background-color: var(--im-background);
white-space: nowrap; white-space: nowrap;
cursor: pointer; cursor: pointer;
border-radius: 10px;
&:hover { &:hover {
background-color: var(--im-background-active); background-color: var(--im-background-active);
@ -166,8 +168,8 @@ export default {
.chat-name { .chat-name {
display: flex; display: flex;
line-height: 20px; line-height: 26px;
height: 20px; height: 26px;
.chat-name-text { .chat-name-text {
flex: 1; flex: 1;
@ -176,14 +178,6 @@ export default {
font-size: var(--im-font-size); font-size: var(--im-font-size);
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
.el-tag {
min-width: 22px;
text-align: center;
border-radius: 10px;
border: 0;
height: 16px;
}
} }
.chat-time-text { .chat-time-text {
@ -198,7 +192,7 @@ export default {
.chat-content { .chat-content {
display: flex; display: flex;
line-height: 22px; line-height: 24px;
.chat-at-text { .chat-at-text {
color: #c70b0b; color: #c70b0b;

24
im-web/src/components/chat/ChatMessageItem.vue

@ -23,7 +23,7 @@
<span class="message-text" v-if="isTextMessage" v-html="htmlText"></span> <span class="message-text" v-if="isTextMessage" v-html="htmlText"></span>
<div class="message-image" v-else-if="msgInfo.type == $enums.MESSAGE_TYPE.IMAGE" <div class="message-image" v-else-if="msgInfo.type == $enums.MESSAGE_TYPE.IMAGE"
@click="showFullImageBox()"> @click="showFullImageBox()">
<img :style="imageStyle" :src="contentData.thumbUrl" loading="lazy" /> <img :style="imageStyle" :src="contentData.thumbUrl" loading="lazy" />
</div> </div>
<div class="message-file" v-else-if="msgInfo.type == $enums.MESSAGE_TYPE.FILE"> <div class="message-file" v-else-if="msgInfo.type == $enums.MESSAGE_TYPE.FILE">
<div class="chat-file-box" v-loading="sending"> <div class="chat-file-box" v-loading="sending">
@ -116,7 +116,7 @@ export default {
}, },
methods: { methods: {
onSendFail() { onSendFail() {
this.$emit("resend",this.msgInfo); this.$emit("resend", this.msgInfo);
}, },
showFullImageBox() { showFullImageBox() {
let imageUrl = JSON.parse(this.msgInfo.content).originUrl; let imageUrl = JSON.parse(this.msgInfo.content).originUrl;
@ -301,18 +301,6 @@ export default {
white-space: pre-wrap; white-space: pre-wrap;
word-break: break-word; word-break: break-word;
&:after {
content: "";
position: absolute;
left: -10px;
top: 13px;
width: 0;
height: 0;
border-style: solid dashed dashed;
border-color: #eee transparent transparent;
overflow: hidden;
border-width: 10px;
}
} }
.message-image { .message-image {
@ -320,6 +308,7 @@ export default {
border: 2px solid var(--im-color-primary-light-9); border: 2px solid var(--im-color-primary-light-9);
overflow: hidden; overflow: hidden;
cursor: pointer; cursor: pointer;
background: var(--im-background);
} }
.message-file { .message-file {
@ -329,6 +318,7 @@ export default {
align-items: center; align-items: center;
cursor: pointer; cursor: pointer;
margin-bottom: 2px; margin-bottom: 2px;
background: var(--im-background);
.chat-file-box { .chat-file-box {
display: flex; display: flex;
@ -466,12 +456,6 @@ export default {
.message-text { .message-text {
background-color: var(--im-color-primary-light-2); background-color: var(--im-color-primary-light-2);
color: #fff; color: #fff;
&:after {
left: auto;
right: -10px;
border-top-color: var(--im-color-primary-light-2);
}
} }
.chat-action { .chat-action {

19
im-web/src/components/common/FullImage.vue

@ -64,12 +64,23 @@ export default {
} }
.close { .close {
display: flex;
align-items: center;
justify-content: center;
position: fixed; position: fixed;
top: 10px; top: 20px;
right: 10px; right: 20px;
color: white;
font-size: 25px;
cursor: pointer; cursor: pointer;
background: #333;
border-radius: 50%;
padding: 10px;
opacity: 0.5;
i {
font-weight: bold;
font-size: 20px;
color: white;
}
} }
} }
</style> </style>

2
im-web/src/components/friend/AddFriend.vue

@ -21,7 +21,7 @@
<div>用户名:{{ user.userName }}</div> <div>用户名:{{ user.userName }}</div>
</div> </div>
</div> </div>
<el-button type="success" size="mini" v-show="!isFriend(user.id)" <el-button type="primary" size="mini" v-show="!isFriend(user.id)"
@click="onAddFriend(user)">添加</el-button> @click="onAddFriend(user)">添加</el-button>
<el-button type="info" size="mini" v-show="isFriend(user.id)" plain disabled>已添加</el-button> <el-button type="info" size="mini" v-show="isFriend(user.id)" plain disabled>已添加</el-button>
</div> </div>

4
im-web/src/components/friend/FriendItem.vue

@ -74,9 +74,11 @@ export default {
height: 50px; height: 50px;
display: flex; display: flex;
position: relative; position: relative;
padding: 5px 10px;
align-items: center; align-items: center;
white-space: nowrap; white-space: nowrap;
border-radius: 10px;
margin: 0 3px;
padding: 5px 8px;
cursor: pointer; cursor: pointer;
&:hover { &:hover {

6
im-web/src/components/group/GroupItem.vue

@ -36,9 +36,9 @@ export default {
height: 50px; height: 50px;
display: flex; display: flex;
position: relative; position: relative;
padding: 5px 10px; border-radius: 10px;
align-items: center; margin: 0 3px;
white-space: nowrap; padding: 5px 8px;
cursor: pointer; cursor: pointer;
&:hover { &:hover {

14
im-web/src/components/group/GroupMemberItem.vue

@ -45,14 +45,16 @@ export default {
align-items: center; align-items: center;
white-space: nowrap; white-space: nowrap;
box-sizing: border-box; box-sizing: border-box;
border-radius: 5px;
margin: 0 1px;
&:hover { &:hover {
background-color: var(--im-background-active); background-color: var(--im-background-active);
} }
&.active { &.active {
background-color: #eeeeee; background-color: var(--im-background-active-dark);
} }
.member-name { .member-name {
flex: 1; flex: 1;

4
im-web/src/store/configStore.js

@ -5,6 +5,7 @@ export default defineStore('configStore', {
state: () => { state: () => {
return { return {
appInit: false, // 应用是否完成初始化 appInit: false, // 应用是否完成初始化
fullScreen: true, // 当前是否全屏
webrtc: {} webrtc: {}
} }
}, },
@ -15,6 +16,9 @@ export default defineStore('configStore', {
setAppInit(appInit) { setAppInit(appInit) {
this.appInit = appInit; this.appInit = appInit;
}, },
setFullScreen(fullScreen) {
this.fullScreen = fullScreen;
},
loadConfig() { loadConfig() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
http({ http({

16
im-web/src/view/Chat.vue

@ -1,6 +1,6 @@
<template> <template>
<el-container class="chat-page"> <el-container class="chat-page">
<el-aside width="260px" class="aside"> <el-aside width="260px" class="aside" :class="{ fullscreen: configStore.fullScreen }">
<div class="header"> <div class="header">
<el-input class="search-text" size="small" placeholder="搜索" v-model="searchText"> <el-input class="search-text" size="small" placeholder="搜索" v-model="searchText">
<i class="el-icon-search el-input__icon" slot="prefix"> </i> <i class="el-icon-search el-input__icon" slot="prefix"> </i>
@ -100,13 +100,15 @@ export default {
.aside { .aside {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
background: var(--im-background); background: white;
border-right: 1px solid #eee;
.header { &.fullscreen {
height: 50px; width: 260px !important;
display: flex;
align-items: center; @media (min-width: 1200px) {
padding: 0 8px; width: 290px !important;
}
} }
.chat-loading { .chat-loading {

11
im-web/src/view/Friend.vue

@ -1,6 +1,6 @@
<template> <template>
<el-container class="friend-page"> <el-container class="friend-page">
<el-aside width="260px" class="aside"> <el-aside width="260px" class="aside" :class="{ fullscreen: configStore.fullScreen }">
<div class="header"> <div class="header">
<el-input class="search-text" size="small" placeholder="搜索" v-model="searchText"> <el-input class="search-text" size="small" placeholder="搜索" v-model="searchText">
<i class="el-icon-search el-input__icon" slot="prefix"> </i> <i class="el-icon-search el-input__icon" slot="prefix"> </i>
@ -227,6 +227,15 @@ export default {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
background: var(--im-background); background: var(--im-background);
border-right: 1px solid #eee;
&.fullscreen {
width: 260px !important;
@media (min-width: 1200px) {
width: 290px !important;
}
}
.header { .header {
height: 50px; height: 50px;

11
im-web/src/view/Group.vue

@ -1,6 +1,6 @@
<template> <template>
<el-container class="group-page"> <el-container class="group-page">
<el-aside width="260px" class="aside"> <el-aside width="260px" class="aside" :class="{ fullscreen: configStore.fullScreen }">
<div class="header"> <div class="header">
<el-input class="search-text" size="small" placeholder="搜索" v-model="searchText"> <el-input class="search-text" size="small" placeholder="搜索" v-model="searchText">
<i class="el-icon-search el-input__icon" slot="prefix"> </i> <i class="el-icon-search el-input__icon" slot="prefix"> </i>
@ -353,6 +353,15 @@ export default {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
background: var(--im-background); background: var(--im-background);
border-right: 1px solid #eee;
&.fullscreen {
width: 260px !important;
@media (min-width: 1200px) {
width: 290px !important;
}
}
.header { .header {
height: 50px; height: 50px;

25
im-web/src/view/Home.vue

@ -1,6 +1,6 @@
<template> <template>
<div class="home-page" @click="closeUserInfo"> <div class="home-page" @click="closeUserInfo">
<div class="app-container" :class="{ fullscreen: isFullscreen }"> <div class="app-container" :class="{ fullscreen: configStore.fullScreen }">
<div class="navi-bar"> <div class="navi-bar">
<div class="navi-bar-box"> <div class="navi-bar-box">
<div class="top"> <div class="top">
@ -30,7 +30,7 @@
</div> </div>
<div class="botoom"> <div class="botoom">
<div class="bottom-item" @click="isFullscreen = !isFullscreen"> <div class="bottom-item" @click="onSwtichFullScreen">
<i class="el-icon-full-screen"></i> <i class="el-icon-full-screen"></i>
</div> </div>
<div class="bottom-item" @click="showSetting"> <div class="bottom-item" @click="showSetting">
@ -77,7 +77,6 @@ export default {
return { return {
showSettingDialog: false, showSettingDialog: false,
lastPlayAudioTime: new Date().getTime() - 1000, lastPlayAudioTime: new Date().getTime() - 1000,
isFullscreen: true,
reconnecting: false, reconnecting: false,
privateMessagesBuffer: [], privateMessagesBuffer: [],
groupMessagesBuffer: [] groupMessagesBuffer: []
@ -204,7 +203,7 @@ export default {
this.chatStore.clear(); this.chatStore.clear();
this.userStore.clear(); this.userStore.clear();
}, },
pullOfflineMessage() { pullOfflineMessage() {
this.chatStore.setLoading(true); this.chatStore.setLoading(true);
const promises = []; const promises = [];
promises.push(this.pullPrivateOfflineMessage(this.chatStore.privateMsgMaxId)); promises.push(this.pullPrivateOfflineMessage(this.chatStore.privateMsgMaxId));
@ -407,6 +406,9 @@ export default {
closeUserInfo() { closeUserInfo() {
this.$refs.userInfo.close(); this.$refs.userInfo.close();
}, },
onSwtichFullScreen() {
this.configStore.setFullScreen(!this.configStore.fullScreen);
},
onExit() { onExit() {
this.unloadStore(); this.unloadStore();
this.configStore.setAppInit(false); this.configStore.setAppInit(false);
@ -538,35 +540,38 @@ export default {
} }
.menu { .menu {
height: 200px;
//margin-top: 10px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-content: center; align-content: center;
flex-wrap: wrap;
margin-top: 20px;
.link { .link {
text-decoration: none; text-decoration: none;
} }
.router-link-active .menu-item { .router-link-active .menu-item {
color: #fff; color: white;
background: var(--im-color-primary-light-2); background: var(--im-color-primary-light-2);
} }
.link:not(.router-link-active) .menu-item:hover { .link:not(.router-link-active) .menu-item:hover {
color: var(--im-color-primary-light-7); background: var(--im-color-primary);
transform: scale(1.1);
} }
.menu-item { .menu-item {
position: relative; position: relative;
color: var(--im-color-primary-light-4); color: #eee;
width: var(--width); width: var(--width);
height: 46px; height: 46px;
width: 46px;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
margin-bottom: 12px; margin-top: 30px;
border-radius: 10px;
.icon { .icon {
font-size: var(--icon-font-size) font-size: var(--icon-font-size)

Loading…
Cancel
Save