oa_app仓库初始化
This commit is contained in:
@@ -0,0 +1,157 @@
|
||||
<template>
|
||||
<view class="page">
|
||||
<fy-header title="通讯录">
|
||||
<template #right>
|
||||
<text class="ico" @click="goGroup">建群</text>
|
||||
</template>
|
||||
</fy-header>
|
||||
<view class="search">
|
||||
<input v-model="q" placeholder="搜索同事 / 部门 / 手机号" />
|
||||
</view>
|
||||
<view class="org" @click="goGroups">
|
||||
<view class="obox">👥</view>
|
||||
<view class="ometa">
|
||||
<text class="on">群聊</text>
|
||||
<text class="os">{{ groupCount }} 个群</text>
|
||||
</view>
|
||||
<text class="arr">›</text>
|
||||
</view>
|
||||
<view class="org" @click="goSearch">
|
||||
<view class="obox">🏛</view>
|
||||
<view class="ometa">
|
||||
<text class="on">全员架构</text>
|
||||
<text class="os">共 {{ deptCount }} 个部门 · {{ peopleCount }} 位在职成员</text>
|
||||
</view>
|
||||
<text class="arr">›</text>
|
||||
</view>
|
||||
<view v-for="g in groups" :key="g.name" class="block">
|
||||
<view class="dept" @click="toggle(g.name)">
|
||||
<text>{{ g.name }}</text>
|
||||
<text class="cnt">({{ g.people.length }})</text>
|
||||
</view>
|
||||
<view v-if="open[g.name] !== false" class="card">
|
||||
<view v-for="p in g.people" :key="p.id" class="item" @click="openPerson(p)">
|
||||
<view class="av-wrap">
|
||||
<image v-if="p.avatar" class="av" :src="p.avatar" mode="aspectFill" />
|
||||
<view v-else class="av txt">{{ p.name.slice(0, 1) }}</view>
|
||||
<view v-if="p.online" class="dot" />
|
||||
</view>
|
||||
<view class="meta">
|
||||
<text class="name">{{ p.name }}</text>
|
||||
<text class="sub">{{ p.online ? '在线' : '离线' }} · {{ p.title }}</text>
|
||||
</view>
|
||||
<text class="chip">{{ p.title }}</text>
|
||||
<text class="mini" @click.stop="chat(p)">💬</text>
|
||||
<text class="mini" @click.stop="call(p)">☎</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="!groups.length" class="empty">没有匹配的同事</view>
|
||||
<text class="foot">仅显示当前所属企业成员 · 数据实时同步</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import FyHeader from '../../components/fy-header.vue'
|
||||
import { store } from '../../utils/store.js'
|
||||
import { toast } from '../../utils/format.js'
|
||||
|
||||
export default {
|
||||
components: { FyHeader },
|
||||
data() {
|
||||
return { q: '', open: {}, off: null }
|
||||
},
|
||||
computed: {
|
||||
peopleCount() {
|
||||
return Object.keys(store.people).length
|
||||
},
|
||||
deptCount() {
|
||||
return new Set(Object.values(store.people).map((p) => p.department || '未分组')).size
|
||||
},
|
||||
groupCount() {
|
||||
return store.conversations.filter((c) => c.type === 'group').length
|
||||
},
|
||||
groups() {
|
||||
const q = this.q.trim()
|
||||
const list = Object.values(store.people).filter((p) => {
|
||||
if (store.me && p.id === store.me.id) return false
|
||||
if (!q) return true
|
||||
return (p.name + p.department + p.phone + p.title).includes(q)
|
||||
})
|
||||
const map = {}
|
||||
list.forEach((p) => {
|
||||
const d = p.department || '未分组'
|
||||
if (!map[d]) map[d] = []
|
||||
map[d].push(p)
|
||||
})
|
||||
return Object.keys(map).sort().map((name) => ({ name, people: map[name] }))
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
if (store.phase !== 'app') uni.reLaunch({ url: '/pages/login/login' })
|
||||
if (this.off) this.off()
|
||||
store.refreshPeoplePhotos()
|
||||
this.off = store.on(() => this.$forceUpdate())
|
||||
},
|
||||
onHide() { if (this.off) this.off() },
|
||||
methods: {
|
||||
toggle(name) {
|
||||
this.open[name] = this.open[name] === false
|
||||
},
|
||||
openPerson(p) {
|
||||
uni.navigateTo({ url: '/pages/contact/detail?id=' + encodeURIComponent(p.id) })
|
||||
},
|
||||
chat(p) {
|
||||
const conv = store.openDirect(p)
|
||||
uni.navigateTo({ url: '/pages/chat/chat?sid=' + encodeURIComponent(conv.id) })
|
||||
},
|
||||
call(p) {
|
||||
if (!p.phone) return toast('该同事未登记手机号')
|
||||
uni.makePhoneCall({ phoneNumber: String(p.phone) })
|
||||
},
|
||||
goSearch() { uni.navigateTo({ url: '/pages/search/search' }) },
|
||||
goGroup() { uni.navigateTo({ url: '/pages/chat/create' }) },
|
||||
goGroups() {
|
||||
const groups = store.conversations.filter((c) => c.type === 'group')
|
||||
if (!groups.length) {
|
||||
uni.navigateTo({ url: '/pages/chat/create' })
|
||||
return
|
||||
}
|
||||
uni.showActionSheet({
|
||||
itemList: groups.slice(0, 6).map((c) => c.name || '群聊'),
|
||||
success: (res) => {
|
||||
const c = groups[res.tapIndex]
|
||||
if (c) uni.navigateTo({ url: '/pages/chat/chat?sid=' + encodeURIComponent(c.id) })
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.search { padding: 16rpx 24rpx; }
|
||||
.search input { height: 80rpx; background: #fff; border-radius: 12rpx; padding: 0 24rpx; font-size: 26rpx; }
|
||||
.org { margin: 0 24rpx 16rpx; background: #fff; border-radius: 16rpx; padding: 20rpx; display: flex; align-items: center; }
|
||||
.obox { width: 64rpx; height: 64rpx; border-radius: 12rpx; background: #eaedff; display: flex; align-items: center; justify-content: center; }
|
||||
.ometa { flex: 1; margin-left: 16rpx; }
|
||||
.on { display: block; font-size: 28rpx; font-weight: 700; }
|
||||
.os { font-size: 22rpx; color: #737686; }
|
||||
.arr { color: #c3c6d7; }
|
||||
.block { margin: 8rpx 24rpx 24rpx; }
|
||||
.dept { display: flex; align-items: center; padding: 16rpx 12rpx; font-size: 26rpx; font-weight: 600; background: #f2f3ff; border-radius: 12rpx 12rpx 0 0; }
|
||||
.cnt { color: #737686; font-weight: 400; font-size: 22rpx; margin-left: 8rpx; }
|
||||
.item { display: flex; align-items: center; padding: 20rpx 20rpx; }
|
||||
.av-wrap { position: relative; width: 72rpx; height: 72rpx; }
|
||||
.av { width: 72rpx; height: 72rpx; border-radius: 50%; }
|
||||
.av.txt { background: #eaedff; color: #434655; display: flex; align-items: center; justify-content: center; font-weight: 600; }
|
||||
.dot { position: absolute; right: 0; bottom: 0; width: 16rpx; height: 16rpx; border-radius: 50%; background: #006c49; border: 2rpx solid #fff; }
|
||||
.meta { flex: 1; margin-left: 16rpx; min-width: 0; }
|
||||
.name { display: block; font-size: 28rpx; font-weight: 600; }
|
||||
.sub { font-size: 22rpx; color: #737686; }
|
||||
.chip { font-size: 20rpx; color: #004ac6; background: #e2e7ff; padding: 4rpx 12rpx; border-radius: 999rpx; margin-right: 8rpx; }
|
||||
.mini { width: 56rpx; text-align: center; font-size: 28rpx; color: #004ac6; }
|
||||
.empty { text-align: center; color: #737686; padding: 80rpx; }
|
||||
.foot { display: block; text-align: center; color: #737686; font-size: 22rpx; padding: 20rpx 0 40rpx; }
|
||||
.ico { padding: 8rpx 16rpx; color: #2563eb; font-size: 26rpx; }
|
||||
</style>
|
||||
Reference in New Issue
Block a user