This commit is contained in:
2022-02-14 10:59:16 +08:00
9 changed files with 437 additions and 329 deletions

View File

@@ -1,266 +1,253 @@
<template>
<view class="content">
<!-- tool -->
<view class="tool-flex">
<view
class="tool-flex-item"
@click="$Router.back()"
>
<uni-icons
type="closeempty"
size="22"
color="#666"
></uni-icons>
</view>
<view
class="tool-flex-item"
@click="onKeyAuth()"
v-if="$Route.query.keyPhone == 1"
>一键登录</view>
</view>
<!-- 欢迎使用 -->
<view class="header">
<view class="title">欢迎使用</view>
<view class="sumbit">ZH健康身边的营养专家</view>
</view>
<!-- 输入手机号相关 -->
<view class="inputs phone">
<label class="label">+86</label>
<input
type="number"
placeholder="输入您的手机号码"
maxlength="11"
v-model="phone"
/>
</view>
<view class="inputs sms">
<input
type="number"
placeholder="输入短信验证码"
maxlength="4"
v-model="code"
/>
<button
class="sms-btn"
type="default"
size="mini"
:disabled="phone == '' || getSms"
@click="getPhoneCode"
>{{getSms ? '重新发送' + smsTime + 's': '发送验证码'}}</button>
</view>
<button
class="btn"
type="default"
:disabled="phone == '' || code == ''"
@click="login"
>登录</button>
<!-- 用户登录注册协议 -->
<view class="agreement">
未注册的手机号码验证后自动创建账号登录即表示同意接受平台
<view @click="$Router.push({name: 'agreement', params: {name : 'secret'}})">隐私协议</view>
<view @click="$Router.push({name: 'agreement', params: {name : 'service'}})">服务协议</view>
</view>
</view>
</template>
<script>
import { getSms, smsAuth } from "@/apis/interfaces/auth";
import userAuth from "@/public/userAuth";
export default {
data() {
return {
phone: "",
code: "",
smsTime: 60,
getSms: false,
};
},
methods: {
// 用户登录
login() {
smsAuth({
mobileNo: this.phone,
code: this.code,
}).then((res) => {
this.$store.commit(
"setToken",
res.token_type + " " + res.access_token
);
this.$Router.back();
}).catch((err) => {
console.log(2222)
uni.showToast({
title: err.message,
icon: "none",
});
});
},
// 获取验证码
getPhoneCode() {
let outTime;
getSms({
mobileNo: this.phone,
})
.then((res) => {
uni.showToast({
title: res,
icon: "none",
});
this.getSms = true;
outTime = setInterval(() => {
if (this.smsTime <= 1) {
this.getSms = false;
this.smsTime = 60;
clearInterval("outTime");
}
this.smsTime -= 1;
}, 1000);
})
.catch((err) => {
uni.showToast({
title: err.message,
icon: "none",
});
});
},
// 一键登录
onKeyAuth() {
const Auth = new userAuth();
this.$Router.back();
Auth.Login();
},
},
};
</script>
<style lang="scss" scoped>
.content {
height: 100vh;
width: 100vw;
padding: $padding * 3;
box-sizing: border-box;
background: white;
@extend .vertical;
// 操作栏
.tool-flex {
position: fixed;
top: 0;
left: 0;
right: 0;
display: flex;
justify-content: space-between;
padding-left: $padding * 2;
padding-right: $padding * 2;
background: white;
@extend .ios-top;
&-item {
line-height: 90rpx;
color: $text-gray;
font-size: $title-size-lg;
}
}
// 表单
.inputs {
background: $window-color;
position: relative;
margin-top: $margin;
height: 90rpx;
line-height: 90rpx;
border-radius: 45rpx;
input {
width: 100%;
height: 90rpx;
line-height: 90rpx;
padding: 0 $padding;
border: none;
box-sizing: border-box;
font-size: $title-size-lg;
}
&.phone {
padding-left: 120rpx;
.label {
position: absolute;
left: 0;
top: 0;
width: 120rpx;
text-align: center;
border-right: solid 1rpx $border-color;
font-size: $title-size-lg;
}
}
&.sms {
padding-right: 200rpx;
.sms-btn[size='mini'] {
width: 200rpx;
height: 90rpx;
line-height: 90rpx;
position: absolute;
top: 0;
right: 0;
padding: 0;
margin: 0;
border-radius: 0 45rpx 45rpx 0;
color: $main-color;
font-size: $title-size-lg;
background: $window-color;
&::after {
border: none;
}
&[disabled] {
color: rgba($color: $main-color, $alpha: .6);
background: rgba($color: $window-color, $alpha: 0);
}
}
}
}
// 头部
.header{
text-align: center;
margin-bottom: 5vh;
.title {
font-size: $title-size + 10;
font-weight: bold;
color: $text-color;
line-height: 70rpx;
}
.sumbit{
line-height: 50rpx;
font-size: $title-size-m;
color: $text-gray-m;
}
}
// 登录按钮
.btn {
margin: 0;
margin-top: $margin*2;
height: 90rpx;
line-height: 90rpx;
padding: 0;
font-size: $title-size;
border-radius: 45rpx;
background: $main-color;
color: white;
font-weight: bold;
&::after{
display: none;
}
&[disabled]{
background: rgba($color: $main-color, $alpha: .5);
}
}
// 协议
.agreement {
padding-top: 5vh;
font-size: $title-size-sm;
color: $text-gray-m;
view {
color: $main-color;
display: inline-block;
padding: 0 10rpx;
}
}
}
<template>
<view class="content">
<!-- tool -->
<view class="tool-flex">
<view class="tool-flex-item" @click="$Router.back()">
<uni-icons type="closeempty" size="22" color="#666"></uni-icons>
</view>
<view class="tool-flex-item" @click="onKeyAuth()" v-if="$Route.query.keyPhone == 1">一键登录</view>
</view>
<!-- 欢迎使用 -->
<view class="header">
<view class="title">欢迎使用</view>
<view class="sumbit">ZH健康身边的营养专家</view>
</view>
<!-- 输入手机号相关 -->
<view class="inputs phone">
<label class="label">+86</label>
<input type="number" placeholder="输入您的手机号码" maxlength="11" v-model="phone" />
</view>
<view class="inputs sms">
<input type="number" placeholder="输入短信验证码" maxlength="4" v-model="code" />
<button class="sms-btn" type="default" size="mini" :disabled="phone == '' || getSms"
@click="getPhoneCode">{{getSms ? '重新发送' + smsTime + 's': '发送验证码'}}</button>
</view>
<button class="btn" type="default" :disabled="phone == '' || code == ''" @click="login">登录</button>
<!-- 用户登录注册协议 -->
<view class="agreement">
未注册的手机号码验证后自动创建账号登录即表示同意接受平台
<view @click="$Router.push({name: 'agreement', params: {name : 'secret'}})">隐私协议</view>
<view @click="$Router.push({name: 'agreement', params: {name : 'service'}})">服务协议</view>
</view>
</view>
</template>
<script>
import {
getSms,
smsAuth
} from "@/apis/interfaces/auth";
import userAuth from "@/public/userAuth";
export default {
data() {
return {
phone: "",
code: "",
smsTime: 60,
getSms: false,
};
},
methods: {
// 用户登录
login() {
smsAuth({
mobileNo: this.phone,
code: this.code,
}).then((res) => {
this.$store.commit(
"setToken",
res.token_type + " " + res.access_token
);
this.$Router.back();
}).catch((err) => {
uni.showToast({
title: err.message,
icon: "none",
});
});
},
// 获取验证码
getPhoneCode() {
let outTime;
getSms({
mobileNo: this.phone,
})
.then((res) => {
uni.showToast({
title: res,
icon: "none",
});
this.getSms = true;
outTime = setInterval(() => {
if (this.smsTime <= 1) {
this.getSms = false;
this.smsTime = 60;
clearInterval("outTime");
}
this.smsTime -= 1;
}, 1000);
})
.catch((err) => {
uni.showToast({
title: err.message,
icon: "none",
});
});
},
// 一键登录
onKeyAuth() {
const Auth = new userAuth();
this.$Router.back();
Auth.Login();
},
},
};
</script>
<style lang="scss" scoped>
.content {
height: 100vh;
width: 100vw;
padding: $padding * 3;
box-sizing: border-box;
background: white;
@extend .vertical;
// 操作栏
.tool-flex {
position: fixed;
top: 0;
left: 0;
right: 0;
display: flex;
justify-content: space-between;
padding-left: $padding * 2;
padding-right: $padding * 2;
background: white;
@extend .ios-top;
&-item {
line-height: 90rpx;
color: $text-gray;
font-size: $title-size-lg;
}
}
// 表单
.inputs {
background: $window-color;
position: relative;
margin-top: $margin;
height: 90rpx;
line-height: 90rpx;
border-radius: 45rpx;
input {
width: 100%;
height: 90rpx;
line-height: 90rpx;
padding: 0 $padding;
border: none;
box-sizing: border-box;
font-size: $title-size-lg;
}
&.phone {
padding-left: 120rpx;
.label {
position: absolute;
left: 0;
top: 0;
width: 120rpx;
text-align: center;
border-right: solid 1rpx $border-color;
font-size: $title-size-lg;
}
}
&.sms {
padding-right: 200rpx;
.sms-btn[size='mini'] {
width: 200rpx;
height: 90rpx;
line-height: 90rpx;
position: absolute;
top: 0;
right: 0;
padding: 0;
margin: 0;
border-radius: 0 45rpx 45rpx 0;
color: $main-color;
font-size: $title-size-lg;
background: $window-color;
&::after {
border: none;
}
&[disabled] {
color: rgba($color: $main-color, $alpha: .6);
background: rgba($color: $window-color, $alpha: 0);
}
}
}
}
// 头部
.header {
text-align: center;
margin-bottom: 5vh;
.title {
font-size: $title-size + 10;
font-weight: bold;
color: $text-color;
line-height: 70rpx;
}
.sumbit {
line-height: 50rpx;
font-size: $title-size-m;
color: $text-gray-m;
}
}
// 登录按钮
.btn {
margin: 0;
margin-top: $margin*2;
height: 90rpx;
line-height: 90rpx;
padding: 0;
font-size: $title-size;
border-radius: 45rpx;
background: $main-color;
color: white;
font-weight: bold;
&::after {
display: none;
}
&[disabled] {
background: rgba($color: $main-color, $alpha: .5);
}
}
// 协议
.agreement {
padding-top: 5vh;
font-size: $title-size-sm;
color: $text-gray-m;
view {
color: $main-color;
display: inline-block;
padding: 0 10rpx;
}
}
}
</style>

