init
This commit is contained in:
@@ -0,0 +1,339 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<lay-out noBottomHeight>
|
||||
<div slot="header">
|
||||
<view class="search-content padding">
|
||||
<view class="uni-input-wrapper"><input class="uni-input" @confirm="initData" v-model="searchData.nickname" placeholder="搜索用户名称" /></view>
|
||||
</view>
|
||||
</div>
|
||||
|
||||
<div slot="content">
|
||||
<!-- 通讯录导航 -->
|
||||
<address-book :bookList="bookList" :letter="letter">
|
||||
<template v-slot:addressBookList>
|
||||
<view class="user-content">
|
||||
<view class="user-list" v-for="(item, index) in Object.keys(bookList)" :key="index">
|
||||
<view class="number padding">{{ item }}</view>
|
||||
<view class="user" v-for="(val, i) in bookList[item]" :key="i" @click="selectUser(val)">
|
||||
<view class="user-list-left"><image :src="val.avatar" mode=""></image></view>
|
||||
<view class="user-list-right">{{ val.nickname }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</address-book>
|
||||
</div>
|
||||
</lay-out>
|
||||
|
||||
<uni-popup ref="userTagModel" type="bottom" animation>
|
||||
<div class="userTag_container">
|
||||
<div class="userTag_container_title">
|
||||
<div :class="{ on: tabOn == 1 }" class="userTag_container_title_message" @click="tabOn = 1"><span>用户标签</span></div>
|
||||
<div :class="{ on: tabOn == 2 }" class="userTag_container_title_message" @click="tabOn = 2"><span>分组标签</span></div>
|
||||
<div class="closeModel" @click="closeUserTagModel"><span class="iconfont"></span></div>
|
||||
</div>
|
||||
|
||||
<scroll-view scroll-y="true" class="userTag_container_list">
|
||||
<div v-if="tabOn == 1" class="userTag_container_list_item" :class="{ mg40: index == 0 }" v-for="(item, index) in userTagList" :key="index">
|
||||
<div class="userTag_container_list_item_label">
|
||||
<span>{{ item.name }}</span>
|
||||
</div>
|
||||
<div class="userTag_container_list_item_value">
|
||||
<span :class="{ select: val.disabled }" v-for="(val, i) in item.label" :key="i" @click="selectTags(val)">{{ val.label }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="tabOn == 2" class="userTag_container_list_item mg40">
|
||||
<div class="userTag_container_list_item_value">
|
||||
<span :class="{ select: val.disabled }" v-for="(val, i) in groupList" :key="val" @click="selectGroups(val)">{{ val.group_name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</scroll-view>
|
||||
<div class="userTag_container_handle" @click="handleSetTags">
|
||||
<div class="userTag_container_handle_button"><span>确定</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</uni-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AddressBook from './addressBookNavigation/addressBookNavigation';
|
||||
import { makePy } from '../../utils/utils';
|
||||
import { navigateTo } from 'pages/utils/uniApi.js';
|
||||
import http from 'pages/api/index';
|
||||
import api from 'pages/api/api.js';
|
||||
export default {
|
||||
components: { AddressBook },
|
||||
data() {
|
||||
return {
|
||||
letter: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'],
|
||||
list: [],
|
||||
search: '',
|
||||
bookList: {},
|
||||
customerServerData: {}, // 客服数据
|
||||
searchData: {
|
||||
nickname: '',
|
||||
label_id: '',
|
||||
group_id: ''
|
||||
},
|
||||
userTagList: [],
|
||||
groupList: [],
|
||||
tabOn: 1,
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.customerServerData = this.$store.state.kefuInfo;
|
||||
this.bookList = this.$store.state.bookList;
|
||||
},
|
||||
onShow() {
|
||||
this.searchData.label_id = '';
|
||||
this.searchData.group_id = '';
|
||||
this.initData();
|
||||
// { id: this.queryUserData.user_id }
|
||||
http(api.userLabelSelect).then(res => {
|
||||
this.userTagList = res;
|
||||
});
|
||||
http(api.UserGroup).then(res => {
|
||||
this.groupList = res;
|
||||
});
|
||||
},
|
||||
onNavigationBarButtonTap() {
|
||||
// this.toTagList();
|
||||
this.$refs.userTagModel.open();
|
||||
},
|
||||
methods: {
|
||||
// 关闭弹窗
|
||||
closeUserTagModel() {
|
||||
this.$refs.userTagModel.close();
|
||||
},
|
||||
// 选择标签
|
||||
selectTags(item) {
|
||||
this.$set(item, 'disabled', !item.disabled);
|
||||
},
|
||||
selectGroups(item) {
|
||||
this.$set(item, 'disabled', !item.disabled);
|
||||
},
|
||||
// 设置标签
|
||||
handleSetTags() {
|
||||
let postData = {
|
||||
label_ids: [],
|
||||
group_ids: []
|
||||
};
|
||||
console.log(111);
|
||||
this.userTagList.forEach(item => {
|
||||
item.label.forEach(val => {
|
||||
if (val.disabled) {
|
||||
postData.label_ids.push(val.id);
|
||||
}
|
||||
});
|
||||
});
|
||||
this.groupList.forEach(item => {
|
||||
if (item.disabled) {
|
||||
postData.group_ids.push(item.id);
|
||||
}
|
||||
});
|
||||
|
||||
console.log(postData);
|
||||
this.searchData.label_id = postData.label_ids.join(',');
|
||||
this.searchData.group_id = postData.group_ids.join();
|
||||
this.closeUserTagModel();
|
||||
this.initData(this.searchData);
|
||||
},
|
||||
// 查询当前客服的客户列表
|
||||
initData() {
|
||||
this.$store.dispatch('getBookList', this.searchData).then(res => {
|
||||
this.bookList = res;
|
||||
});
|
||||
},
|
||||
|
||||
toTagList() {
|
||||
navigateTo(1, '/pages/view/setTags/index');
|
||||
},
|
||||
selectUser(item) {
|
||||
navigateTo(1, '/pages/view/customerServer/customerMessage', { user_id: item.to_user_id });
|
||||
},
|
||||
// 对通讯录按字母顺序做排序
|
||||
letterSrot() {
|
||||
const sortList = [];
|
||||
const list = this.list;
|
||||
this.letter.forEach(item => {
|
||||
const obj = {};
|
||||
obj.key = item;
|
||||
obj.list = [];
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
if (item == makePy(list[i].username).substr(0, 1)) {
|
||||
obj.list.push(list[i]);
|
||||
list.splice(i, 1);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
if (obj.list.length) sortList.push(obj);
|
||||
});
|
||||
this.bookList = sortList;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@padding-l-r: 30rpx;
|
||||
@padding-t-p: 20rpx;
|
||||
@bgc-f: #ffffff;
|
||||
@fontSize: 28rpx;
|
||||
@imgSize: 64rpx;
|
||||
.padding {
|
||||
padding: @padding-t-p @padding-l-r;
|
||||
}
|
||||
.search-content {
|
||||
position: relative;
|
||||
background-color: @bgc-f;
|
||||
input {
|
||||
border: none;
|
||||
background-color: #f5f6f9;
|
||||
color: #c4c4c4;
|
||||
font-size: @fontSize;
|
||||
border-radius: 39px;
|
||||
padding: @padding-t-p 0 @padding-t-p @padding-l-r;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
.user-content {
|
||||
background-color: #eeeeee;
|
||||
.user-list {
|
||||
.number {
|
||||
color: #666666;
|
||||
font-size: @fontSize - 2rpx;
|
||||
}
|
||||
.user {
|
||||
background-color: @bgc-f;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: @padding-t-p @padding-l-r;
|
||||
border-bottom: 1rpx solid #f0f2f7;
|
||||
.user-list-left {
|
||||
width: @imgSize;
|
||||
height: @imgSize;
|
||||
padding-right: 20rpx;
|
||||
image {
|
||||
width: @imgSize;
|
||||
height: @imgSize;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
.user-list-right {
|
||||
color: #282828;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.header {
|
||||
&_content {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
height: 116rpx;
|
||||
background: #1890fc;
|
||||
padding: 0 30rpx;
|
||||
|
||||
/* #ifdef APP-PLUS */
|
||||
padding-top: 64rpx;
|
||||
/* #endif */
|
||||
color: #fff;
|
||||
> div {
|
||||
flex: 1;
|
||||
}
|
||||
> div:nth-child(2) {
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
> div:nth-child(3) {
|
||||
font-size: 14px;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
.userTag_container {
|
||||
padding: 30rpx 40rpx;
|
||||
// padding-bottom: 140rpx;
|
||||
background: #fff;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
&_title {
|
||||
display: flex;
|
||||
// justify-content: flex-end;
|
||||
position: relative;
|
||||
&_message {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
// position: absolute;
|
||||
// top: 50%;
|
||||
// left: 50%;
|
||||
// transform: translate(-50%, -50%);
|
||||
&.on {
|
||||
font-weight: bold;
|
||||
color: #3875EA;
|
||||
}
|
||||
}
|
||||
.closeModel {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
color: #c8cad0;
|
||||
.iconfont {
|
||||
font-size: 36rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&_list {
|
||||
height: 600rpx;
|
||||
&_item {
|
||||
margin-top: 78rpx;
|
||||
&_label {
|
||||
color: #282828;
|
||||
font-weight: bold;
|
||||
margin-bottom: 26rpx;
|
||||
}
|
||||
|
||||
&_value {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 178rpx);
|
||||
grid-row-gap: 26rpx;
|
||||
grid-column-gap: 26rpx;
|
||||
span {
|
||||
font-size: 14px;
|
||||
display: inline-block;
|
||||
background: #f0f0f0;
|
||||
text-align: center;
|
||||
padding: 12rpx 0;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
.select {
|
||||
background: @primaryColor;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.mg0 {
|
||||
margin-top: 40rpx;
|
||||
}
|
||||
}
|
||||
|
||||
&_handle {
|
||||
width: 610rpx;
|
||||
height: 76rpx;
|
||||
background: @primaryColor;
|
||||
opacity: 1;
|
||||
border-radius: 43px;
|
||||
margin: auto;
|
||||
margin-top: 44rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,265 @@
|
||||
<template>
|
||||
<view>
|
||||
<!-- 右边字母选择导航条 -->
|
||||
<view class="searchLetter touchClass" :style="{ height: itemH * searchLetter.length + 'px', paddingRight: paddingRight + 'upx', width: searchLetterWidth + 'upx' }">
|
||||
<view
|
||||
v-for="(item, index) in searchLetter"
|
||||
:style="{ height: itemH + 'px' }"
|
||||
:key="index"
|
||||
:data-letter="item.name"
|
||||
@touchstart.stop.prevent="searchStart"
|
||||
@touchmove.stop.prevent="searchMove"
|
||||
@touchend.stop.prevent="searchEnd"
|
||||
>
|
||||
{{ item.name }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 字母选择提示框 -->
|
||||
<block v-if="isShowLetter">
|
||||
<view class="showSlectedLetter">{{ showLetter }}</view>
|
||||
</block>
|
||||
|
||||
<!-- 通讯录列表 -->
|
||||
<scroll-view scroll-y :scrollTop="scrollTop"><slot name="addressBookList"></slot></scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'addressBookNavigation',
|
||||
props: {
|
||||
//通讯录名字集合
|
||||
bookList: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {};
|
||||
},
|
||||
required: true
|
||||
},
|
||||
//索引集合
|
||||
letter: {
|
||||
type: Array,
|
||||
default() {
|
||||
return ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
|
||||
}
|
||||
},
|
||||
//通讯录索引字母显示高度 upx
|
||||
bookKeyHeight: {
|
||||
type: Number,
|
||||
default() {
|
||||
return 100;
|
||||
}
|
||||
},
|
||||
//通讯录名字显示高度 upx
|
||||
bookItemHeight: {
|
||||
type: Number,
|
||||
default() {
|
||||
return 40;
|
||||
}
|
||||
},
|
||||
//右边索引条右边距 upx
|
||||
paddingRight: {
|
||||
type: Number,
|
||||
default() {
|
||||
return 20;
|
||||
}
|
||||
},
|
||||
//若有搜索框则是搜索框高度 upx
|
||||
searchHeight: {
|
||||
type: Number,
|
||||
default() {
|
||||
return 20;
|
||||
}
|
||||
},
|
||||
//右边索引条距离搜索框位置 upx
|
||||
searchLetterTop: {
|
||||
type: Number,
|
||||
default() {
|
||||
return 60;
|
||||
}
|
||||
},
|
||||
//右边索引条宽度 upx
|
||||
searchLetterWidth: {
|
||||
type: Number,
|
||||
default() {
|
||||
return 40;
|
||||
}
|
||||
},
|
||||
//减去的右边导航条高度 upx
|
||||
subtractiveSearchLetterHeight: {
|
||||
type: Number,
|
||||
default() {
|
||||
return 80;
|
||||
}
|
||||
},
|
||||
//底部tab高度 使用原生导航栏固定为50px 自定义tab传入自定义tab高度 单位为px
|
||||
tabHeight: {
|
||||
type: Number,
|
||||
default() {
|
||||
return 100;
|
||||
}
|
||||
},
|
||||
//导航栏高度
|
||||
navHeight: {
|
||||
type: Number,
|
||||
default() {
|
||||
return 44;
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
searchLetter: [],
|
||||
//右边索引条单个字母元素高度
|
||||
itemH: 0,
|
||||
//可滑动区域高度
|
||||
usableHeight: 0,
|
||||
screenWidth: 0,
|
||||
isShowLetter: false,
|
||||
showLetter: '',
|
||||
scrollTop: 0,
|
||||
badPageY: uni.upx2px(this.searchHeight + this.searchLetterTop),
|
||||
letterPositionTop: 0,
|
||||
scrollViewPositionTop: 0
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
//#ifdef H5
|
||||
this.letterPositionTop = this.searchHeight + this.searchLetterTop + 88;
|
||||
this.scrollViewPositionTop = this.searchHeight + 88;
|
||||
//#endif
|
||||
//#ifndef H5
|
||||
this.letterPositionTop = this.searchHeight + this.searchLetterTop;
|
||||
this.scrollViewPositionTop = this.searchHeight;
|
||||
//#endif
|
||||
// #ifdef APP-PLUS
|
||||
this.letterPositionTop = this.searchHeight + this.searchLetterTop;
|
||||
this.scrollViewPositionTop = this.searchHeight + 260;
|
||||
console.log(1);
|
||||
// #endif
|
||||
this.countLetterHeight();
|
||||
},
|
||||
methods: {
|
||||
//计算和记录右边每个搜索字母的高度和位置
|
||||
countLetterHeight() {
|
||||
const sysInfo = uni.getSystemInfoSync();
|
||||
//#ifdef H5
|
||||
const usableHeight = sysInfo.screenHeight - uni.upx2px(this.searchHeight) - this.tabHeight - this.navHeight;
|
||||
//#endif
|
||||
//#ifndef H5
|
||||
const usableHeight = sysInfo.screenHeight - uni.upx2px(this.searchHeight) - this.tabHeight - this.navHeight - sysInfo.statusBarHeight;
|
||||
//#endif
|
||||
this.screenWidth = sysInfo.screenWidth;
|
||||
const letter = this.letter;
|
||||
const itemH = (usableHeight - uni.upx2px(this.subtractiveSearchLetterHeight) - 20) / letter.length;
|
||||
const tempObj = [];
|
||||
for (let i = 0; i < letter.length; i++) {
|
||||
tempObj.push({
|
||||
name: letter[i],
|
||||
tHeight: i * itemH,
|
||||
bHeight: (i + 1) * itemH
|
||||
});
|
||||
}
|
||||
this.usableHeight = usableHeight;
|
||||
this.itemH = itemH;
|
||||
this.searchLetter = tempObj;
|
||||
},
|
||||
searchEnd(e) {
|
||||
const that = this;
|
||||
setTimeout(() => (that.isShowLetter = false), 500);
|
||||
},
|
||||
//点击选择
|
||||
searchStart(e) {
|
||||
console.log(e);
|
||||
const pageY = e.touches[0].pageY - this.badPageY;
|
||||
this.nowLetter(pageY);
|
||||
},
|
||||
//滑动选择
|
||||
searchMove(e) {
|
||||
const pageY = e.touches[0].pageY - this.badPageY;
|
||||
const pageX = e.touches[0].pageX;
|
||||
if (this.screenWidth - pageX > uni.upx2px(this.searchLetterWidth + this.paddingRight)) {
|
||||
this.isShowLetter = false;
|
||||
return;
|
||||
}
|
||||
if (pageY < 0 || pageY > this.itemH * this.searchLetter.length) {
|
||||
this.isShowLetter = false;
|
||||
return;
|
||||
}
|
||||
this.nowLetter(pageY);
|
||||
},
|
||||
//计算当前选中的字母并显示
|
||||
nowLetter(pageY) {
|
||||
const letterData = this.searchLetter;
|
||||
for (let i = 0; i < letterData.length; i++) {
|
||||
if (letterData[i].tHeight <= pageY && pageY <= letterData[i].bHeight) {
|
||||
this.showLetter = letterData[i].name;
|
||||
this.isShowLetter = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.scrollPage(this.showLetter);
|
||||
},
|
||||
//计算要滑动的距离
|
||||
countScrollTop(showLetter) {
|
||||
let scrollTop = 0;
|
||||
let cityCount = 0;
|
||||
let initialCount = 0;
|
||||
for (let item of Object.keys(this.bookList)) {
|
||||
if (showLetter == item) {
|
||||
scrollTop = initialCount * uni.upx2px(this.bookKeyHeight) + cityCount * uni.upx2px(this.bookItemHeight);
|
||||
break;
|
||||
} else {
|
||||
initialCount++;
|
||||
cityCount += this.bookList[item].length;
|
||||
}
|
||||
}
|
||||
return scrollTop;
|
||||
},
|
||||
//页面滑动到与选中字母对应的位置
|
||||
scrollPage(showLetter) {
|
||||
const scroll = this.countScrollTop(showLetter);
|
||||
if (scroll != 0 || showLetter == Object.keys(this.bookList)[0]) this.scrollTop = scroll;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.searchLetter {
|
||||
position: fixed;
|
||||
top: 126rpx;
|
||||
right: 0;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
color: #666;
|
||||
z-index: 999;
|
||||
}
|
||||
.touchClass {
|
||||
color: #5a5a5a;
|
||||
font-size: 28upx;
|
||||
}
|
||||
|
||||
.showSlectedLetter {
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 100upx;
|
||||
height: 100upx;
|
||||
border-radius: 10upx;
|
||||
font-size: 44upx;
|
||||
z-index: 99;
|
||||
color: #fff;
|
||||
}
|
||||
scroll-view {
|
||||
// position: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user