Browse Source

uniapp优化

master
libaogang 1 year ago
parent
commit
b7d447a420
  1. 31
      im-uniapp/App.vue
  2. 24
      im-uniapp/components/chat-at-box/chat-at-box.vue
  3. 5
      im-uniapp/components/chat-group-readed/chat-group-readed.vue
  4. 57
      im-uniapp/components/chat-item/chat-item.vue
  5. 79
      im-uniapp/components/chat-message-item/chat-message-item.vue
  6. 32
      im-uniapp/components/chat-record/chat-record.vue
  7. 21
      im-uniapp/components/friend-item/friend-item.vue
  8. 23
      im-uniapp/components/group-item/group-item.vue
  9. 37
      im-uniapp/components/head-image/head-image.vue
  10. 118
      im-uniapp/components/nav-bar/nav-bar.vue
  11. 32
      im-uniapp/components/pop-menu/pop-menu.vue
  12. 60
      im-uniapp/im-var.scss
  13. 141
      im-uniapp/im.scss
  14. 7
      im-uniapp/pages.json
  15. 61
      im-uniapp/pages/chat/chat-box.vue
  16. 31
      im-uniapp/pages/chat/chat.vue
  17. 143
      im-uniapp/pages/common/user-info.vue
  18. 14
      im-uniapp/pages/friend/friend-add.vue
  19. 45
      im-uniapp/pages/friend/friend.vue
  20. 60
      im-uniapp/pages/group/group-edit.vue
  21. 65
      im-uniapp/pages/group/group-info.vue
  22. 33
      im-uniapp/pages/group/group-invite.vue
  23. 25
      im-uniapp/pages/group/group-member.vue
  24. 22
      im-uniapp/pages/group/group.vue
  25. 13
      im-uniapp/pages/login/login.vue
  26. 58
      im-uniapp/pages/mine/mine-edit.vue
  27. 32
      im-uniapp/pages/mine/mine-password.vue
  28. 112
      im-uniapp/pages/mine/mine.vue
  29. 11
      im-uniapp/pages/register/register.vue
  30. 46
      im-uniapp/uni.scss

31
im-uniapp/App.vue

@ -383,6 +383,7 @@
<style lang="scss"> <style lang="scss">
@import "@/uni_modules/uview-plus/index.scss"; @import "@/uni_modules/uview-plus/index.scss";
@import "@/im.scss";
@import url('./static/icon/iconfont.css'); @import url('./static/icon/iconfont.css');
// #ifdef H5 // #ifdef H5
@ -392,17 +393,37 @@
// #endif // #endif
.tab-page { .tab-page {
position: relative;
display: flex;
flex-direction: column;
// #ifdef H5 // #ifdef H5
height: calc(100vh - 50px); // h5100vh height: calc(100vh - 50px - $im-nav-bar-height); // h5100vh
top: $im-nav-bar-height;
// #endif // #endif
// #ifndef H5 // #ifndef H5
height: calc(100vh); height: calc(100vh - var(--status-bar-height) - $im-nav-bar-height); // app
top: calc($im-nav-bar-height + var(--status-bar-height));
// #endif // #endif
background-color: #f8f8f8; color: $im-text-color;
background-color: $im-bg;
font-size: $im-font-size;
font-family: $font-family;
} }
.page { .page {
height: calc(100vh); position: relative;
background-color: #f8f8f8; // #ifdef H5
height: calc(100vh - $im-nav-bar-height); // app
top: $im-nav-bar-height;
// #endif
// #ifndef H5
height: calc(100vh - var(--status-bar-height) - $im-nav-bar-height); // app
top: calc($im-nav-bar-height + var(--status-bar-height));
// #endif
color: $im-text-color;
background-color: $im-bg;
font-size: $im-font-size;
font-family: $font-family;
} }
</style> </style>

24
im-uniapp/components/chat-at-box/chat-at-box.vue

