This commit is contained in:
212
pages/sys/workbench/book/book.vue
Normal file
212
pages/sys/workbench/book/book.vue
Normal file
@@ -0,0 +1,212 @@
|
||||
<template>
|
||||
<view class="page">
|
||||
<!-- 搜索框 -->
|
||||
<view class="search-box">
|
||||
<input type="text" class="search-input" placeholder="部门、岗位、姓名" v-model="keyword"/>
|
||||
</view>
|
||||
|
||||
<!-- 联系人列表 -->
|
||||
<scroll-view
|
||||
scroll-y
|
||||
class="contact-list"
|
||||
:scroll-into-view="currentView"
|
||||
scroll-with-animation
|
||||
>
|
||||
<block v-for="(group, gIndex) in contacts" :key="gIndex">
|
||||
<view class="group-title" :id="'group-' + group.letter">{{ group.letter }}</view>
|
||||
<view class="contact-item" v-for="(item, index) in group.list" :key="index">
|
||||
<image class="avatar" :src="item.avatar"></image>
|
||||
<view class="contact-info">
|
||||
<text class="name" :class="{'highlight': item.isHighlight}">{{ item.name }}</text>
|
||||
<text class="desc">{{ item.job }} {{ item.phone }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</scroll-view>
|
||||
|
||||
|
||||
<!-- 字母索引栏 -->
|
||||
<view
|
||||
class="index-bar"
|
||||
@touchstart="onTouch"
|
||||
@touchmove.stop.prevent="onTouch"
|
||||
@touchend="onTouchEnd"
|
||||
@touchcancel="onTouchEnd"
|
||||
>
|
||||
<view
|
||||
v-for="(letter, i) in indexList"
|
||||
:key="i"
|
||||
class="index-item"
|
||||
:style="{height: indexItemHeight + 'rpx', lineHeight: indexItemHeight + 'rpx'}"
|
||||
>
|
||||
{{ letter }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
<!-- 居中大字母提示 -->
|
||||
<view v-if="showLetter" class="letter-toast">
|
||||
{{ showLetter }}
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
keyword: "",
|
||||
currentView: "",
|
||||
showLetter: "",
|
||||
indexList: "ABCDEFGHIJKLMNOPQRSTUVWXYZ#".split(""),
|
||||
indexItemHeight: 30, // 索引单个高度 (rpx),可调整
|
||||
contacts: [
|
||||
{ letter: "A", list: [{ name: "张晓明", phone: "17895698899", job: "保洁", avatar: "https://img.yzcdn.cn/vant/cat.jpeg", isHighlight: true }] },
|
||||
{ letter: "B", list: [
|
||||
{ name: "阿俊", phone: "17895698899", job: "保洁", avatar: "https://img.yzcdn.cn/vant/dog.jpeg" },
|
||||
{ name: "阿俊", phone: "17895698899", job: "保洁", avatar: "https://img.yzcdn.cn/vant/cat.jpeg" },
|
||||
{ name: "阿俊", phone: "17895698899", job: "保洁", avatar: "https://img.yzcdn.cn/vant/elephant.jpeg" }
|
||||
]},
|
||||
{ letter: "C", list: [
|
||||
{ name: "阿俊", phone: "17895698899", job: "保洁", avatar: "https://img.yzcdn.cn/vant/horse.jpeg" },
|
||||
{ name: "阿俊", phone: "17895698899", job: "保洁", avatar: "https://img.yzcdn.cn/vant/lion.jpeg" }
|
||||
]}
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 开始/移动
|
||||
onTouch(e) {
|
||||
const touchY = e.touches[0].clientY
|
||||
this.calcIndexByY(touchY)
|
||||
},
|
||||
// 松手/取消时隐藏
|
||||
onTouchEnd() {
|
||||
setTimeout(() => {
|
||||
this.showLetter = ""
|
||||
}, 300) // 0.3 秒后消失
|
||||
},
|
||||
|
||||
// 计算位置 → 滚动 & 显示大字母
|
||||
calcIndexByY(y) {
|
||||
const query = uni.createSelectorQuery().in(this)
|
||||
query.select('.index-bar').boundingClientRect(rect => {
|
||||
if (!rect) return
|
||||
const top = rect.top
|
||||
const index = Math.floor((y - top) / (rect.height / this.indexList.length))
|
||||
if (index >= 0 && index < this.indexList.length) {
|
||||
const letter = this.indexList[index]
|
||||
this.scrollTo(letter)
|
||||
}
|
||||
}).exec()
|
||||
},
|
||||
scrollTo(letter) {
|
||||
const exists = this.contacts.find(item => item.letter === letter)
|
||||
if (exists) {
|
||||
this.currentView = "group-" + letter
|
||||
}
|
||||
this.showLetter = letter
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
background-color: #fff;
|
||||
}
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 90rpx;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
.back {
|
||||
font-size: 40rpx;
|
||||
}
|
||||
.title {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 34rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
.search-box {
|
||||
padding: 20rpx;
|
||||
}
|
||||
.search-input {
|
||||
width: auto;
|
||||
height: 63rpx;
|
||||
background: #F2F3F5;
|
||||
border-radius: 25rpx;
|
||||
padding-left: 20rpx;
|
||||
font-size: 28rpx;
|
||||
margin-left: 18rpx;
|
||||
margin-right: 18rpx;
|
||||
}
|
||||
.contact-list {
|
||||
flex: 1;
|
||||
}
|
||||
.group-title {
|
||||
padding: 10rpx 20rpx;
|
||||
background: #f5f5f5;
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
}
|
||||
.contact-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 20rpx;
|
||||
border-bottom: 1px solid #f5f5f5;
|
||||
}
|
||||
.avatar {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 50%;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
.contact-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.name {
|
||||
font-size: 30rpx;
|
||||
}
|
||||
.name.highlight {
|
||||
color: orange;
|
||||
}
|
||||
.desc {
|
||||
font-size: 24rpx;
|
||||
color: #888;
|
||||
margin-top: 6rpx;
|
||||
}
|
||||
.index-bar {
|
||||
position: fixed;
|
||||
right: 10rpx;
|
||||
top: 200rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
background-color: transparent;
|
||||
user-select: none;
|
||||
}
|
||||
.index-item {
|
||||
font-size: 22rpx;
|
||||
color: #3a6ea5;
|
||||
}
|
||||
.letter-toast {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background: rgba(0,0,0,0.6);
|
||||
color: #fff;
|
||||
font-size: 80rpx;
|
||||
font-weight: bold;
|
||||
padding: 40rpx 60rpx;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user