first commit
This commit is contained in:
433
l-im-app-imooc-master/l-im-app-imooc/pages/chat/chat/chat.vue
Normal file
433
l-im-app-imooc-master/l-im-app-imooc/pages/chat/chat/chat.vue
Normal file
@@ -0,0 +1,433 @@
|
||||
<template>
|
||||
<view>
|
||||
|
||||
<!-- 导航栏 -->
|
||||
<nav-bar :title="detail.name" :noreadnum="999" showBack>
|
||||
<icon-button slot="right" :icon="'\ue6fd'" ></icon-button>
|
||||
</nav-bar>
|
||||
|
||||
<!-- 聊天内容区域 -->
|
||||
<scroll-view scroll-y class="bg-light position-fixed left-0 right-0 px-3"
|
||||
style="bottom: 105rpx;box-sizing: border-box;" :style="chatBodyBottom" :show-scrollbar="false"
|
||||
:scroll-into-view="scrollIntoView" :scroll-with-animation="true" @click="clickPage">
|
||||
|
||||
<!-- 聊天信息列表组件 -->
|
||||
<view v-for="(item,index) in list" :key="index" :id="'chatItem_'+index">
|
||||
<chat-item :item="item" :index="index" ref="chatItem"
|
||||
:pretime=" index > 0 ? list[index-1].createTime : 0" @long="long"
|
||||
:shownickname="currentChatItem.shownickname"></chat-item>
|
||||
</view>
|
||||
|
||||
</scroll-view>
|
||||
|
||||
<!-- #ifdef APP-PLUS-NVUE -->
|
||||
<div v-if="mode === 'action' || mode === 'emoticon'" class="position-fixed top-0 right-0 left-0"
|
||||
:style="'bottom:'+maskBottom+'px;'" @click="clickPage"></div>
|
||||
<!-- #endif -->
|
||||
|
||||
<!-- 底部输入框 -->
|
||||
<view class="position-fixed left-0 right-0 border-top flex align-center"
|
||||
style="background-color: #F7F7F6;height: 105rpx;" :style="'bottom:'+KeyboardHeight+'px;'">
|
||||
<icon-button :icon="'\ue606'" @click="changeVoiceOrText"></icon-button>
|
||||
<view class="flex-1">
|
||||
<textarea fixed class="bg-white rounded p-2 font-md" style="height: 50rpx;max-width: 450rpx;"
|
||||
:adjust-position="false" v-model="text" @focus="mode = 'text'" />
|
||||
</view>
|
||||
<!-- 表情 -->
|
||||
<!-- <icon-button :icon="'\ue605'"></icon-button> -->
|
||||
<template v-if="text.length === 0">
|
||||
<!-- 扩展菜单 -->
|
||||
<icon-button :icon="'\ue603'" @click="openActionOrEmoticon('action')"></icon-button>
|
||||
</template>
|
||||
<view v-else class="flex-shrink">
|
||||
<!-- 发送按钮 -->
|
||||
<main-button name="发送" @click="send('text')"></main-button>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
<!-- 扩展菜单 -->
|
||||
<popup ref="action" bottom transformOrigin="center bottom" @hide="KeyboardHeight = 0" :mask="false">
|
||||
<view style="height: 580rpx;" class="border-top border-light-secondary bg-light">
|
||||
<swiper :indicator-dots="actionLists.length > 1" style="height: 510rpx;">
|
||||
<swiper-item class="row pl-5" v-for="(item,index) in actionLists" :key="index">
|
||||
<view class="col-3 flex flex-column align-center justify-center" style="height: 255rpx;"
|
||||
v-for="(item2,index2) in item" :key="index2" @click="actionEvent(item2)">
|
||||
<image :src="item2.icon" mode="widthFix" style="width: 100rpx;height: 100rpx;"></image>
|
||||
<text class="font-sm text-muted mt-2">{{item2.name}}</text>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
</popup>
|
||||
|
||||
|
||||
<!-- 弹出层 -->
|
||||
<popup ref="extend" :bodyWidth="240" :bodyHeight="450" :tabbarHeight="105">
|
||||
<view class="flex flex-column" style="width: 240rpx;" :style="getMenusStyle">
|
||||
<view class="flex-1 flex align-center" hover-class="bg-light" v-for="(item,index) in menusList"
|
||||
:key="index" @click="clickEvent(item.event)">
|
||||
<text class="font-md pl-3">{{item.name}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</popup>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// #ifdef APP-PLUS-NVUE
|
||||
const dom = weex.requireModule('dom')
|
||||
// #endif
|
||||
|
||||
const sdk = uni.lim.im;
|
||||
|
||||
import navBar from "@/components/ui/nav-bar.vue"
|
||||
import iconButton from "@/components/ui/icon-button.vue"
|
||||
import chatItem from '@/components/ui/chat-item.vue';
|
||||
import popup from "@/components/ui/popup.vue"
|
||||
import mainButton from '@/components/ui/main-button.vue';
|
||||
|
||||
|
||||
import {
|
||||
mapState,
|
||||
mapMutations
|
||||
} from 'vuex'
|
||||
|
||||
import auth from '@/common/mixin/auth.js';
|
||||
import $H from '@/common/lib/request.js';
|
||||
import $C from '@/common/lib/config.js';
|
||||
|
||||
export default {
|
||||
mixins: [auth],
|
||||
components: {
|
||||
navBar,
|
||||
iconButton,
|
||||
chatItem,
|
||||
popup,
|
||||
mainButton
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
scrollIntoView: "",
|
||||
toId: "",
|
||||
// 模式 text输入文字,emoticon表情,action操作,audio音频
|
||||
mode: "text",
|
||||
// 扩展菜单列表
|
||||
actionList: [
|
||||
[{
|
||||
name: "相册",
|
||||
icon: "/static/images/extends/pic.png",
|
||||
event: "uploadImage"
|
||||
}, {
|
||||
name: "拍摄",
|
||||
icon: "/static/images/extends/video.png",
|
||||
event: "uploadVideo"
|
||||
}, {
|
||||
name: "收藏",
|
||||
icon: "/static/images/extends/shoucan.png",
|
||||
event: "openFava"
|
||||
}, {
|
||||
name: "名片",
|
||||
icon: "/static/images/extends/man.png",
|
||||
event: "sendCard"
|
||||
}, {
|
||||
name: "语音通话",
|
||||
icon: "/static/images/extends/phone.png",
|
||||
event: ""
|
||||
}, {
|
||||
name: "位置",
|
||||
icon: "/static/images/extends/path.png",
|
||||
event: ""
|
||||
}]
|
||||
],
|
||||
emoticonList: [],
|
||||
// 键盘高度
|
||||
KeyboardHeight: 0,
|
||||
menusList: [],
|
||||
navBarHeight: 0,
|
||||
list: [{
|
||||
userId: 'lld',
|
||||
avatar: "/static/images/userpic.png",
|
||||
data: "你好啊你好啊你好啊你好啊你好啊你好啊你好啊",
|
||||
nickname: "lld",
|
||||
type: "text",
|
||||
createTime: 1657465771,
|
||||
isRemove: false
|
||||
}, {
|
||||
userId: 'lld2',
|
||||
avatar: "/static/images/userpic.png",
|
||||
data: "1234567890",
|
||||
nickname: "lld2",
|
||||
type: "text",
|
||||
createTime: 1658329771,
|
||||
isRemove: false
|
||||
}, {
|
||||
userId: 'lld',
|
||||
avatar: "/static/images/userpic.png",
|
||||
data: "你好啊你好啊你好啊你好啊你好啊你好啊你好啊",
|
||||
nickname: "lld",
|
||||
type: "text",
|
||||
createTime: 1657465771,
|
||||
isRemove: false
|
||||
}, {
|
||||
userId: 'lld2',
|
||||
avatar: "/static/images/userpic.png",
|
||||
data: "1234567890",
|
||||
nickname: "lld2",
|
||||
type: "text",
|
||||
createTime: 1658329771,
|
||||
isRemove: false
|
||||
}],
|
||||
// 当前操作的气泡索引
|
||||
propIndex: -1,
|
||||
// 输入文字
|
||||
text: "",
|
||||
|
||||
detail: {
|
||||
id: 0,
|
||||
name: "",
|
||||
avatar: "",
|
||||
chat_type: "user"
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
var statusBarHeight = 0
|
||||
// #ifdef APP-PLUS-NVUE
|
||||
statusBarHeight = plus.navigator.getStatusbarHeight()
|
||||
// #endif
|
||||
this.navBarHeight = statusBarHeight + uni.upx2px(90)
|
||||
|
||||
// 监听键盘高度变化
|
||||
uni.onKeyboardHeightChange(res => {
|
||||
if (this.mode !== 'action' && this.mode !== 'emoticon') {
|
||||
this.KeyboardHeight = res.height
|
||||
}
|
||||
if (this.KeyboardHeight > 0) {
|
||||
this.pageToBottom()
|
||||
}
|
||||
})
|
||||
|
||||
this.pageToBottom()
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
}),
|
||||
// 当前会话配置信息
|
||||
currentChatItem() {
|
||||
return {}
|
||||
},
|
||||
// 获取蒙版的位置
|
||||
maskBottom() {
|
||||
return this.KeyboardHeight + uni.upx2px(105)
|
||||
},
|
||||
// 动态获取菜单高度
|
||||
getMenusHeight() {
|
||||
let H = 100
|
||||
return this.menusList.length * H
|
||||
},
|
||||
// 获取菜单的样式
|
||||
getMenusStyle() {
|
||||
return `height: ${this.getMenusHeight}rpx;`
|
||||
},
|
||||
// 判断是否操作本人信息
|
||||
isdoSelf() {
|
||||
// 获取本人id(假设拿到了)
|
||||
let id = 1
|
||||
let user_id = this.propIndex > -1 ? this.list[this.propIndex].user_id : 0
|
||||
return user_id === id
|
||||
},
|
||||
// 聊天区域bottom
|
||||
chatBodyBottom() {
|
||||
return `bottom:${uni.upx2px(105) + this.KeyboardHeight}px;top:${this.navBarHeight}px;`
|
||||
},
|
||||
// 获取操作或者表情列表
|
||||
actionLists() {
|
||||
return (this.mode === 'emoticon' || this.mode === 'action') ? this[this.mode + 'List'] : []
|
||||
},
|
||||
// 所有信息的图片地址
|
||||
imageList() {
|
||||
let arr = []
|
||||
this.list.forEach((item) => {
|
||||
if (item.type === 'emoticon' || item.type === 'image') {
|
||||
arr.push(item.data)
|
||||
}
|
||||
})
|
||||
return arr
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
mode(newValue, oldValue) {
|
||||
if (newValue !== 'action' && newValue !== 'emoticon') {
|
||||
this.$refs.action.hide()
|
||||
}
|
||||
if (newValue !== 'text') {
|
||||
uni.hideKeyboard()
|
||||
}
|
||||
}
|
||||
},
|
||||
onLoad(e) {
|
||||
var toIdObj = JSON.parse(decodeURIComponent(e.params))
|
||||
this.toId = toIdObj.id;
|
||||
// // 监听接收聊天信息
|
||||
uni.$on('P2PMessage', this.onMessage)
|
||||
},
|
||||
destroyed() {
|
||||
// // 销毁监听接收聊天消息
|
||||
uni.$off('P2PMessage',this.onMessage)
|
||||
},
|
||||
methods: {
|
||||
onMessage(message) {
|
||||
if(message.fromId != this.toId){
|
||||
return;
|
||||
}
|
||||
console.log('[聊天页] 监听接收聊天信息', message);
|
||||
var messageBody = JSON.parse(message.messageBody);
|
||||
if(messageBody.type == 1){
|
||||
let msg = {
|
||||
userId:message.fromId,
|
||||
avatar: "/static/images/userpic.png",
|
||||
data: messageBody.content == '' ? '空消息' : messageBody.content,
|
||||
nickname:message.fromId,
|
||||
type: "text",
|
||||
createTime: message.messageTime / 1000,
|
||||
isRemove: false
|
||||
}
|
||||
this.list.push(msg)
|
||||
}
|
||||
this.pageToBottom()
|
||||
},
|
||||
__init() {},
|
||||
// 打开扩展菜单或者表情包
|
||||
openActionOrEmoticon(mode = 'action') {
|
||||
this.mode = mode
|
||||
this.$refs.action.show()
|
||||
|
||||
uni.hideKeyboard()
|
||||
this.KeyboardHeight = uni.upx2px(580)
|
||||
},
|
||||
// 发送
|
||||
send(type, data = '', options = {}) {
|
||||
// 组织数据格式
|
||||
if (type == 'text') {
|
||||
sdk.sendP2PMessage(sdk.createP2PTextMessage(this.toId, this.text))
|
||||
let uid = sdk.getUserId();
|
||||
let msg = {
|
||||
userId:uid,
|
||||
avatar: "/static/images/userpic.png",
|
||||
data: this.text,
|
||||
nickname:uid,
|
||||
type: "text",
|
||||
createTime: Date.parse(new Date()) / 1000,
|
||||
isRemove: false
|
||||
}
|
||||
this.list.push(msg)
|
||||
}
|
||||
// 发送文字成功,清空输入框
|
||||
if (type === 'text') {
|
||||
this.text = ''
|
||||
}
|
||||
// 置于底部
|
||||
this.pageToBottom()
|
||||
},
|
||||
// 回到底部
|
||||
pageToBottom() {
|
||||
// #ifdef APP-PLUS-NVUE
|
||||
let chatItem = this.$refs.chatItem
|
||||
let lastIndex = chatItem.length > 0 ? chatItem.length - 1 : 0
|
||||
if (chatItem[lastIndex]) {
|
||||
dom.scrollToElement(chatItem[lastIndex], {})
|
||||
}
|
||||
// #endif
|
||||
// #ifndef APP-NVUE
|
||||
setTimeout(() => {
|
||||
let lastIndex = this.list.length - 1
|
||||
this.scrollIntoView = 'chatItem_' + lastIndex
|
||||
}, 300)
|
||||
// #endif
|
||||
},
|
||||
// 长按消息气泡
|
||||
long({
|
||||
x,
|
||||
y,
|
||||
index
|
||||
}) {
|
||||
// 初始化 索引
|
||||
this.propIndex = index
|
||||
// 组装菜单
|
||||
let menus = [{
|
||||
name: "发送给朋友",
|
||||
event: 'sendToChatItem'
|
||||
}, {
|
||||
name: "收藏",
|
||||
event: 'fava'
|
||||
}, {
|
||||
name: "删除",
|
||||
event: 'delete'
|
||||
}]
|
||||
let item = this.list[this.propIndex]
|
||||
menus.push({
|
||||
name: "撤回",
|
||||
event: 'removeChatItem'
|
||||
})
|
||||
// #ifndef H5
|
||||
if (item.type === 'text') {
|
||||
menus.unshift({
|
||||
name: "复制",
|
||||
event: 'copy',
|
||||
})
|
||||
}
|
||||
// #endif
|
||||
this.menusList = menus
|
||||
// 显示扩展菜单
|
||||
this.$refs.extend.show(x, y)
|
||||
},
|
||||
// 操作菜单方法分发
|
||||
clickEvent(event) {
|
||||
// 关闭菜单
|
||||
this.$refs.extend.hide()
|
||||
},
|
||||
// 扩展菜单
|
||||
actionEvent(e) {
|
||||
switch (e.event) {
|
||||
case 'uploadImage': // 选择相册
|
||||
uni.chooseImage({
|
||||
count: 9,
|
||||
success: (res) => {
|
||||
// 发送到服务器
|
||||
// 渲染到页面
|
||||
res.tempFilePaths.forEach((item) => {
|
||||
this.send('image', item)
|
||||
})
|
||||
}
|
||||
})
|
||||
break;
|
||||
case 'uploadVideo': // 发送短视频
|
||||
uni.chooseVideo({
|
||||
maxDuration: 10,
|
||||
success: (res) => {
|
||||
this.send('video', res.tempFilePath)
|
||||
// 渲染页面
|
||||
// 发送到服务端(获取视频封面,返回url)
|
||||
// 修改本地的发送状态
|
||||
}
|
||||
})
|
||||
break;
|
||||
}
|
||||
},
|
||||
// 点击页面
|
||||
clickPage() {
|
||||
this.mode = ''
|
||||
},
|
||||
// 切换音频录制和文本输入
|
||||
changeVoiceOrText() {
|
||||
this.mode = this.mode !== 'audio' ? 'audio' : 'text'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,144 @@
|
||||
<template>
|
||||
<view>
|
||||
<view>
|
||||
<view class="flex align-center justify-center"
|
||||
style="height: 350rpx;">
|
||||
<text style="font-size: 50rpx;">LOGO</text>
|
||||
</view>
|
||||
<view class="px-3">
|
||||
<input type="text" class="bg-light px-3 mb-3 font" :placeholder=getUserNameText style="height: 100rpx;" v-model="form.userName"/>
|
||||
<input type="text" class="bg-light px-3 mb-3 font" placeholder="请输入密码" style="height: 100rpx;" v-model="form.password"/>
|
||||
<input v-if="type === 'reg'" type="text" class="bg-light px-3 mb-3 font" placeholder="请输入确认密码" style="height: 100rpx;" v-model="form.repassword"/>
|
||||
</view>
|
||||
<view class="p-3 flex align-center justify-center">
|
||||
<view class="main-bg-color rounded p-3 flex align-center justify-center flex-1"
|
||||
hover-class="main-bg-hover-color" @click="submit">
|
||||
<text class="text-white font-md">{{type === 'login' ? '登 录' : '注 册'}}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="flex align-center justify-center">
|
||||
<text class="text-light-muted font p-2" @click="changeType">{{type === 'login' ? '注册账号' : '马上登录'}}</text>
|
||||
<text class="text-light-muted font">|</text>
|
||||
<text class="text-light-muted font p-2">忘记密码</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import $H from '@/common/lib/request.js';
|
||||
import Vue from 'vue'
|
||||
|
||||
const ListenerMap = {
|
||||
onSocketConnectEvent: (option, status, data) => {
|
||||
console.log("已建立连接:" + JSON.stringify(status));
|
||||
},
|
||||
onSocketErrorEvent: (error) => {
|
||||
console.log("连接出现错误:" + userId);
|
||||
},
|
||||
onSocketReConnectEvent: () => {
|
||||
console.log("正在重连:" );
|
||||
},
|
||||
onSocketCloseEvent: () => {
|
||||
console.log("连接关闭:" );
|
||||
},onSocketReConnectSuccessEvent: () => {
|
||||
console.log("重连成功" );
|
||||
},
|
||||
onTestMessage: (e) => {
|
||||
console.log("onTestMessage :" + e );
|
||||
},
|
||||
onP2PMessage: (e) => {
|
||||
console.log("onP2PMessage :" + e );
|
||||
e = JSON.parse(e)
|
||||
uni.$emit('P2PMessage', e.data);
|
||||
},
|
||||
onLogin: (uid) => {
|
||||
console.log("用户"+uid+"登陆sdk成功" );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
type:"login",
|
||||
form: {
|
||||
userName:"lld",
|
||||
password:"lld",
|
||||
repassword:"",
|
||||
loginType:1
|
||||
},
|
||||
show:true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
changeType(){
|
||||
// this.type = this.type === 'login' ? 'reg' : 'login'
|
||||
// this.form = {
|
||||
// username:"",
|
||||
// password:"",
|
||||
// repassword:""
|
||||
// }
|
||||
},
|
||||
submit() {
|
||||
if(this.type === 'login'){
|
||||
$H.post('/login',this.form,{
|
||||
token:false
|
||||
}).then(res=>{
|
||||
console.log(res)
|
||||
if(res.code !== 200){
|
||||
uni.showToast({
|
||||
title: res.msg,
|
||||
icon: 'none'
|
||||
});
|
||||
}else{
|
||||
//app服务登录成功,去登录im
|
||||
const lim = this.imsdk
|
||||
const sdk = lim.im;
|
||||
|
||||
var userId = this.form.userName;
|
||||
var listeners = {};
|
||||
for (const v in ListenerMap) {
|
||||
listeners[v] = ListenerMap[v];
|
||||
}
|
||||
|
||||
sdk.init("http://127.0.0.1:8000/v1",res.data.appId,res.data.userId,res.data.imUserSign,listeners,function (sdk) {
|
||||
if(sdk){
|
||||
console.log('sdk 成功连接的回调, 可以使用 sdk 请求数据了.');
|
||||
return uni.switchTab({
|
||||
url:"/pages/tabbar/index/index"
|
||||
})
|
||||
}
|
||||
else {
|
||||
console.log('sdk 初始化失败.');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
getUserNameText(){
|
||||
if(this.type === 'login'){
|
||||
return "请输入用户名";
|
||||
}
|
||||
else if(this.type === 'reg'){
|
||||
return "请输入手机号";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<view class="page">
|
||||
<!-- 导航栏 -->
|
||||
<nav-bar title="我的设置" showBack :showRight="false"></nav-bar>
|
||||
<!-- 退出登录 -->
|
||||
<divider></divider>
|
||||
<view class="py-3 flex align-center justify-center bg-white" hover-class="bg-light" @click="logout">
|
||||
<text class="font-md text-primary">退出登录</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import navBar from "@/components/ui/nav-bar.vue"
|
||||
import divider from "@/components/ui/divider.vue"
|
||||
import $H from '@/common/lib/request.js';
|
||||
export default {
|
||||
components: {
|
||||
navBar,
|
||||
divider
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
logout() {
|
||||
// 跳转到登录页
|
||||
uni.reLaunch({
|
||||
url: "/pages/common/login/login"
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<view class="page">
|
||||
<!-- 导航栏 -->
|
||||
<nav-bar title="个人资料" showBack :showRight="false"></nav-bar>
|
||||
<list-item title="头像" showRight :showLeftIcon="false">
|
||||
<avater slot="right" :src="user.avatar"></avater>
|
||||
</list-item>
|
||||
<list-item title="昵称" showRight :showLeftIcon="false">
|
||||
<text slot="right" class="font text-muted">{{user.nickname}}</text>
|
||||
</list-item>
|
||||
<list-item title="账号" showRight :showLeftIcon="false">
|
||||
<text slot="right" class="font text-muted">{{user.username}}</text>
|
||||
</list-item>
|
||||
|
||||
<confirm ref="confirm" :title="confirmTitle">
|
||||
<input type="text" v-model="confirmText" :placeholder="placeholder" class="border-bottom font-md"/>
|
||||
</confirm>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import navBar from "@/components/ui/nav-bar.vue"
|
||||
import avater from '@/components/ui/avater.vue';
|
||||
import listItem from "@/components/ui/list-item.vue"
|
||||
import confirm from '@/components/ui/confirm.vue';
|
||||
|
||||
import $H from '@/common/lib/request.js';
|
||||
export default {
|
||||
components: {
|
||||
navBar,
|
||||
avater,
|
||||
listItem,
|
||||
confirm
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
confirmText:"",
|
||||
confirmType:"",
|
||||
user:{
|
||||
avatar:"",
|
||||
nickname:"lld",
|
||||
username:"lld"
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
confirmTitle() {
|
||||
return this.confirmType == 'username' ? '修改账号' :'修改昵称'
|
||||
},
|
||||
placeholder(){
|
||||
return this.confirmType == 'username' ? '输入账号' :'输入昵称'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,71 @@
|
||||
<template>
|
||||
<view class="page">
|
||||
<!-- 导航栏 -->
|
||||
<nav-bar title="发现"></nav-bar>
|
||||
|
||||
<!-- 通讯录列表 -->
|
||||
<list-item title="朋友圈" showRight>
|
||||
<text slot="icon" class="iconfont font-lg py-1"></text>
|
||||
<view slot="right" class="p-1">
|
||||
<view class="position-relative" v-if="!notice.num">
|
||||
<text class="rounded-circle bg-danger position-absolute" style="width: 20rpx;height: 20rpx;top: 0;right: 0;"></text>
|
||||
</view>
|
||||
<badge v-if="notice.num" :value="notice.num"></badge>
|
||||
</view>
|
||||
</list-item>
|
||||
<divider></divider>
|
||||
<list-item title="扫一扫" showRight>
|
||||
<text slot="icon" class="iconfont font-lg py-1"></text>
|
||||
</list-item>
|
||||
<list-item title="摇一摇" showRight>
|
||||
<text slot="icon" class="iconfont font-lg py-1"></text>
|
||||
</list-item>
|
||||
<divider></divider>
|
||||
<list-item title="看一看" showRight>
|
||||
<text slot="icon" class="iconfont font-lg py-1"></text>
|
||||
</list-item>
|
||||
<list-item title="搜一搜" showRight>
|
||||
<text slot="icon" class="iconfont font-lg py-1"></text>
|
||||
</list-item>
|
||||
<divider></divider>
|
||||
<list-item title="购物" showRight>
|
||||
<text slot="icon" class="iconfont font-lg py-1"></text>
|
||||
</list-item>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import navBar from "@/components/ui/nav-bar.vue"
|
||||
import listItem from "@/components/ui/list-item.vue"
|
||||
import divider from "@/components/ui/divider.vue"
|
||||
import badge from "@/components/ui/badge.vue"
|
||||
import auth from '@/common/mixin/auth.js'
|
||||
|
||||
export default {
|
||||
mixins:[auth],
|
||||
components: {
|
||||
navBar,
|
||||
listItem,
|
||||
divider,
|
||||
badge
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
notice:{
|
||||
num: 1,
|
||||
userId:"lld",
|
||||
avatar:"/static/images/userpic.png"
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,151 @@
|
||||
<template>
|
||||
|
||||
<view>
|
||||
<!-- 导航栏 -->
|
||||
<nav-bar title="微信(10)">
|
||||
</nav-bar>
|
||||
|
||||
<!-- 置顶列表 -->
|
||||
<block v-for="(item,index) in list" :key="index">
|
||||
<media-list v-if="item.istop" :item="item" :index="index" @long="long"></media-list>
|
||||
</block>
|
||||
|
||||
<!-- 非置顶列表 -->
|
||||
<block v-for="(item,index) in list" :key="index">
|
||||
<media-list v-if="!item.istop" :item="item" :index="index" @long="long"></media-list>
|
||||
</block>
|
||||
|
||||
<!-- 弹出层 -->
|
||||
<popup ref="extend" :bodyWidth="240" :bodyHeight="getMenusHeight">
|
||||
<view class="flex flex-column" style="width: 240rpx;" :style="getMenusStyle">
|
||||
<view class="flex-1 flex align-center" hover-class="bg-light" v-for="(item,index) in menus" :key="index"
|
||||
@click="clickEvent(item.event)">
|
||||
<text class="font-md pl-3">{{item.name}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</popup>
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import navBar from "@/components/ui/nav-bar.vue"
|
||||
import mediaList from "@/components/ui/media-list.vue"
|
||||
import popup from "@/components/ui/popup.vue"
|
||||
import auth from '@/common/mixin/auth.js'
|
||||
|
||||
export default {
|
||||
mixins:[auth],
|
||||
components: {
|
||||
navBar,
|
||||
mediaList,
|
||||
popup
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
propIndex: -1,
|
||||
list: [{
|
||||
avatar: "/static/images/userpic.png",
|
||||
nickname: "lld",
|
||||
id: "lld",
|
||||
updateTime: 1657554934224,
|
||||
data: "我是lld",
|
||||
istop: true,
|
||||
noreadnum: 1
|
||||
},
|
||||
{
|
||||
avatar: "/static/images/userpic.png",
|
||||
nickname: "lld2",
|
||||
id: "lld2",
|
||||
updateTime: 1654962934000,
|
||||
data: "我是lld2",
|
||||
istop: false,
|
||||
noreadnum: 0
|
||||
},
|
||||
{
|
||||
avatar: "../../../static/images/userpic.png",
|
||||
nickname: "lld3",
|
||||
id: "lld3",
|
||||
updateTime: 1626018934000,
|
||||
data: "我是lld3",
|
||||
istop: true,
|
||||
noreadnum: 1
|
||||
}
|
||||
],
|
||||
|
||||
menus: [{
|
||||
name: "设为置顶",
|
||||
event: "setTop"
|
||||
},
|
||||
{
|
||||
name: "删除该聊天",
|
||||
event: "delChat"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
|
||||
},
|
||||
onShow() {
|
||||
|
||||
},
|
||||
computed:{
|
||||
// 动态获取菜单高度
|
||||
getMenusHeight(){
|
||||
let H = 100
|
||||
return this.menus.length * H
|
||||
},
|
||||
// 获取菜单的样式
|
||||
getMenusStyle(){
|
||||
return `height: ${this.getMenusHeight}rpx;`
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
openExtend() {
|
||||
this.$refs.extend.show();
|
||||
},
|
||||
long({
|
||||
x,
|
||||
y,
|
||||
index
|
||||
}) {
|
||||
// 初始化 索引
|
||||
this.propIndex = index
|
||||
// 拿到当前对象
|
||||
let item = this.list[index]
|
||||
// 判断之前是否处于置顶状态
|
||||
this.menus[0].name = item.istop ? '取消置顶' : '设为置顶'
|
||||
this.$refs.extend.show(x, y)
|
||||
},
|
||||
// 分发菜单事件
|
||||
clickEvent(event){
|
||||
switch (event){
|
||||
case "setTop": // 置顶/取消置顶会话
|
||||
this.setTop()
|
||||
break;
|
||||
case "delChat": // 删除当前会话
|
||||
this.delChat()
|
||||
break;
|
||||
}
|
||||
this.$refs.extend.hide()
|
||||
},
|
||||
// 置顶/取消置顶会话
|
||||
setTop(){
|
||||
let item = this.list[this.propIndex]
|
||||
item.istop = !item.istop
|
||||
},
|
||||
// 删除当前会话
|
||||
delChat(){
|
||||
this.list.splice(this.propIndex,1);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
|
||||
</style>
|
||||
166
l-im-app-imooc-master/l-im-app-imooc/pages/tabbar/mail/mail.vue
Normal file
166
l-im-app-imooc-master/l-im-app-imooc/pages/tabbar/mail/mail.vue
Normal file
@@ -0,0 +1,166 @@
|
||||
<template>
|
||||
<view>
|
||||
<!-- 导航栏 -->
|
||||
<nav-bar title="通讯录" :showBack="false" :showRight="false">
|
||||
|
||||
</nav-bar>
|
||||
|
||||
<scroll-view scroll-y="true" :style="'height:'+scrollHeight+'px;'" :scroll-into-view="scrollInto">
|
||||
<!-- 通讯录列表 :showRight="item.id === 'friend' && applyCount > 0" -->
|
||||
<list-item v-for="(item,index) in topList" :title="item.title" :key="item.id" :cover="item.cover">
|
||||
</list-item>
|
||||
</scroll-view>
|
||||
|
||||
|
||||
<!-- 侧边导航条 -->
|
||||
<view class="position-fixed right-0 bottom-0 bg-light flex flex-column" :style="'top:' +top+ 'px'"
|
||||
style="width: 50rpx;">
|
||||
</view>
|
||||
|
||||
<!-- 侧边导航条 -->
|
||||
<!-- <view class="position-fixed right-0 bottom-0 bg-light flex flex-column" :style="'top:'+top+'px;'"
|
||||
style="width: 50rpx;" @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend">
|
||||
<view class="flex-1 flex align-center justify-center" v-for="(item,index) in list.keys()" :key="index">
|
||||
<text class="font-sm text-muted">{{item}}</text>
|
||||
</view>
|
||||
</view> -->
|
||||
|
||||
<!-- <view class="position-fixed rounded-circle bg-light border flex align-center justify-center" v-if="current"
|
||||
style="width: 150rpx;height: 150rpx;left: 300rpx;"
|
||||
:style="'top:'+modalTop+'px;'">
|
||||
<text class="font-lg">{{current}}</text>
|
||||
</view> -->
|
||||
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import navBar from "@/components/ui/nav-bar.vue"
|
||||
import listItem from "@/components/ui/list-item.vue"
|
||||
import auth from '@/common/mixin/auth.js'
|
||||
import badge from "@/components/ui/badge.vue"
|
||||
|
||||
export default {
|
||||
mixins:[auth],
|
||||
components: {
|
||||
navBar,
|
||||
listItem,
|
||||
badge
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
top: 0,
|
||||
friendRequestNum: 0,
|
||||
topList: [{
|
||||
id: "friend",
|
||||
title: "新的朋友",
|
||||
cover: "/static/images/mail/friend.png",
|
||||
path: "mail/apply-list/apply-list"
|
||||
},
|
||||
{
|
||||
id: "group",
|
||||
title: "群聊",
|
||||
cover: "/static/images/mail/group.png",
|
||||
path: "mail/group-list/group-list"
|
||||
},
|
||||
{
|
||||
id: "tag",
|
||||
title: "标签",
|
||||
cover: "/static/images/mail/tag.png",
|
||||
path: "mail/tag-list/tag-list"
|
||||
}
|
||||
],
|
||||
// list: new Map(),
|
||||
list:
|
||||
[{
|
||||
"letter": "A",
|
||||
"data": [
|
||||
"AAAAA微商",
|
||||
"a ",
|
||||
"澳门风云"
|
||||
]
|
||||
},
|
||||
{
|
||||
"letter": "B",
|
||||
"data": [
|
||||
"宝贝",
|
||||
]
|
||||
},
|
||||
{
|
||||
"letter": "C",
|
||||
"data": [
|
||||
"草原",
|
||||
]
|
||||
},
|
||||
{
|
||||
"letter": "D",
|
||||
"data": []
|
||||
},
|
||||
{
|
||||
"letter": "E",
|
||||
"data": []
|
||||
},
|
||||
{
|
||||
"letter": "F",
|
||||
"data": []
|
||||
},
|
||||
{
|
||||
"letter": "G",
|
||||
"data": []
|
||||
},
|
||||
{
|
||||
"letter": "H",
|
||||
"data": [
|
||||
"黄飞鸿",
|
||||
"黄继光"
|
||||
]
|
||||
},
|
||||
{
|
||||
"letter": "I",
|
||||
"data": [
|
||||
"ICON",
|
||||
"icc",
|
||||
"icc",
|
||||
"icc",
|
||||
"icc"
|
||||
]
|
||||
}
|
||||
]
|
||||
,
|
||||
|
||||
top: 0,
|
||||
scrollHeight: 0,
|
||||
scrollInto: '',
|
||||
current: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
},
|
||||
onLoad() {
|
||||
let res = uni.getSystemInfoSync()
|
||||
this.top = res.statusBarHeight + uni.upx2px(90)
|
||||
this.scrollHeight = res.windowHeight - this.top
|
||||
},
|
||||
onShow() {
|
||||
},
|
||||
computed: {
|
||||
// 每个索引的高度
|
||||
itemHeight() {
|
||||
let count = this.list.size
|
||||
// debugger;
|
||||
if (count < 1) {
|
||||
return 0
|
||||
}
|
||||
return this.scrollHeight / count
|
||||
},
|
||||
modalTop(){
|
||||
return (this.scrollHeight - uni.upx2px(150)) / 2
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
77
l-im-app-imooc-master/l-im-app-imooc/pages/tabbar/my/my.vue
Normal file
77
l-im-app-imooc-master/l-im-app-imooc/pages/tabbar/my/my.vue
Normal file
@@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<view class="page">
|
||||
<!-- 导航栏 -->
|
||||
<nav-bar bgColor="bg-white">
|
||||
<icon-button slot="right" :icon="'\ue6ed'"></icon-button>
|
||||
</nav-bar>
|
||||
|
||||
<list-item :cover="user.photo ? user.photo : '/static/images/userpic.jpg'"
|
||||
coverSize="120" :title="user.nickName" showRight @click="open('my/userinfo/userinfo')">
|
||||
<view class="flex flex-column">
|
||||
<text class="text-dark font-lg font-weight-bold">{{user.nickName}}</text>
|
||||
<text class="text-light-muted font mt-2">仿微信号:{{user.nickName}}</text>
|
||||
</view>
|
||||
<view slot="right">
|
||||
<text class="iconfont font-md text-light-muted"></text>
|
||||
</view>
|
||||
</list-item>
|
||||
|
||||
<divider></divider>
|
||||
|
||||
<list-item title="支付" showRight>
|
||||
<text slot="icon" class="iconfont font-lg py-1"></text>
|
||||
</list-item>
|
||||
|
||||
<divider></divider>
|
||||
|
||||
<list-item title="相册" showRight
|
||||
@click="open()">
|
||||
<text slot="icon" class="iconfont font-lg py-1"></text>
|
||||
</list-item>
|
||||
|
||||
<divider></divider>
|
||||
|
||||
<list-item title="设置" showRight @click="open('my/setting/setting')">
|
||||
<text slot="icon" class="iconfont font-lg py-1"></text>
|
||||
</list-item>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import navBar from "@/components/ui/nav-bar.vue"
|
||||
import iconButton from "@/components/ui/icon-button.vue"
|
||||
import listItem from "@/components/ui/list-item.vue"
|
||||
import divider from "@/components/ui/divider.vue"
|
||||
import auth from '@/common/mixin/auth.js'
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
components:{
|
||||
navBar,
|
||||
listItem,
|
||||
iconButton,
|
||||
divider
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
user:{
|
||||
nickName:"lld"
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
open(path){
|
||||
uni.navigateTo({
|
||||
url: '/pages/'+path
|
||||
});
|
||||
},
|
||||
},
|
||||
computed:{
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user