@ -10,7 +10,7 @@
<scroll-view v-show="atUserIds.length>0" scroll-x="true" scroll-left="120"> <scroll-view v-show="atUserIds.length>0" scroll-x="true" scroll-left="120">
<view class="at-user-items"> <view class="at-user-items">
<view v-for="m in showMembers" v-show="m.checked" class="at-user-item"> <view v-for="m in showMembers" v-show="m.checked" class="at-user-item">
<head-image :name="m.showNickName" :url="m.headImage" :size="60"></head-image> <head-image :name="m.showNickName" :url="m.headImage" size="mini"></head-image>
</view> </view>
</view> </view>
</scroll-view> </scroll-view>
@ -21,13 +21,13 @@
<scroll-view class="scroll-bar" scroll-with-animation="true" scroll-y="true"> <scroll-view class="scroll-bar" scroll-with-animation="true" scroll-y="true">
<view v-for="m in showMembers" v-show="m.showNickName.includes(searchText)" <view v-for="m in showMembers" v-show="m.showNickName.includes(searchText)"
:key="m.userId"> :key="m.userId">
<view class="member-item" @click="onSwitchChecked(m)"> <view class="member-item" :class="{checked: m.checked}" @click="onSwitchChecked(m)">
<head-image :name="m.showNickName" :online="m.online" :url="m.headImage" <head-image :name="m.showNickName" :online="m.online" :url="m.headImage"
:size="90"></head-image> size="small"></head-image>
<view class="member-name">{{ m.showNickName}}</view> <view class="member-name">{{ m.showNickName}}</view>
<view class="member-checked"> <!-- <view class="member-checked">-->
<radio :checked="m.checked" @click.stop="onSwitchChecked(m)" /> <!-- <radio :checked="m.checked" @click.stop="onSwitchChecked(m)" />-->
</view> <!-- </view>-->
</view> </view>
</view> </view>
</scroll-view> </scroll-view>
@ -112,7 +112,7 @@
flex-direction: column; flex-direction: column;
background-color: white; background-color: white;
padding: 10rpx; padding: 10rpx;
border-radius: 15rpx; //border-radius: 15rpx;
.chat-at-top { .chat-at-top {
display: flex; display: flex;
@ -148,19 +148,23 @@
overflow: hidden; overflow: hidden;
.member-item { .member-item {
height: 120rpx; height: 110rpx;
display: flex; display: flex;
position: relative; position: relative;
padding: 0 30rpx; padding: 0 30rpx;
align-items: center; align-items: center;
background-color: white; background-color: white;
white-space: nowrap; white-space: nowrap;
margin-bottom: 1px;
&.checked {
background-color: $im-color-primary-light-9;
}
.member-name { .member-name {
flex: 1; flex: 1;
padding-left: 20rpx; padding-left: 20rpx;
font-size: 30rpx; font-size: $im-font-size;
font-weight: 600;
line-height: 60rpx; line-height: 60rpx;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;

5
im-uniapp/components/chat-group-readed/chat-group-readed.vue

@ -2,7 +2,7 @@
<uni-popup ref="popup" type="bottom"> <uni-popup ref="popup" type="bottom">
<view class="chat-group-readed"> <view class="chat-group-readed">
<view class="uni-padding-wrap uni-common-mt"> <view class="uni-padding-wrap uni-common-mt">
<uni-segmented-control :current="current" :values="items" style-type="button" active-color="#587ff0" @clickItem="onClickItem"/> <uni-segmented-control :current="current" :values="items" style-type="button" @clickItem="onClickItem"/>
</view> </view>
<view class="content"> <view class="content">
<view v-if="current === 0"> <view v-if="current === 0">
@ -100,7 +100,8 @@
flex-direction: column; flex-direction: column;
background-color: white; background-color: white;
padding: 10rpx; padding: 10rpx;
border-radius: 15rpx;
//border-radius: 15rpx;
.scroll-bar { .scroll-bar {
height: 800rpx; height: 800rpx;
} }

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

@ -3,13 +3,13 @@
<!--rich-text中的表情包会屏蔽事件所以这里用一个遮罩层捕获点击事件 --> <!--rich-text中的表情包会屏蔽事件所以这里用一个遮罩层捕获点击事件 -->
<view class="mask" @tap="showChatBox()"></view> <view class="mask" @tap="showChatBox()"></view>
<view class="left"> <view class="left">
<head-image :url="chat.headImage" :name="chat.showName" :size="90"></head-image> <head-image :url="chat.headImage" :name="chat.showName"></head-image>
</view> </view>
<view class="chat-right"> <view class="chat-right">
<view class="chat-name"> <view class="chat-name">
<view class="chat-name-text"> <view class="chat-name-text">
<view>{{chat.showName}}</view> <view>{{chat.showName}}</view>
<uni-tag v-if="chat.type=='GROUP'" circle text="群" size="small"></uni-tag> <uni-tag v-if="chat.type=='GROUP'" circle text="群" size="small" type="primary"></uni-tag>
</view> </view>
<view class="chat-time">{{$date.toTimeText(chat.lastSendTime,true)}}</view> <view class="chat-time">{{$date.toTimeText(chat.lastSendTime,true)}}</view>
</view> </view>
@ -17,7 +17,7 @@
<view class="chat-at-text">{{atText}}</view> <view class="chat-at-text">{{atText}}</view>
<view class="chat-send-name" v-if="isShowSendName">{{chat.sendNickName+':&nbsp;'}}</view> <view class="chat-send-name" v-if="isShowSendName">{{chat.sendNickName+':&nbsp;'}}</view>
<rich-text class="chat-content-text" :nodes="$emo.transform(chat.lastContent)"></rich-text> <rich-text class="chat-content-text" :nodes="$emo.transform(chat.lastContent)"></rich-text>
<uni-badge v-if="chat.unreadCount>0" size="small" :max-num="99" :text="chat.unreadCount" /> <uni-badge v-if="chat.unreadCount>0" :max-num="99" :text="chat.unreadCount" />
</view> </view>
</view> </view>
</view> </view>
@ -76,28 +76,29 @@
<style scoped lang="scss"> <style scoped lang="scss">
.chat-item { .chat-item {
height: 100rpx; height: 96rpx;
display: flex; display: flex;
margin-bottom: 2rpx; margin-bottom: 2rpx;
position: relative; position: relative;
padding: 10rpx 20rpx; padding: 18rpx 20rpx;
align-items: center; align-items: center;
background-color: white; background-color: white;
white-space: nowrap; white-space: nowrap;
&:hover { &:hover {
background-color: #f5f6ff; background-color: $im-bg-active;
} }
&.active { &.active {
background-color: #f5f6ff; background-color: $im-bg-active;
} }
.mask { .mask {
position: absolute; position: absolute;
width: 100%; width: 100%;
height: 100%; height: 100%;
left: 0;
right: 0;
z-index: 99; z-index: 99;
} }
@ -108,27 +109,24 @@
align-items: center; align-items: center;
width: 100rpx; width: 100rpx;
height: 100rpx; height: 100rpx;
} }
.chat-right { .chat-right {
height: 100%;
flex: 1; flex: 1;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center;
padding-left: 20rpx; padding-left: 20rpx;
text-align: left; text-align: left;
overflow: hidden; overflow: hidden;
.chat-name { .chat-name {
display: flex; display: flex;
line-height: 44rpx;
height: 44rpx;
.chat-name-text { .chat-name-text {
flex: 1; flex: 1;
font-size: 30rpx; font-size: $im-font-size-large;
font-weight: 600;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
display: flex; display: flex;
@ -138,19 +136,15 @@
text-align: center; text-align: center;
margin-left: 5rpx; margin-left: 5rpx;
border: 0; border: 0;
height: 30rpx;
line-height: 30rpx;
font-size: 20rpx;
padding: 1px 5px; padding: 1px 5px;
background-color: #de1c1c; //opacity: 0.8;
opacity: 0.8;
} }
} }
.chat-time { .chat-time {
font-size: 26rpx; font-size: $im-font-size-smaller-extra;
text-align: right; color: $im-text-color-lighter;
color: #888888; text-align: right;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
} }
@ -158,24 +152,27 @@
.chat-content { .chat-content {
display: flex; display: flex;
line-height: 60rpx; font-size: $im-font-size-smaller;
height: 60rpx; color: $im-text-color-lighter;
padding-top: 8rpx;
.chat-at-text { .chat-at-text {
color: #c70b0b; color: $im-color-danger;
font-size: 24rpx;
} }
.chat-send-name { .chat-send-name {
font-size: 26rpx; font-size: $im-font-size-smaller;
} }
.chat-content-text { .chat-content-text {
flex: 1; flex: 1;
font-size: 28rpx;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
img {
width: 40rpx !important;
height: 40rpx !important;
}
} }
} }

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

@ -9,7 +9,7 @@
</view> </view>
<view class="chat-msg-normal" v-if="isNormal" :class="{'chat-msg-mine':msgInfo.selfSend}"> <view class="chat-msg-normal" v-if="isNormal" :class="{'chat-msg-mine':msgInfo.selfSend}">
<head-image class="avatar" @longpress.prevent="$emit('longPressHead')" :id="msgInfo.sendId" :url="headImage" <head-image class="avatar" @longpress.prevent="$emit('longPressHead')" :id="msgInfo.sendId" :url="headImage"
:name="showName" :size="80"></head-image> :name="showName" size="small"></head-image>
<view class="chat-msg-content"> <view class="chat-msg-content">
<view v-if="msgInfo.groupId && !msgInfo.selfSend" class="chat-msg-top"> <view v-if="msgInfo.groupId && !msgInfo.selfSend" class="chat-msg-top">
<text>{{showName}}</text> <text>{{showName}}</text>
@ -23,7 +23,7 @@
<view class="chat-msg-image" v-if="msgInfo.type==$enums.MESSAGE_TYPE.IMAGE"> <view class="chat-msg-image" v-if="msgInfo.type==$enums.MESSAGE_TYPE.IMAGE">
<pop-menu :items="menuItems" @select="onSelectMenu"> <pop-menu :items="menuItems" @select="onSelectMenu">
<view class="img-load-box"> <view class="img-load-box">
<image class="send-image" mode="heightFix" :src="JSON.parse(msgInfo.content).thumbUrl" <image class="send-image" mode="widthFix" :src="JSON.parse(msgInfo.content).thumbUrl"
lazy-load="true" @click.stop="onShowFullImage()"> lazy-load="true" @click.stop="onShowFullImage()">
</image> </image>
<loading v-if="loading"></loading> <loading v-if="loading"></loading>
@ -230,15 +230,14 @@
.chat-msg-tip { .chat-msg-tip {
line-height: 60rpx; line-height: 60rpx;
text-align: center; text-align: center;
color: #555; color: $im-text-color-lighter;
font-size: 24rpx; font-size: $im-font-size-smaller-extra;
padding: 10rpx; padding: 10rpx;
} }
.chat-msg-normal { .chat-msg-normal {
position: relative; position: relative;
font-size: 0; margin-bottom: 22rpx;
margin-bottom: 15rpx;
padding-left: 110rpx; padding-left: 110rpx;
min-height: 80rpx; min-height: 80rpx;
@ -254,10 +253,9 @@
.chat-msg-top { .chat-msg-top {
display: flex; display: flex;
flex-wrap: nowrap; flex-wrap: nowrap;
color: #333; color: $im-text-color-lighter;
font-size: 24rpx; font-size: $im-font-size-smaller;
line-height: 24rpx; line-height: $im-font-size-smaller;
} }
.chat-msg-bottom { .chat-msg-bottom {
@ -266,13 +264,13 @@
.chat-msg-text { .chat-msg-text {
position: relative; position: relative;
line-height: 60rpx; line-height: 1.6;
margin-top: 10rpx; margin-top: 10rpx;
padding: 8rpx 20rpx; padding: 16rpx 24rpx;
background-color: #eee; background-color: $im-bg;
border-radius: 20rpx; border-radius: 20rpx;
color: #333; color: $im-text-color;
font-size: 30rpx; font-size: $im-font-size;
text-align: left; text-align: left;
display: block; display: block;
word-break: break-all; word-break: break-all;
@ -287,9 +285,10 @@
width: 6rpx; width: 6rpx;
height: 6rpx; height: 6rpx;
border-style: solid dashed dashed; border-style: solid dashed dashed;
border-color: #eee transparent transparent; border-color: $im-bg transparent transparent;
overflow: hidden; overflow: hidden;
border-width: 18rpx; border-width: 18rpx;
//box-shadow: $im-box-shadow-dark;
} }
} }
@ -305,18 +304,16 @@
.send-image { .send-image {
min-width: 200rpx; min-width: 200rpx;
min-height: 200rpx; max-width: 420rpx;
max-width: 400rpx;
max-height: 400rpx;
border: 8rpx solid #ebebf5;
cursor: pointer; cursor: pointer;
border-radius: 4px;
} }
} }
.send-fail { .send-fail {
color: #e60c0c; color: $im-color-danger;
font-size: 30px; font-size: $im-font-size;
cursor: pointer; cursor: pointer;
margin: 0 20px; margin: 0 20px;
} }
@ -334,12 +331,10 @@
display: flex; display: flex;
flex-wrap: nowrap; flex-wrap: nowrap;
align-items: center; align-items: center;
min-height: 80px; min-height: 60px;
border: #eee solid 1px; border-radius: 4px;
border-radius: 10rpx;
background-color: #eeeeee;
padding: 10px 15px; padding: 10px 15px;
box-shadow: 2px 2px 2px #c0c0c0; box-shadow: $im-box-shadow-dark;
.chat-file-info { .chat-file-info {
flex: 1; flex: 1;
@ -349,7 +344,6 @@
width: 300rpx; width: 300rpx;
.chat-file-name { .chat-file-name {
font-size: 16px;
font-weight: 600; font-weight: 600;
margin-bottom: 15px; margin-bottom: 15px;
word-break: break-all; word-break: break-all;
@ -380,7 +374,7 @@
} }
.icon-voice-play { .icon-voice-play {
font-size: 20px; font-size: 18px;
padding-right: 8px; padding-right: 8px;
} }
} }
@ -396,29 +390,28 @@
} }
.chat-msg-status { .chat-msg-status {
display: block; line-height: $im-font-size-smaller-extra;
font-size: $im-font-size-smaller-extra;
padding-top: 2rpx;
.chat-readed { .chat-readed {
font-size: 12px; display: block;
color: #888; padding-top: 2rpx;
font-weight: 600; color: $im-text-color-lighter;
} }
.chat-unread { .chat-unread {
font-size: 12px; color: $im-color-danger;
color: #f23c0f;
font-weight: 600;
} }
} }
.chat-receipt { .chat-receipt {
font-size: 13px; font-size: $im-font-size-smaller;
color: darkblue; color: $im-text-color-lighter;
font-weight: 600; font-weight: 600;
.icon-ok { .icon-ok {
font-size: 20px; font-size: 20px;
color: #329432; color: $im-color-success;
} }
} }
} }
@ -444,13 +437,13 @@
.chat-msg-text { .chat-msg-text {
margin-left: 10px; margin-left: 10px;
background-color: #587ff0; background-color: $im-color-primary-light-2;
color: #fff; color: #fff;
&:after { &:after {
left: auto; left: auto;
right: -10px; right: -9px;
border-top-color: #587ff0; border-top-color: $im-color-primary-light-2;
} }
} }

32
im-uniapp/components/chat-record/chat-record.vue

@ -1,6 +1,6 @@
<template> <template>
<view class="chat-record"> <view class="chat-record">
<view class="chat-record-bar" id="chat-record-bar" :style="recordBarStyle" @click.stop="" <view class="chat-record-bar" :class="{recording: recording }" id="chat-record-bar" @click.stop=""
@touchstart.prevent="onStartRecord" @touchmove.prevent="onTouchMove" @touchend.prevent="onEndRecord"> @touchstart.prevent="onStartRecord" @touchmove.prevent="onTouchMove" @touchend.prevent="onEndRecord">
{{recording?'正在录音':'长按 说话'}}</view> {{recording?'正在录音':'长按 说话'}}</view>
<view v-if="recording" class="chat-record-window" :style="recordWindowStyle"> <view v-if="recording" class="chat-record-window" :style="recordWindowStyle">
@ -130,12 +130,6 @@
const bottom = windowHeight - this.recordBarTop + 12; const bottom = windowHeight - this.recordBarTop + 12;
return `bottom:${bottom}px;` return `bottom:${bottom}px;`
}, },
recordBarStyle() {
const bgColor = this.recording ? "royalblue" : "white";
const textColor = this.recording ? "white" : "black";
return `background-color:${bgColor};
color:${textColor};`
},
recordTip() { recordTip() {
if (this.druation > 50) { if (this.druation > 50) {
return `${60-this.druation}s后将停止录音`; return `${60-this.druation}s后将停止录音`;
@ -157,7 +151,7 @@
height: 80rpx; height: 80rpx;
.note { .note {
background: linear-gradient(to top, #395ff3 0%, #89aff3 100%); background: linear-gradient(to top, $im-color-primary-light-1 0%, $im-color-primary-light-6 100%);
width: 4px; width: 4px;
height: 50%; height: 50%;
border-radius: 5rpx; border-radius: 5rpx;
@ -167,19 +161,19 @@
@keyframes loading { @keyframes loading {
0% { 0% {
background-image: linear-gradient(to right, #395ff3 0%, #89aff3 100%); background-image: linear-gradient(to right, $im-color-primary-light-1 0%, $im-color-primary-light-6 100%);
height: 20%; height: 20%;
border-radius: 5rpx; border-radius: 5rpx;
} }
50% { 50% {
background-image: linear-gradient(to top, #395ff3 0%, #a9cff3 100%); background-image: linear-gradient(to top, $im-color-primary-light-1 0%, $im-color-primary-light-6 100%);
height: 80%; height: 80%;
border-radius: 5rpx; border-radius: 5rpx;
} }
100% { 100% {
background-image: linear-gradient(to top, #395ff3 0%, #a9cff3 100%); background-image: linear-gradient(to top, $im-color-primary-light-1 0%, $im-color-primary-light-6 100%);
height: 20%; height: 20%;
border-radius: 5rpx; border-radius: 5rpx;
} }
@ -192,13 +186,19 @@
margin: 10rpx; margin: 10rpx;
border-radius: 10rpx; border-radius: 10rpx;
text-align: center; text-align: center;
box-shadow: $im-box-shadow;
&.recording {
background-color: $im-color-primary;
color: #fff;
}
} }
.chat-record-window { .chat-record-window {
position: fixed; position: fixed;
left: 0; left: 0;
right: 0;
height: 360rpx; height: 360rpx;
width: 100%;
background-color: rgba(255, 255, 255, 0.95); background-color: rgba(255, 255, 255, 0.95);
padding: 30rpx; padding: 30rpx;
@ -211,7 +211,8 @@
.rc-tip { .rc-tip {
text-align: center; text-align: center;
font-size: 30rpx; font-size: $im-font-size-small;
color: $im-text-color-light;
margin-top: 20rpx; margin-top: 20rpx;
} }
@ -229,12 +230,9 @@
} }
.red { .red {
color: red !important; color: $im-color-danger !important;
} }
.black {
color: gray;
}
} }
} }
</style> </style>

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

@ -1,7 +1,6 @@
<template> <template>
<view class="friend-item" @click="showFriendInfo()"> <view class="friend-item" @click="showFriendInfo()">
<head-image :name="friend.nickName" :online="friend.online" :url="friend.headImage" <head-image :name="friend.nickName" :online="friend.online" :url="friend.headImage" size="smaller"></head-image>
:size="90"></head-image>
<view class="friend-info"> <view class="friend-info">
<view class="friend-name">{{ friend.nickName}}</view> <view class="friend-name">{{ friend.nickName}}</view>
<view class="friend-online"> <view class="friend-online">
@ -37,7 +36,7 @@
<style scope lang="scss"> <style scope lang="scss">
.friend-item { .friend-item {
height: 100rpx; height: 80rpx;
display: flex; display: flex;
margin-bottom: 1rpx; margin-bottom: 1rpx;
position: relative; position: relative;
@ -48,7 +47,7 @@
white-space: nowrap; white-space: nowrap;
&:hover { &:hover {
background-color: #f5f6ff; background-color: $im-bg;
} }
.friend-info { .friend-info {
@ -59,21 +58,19 @@
text-align: left; text-align: left;
.friend-name { .friend-name {
font-size: 30rpx; font-size: $im-font-size;
font-weight: 600;
line-height: 60rpx;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
} }
.friend-online { .friend-online {
margin-top: 4rpx;
.online { .online {
padding-right: 4rpx; padding-right: 4rpx;
width: 32rpx; width: 24rpx;
height: 32rpx; height: 24rpx;
} }
} }
} }
} }
</style> </style>

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

@ -1,7 +1,7 @@
<template> <template>
<view class="group-item" @click="showGroupInfo()"> <view class="group-item" @click="showGroupInfo()">
<head-image :name="group.showGroupName" <head-image :name="group.showGroupName"
:url="group.headImage" :size="90"></head-image> :url="group.headImage"></head-image>
<view class="group-name"> <view class="group-name">
<view>{{ group.showGroupName}}</view> <view>{{ group.showGroupName}}</view>
</view> </view>
@ -33,21 +33,24 @@
.group-item { .group-item {
height: 100rpx; height: 100rpx;
display: flex; display: flex;
margin-bottom: 1rpx; margin-bottom: 2rpx;
position: relative; position: relative;
padding: 10rpx; padding: 18rpx 20rpx;
padding-left: 20rpx;
align-items: center; align-items: center;
background-color: white; background-color: white;
white-space: nowrap; white-space: nowrap;
&:hover {
background-color: #f5f6ff;
}
.group-name { &:hover {
font-size: 32rpx; background-color: $im-bg-active;
}
&.active {
background-color: $im-bg-active;
}
.group-name {
font-size: $im-font-size;
padding-left: 20rpx; padding-left: 20rpx;
font-weight: 600;
text-align: left; text-align: left;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;

37
im-uniapp/components/head-image/head-image.vue

@ -3,7 +3,7 @@
<image class="avatar-image" v-if="url" :src="url" <image class="avatar-image" v-if="url" :src="url"
:style="avatarImageStyle" lazy-load="true" mode="aspectFill"/> :style="avatarImageStyle" lazy-load="true" mode="aspectFill"/>
<view class="avatar-text" v-if="!url" :style="avatarTextStyle"> <view class="avatar-text" v-if="!url" :style="avatarTextStyle">
{{name.substring(0,1).toUpperCase()}} {{name?.substring(0,1).toUpperCase()}}
</view> </view>
<view v-if="online" class="online" title="用户当前在线"> <view v-if="online" class="online" title="用户当前在线">
</view> </view>
@ -24,20 +24,20 @@
type: Number type: Number
}, },
size: { size: {
type: Number, type: [Number, String],
default: 20 default: 'default'
}, },
url: { url: {
type: String type: String
}, },
name: { name: {
type: String, type: String,
default: "?" default: null
}, },
online: { online: {
type: Boolean, type: Boolean,
default: false default: false
} },
}, },
methods: { methods: {
showUserInfo(e) { showUserInfo(e) {
@ -49,15 +49,30 @@
} }
}, },
computed: { computed: {
_size(){
if(typeof this.size === 'number'){
return this.size;
} else if(typeof this.size === 'string'){
return {
'default': 96,
'small': 84,
'smaller': 72,
'mini': 60,
'minier': 48,
'lage': 108,
'lager': 120,
}[this.size]
}
},
avatarImageStyle() { avatarImageStyle() {
return `width:${this.size}rpx; return `width:${this._size}rpx;
height:${this.size}rpx;` height:${this._size}rpx;`
}, },
avatarTextStyle() { avatarTextStyle() {
return `width: ${this.size}rpx; return `width: ${this._size}rpx;
height:${this.size}rpx; height:${this._size}rpx;
background-color:${this.textColor}; background-color:${this.name ? this.textColor : '#fff'};
font-size:${this.size*0.5}rpx; font-size:${this._size*0.5}rpx;
` `
}, },
textColor() { textColor() {

118
im-uniapp/components/nav-bar/nav-bar.vue

@ -0,0 +1,118 @@
<template>
<view class="im-nav-bar">
<!-- #ifndef H5 -->
<view style="height: var(--status-bar-height)"></view>
<!-- #endif -->
<view class="im-nav-bar-content">
<view class="back" @click="handleBackClick" v-if="back">
<uni-icons type="back" :size="iconFontSize"></uni-icons>
</view>
<view class="title" v-if="title">
<slot></slot>
</view>
<view class="btn">
<uni-icons class="btn-item" v-if="search" type="search" :size="iconFontSize" @click="$emit('search')"></uni-icons>
<uni-icons class="btn-item" v-if="add" type="plusempty" :size="iconFontSize" @click="$emit('add')"></uni-icons>
<uni-icons class="btn-item" v-if="more" type="more-filled" :size="iconFontSize" @click="$emit('more')"></uni-icons>
</view>
</view>
</view>
</template>
<script>
export default {
name: "nav-bar",
props: {
back: {
type: Boolean,
default: false
},
title: {
type: Boolean,
default: true
},
search: {
type: Boolean,
default: false
},
add: {
type: Boolean,
default: false
},
more: {
type: Boolean,
default: false
},
iconFontSize: {
type: Number,
default: 24
}
},
data() {
return {}
},
computed: {
height() {
}
},
methods: {
handleBackClick() {
uni.navigateBack({
delta: 1
})
}
}
}
</script>
<style scoped lang="scss">
.im-nav-bar {
background-color: #fff;
//background-color: $im-bg;
position: fixed;
top: 0;
width: 100%;
color: $im-text-color;
border-bottom: 1px solid $im-border-light;
font-size: $im-font-size-large;
z-index: 99;
.im-nav-bar-content {
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
height: $im-nav-bar-height;
.title {
}
.back {
position: absolute;
left: 0;
height: 100%;
display: flex;
align-items: center;
padding: 12px;
font-size: 22px;
box-sizing: border-box;
}
.btn {
position: absolute;
right: 0;
height: 100%;
display: flex;
padding: 12px;
align-items: center;
box-sizing: border-box;
.btn-item {
margin-left: 8px;
}
}
}
}
</style>

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

@ -6,7 +6,7 @@
<view v-if="isShowMenu" class="pop-menu" @touchstart="onClose()" @contextmenu.prevent=""></view> <view v-if="isShowMenu" class="pop-menu" @touchstart="onClose()" @contextmenu.prevent=""></view>
<view v-if="isShowMenu" class="menu" :style="menuStyle"> <view v-if="isShowMenu" class="menu" :style="menuStyle">
<view class="menu-item" v-for="(item) in items" :key="item.key" @click.prevent="onSelectMenu(item)"> <view class="menu-item" v-for="(item) in items" :key="item.key" @click.prevent="onSelectMenu(item)">
<uni-icons class="menu-icon" :type="item.icon" :style="itemStyle(item)" size="22"></uni-icons> <!-- <uni-icons class="menu-icon" :type="item.icon" :style="itemStyle(item)" size="20"></uni-icons>-->
<text :style="itemStyle(item)"> {{item.name}}</text> <text :style="itemStyle(item)"> {{item.name}}</text>
</view> </view>
</view> </view>
@ -75,7 +75,7 @@
if(item.color){ if(item.color){
return `color:${item.color};` return `color:${item.color};`
} }
return `color:#4f76e6;`; // return `color:#4f76e6;`;
} }
} }
} }
@ -90,29 +90,29 @@
bottom: 0; bottom: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
background-color: #333;
z-index: 999; z-index: 999;
opacity: 0.5;
} }
.menu { .menu {
position: fixed; position: fixed;
border: 1px solid #b4b4b4; border-radius: 4px;
border-radius: 7px;
overflow: hidden; overflow: hidden;
background-color: #f5f6ff; background-color: #fff;
z-index: 1000; z-index: 1000;
box-shadow: $im-box-shadow-dark;
.menu-item { .menu-item {
height: 25px; height: 28px;
min-width: 150rpx; min-width: 120rpx;
line-height: 25px; line-height: 28px;
font-size: 18px; font-size: $im-font-size-small;
display: flex; display: flex;
padding: 10px; padding: 6px 20px;
justify-content: center; justify-content: flex-start;
border-bottom: 1px solid #d0d0d8;
&:hover {
background: $im-bg-active;
}
.menu-icon { .menu-icon {
margin-right: 10rpx; margin-right: 10rpx;
} }

60
im-uniapp/im-var.scss

@ -0,0 +1,60 @@
// 颜色
$im-color-primary: #3e45d7;
$im-color-primary-light-1: mix(#fff, $im-color-primary, 10%);
$im-color-primary-light-2: mix(#fff, $im-color-primary, 20%);
$im-color-primary-light-3: mix(#fff, $im-color-primary, 30%);
$im-color-primary-light-4: mix(#fff, $im-color-primary, 40%);
$im-color-primary-light-5: mix(#fff, $im-color-primary, 50%);
$im-color-primary-light-6: mix(#fff, $im-color-primary, 60%);
$im-color-primary-light-7: mix(#fff, $im-color-primary, 70%);
$im-color-primary-light-8: mix(#fff, $im-color-primary, 80%);
$im-color-primary-light-9: mix(#fff, $im-color-primary, 90%);
$im-color-primary-dark-1: mix(#000, $im-color-primary, 10%);
$im-color-primary-dark-2: mix(#000, $im-color-primary, 20%);
$im-color-primary-dark-3: mix(#000, $im-color-primary, 30%);
$im-color-primary-dark-4: mix(#000, $im-color-primary, 40%);
$im-color-success: #18bc37;
$im-color-warning: #f3a73f;
$im-color-danger: #e43d33;
$im-color-info: #8f939c;
// 文字颜色
$im-text-color: #000000;
$im-text-color-light: #6a6a6a;
$im-text-color-lighter: #909399;
$im-text-color-lighter-extra: #c7c7c7;
// 边框颜色
$im-border: #F0F0F0;
$im-border-light: #EDEDED;
$im-border-lighter: #DCDCDC;
$im-border-lighter-extra: #B9B9B9;
// 文字大小
$im-font-size: 30rpx;
$im-font-size-small: 28rpx;
$im-font-size-smaller: 26rpx;
$im-font-size-smaller-extra: 24rpx;
$im-font-size-large: 32rpx;
$im-font-size-larger: 34rpx;
$im-font-size-larger-extra: 36rpx;
// 阴影
$im-box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);
$im-box-shadow-light: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
$im-box-shadow-lighter: 0px 0px 6px rgba(0, 0, 0, .12);
$im-box-shadow-dark: 0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5);
// 背景
$im-bg: #f7f7f7;
$im-bg-active: #f1f1f1;
// 标题
$im-title-size: 26px;
$im-title-size-1: 22px;
$im-title-size-2: 18px;
$font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, SimSun, sans-serif;
$im-nav-bar-height: 50px;

141
im-uniapp/im.scss

@ -0,0 +1,141 @@
/** 原生button样式 **/
uni-button {
font-size: $im-font-size !important;
}
uni-button[type='primary'] {
colo: #fff !important;
background-color: $im-color-primary !important;
}
uni-button[type='primary'][plain] {
color: $im-color-primary !important;
border: 1px solid $im-color-primary;
background-color: transparent;
}
uni-button[type='warn'] {
colo: #fff !important;
background-color: $im-color-danger !important;
}
uni-button[type='warn'][plain] {
color: $im-color-danger !important;
border: 1px solid $im-color-danger !important;
background-color: transparent !important;
}
uni-button[size='mini'] {
font-size: $im-font-size-smaller !important;
}
.button-hover[type='primary'] {
colo: #fff !important;
background-color: $im-color-primary-dark-1 !important;
}
/** uni-ui input激活后边框、图标颜色 **/
.uni-easyinput__content.is-focused:not(.is-input-error-border) {
border-color: $im-color-primary-light-2 !important;
.content-clear-icon {
color: $im-color-primary-light-2 !important;
}
}
/** 底部导航 **/
.uni-tabbar-bottom .uni-tabbar {
box-shadow: $im-box-shadow;
}
.uni-tabbar-border {
display: none;
}
.segmented-control {
border-color: $im-color-primary !important;
.segmented-control__item--button {
border-color: $im-color-primary !important;
}
.segmented-control__item--button--active {
background-color: $im-color-primary !important;
.segmented-control__text{
color: #fff !important;
}
}
.segmented-control__text{
color: $im-color-primary !important;
}
}
.uni-radio-input {
//border-color: $im-color-primary !important;
//background-color: $im-color-primary !important;
}
.uni-section__content-title {
font-size: $im-font-size !important;
color: $im-text-color-light;
}
.uni-forms-item__label {
color: $im-text-color;
font-size: $im-font-size !important;
}
.uni-forms-item {
//margin-bottom: 8px !important;
}
.uni-easyinput__content-input {
font-size: $im-font-size !important;
}
.uni-easyinput__placeholder-class {
color: $im-text-color-lighter;
font-size: $im-font-size !important;;
}
.uni-easyinput__content-textarea {
font-size: $im-font-size !important;;
}
.uni-input-input:disabled {
color: $im-text-color-light;
}
.uni-forms-item.is-direction-top .uni-forms-item__label {
padding: 0 !important;
}
.uni-data-checklist .checklist-group .checklist-box .checklist-content .checklist-text {
font-size: $im-font-size !important;
}
.uni-card .uni-card__content {
color: unset !important;
padding: 10px 0 !important;
}
.uni-tag-text--small{
font-size: 10px !important;
font-weight: bolder !important;
}
.nav-bar {
height: 100rpx;
padding: 0 20rpx;
display: flex;
align-items: center;
background-color: white;
border-bottom: 1px solid $im-border;
.nav-search {
flex: 1;
}
.nav-add {
cursor: pointer;
}
}
.bottom-btn {
margin: 40rpx 40rpx;
uni-button + uni-button {
margin-top: 20rpx;
}
}

7
im-uniapp/pages.json

@ -44,10 +44,9 @@
} }
], ],
"globalStyle": { "globalStyle": {
"navigationBarTitleText": "盒子IM", "navigationStyle": "custom",
"navigationBarTextStyle": "black", "navigationBarBackgroundColor": "#f7f7f7",
"navigationBarBackgroundColor": "#F0F0F0", "backgroundColor": "#f7f7f7"
"backgroundColor": "#fdfdfd"
}, },
"tabBar": { "tabBar": {
"color": "#000000", "color": "#000000",

61
im-uniapp/pages/chat/chat-box.vue

@ -1,9 +1,6 @@
<template> <template>
<view class="page chat-box"> <view class="page chat-box">
<view class="header"> <nav-bar back more @more="onShowMore">{{title}}</nav-bar>
<text class="title">{{title}}</text>
<uni-icons class="btn-side right" type="more-filled" size="30" @click="onShowMore()"></uni-icons>
</view>
<view class="chat-msg" @click="switchChatTabBox('none',true)"> <view class="chat-msg" @click="switchChatTabBox('none',true)">
<scroll-view class="scroll-box" scroll-y="true" upper-threshold="200" @scrolltoupper="onScrollToTop" <scroll-view class="scroll-box" scroll-y="true" upper-threshold="200" @scrolltoupper="onScrollToTop"
:scroll-into-view="'chat-item-'+scrollMsgIdx"> :scroll-into-view="'chat-item-'+scrollMsgIdx">
@ -21,7 +18,7 @@
<scroll-view v-if="atUserIds.length>0" class="chat-at-scroll-box" scroll-x="true" scroll-left="120"> <scroll-view v-if="atUserIds.length>0" class="chat-at-scroll-box" scroll-x="true" scroll-left="120">
<view class="chat-at-items"> <view class="chat-at-items">
<view v-for="m in atUserItems" class="chat-at-item"> <view v-for="m in atUserItems" class="chat-at-item">
<head-image :name="m.showNickName" :url="m.headImage" :size="50"></head-image> <head-image :name="m.showNickName" :url="m.headImage" size="minier"></head-image>
</view> </view>
</view> </view>
</scroll-view> </scroll-view>
@ -779,12 +776,13 @@
padding: 5px; padding: 5px;
background-color: #f9f9f9; background-color: #f9f9f9;
line-height: 50px; line-height: 50px;
font-size: 36rpx; font-size: $im-font-size-large;
box-shadow: $im-box-shadow-lighter;
z-index: 1;
.btn-side { .btn-side {
position: absolute; position: absolute;
line-height: 60rpx; line-height: 60rpx;
font-size: 28rpx;
cursor: pointer; cursor: pointer;
&.right { &.right {
@ -811,9 +809,9 @@
padding: 0 10rpx; padding: 0 10rpx;
.icon-at { .icon-at {
font-size: 35rpx; font-size: $im-font-size-larger;
color: darkblue; color: $im-color-primary;
font-weight: 600; font-weight: bold;
} }
.chat-at-scroll-box { .chat-at-scroll-box {
@ -833,33 +831,37 @@
} }
$icon-color: rgba(0,0,0, 0.88);
.send-bar { .send-bar {
display: flex; display: flex;
align-items: center; align-items: center;
padding: 10rpx; padding: 10rpx;
margin-bottom: 10rpx; //margin-bottom: 10rpx;
border-top: #eee solid 1px; border-top: $im-border solid 1px;
background-color: #f7f8fd; background-color: $im-bg;
height: 80rpx; height: 80rpx;
//box-shadow: $im-box-shadow-lighter;
z-index: 1;
.iconfont { .iconfont {
font-size: 68rpx; font-size: 60rpx;
margin: 6rpx; margin: 0 10rpx;
color: $icon-color;
} }
.chat-record { .chat-record {
flex: 1; flex: 1;
} }
.send-text { .send-text {
flex: 1; flex: 1;
overflow: auto; overflow: auto;
padding: 20rpx; padding: 14rpx 20rpx;
background-color: #fff; background-color: #fff;
border-radius: 20rpx; border-radius: 8rpx;
font-size: 30rpx; font-size: $im-font-size;
box-sizing: border-box; box-sizing: border-box;
margin: 0 10rpx;
.send-text-area { .send-text-area {
width: 100%; width: 100%;
@ -875,28 +877,30 @@
.chat-tab-bar { .chat-tab-bar {
height: 500rpx; height: 500rpx;
padding: 20rpx; padding: 20rpx;
background-color: #f8f8f8; background-color: $im-bg;
.chat-tools { .chat-tools {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
padding-top: 20rpx;
.chat-tools-item { .chat-tools-item {
width: 140rpx; width: 25%;
padding: 16rpx; padding: 16rpx;
box-sizing: border-box;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
.tool-icon { .tool-icon {
padding: 28rpx; padding: 26rpx;
font-size: 60rpx; font-size: 54rpx;
border-radius: 20%; border-radius: 20%;
background-color: white; background-color: white;
color: black; color: $icon-color;
&.active { &:active {
background-color: #ddd; background-color: $im-bg-active;
} }
} }
@ -914,10 +918,11 @@
.emotion-item-list { .emotion-item-list {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
justify-content: space-between;
.emotion-item { .emotion-item {
width: 40px; width: 34px;
height: 40px; height: 34px;
text-align: center; text-align: center;
cursor: pointer; cursor: pointer;
padding: 6px; padding: 6px;

31
im-uniapp/pages/chat/chat.vue

@ -1,17 +1,18 @@
<template> <template>
<view class="tab-page"> <view class="tab-page">
<nav-bar search @search="showSearch = !showSearch">消息</nav-bar>
<view v-if="loading" class="chat-loading"> <view v-if="loading" class="chat-loading">
<loading :size="50" :mask="false"> <loading :size="50" :mask="false">
<view>消息接收中...</view> <view>消息接收中...</view>
</loading> </loading>
</view> </view>
<view class="nav-bar"> <view class="nav-bar" v-if="showSearch">
<view class="nav-search"> <view class="nav-search">
<uni-search-bar radius="100" v-model="searchText" cancelButton="none" placeholder="搜索"></uni-search-bar> <uni-search-bar radius="100" v-model="searchText" cancelButton="none" placeholder="搜索"></uni-search-bar>
</view> </view>
</view> </view>
<view class="chat-tip" v-if="!loading && chatStore.chats.length==0"> <view class="chat-tip" v-if="!loading && chatStore.chats.length==0">
温馨提示您现在还没有任何聊天消息快跟您的好友发起聊天吧~ 温馨提示您现在还没有任何聊天消息快跟您的好友发起聊天吧~
</view> </view>
<scroll-view class="scroll-bar" v-else scroll-with-animation="true" scroll-y="true"> <scroll-view class="scroll-bar" v-else scroll-with-animation="true" scroll-y="true">
<view v-for="(chat,index) in chatStore.chats" :key="index"> <view v-for="(chat,index) in chatStore.chats" :key="index">
@ -31,6 +32,7 @@
export default { export default {
data() { data() {
return { return {
showSearch: false,
searchText: "", searchText: "",
menu: { menu: {
show: false, show: false,
@ -120,34 +122,16 @@
<style scoped lang="scss"> <style scoped lang="scss">
.tab-page { .tab-page {
position: relative; position: relative;
border: #dddddd solid 1px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
.nav-bar {
padding: 2rpx 20rpx;
display: flex;
align-items: center;
background-color: white;
border-bottom: 1px solid #ddd;
height: 110rpx;
.nav-search {
flex: 1;
height: 110rpx;
}
}
.chat-tip { .chat-tip {
position: absolute; position: absolute;
top: 400rpx; top: 400rpx;
padding: 50rpx; padding: 50rpx;
line-height: 50rpx; line-height: 50rpx;
text-align: left; text-align: center;
color: darkblue; color: $im-text-color-lighter;
font-size: 30rpx;
} }
.chat-loading { .chat-loading {
@ -158,11 +142,10 @@
position: fixed; position: fixed;
top: 0; top: 0;
z-index: 999; z-index: 999;
color: blue; color: $im-text-color-lighter;
.loading-box { .loading-box {
position: relative; position: relative;
} }
} }

143
im-uniapp/pages/common/user-info.vue

@ -1,33 +1,47 @@
<template> <template>
<view class="page user-info"> <view class="page user-info">
<view class="content"> <nav-bar back>用户信息</nav-bar>
<head-image :name="userInfo.nickName" :url="userInfo.headImageThumb" <uni-card :is-shadow="false" is-full :border="false">
:size="160" @click="onShowFullImage()"></head-image> <view class="content">
<head-image :name="userInfo.nickName" :url="userInfo.headImageThumb"
<view class="info-item"> :size="160" @click="onShowFullImage()"></head-image>
<view class="info-primary">
<text class="info-username"> <view class="info-item">
{{userInfo.userName}} <view class="info-primary">
</text> <text class="info-username">
<uni-icons v-show="userInfo.sex==0" class="sex-boy" type="person-filled" size="20" {{userInfo.userName}}
color="darkblue"></uni-icons> </text>
<uni-icons v-show="userInfo.sex==1" class="sex-girl" type="person-filled" size="20" <text v-show="userInfo.sex==0" class="iconfont icon-man"
color="darkred"></uni-icons> color="darkblue"></text>
</view> <text v-show="userInfo.sex==1" class="iconfont icon-girl"
<text> color="darkred"></text>
昵称 {{userInfo.nickName}} </view>
</text> <view class="info-text">
<text> <text class="label-text">
签名 {{userInfo.signature}} 昵称:
</text> </text>
</view> <text class="content-text">
</view> {{userInfo.nickName}}
<view class="line"></view> </text>
<view class="btn-group"> </view>
<button class="btn" v-show="isFriend" type="primary" @click="onSendMessage()">发消息</button> <view class="info-text">
<button class="btn" v-show="!isFriend" type="primary" @click="onAddFriend()">加为好友</button> <view>
<button class="btn" v-show="isFriend" type="warn" @click="onDelFriend()">删除好友</button> <text class="label-text">
</view> 签名:
</text>
<text class="content-text">
{{userInfo.signature}}
</text>
</view>
</view>
</view>
</view>
</uni-card>
<view class="bottom-btn">
<button class="btn" v-show="isFriend" type="primary" @click="onSendMessage()">发消息</button>
<button class="btn" v-show="!isFriend" type="primary" @click="onAddFriend()">加为好友</button>
<button class="btn" v-show="isFriend" type="warn" @click="onDelFriend()">删除好友</button>
</view>
</view> </view>
</template> </template>
@ -155,38 +169,49 @@
justify-content: space-between; justify-content: space-between;
padding: 20rpx; padding: 20rpx;
.info-item { .info-item {
display: flex; display: flex;
align-items: flex-start; align-items: flex-start;
flex-direction: column; flex-direction: column;
padding-left: 40rpx; padding-left: 40rpx;
flex: 1; flex: 1;
.info-primary {
display: flex;
align-items: center;
.info-username {
font-size: 40rpx;
font-weight: 600;
}
}
}
}
.line { .info-text {
margin: 20rpx; line-height: 1.5;
border-bottom: 1px solid #aaaaaa; //margin-bottom: 10rpx;
} }
.btn-group { .label-text {
margin: 100rpx; font-size: $im-font-size-small;
color: $im-text-color-light;
.btn{
margin-top: 20rpx; }
} .content-text {
font-size: $im-font-size-small;
color: $im-text-color-light;
}
.info-primary {
display: flex;
align-items: center;
margin-bottom: 10rpx;
.info-username {
font-size: $im-font-size-large;
font-weight: 600;
}
.icon-man {
color: $im-text-color;
font-size: $im-font-size-large;
padding-left: 10rpx;
}
.icon-girl {
color: darkred;
}
}
}
} }
} }
</style> </style>

14
im-uniapp/pages/friend/friend-add.vue

@ -1,16 +1,18 @@
<template> <template>
<view class="page friend-add"> <view class="page friend-add">
<view class="search-bar"> <nav-bar back>添加好友</nav-bar>
<view class="nav-bar">
<view class="nav-search">
<uni-search-bar v-model="searchText" radius="100" :focus="true" @confirm="onSearch()" @cancel="onCancel()" <uni-search-bar v-model="searchText" radius="100" :focus="true" @confirm="onSearch()" @cancel="onCancel()"
placeholder="用户名/昵称"></uni-search-bar> placeholder="用户名/昵称"></uni-search-bar>
</view>
</view> </view>
<view class="user-items"> <view class="user-items">
<scroll-view class="scroll-bar" scroll-with-animation="true" scroll-y="true"> <scroll-view class="scroll-bar" scroll-with-animation="true" scroll-y="true">
<view v-for="(user) in users" :key="user.id" v-show="user.id != userStore.userInfo.id"> <view v-for="(user) in users" :key="user.id" v-show="user.id != userStore.userInfo.id">
<view class="user-item"> <view class="user-item">
<head-image :id="user.id" :name="user.nickName" <head-image :id="user.id" :name="user.nickName"
:online="user.online" :url="user.headImage" :online="user.online" :url="user.headImage"></head-image>
:size="100"></head-image>
<view class="user-name">{{ user.nickName}}</view> <view class="user-name">{{ user.nickName}}</view>
<view class="user-btns"> <view class="user-btns">
<button type="primary" v-show="!isFriend(user.id)" size="mini" <button type="primary" v-show="!isFriend(user.id)" size="mini"
@ -82,9 +84,6 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
.search-bar {
background: white;
}
.user-items{ .user-items{
position: relative; position: relative;
flex: 1; flex: 1;
@ -102,8 +101,7 @@
.user-name { .user-name {
flex:1; flex:1;
padding-left: 20rpx; padding-left: 20rpx;
font-size: 30rpx; font-size: $im-font-size;
font-weight: 600;
line-height: 60rpx; line-height: 60rpx;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;

45
im-uniapp/pages/friend/friend.vue

@ -1,12 +1,10 @@
<template> <template>
<nav-bar add search @add="onAddNewFriends" @search="showSearch = !showSearch">好友</nav-bar>
<view class="tab-page friend"> <view class="tab-page friend">
<view class="nav-bar"> <view class="nav-bar" v-if="showSearch">
<view class="nav-search"> <view class="nav-search">
<uni-search-bar v-model="searchText" radius="100" cancelButton="none" placeholder="点击搜索好友"></uni-search-bar> <uni-search-bar v-model="searchText" radius="100" cancelButton="none" placeholder="点击搜索好友"></uni-search-bar>
</view> </view>
<view class="nav-add" @click="onAddNewFriends()">
<uni-icons type="personadd" size="35"></uni-icons>
</view>
</view> </view>
<view class="friend-tip" v-if="friends.length==0"> <view class="friend-tip" v-if="friends.length==0">
温馨提示您现在还没有任何好友快点击右上方'+'按钮添加好友吧~ 温馨提示您现在还没有任何好友快点击右上方'+'按钮添加好友吧~
@ -15,8 +13,7 @@
<up-index-list :index-list="friendIdx" > <up-index-list :index-list="friendIdx" >
<template v-for="(friends,i) in friendGroups"> <template v-for="(friends,i) in friendGroups">
<up-index-item> <up-index-item>
<up-index-anchor :text="friendIdx[i]=='*'?'在线':friendIdx[i]" <up-index-anchor :text="friendIdx[i]=='*'?'在线':friendIdx[i]"></up-index-anchor>
bgColor="#f2f3fd"></up-index-anchor>
<view v-for="(friend,idx) in friends" :key="idx"> <view v-for="(friend,idx) in friends" :key="idx">
<friend-item :friend="friend"></friend-item> <friend-item :friend="friend"></friend-item>
</view> </view>
@ -34,6 +31,7 @@
export default { export default {
data() { data() {
return { return {
showSearch: false,
searchText: '' searchText: ''
} }
}, },
@ -109,30 +107,29 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
:deep(.u-index-anchor){
height: 60rpx !important;
background-color: unset !important;
border-bottom: none !important;
}
:deep(.u-index-anchor__text){
color: $im-text-color !important;
}
:deep(.u-index-list__letter__item){
width: 48rpx !important;
height: 48rpx !important;
}
:deep(.u-index-list__letter__item__index){
font-size: $im-font-size-small !important;
}
.friend-tip { .friend-tip {
position: absolute; position: absolute;
top: 400rpx; top: 400rpx;
padding: 50rpx; padding: 50rpx;
text-align: center; text-align: center;
line-height: 50rpx; line-height: 50rpx;
text-align: left; color: $im-text-color-lighter;
color: darkblue;
font-size: 30rpx;
}
.nav-bar {
padding: 2rpx 10rpx;
display: flex;
align-items: center;
background-color: white;
.nav-search {
flex: 1;
}
.nav-add {
cursor: pointer;
}
} }
.friend-items { .friend-items {

60
im-uniapp/pages/group/group-edit.vue

@ -1,29 +1,32 @@
<template> <template>
<view v-if="userStore.userInfo.type == 1" class="page group-edit"> <nav-bar back>修改群资料</nav-bar>
<uni-forms ref="form" :modelValue="group" :rules="rules" validate-trigger="bind" label-position="top" <view v-if="userStore.userInfo.type == 1" class="page group-edit">
label-width="100%"> <uni-card :is-shadow="false" is-full :border="false">
<uni-forms-item label="群聊头像:" name="headImage"> <uni-forms ref="form" :modelValue="group" :rules="rules" validate-trigger="bind" label-position="top"
<image-upload v-if="isOwner" :onSuccess="onUnloadImageSuccess"> label-width="100%">
<image :src="group.headImageThumb" class="group-image"></image> <uni-forms-item name="headImage" class="avatar">
</image-upload> <image-upload v-if="isOwner" :onSuccess="onUnloadImageSuccess">
<head-image v-if="!isOwner" :name="group.showGroupName" <image :src="group.headImageThumb" class="group-image"></image>
:url="group.headImageThumb" :size="200"></head-image> </image-upload>
</uni-forms-item> <head-image v-if="!isOwner" :name="group.showGroupName"
<uni-forms-item label="群聊名称:" name="name" :required="true"> :url="group.headImageThumb" :size="200"></head-image>
<uni-easyinput type="text" v-model="group.name" :disabled="!isOwner" placeholder="请输入群聊名称" /> </uni-forms-item>
</uni-forms-item> <uni-forms-item label="群聊名称" name="name" :required="true">
<uni-forms-item label="群聊备注:" name="remarkGroupName"> <uni-easyinput type="text" v-model="group.name" :disabled="!isOwner" placeholder="请输入群聊名称" />
<uni-easyinput v-model="group.remarkGroupName" type="text" :placeholder="group.name" /> </uni-forms-item>
</uni-forms-item> <uni-forms-item label="群聊备注" name="remarkGroupName">
<uni-forms-item label="我在本群的昵称:" name="remarkNickName"> <uni-easyinput v-model="group.remarkGroupName" type="text" :placeholder="group.name" />
<uni-easyinput v-model="group.remarkNickName" type="text" :placeholder="userStore.userInfo.nickName" /> </uni-forms-item>
</uni-forms-item> <uni-forms-item label="我在本群的昵称" name="remarkNickName">
<uni-forms-item label="群公告:" name="notice"> <uni-easyinput v-model="group.remarkNickName" type="text" :placeholder="userStore.userInfo.nickName" />
<uni-easyinput type="textarea" v-model="group.notice" :disabled="!isOwner" placeholder="请输入群公告" /> </uni-forms-item>
</uni-forms-item> <uni-forms-item label="群公告" name="notice">
</uni-forms> <uni-easyinput type="textarea" v-model="group.notice" :disabled="!isOwner" placeholder="请输入群公告" />
<button type="primary" @click="submit()">提交</button> </uni-forms-item>
</view> </uni-forms>
</uni-card>
<button class="bottom-btn" type="primary" @click="submit()">提交</button>
</view>
</template> </template>
<script> <script>
@ -138,7 +141,7 @@
<style lang="scss" scoped> <style lang="scss" scoped>
.group-edit { .group-edit {
padding: 20rpx; //padding: 20rpx;
.group-image { .group-image {
width: 200rpx; width: 200rpx;
@ -147,4 +150,7 @@
border-radius: 5%; border-radius: 5%;
} }
} }
</style> .avatar {
margin-top: -30px;
}
</style>

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

@ -1,53 +1,55 @@
<template> <template>
<view v-if="userStore.userInfo.type == 1" class="page group-info"> <view v-if="userStore.userInfo.type == 1" class="page group-info">
<nav-bar back>群聊信息</nav-bar>
<view v-if="!group.quit" class="group-members"> <view v-if="!group.quit" class="group-members">
<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"> <view class="member-item" v-if="idx<9">
<head-image :id="member.userId" :name="member.showNickName" :url="member.headImage" <head-image :id="member.userId" :name="member.showNickName" :url="member.headImage" size="small"
:size="100" :online="member.online" ></head-image> :online="member.online" ></head-image>
<view class="member-name"> <view class="member-name">
<text>{{member.showNickName}}</text> <text>{{member.showNickName}}</text>
</view> </view>
</view> </view>
</view> </view>
<view class="invite-btn" @click="onInviteMember()"> <view class="invite-btn" @click="onInviteMember()">
<uni-icons type="plusempty" size="28" color="#888888"></uni-icons> <uni-icons type="plusempty" size="20" color="#888888"></uni-icons>
</view> </view>
</view> </view>
<view class="member-more" @click="onShowMoreMmeber()">{{`查看全部群成员${groupMembers.length}`}}></view> <view class="member-more" @click="onShowMoreMmeber()">{{`查看全部群成员${groupMembers.length}`}}></view>
</view> </view>
<view class="group-detail"> <view class="group-detail">
<uni-section title="群聊名称:" titleFontSize="14px">
<uni-section title="群聊名称">
<template v-slot:right> <template v-slot:right>
<text class="detail-text">{{group.name}}</text> <text class="detail-text">{{group.name}}</text>
</template> </template>
</uni-section> </uni-section>
<uni-section title="群主:" titleFontSize="14px"> <uni-section title="群主">
<template v-slot:right> <template v-slot:right>
<text class="detail-text">{{ownerName}}</text> <text class="detail-text">{{ownerName}}</text>
</template> </template>
</uni-section> </uni-section>
<uni-section title="群名备注:" titleFontSize="14px"> <uni-section title="群名备注">
<template v-slot:right> <template v-slot:right>
<text class="detail-text"> {{group.remarkGroupName}}</text> <text class="detail-text"> {{group.remarkGroupName}}</text>
</template> </template>
</uni-section> </uni-section>
<uni-section title="我在本群的昵称:" titleFontSize="14px"> <uni-section title="我在本群的昵称">
<template v-slot:right> <template v-slot:right>
<text class="detail-text"> {{group.showNickName}}</text> <text class="detail-text"> {{group.showNickName}}</text>
</template> </template>
</uni-section> </uni-section>
<uni-section v-if="group.notice" title="群公告:" titleFontSize="14px"> <uni-section v-if="group.notice" title="群公告">
<uni-notice-bar :text="group.notice" /> <uni-notice-bar :text="group.notice" />
</uni-section> </uni-section>
<view v-if="!group.quit" class="group-edit" @click="onEditGroup()">修改群聊资料 > </view> <view v-if="!group.quit" class="group-edit" @click="onEditGroup()">修改群聊资料 > </view>
</view> </view>
<view v-if="!group.quit" class="btn-group"> <view v-if="!group.quit" class="bottom-btn">
<button class="btn" type="primary" @click="onSendMessage()">发消息</button> <button type="primary" @click="onSendMessage()">发消息</button>
<button class="btn" v-show="!isOwner" type="warn" @click="onQuitGroup()">退出群聊</button> <button v-show="!isOwner" type="warn" @click="onQuitGroup()">退出群聊</button>
<button class="btn" v-show="isOwner" type="warn" @click="onDissolveGroup()">解散群聊</button> <button v-show="isOwner" type="warn" @click="onDissolveGroup()">解散群聊</button>
</view> </view>
</view> </view>
</template> </template>
@ -211,16 +213,16 @@
position: relative; position: relative;
align-items: center; align-items: center;
padding-right: 5px; padding-right: 5px;
background-color: #fafafa;
white-space: nowrap; white-space: nowrap;
.member-name { .member-name {
width: 100%; width: 100%;
flex: 1; flex: 1;
font-size: 14px;
overflow: hidden; overflow: hidden;
text-align: center; text-align: center;
white-space: nowrap; white-space: nowrap;
padding-top: 8rpx;
font-size: $im-font-size-smaller;
} }
} }
@ -228,53 +230,38 @@
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
width: 100rpx; width: 86rpx;
height: 100rpx; height: 86rpx;
margin: 10rpx; margin: 10rpx;
border: #686868 dashed 2px; border: $im-border solid 2rpx;
border-radius: 10%; border-radius: 10%;
} }
} }
.member-more { .member-more {
padding-top: 30rpx; padding-top: 24rpx;
text-align: center; text-align: center;
font-size: 32rpx; font-size: $im-font-size-small;
color: #333; color: $im-text-color-lighter;
} }
} }
.group-detail { .group-detail {
margin-top: 30rpx; margin-top: 30rpx;
padding: 30rpx; padding: 20rpx 20rpx;
background: white; background: white;
.detail-text{ .detail-text{
font-size: 28rpx; font-size: $im-font-size;
font-weight: 600;
} }
.group-edit { .group-edit {
padding-top: 30rpx; padding-top: 30rpx;
text-align: center; text-align: center;
font-size: 32rpx; font-size: $im-font-size-small;
color: #333; color: $im-text-color-lighter;
}
}
.btn-group {
margin-top: 30rpx;
padding: 30rpx;
background: white;
.btn {
margin: 10rpx;
} }
} }
} }
</style> </style>

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

@ -1,28 +1,27 @@
<template> <template>
<view class="page group-invite"> <view class="page group-invite">
<view class="search-bar"> <view class="nav-bar">
<uni-search-bar v-model="searchText" radius="100" cancelButton="none" placeholder="输入好友昵称搜索"></uni-search-bar> <view class="nav-search">
</view> <uni-search-bar v-model="searchText" radius="100" cancelButton="none" placeholder="输入好友昵称搜索"></uni-search-bar>
</view>
</view>
<view class="friend-items"> <view class="friend-items">
<scroll-view class="scroll-bar" scroll-with-animation="true" scroll-y="true"> <scroll-view class="scroll-bar" scroll-with-animation="true" scroll-y="true">
<view v-for="friend in friendItems" v-show="!searchText || friend.nickName.includes(searchText)" <view v-for="friend in friendItems" v-show="!searchText || friend.nickName.includes(searchText)"
:key="friend.id"> :key="friend.id">
<view class="friend-item" @click="onSwitchChecked(friend)"> <view class="friend-item" @click="onSwitchChecked(friend)" :class="{checked: friend.checked, disabled: friend.disabled}">
<head-image :name="friend.nickName" <head-image :name="friend.nickName"
:online="friend.online" :url="friend.headImage" :online="friend.online" :url="friend.headImage"></head-image>
:size="100"></head-image>
<view class="friend-name">{{ friend.nickName}}</view> <view class="friend-name">{{ friend.nickName}}</view>
<view class="friend-checked"> <!-- <view class="friend-checked">-->
<radio :checked="friend.checked" :disabled="friend.disabled" @click.stop="onSwitchChecked(friend)"/> <!-- <radio :checked="friend.checked" :disabled="friend.disabled" @click.stop="onSwitchChecked(friend)"/>-->
</view> <!-- </view>-->
</view> </view>
</view> </view>
</scroll-view> </scroll-view>
</view> </view>
<view> <button class="bottom-btn" type="primary" :disabled="inviteSize==0" @click="onInviteFriends()">邀请({{inviteSize}}) </button>
<button type="primary" :disabled="inviteSize==0" @click="onInviteFriends()">邀请({{inviteSize}}) </button>
</view>
</view> </view>
</template> </template>
@ -139,7 +138,15 @@
align-items: center; align-items: center;
background-color: white; background-color: white;
white-space: nowrap; white-space: nowrap;
&.disabled {
background-color: $im-bg-active !important;
}
&.checked {
background-color: $im-color-primary-light-9;
}
.friend-name { .friend-name {
flex:1; flex:1;
padding-left: 20rpx; padding-left: 20rpx;

25
im-uniapp/pages/group/group-member.vue

@ -1,26 +1,24 @@
<template> <template>
<view class="page group-member"> <view class="page group-member">
<view class="search-bar"> <nav-bar back>群成员</nav-bar>
<uni-search-bar v-model="searchText" radius="100" cancelButton="none" placeholder="输入昵称搜索"></uni-search-bar> <view class="nav-bar">
</view> <view class="nav-search">
<uni-search-bar v-model="searchText" radius="100" cancelButton="none" placeholder="输入昵称搜索"></uni-search-bar>
</view>
</view>
<view class="member-items"> <view class="member-items">
<scroll-view class="scroll-bar" scroll-with-animation="true" scroll-y="true"> <scroll-view class="scroll-bar" scroll-with-animation="true" scroll-y="true">
<view v-for="(member,idx) in groupMembers" <view v-for="(member,idx) in groupMembers"
v-show="!searchText || member.showNickName.includes(searchText)" :key="idx"> v-show="!searchText || member.showNickName.includes(searchText)" :key="idx">
<view class="member-item" @click="onShowUserInfo(member.userId)"> <view class="member-item" @click="onShowUserInfo(member.userId)">
<head-image :name="member.showNickName" <head-image :name="member.showNickName" :online="member.online" :url="member.headImage"></head-image>
:online="member.online" :url="member.headImage"
:size="100"></head-image>
<view class="member-name">{{ member.showNickName}} <view class="member-name">{{ member.showNickName}}
<uni-tag v-if="member.userId==group.ownerId" <uni-tag v-if="member.userId==group.ownerId"
text="群主" size="small" circle text="群主" size="small" circle type="error">
custom-style="background-color: #e30a0a;">
</uni-tag> </uni-tag>
<uni-tag v-if="member.userId==userStore.userInfo.id" <uni-tag v-if="member.userId==userStore.userInfo.id"
text="我" size="small" circle></uni-tag> text="我" size="small" circle></uni-tag>
</view> </view>
<view class="member-kick"> <view class="member-kick">
<button type="warn" plain v-show="isOwner && !isSelf(member.userId)" size="mini" <button type="warn" plain v-show="isOwner && !isSelf(member.userId)" size="mini"
@click.stop="onKickOut(member,idx)">移出群聊</button> @click.stop="onKickOut(member,idx)">移出群聊</button>
@ -135,9 +133,8 @@
align-items: center; align-items: center;
flex:1; flex:1;
padding-left: 20rpx; padding-left: 20rpx;
font-size: 30rpx; font-size: $im-font-size;
font-weight: 600; line-height: $im-font-size * 2;
line-height: 60rpx;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;

22
im-uniapp/pages/group/group.vue

@ -1,13 +1,11 @@
<template> <template>
<view class="tab-page group"> <view class="tab-page group">
<view class="nav-bar"> <nav-bar add search @add="onCreateNewGroup" @search="showSearch = !showSearch">群聊</nav-bar>
<view class="nav-bar" v-if="showSearch">
<view class="nav-search"> <view class="nav-search">
<uni-search-bar v-model="searchText" cancelButton="none" radius="100" <uni-search-bar v-model="searchText" cancelButton="none" radius="100"
placeholder="点击搜索群聊"></uni-search-bar> placeholder="点击搜索群聊"></uni-search-bar>
</view> </view>
<view class="nav-add" @click="onCreateNewGroup()">
<uni-icons type="personadd" size="35"></uni-icons>
</view>
</view> </view>
<view class="group-tip" v-if="groupStore.groups.length==0"> <view class="group-tip" v-if="groupStore.groups.length==0">
温馨提示您现在还没有加入任何群聊点击右上方'+'按钮可以创建群聊哦~ 温馨提示您现在还没有加入任何群聊点击右上方'+'按钮可以创建群聊哦~
@ -27,6 +25,7 @@
export default { export default {
data() { data() {
return { return {
showSearch: false,
searchText: "" searchText: ""
} }
}, },
@ -50,21 +49,6 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
.nav-bar {
padding: 2rpx 10rpx;
display: flex;
align-items: center;
background-color: white;
.nav-search {
flex: 1;
}
.nav-add {
cursor: pointer;
}
}
.group-tip { .group-tip {
position: absolute; position: absolute;
top: 400rpx; top: 400rpx;

13
im-uniapp/pages/login/login.vue

@ -1,12 +1,13 @@
<template> <template>
<view class="page login"> <view class="page login">
<nav-bar>盒子im</nav-bar>
<view class="title">欢迎登录</view> <view class="title">欢迎登录</view>
<uni-forms class="form" :modelValue="loginForm" :rules="rules" validate-trigger="bind"> <uni-forms class="form" :modelValue="loginForm" :rules="rules" validate-trigger="bind">
<uni-forms-item name="userName"> <uni-forms-item name="userName">
<uni-easyinput type="text" v-model="loginForm.userName" prefix-icon="person" placeholder="用户名" /> <uni-easyinput type="text" v-model="loginForm.userName" prefix-icon="person" placeholder="用户名" />
</uni-forms-item> </uni-forms-item>
<uni-forms-item name="password"> <uni-forms-item name="password">
<uni-easyinput type="password" v-model="loginForm.password" prefix-icon="locked" placeholder="密码" /> <uni-easyinput type="password" v-model="loginForm.password" prefix-icon="locked" placeholder="密码" />
</uni-forms-item> </uni-forms-item>
<button class="btn-submit" @click="submit" type="primary">登录</button> <button class="btn-submit" @click="submit" type="primary">登录</button>
</uni-forms> </uni-forms>
@ -74,10 +75,10 @@
.title { .title {
padding-top: 150rpx; padding-top: 150rpx;
padding-bottom: 50rpx; padding-bottom: 50rpx;
color: royalblue; color: $im-color-primary;
text-align: center; text-align: center;
font-size: 60rpx; font-size: 24px;
font-weight: 600; font-weight: bold;
} }
.form { .form {
@ -93,9 +94,9 @@
position: fixed; position: fixed;
width: 100%; width: 100%;
bottom: 100rpx; bottom: 100rpx;
color: royalblue; color: $im-color-primary;
text-align: center; text-align: center;
font-size: 32rpx; font-size: $im-font-size;
} }
} }
</style> </style>

58
im-uniapp/pages/mine/mine-edit.vue

@ -1,29 +1,29 @@
<template> <template>
<view class="page mine-edit"> <view class="page mine-edit">
<uni-forms ref="form" :modelValue="userInfo" label-position="top" <nav-bar back>修改我的信息</nav-bar>
label-width="100%"> <uni-card :is-shadow="false" is-full :border="false">
<uni-forms-item label="头像:" name="headImage"> <uni-forms ref="form" :modelValue="userInfo" label-position="top"
<image-upload :onSuccess="onUnloadImageSuccess"> label-width="100%">
<image :src="userInfo.headImageThumb" class="head-image"></image> <uni-forms-item name="headImage" class="avatar">
</image-upload> <image-upload :onSuccess="onUnloadImageSuccess">
</uni-forms-item> <image :src="userInfo.headImageThumb" class="head-image"></image>
<uni-forms-item label="用户名:" name="userName"> </image-upload>
<uni-easyinput type="text" v-model="userInfo.userName" :disabled="true" /> </uni-forms-item>
</uni-forms-item> <uni-forms-item label="用户名" name="userName">
<uni-forms-item label="昵称:" name="nickName"> <uni-easyinput type="text" v-model="userInfo.userName" :disabled="true" />
<uni-easyinput v-model="userInfo.nickName" type="text" :placeholder="userInfo.userName" /> </uni-forms-item>
</uni-forms-item> <uni-forms-item label="昵称" name="nickName">
<uni-forms-item label="性别:" name="sex"> <uni-easyinput v-model="userInfo.nickName" type="text" :placeholder="userInfo.userName" />
<radio-group @change="onSexchange"> </uni-forms-item>
<label class="radio"><radio value="0" :checked="userInfo.sex==0" /></label> <uni-forms-item label="性别" name="sex">
<label class="radio"><radio value="1" :checked="userInfo.sex==1" /> </label> <uni-data-checkbox v-model="userInfo.sex" :localdata="[{text: '男', value: 0}, {text: '女', value: 1}]"></uni-data-checkbox>
</radio-group> </uni-forms-item>
</uni-forms-item> <uni-forms-item label="签名" name="signature">
<uni-forms-item label="签名:" name="signature"> <uni-easyinput type="textarea" v-model="userInfo.signature" placeholder="编辑个性标签,展示我的独特态度" />
<uni-easyinput type="textarea" v-model="userInfo.signature" placeholder="编辑个性标签,展示我的独特态度" /> </uni-forms-item>
</uni-forms-item> </uni-forms>
</uni-forms> </uni-card>
<button type="primary" @click="onSubmit()">提交</button> <button type="primary" class="bottom-btn" @click="onSubmit()">提交</button>
</view> </view>
</template> </template>
@ -56,7 +56,7 @@
setTimeout(()=>{ setTimeout(()=>{
uni.navigateBack(); uni.navigateBack();
},1000); },1000);
}) })
} }
}, },
onLoad() { onLoad() {
@ -69,11 +69,13 @@
<style scoped lang="scss"> <style scoped lang="scss">
.mine-edit { .mine-edit {
padding: 20rpx;
.head-image { .head-image {
width: 200rpx; width: 200rpx;
height: 200rpx; height: 200rpx;
} }
} }
</style>
.avatar {
margin-top: -30px;
}
</style>

32
im-uniapp/pages/mine/mine-password.vue

@ -1,18 +1,20 @@
<template> <template>
<view class="page mine-password"> <view class="page mine-password">
<uni-forms ref="form" :modelValue="formData" label-position="top" label-width="100%" > <nav-bar back>修改密码</nav-bar>
<uni-forms-item label="原密码:" name="oldPassword"> <uni-card :is-shadow="false" is-full :border="false">
<uni-easyinput type="password" v-model="formData.oldPassword" /> <uni-forms ref="form" :modelValue="formData" label-position="top" label-width="100%" >
</uni-forms-item> <uni-forms-item label="原密码" name="oldPassword">
<uni-forms-item label="新密码:" name="newPassword"> <uni-easyinput type="password" v-model="formData.oldPassword" />
<uni-easyinput type="password" v-model="formData.newPassword" /> </uni-forms-item>
</uni-forms-item> <uni-forms-item label="新密码" name="newPassword">
<uni-forms-item label="确认密码:" name="confirmPassword"> <uni-easyinput type="password" v-model="formData.newPassword" />
<uni-easyinput type="password" v-model="formData.confirmPassword" /> </uni-forms-item>
</uni-forms-item> <uni-forms-item label="确认密码" name="confirmPassword">
<button type="primary" @click="onSubmit()">提交</button> <uni-easyinput type="password" v-model="formData.confirmPassword" />
</uni-forms> </uni-forms-item>
</uni-forms>
</uni-card>
<button class="bottom-btn" type="primary" @click="onSubmit()">提交</button>
</view> </view>
</template> </template>
@ -97,8 +99,4 @@
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.mine-password {
padding: 20rpx;
}
</style> </style>

112
im-uniapp/pages/mine/mine.vue

@ -1,30 +1,46 @@
<template> <template>
<view class="page mine"> <view class="page mine">
<view class="content" @click="onModifyInfo()"> <nav-bar>我的</nav-bar>
<head-image :name="userInfo.nickName" <uni-card :is-shadow="false" is-full :border="false">
:url="userInfo.headImage" <view class="content" @click="onModifyInfo()">
:size="160"></head-image> <head-image :name="userInfo.nickName"
<view class="info-item"> :url="userInfo.headImage"
<view class="info-primary"> :size="160"></head-image>
<text class="info-username"> <view class="info-item">
{{userInfo.userName}} <view class="info-primary">
</text> <text class="info-username">
<text v-show="userInfo.sex==0" class="iconfont icon-man" {{userInfo.userName}}
color="darkblue"></text> </text>
<text v-show="userInfo.sex==1" class="iconfont icon-girl" <text v-show="userInfo.sex==0" class="iconfont icon-man"
color="darkred"></text> color="darkblue"></text>
</view> <text v-show="userInfo.sex==1" class="iconfont icon-girl"
<text> color="darkred"></text>
昵称 {{userInfo.nickName}} </view>
</text> <view class="info-text">
<text> <text class="label-text">
签名 {{userInfo.signature}} 昵称:
</text> </text>
</view> <text class="content-text">
<view class="info-arrow">></view> {{userInfo.nickName}}
</view> </text>
<view class="line"></view> </view>
<view class="btn-group"> <view class="info-text">
<view>
<text class="label-text">
签名:
</text>
<text class="content-text">
{{userInfo.signature}}
</text>
</view>
</view>
</view>
<view class="info-arrow">
</view>
</view>
</uni-card>
<view class="bottom-btn">
<button class="btn" type="primary" @click="onModifyPassword()">修改密码</button> <button class="btn" type="primary" @click="onModifyPassword()">修改密码</button>
<button class="btn" type="warn" @click="onQuit()">退出</button> <button class="btn" type="warn" @click="onQuit()">退出</button>
</view> </view>
@ -72,7 +88,7 @@
<style scoped lang="scss"> <style scoped lang="scss">
.mine { .mine {
.content { .content {
height: 200rpx; //height: 200rpx;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
@ -85,18 +101,36 @@
padding-left: 40rpx; padding-left: 40rpx;
flex: 1; flex: 1;
.info-text {
line-height: 1.5;
//margin-bottom: 10rpx;
}
.label-text {
font-size: $im-font-size-small;
color: $im-text-color-light;
}
.content-text {
font-size: $im-font-size-small;
color: $im-text-color-light;
}
.info-primary { .info-primary {
display: flex; display: flex;
align-items: center; align-items: center;
margin-bottom: 10rpx;
.info-username { .info-username {
font-size: 40rpx; font-size: $im-font-size-large;
font-weight: 600; font-weight: 600;
} }
.icon-man { .icon-man {
color: darkblue; color: $im-text-color;
font-size: $im-font-size-large;
padding-left: 10rpx;
} }
.icon-girl { .icon-girl {
color: darkred; color: darkred;
} }
@ -106,22 +140,10 @@
.info-arrow { .info-arrow {
width: 50rpx; width: 50rpx;
font-size: 30rpx; font-size: 30rpx;
font-weight: 600; position: relative;
left: 30rpx;
} }
} }
.line {
margin: 20rpx;
border-bottom: 1px solid #aaaaaa;
}
.btn-group {
margin: 100rpx;
.btn {
margin-top: 20rpx;
}
}
} }
</style> </style>

11
im-uniapp/pages/register/register.vue

@ -1,5 +1,6 @@
<template> <template>
<view class="register"> <view class="page register">
<nav-bar back>盒子im</nav-bar>
<view class="title">欢迎注册</view> <view class="title">欢迎注册</view>
<uni-forms class="form" :modelValue="dataForm" :rules="rules" validate-trigger="bind" label-width="80px"> <uni-forms class="form" :modelValue="dataForm" :rules="rules" validate-trigger="bind" label-width="80px">
<uni-forms-item name="userName" label="用户名"> <uni-forms-item name="userName" label="用户名">
@ -14,7 +15,7 @@
<uni-forms-item name="corfirmPassword" label="确认密码"> <uni-forms-item name="corfirmPassword" label="确认密码">
<uni-easyinput type="password" v-model="dataForm.corfirmPassword" placeholder="确认密码" /> <uni-easyinput type="password" v-model="dataForm.corfirmPassword" placeholder="确认密码" />
</uni-forms-item> </uni-forms-item>
<button class="btn-submit" @click="submit" type="warn">注册并登陆</button> <button class="btn-submit" @click="submit" type="primary">注册并登陆</button>
</uni-forms> </uni-forms>
<navigator class="nav-login" url="/pages/login/login" > <navigator class="nav-login" url="/pages/login/login" >
返回登陆页面 返回登陆页面
@ -116,9 +117,9 @@
.title { .title {
padding-top: 150rpx; padding-top: 150rpx;
padding-bottom: 50rpx; padding-bottom: 50rpx;
color: royalblue; color: $im-color-primary;
text-align: center; text-align: center;
font-size: 60rpx; font-size: 24px;
font-weight: 600; font-weight: 600;
} }
@ -135,7 +136,7 @@
position: fixed; position: fixed;
width: 100%; width: 100%;
bottom: 100rpx; bottom: 100rpx;
color: royalblue; color: $im-color-primary;
text-align: center; text-align: center;
font-size: 32rpx; font-size: 32rpx;
} }

46
im-uniapp/uni.scss

@ -1,5 +1,51 @@
@import '@/uni_modules/uview-plus/theme.scss'; @import '@/uni_modules/uview-plus/theme.scss';
@import '@/uni_modules/uni-scss/variables.scss'; @import '@/uni_modules/uni-scss/variables.scss';
@import '@/im-var.scss';
// 修改uni-ui主题
$uni-primary: $im-color-primary;
$uni-success: $im-color-success;
$uni-warning: $im-color-warning;
$uni-error: $im-color-danger;
$uni-info: $im-color-info;
// $uni-main-color: #3a3a3a; // 主要文字
// $uni-base-color: #6a6a6a; // 常规文字
// $uni-secondary-color: #909399; // 次要文字
// $uni-extra-color: #c7c7c7; // 辅助说明
// // 边框颜色
// $uni-border-1: #F0F0F0;
// $uni-border-2: #EDEDED;
// $uni-border-3: #DCDCDC;
// $uni-border-4: #B9B9B9;
// // 常规色
// $uni-black: #000000;
// $uni-white: #ffffff;
// $uni-transparent: rgba($color: #000000, $alpha: 0);
// // 背景色
// $uni-bg-color: #f7f7f7;
// /* 水平间距 */
// $uni-spacing-sm: 8px;
// $uni-spacing-base: 15px;
// $uni-spacing-lg: 30px;
// // 阴影
// $uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5);
// $uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2);
// $uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5);
// // 蒙版
// $uni-mask: rgba($color: #000000, $alpha: 0.4);
/**************************************************/
/* 行为相关颜色 */ /* 行为相关颜色 */
$uni-color-primary: #007aff; $uni-color-primary: #007aff;
$uni-color-success: #4cd964; $uni-color-success: #4cd964;

Loading…
Cancel
Save