View File

@@ -1,12 +1,13 @@
<template>
<view class="message--cell">
<view class="avatar">
<u-badge max="99" shape="horn" absolute :offset="[-5, -8]" :value="item.unreadMessageCount" />
<u-badge max="99" shape="horn" absolute :offset="[-5, -8]" :value="item.unreadMessageCount" />
<u-avatar :src="contact(item.targetId).portraitUrl" shape="square" size="44" />
</view>
<view class="content">
<view class="header">
<view class="name">{{ contact(item.targetId).name }} <span v-if="item.conversationType === 3" class='qun'>[]</span></view>
<view class="name">{{ contact(item.targetId).name }} <text v-if="item.conversationType === 3"
class='qun'>[]</text></view>
<view class="time">{{ item.sentTime|timeCustomCN }}</view>
</view>
<message-preview class="preview" :msg="item.latestMessage" :conversationType="item.conversationType"
@@ -41,22 +42,22 @@
</script>
<style lang="scss" scoped>
.message--cell {
display: flex;
padding: 20rpx 0 0 20rpx;
.message--cell {
display: flex;
padding: 20rpx 0 0 20rpx;
.avatar {
position: relative;
.u-badge {
z-index: 998;
}
}
}
.content {
.content {
margin-left: 30rpx;
box-sizing: border-box;
position: relative;
position: relative;
flex: 1;
border-bottom-width: 0.5px !important;
@@ -69,9 +70,11 @@
.name {
font-size: $title-size + 2;
color: #454545;
color: #454545;
.qun{
color: #454545;
display: flex;
align-items: center;
.qun {
color: $main-color;
font-size: $title-size-m;
margin-left: 4px;

View File

@@ -12,7 +12,7 @@
<u-sticky>
<view class="header-search">
<u-search placeholder="输入用户账号、手机号" height="74" searchIcon="search" @custom="search"
v-model="searchValue" @search="search" inputAlign="center" bgColor="#f9f9f9" :focus="focused" />
v-model="searchValue" @search="search" bgColor="#f9f9f9" :focus="focused" />
</view>
</u-sticky>
<block v-if="searchResult.length > 0">

View File

@@ -23,7 +23,8 @@
},
methods: {
onCreate() {
createGroupAnnouncement(this.targetId, this.content).then(res => {
createGroupAnnouncement(this.targetId, this.content).then(res => {
uni.$emit('groupAnnouncementCreated')
uni.showToast({
title: '发布成功',
success: () => {

View File

@@ -38,11 +38,15 @@
this.isAdmin = res.group.is_admin
})
this.initData()
uni.$on('groupAnnouncementCreated', this.initData)
},
onUnload() {
uni.$off('groupAnnouncementCreated')
},
onNavigationBarButtonTap() {
if (this.isAdmin) {
uni.navigateTo({
url: '/pages/im/group/announceCreate?targetId=' + this.targetId
url: '/pages/im/group/announceCreate?targetId=' + this.targetId
})
} else {
uni.showToast({
@@ -55,7 +59,6 @@
initData() {
getGroupAnnouncements(this.targetId).then(res => {
this.announcements = res
console.log(res);
this.loading = false
})
},

View File

@@ -61,10 +61,12 @@
if (msg.targetId == this.targetId) {
this.getMessageList()
}
})
})
uni.$once('cleanGroupMessage', this.getMessageList)
},
onBackPress() {
uni.$off('onReceiveMessage')
uni.$off('onReceiveMessage')
console.log('Off onReceiveMessage');
},
onNavigationBarButtonTap() {
uni.navigateTo({

View File

@@ -11,9 +11,9 @@
color="#999999"></u-avatar>
<view class="name">邀请用户</view>
</view>
</view>
<view @click="loadMore" class="loadmore">查看更多群成员</view>
</view>
<view @click="loadMore" class="loadmore">查看更多群成员 ></view>
</view>
<u-cell-group class="cells">
@@ -26,19 +26,19 @@
</u-cell>
</u-cell-group>
<u-cell-group class="cells" v-if="group.is_owner">
<u-cell-group class="cells" v-if="group.is_admin">
<u-cell isLink title="修改群聊名称" :value="group.name" @click="onGroupName"></u-cell>
<u-cell isLink title="修改群头像">
<u-avatar slot="value" size="24" shape="square" :src="group.cover"></u-avatar>
</u-cell>
</u-cell-group>
<view class="cells actions u-border-top">
<view class="cells actions u-border-top" v-if="loaded">
<view class="action u-border-bottom" @click="onClean">清空聊天记录</view>
<view class="action u-border-bottom" v-if="group.is_owner" @click="onDismiss">解散群聊</view>
<view class="action u-border-bottom" v-else @click="onQuite">删除并退出</view>
</view>
</view>
</view>
</template>
@@ -58,16 +58,11 @@
members: [],
status: false,
isTop: false,
loaded: false
}
},
onLoad(e) {
this.targetId = e.targetId
getGroupInfo(this.targetId).then(res => {
this.group = res.group
console.log(this.group);
this.announcement = res.announcement
this.members = res.members
})
RongIMLib.getConversationNotificationStatus(this.conversationType, this.targetId, ({
status
}) => {
@@ -80,9 +75,22 @@
if (code == 0) {
this.isTop = conversation.isTop
}
})
})
this.initData()
uni.$on('groupAnnouncementCreated', this.initData)
},
onUnload() {
uni.$off('groupAnnouncementCreated')
},
methods: {
initData() {
getGroupInfo(this.targetId).then(res => {
this.group = res.group
this.announcement = res.announcement
this.members = res.members
this.loaded = true
})
},
setStatus() {
RongIMLib.setConversationNotificationStatus(this.conversationType, this.targetId, this.status,
({
@@ -132,6 +140,7 @@
icon: 'none',
title: '清空成功'
})
uni.$emit('cleanGroupMessage')
})
}
}
@@ -178,23 +187,26 @@
width: 126rpx;
margin-left: 20rpx;
margin-bottom: 20rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.name {
.name {
color: $text-gray-m;
width: 126rpx;
text-align: center;
font-size: 28rpx;
font-size: 26rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
word-break: break-word;
text-overflow: ellipsis;
white-space: nowrap;
word-break: break-word;
}
}
}
.loadmore {
font-size: 28rpx;
font-size: 26rpx;
color: $text-gray-m;
text-align: center;
}

View File

@@ -1,17 +1,28 @@
<template>
<view class="members">
<view class="users">
<view class="user" v-for="(item, index) in members" :key="index" @click="toUser(item)">
<view class="user" v-if="isAdmin">
<u-avatar @click="inviteUser" size="44" shape="square" icon="plus" bg-color="#eeeeee" color="#999999">
</u-avatar>
<view class="name">邀请用户</view>
</view>
<view :class="['user', {'active': item.targetId == currentUser.targetId}]" @longpress="showAction(item)"
v-for="(item, index) in members" :key="index" @click="toUser(item)">
<u-avatar size="44" shape="square" :src="item.portraitUrl"></u-avatar>
<view class="name">{{ item.name }}</view>
</view>
</view>
<view class="loadmore">成员总数{{ members.length }}</view>
<u-action-sheet :actions="userActions" :title="actionTitle" cancelText="取消" @close="hideAction"
@select="doAction" :show="actionShow">
</u-action-sheet>
</view>
</template>
<script>
import {
getGroupInfo,
import {
getGroupBase,
getGroupUsers
} from '@/apis/interfaces/im.js'
@@ -19,24 +30,90 @@
data() {
return {
targetId: '',
members: []
members: [],
isOwner: false,
isAdmin: false,
actionShow: false,
userActions: [{
type: 0,
name: '设置管理员',
disabled: false
},
{
type: 1,
name: '解除管理员',
disabled: false
},
{
type: 2,
name: '移除成员',
disabled: false
}
],
actionTitle: '',
currentUser: {}
}
},
onLoad(e) {
this.targetId = e.targetId
getGroupInfo(this.targetId).then(res => {
})
getGroupUsers(this.targetId).then(res => {
this.members = res
this.targetId = e.targetId
getGroupBase(this.targetId).then(res => {
this.isOwner = res.is_owner
this.isAdmin = res.is_admin
if (this.isOwner) {
this.userActions.push({
type: 3,
name: '转移群主',
disabled: false
})
}
})
},
methods: {
toUser(item) {
uni.navigateTo({
url: '/pages/im/friends/info?targetId=' + item.targetId
})
}
this.getUserList()
},
methods: {
getUserList() {
getGroupUsers(this.targetId).then(res => {
this.members = res
})
},
toUser(item) {
uni.navigateTo({
url: '/pages/im/friends/info?targetId=' + item.targetId
})
},
showAction(item) {
this.currentUser = item
this.actionTitle = item.name
this.actionShow = true
// 根据当前用户,是不是管理,来控制按钮的可用性
this.userActions[0].disabled = true
},
hideAction(item) {
this.actionShow = false
this.actionTitle = ''
this.currentUser = {}
this.userActions[0].disabled = false
this.userActions[1].disabled = false
},
doAction(e) {
switch (e.type) {
case 0:
// 设置管理
break;
case 1:
// 取消管理
break;
case 2:
// 移除成员
break;
case 3:
// 转移管理员
break;
}
this.getUserList()
},
inviteUser() {
}
}
}
</script>
@@ -56,19 +133,32 @@
width: 126rpx;
margin-left: 20rpx;
margin-bottom: 20rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.name {
width: 126rpx;
text-align: center;
font-size: 28rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
word-break: break-word;
&.active {
background-color: $window-color;
}
.name {
color: $text-gray-m;
width: 126rpx;
text-align: center;
font-size: 26rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
word-break: break-word;
}
}
}
.loadmore {
font-size: 26rpx;
color: $text-gray-m;
text-align: center;
}
}
</style>