群聊
This commit is contained in:
+8
-6
@@ -26,7 +26,7 @@
|
||||
<view v-if="!list.length" class="empty">暂无消息,发一条试试</view>
|
||||
<view v-for="(m, i) in list" :key="m.id || i">
|
||||
<view v-if="showTime(i)" class="chip-time">{{ timeOf(m) }}</view>
|
||||
<view v-if="m.recalled" class="sys">{{ m.text || '已撤回一条消息' }}</view>
|
||||
<view v-if="m.recalled || m.kind === 'system'" class="sys">{{ m.text || '已撤回一条消息' }}</view>
|
||||
<view
|
||||
v-else
|
||||
class="row"
|
||||
@@ -37,7 +37,7 @@
|
||||
<view v-if="selecting" class="ck" :class="{ on: isPicked(m) }" />
|
||||
<view v-if="!m.mine" class="av" @click.stop="openSender(m)">
|
||||
<fy-file-mark v-if="isFiles" />
|
||||
<image v-else-if="avatarOf(m)" :src="avatarOf(m)" mode="aspectFill" />
|
||||
<image v-else-if="avatarOf(m)" class="face" :src="avatarOf(m)" mode="aspectFill" />
|
||||
<text v-else>{{ initialOf(m) }}</text>
|
||||
</view>
|
||||
<view class="col" :class="{ mine: m.mine }">
|
||||
@@ -61,7 +61,7 @@
|
||||
<text v-if="m.mine" class="tm" :class="{ read: readDone(m) }" @click="showRead(m)">{{ readLabel(m) }}</text>
|
||||
</view>
|
||||
<view v-if="m.mine" class="av self">
|
||||
<image v-if="myAvatar" :src="myAvatar" mode="aspectFill" />
|
||||
<image v-if="myAvatar" class="face" :src="myAvatar" mode="aspectFill" />
|
||||
<text v-else>{{ myInitial }}</text>
|
||||
</view>
|
||||
</view>
|
||||
@@ -779,7 +779,9 @@ export default {
|
||||
}
|
||||
},
|
||||
openSender(m) {
|
||||
if (m.fromId) uni.navigateTo({ url: '/pages/contact/detail?id=' + encodeURIComponent(m.fromId) })
|
||||
const id = m && m.fromId
|
||||
if (!id || !store.person(id)) return
|
||||
uni.navigateTo({ url: '/pages/contact/detail?id=' + encodeURIComponent(id) })
|
||||
},
|
||||
goMore() {
|
||||
if (this.isGroup) uni.navigateTo({ url: '/pages/chat/group?sid=' + encodeURIComponent(this.sid) })
|
||||
@@ -836,8 +838,8 @@ export default {
|
||||
.col { max-width: 72%; display: flex; flex-direction: column; }
|
||||
.col.mine { align-items: flex-end; }
|
||||
.av { width: 76rpx; height: 76rpx; border-radius: 16rpx; background: #E8F1FF; color: #1677FF; overflow: hidden; flex-shrink: 0; display: flex; align-items: center; justify-content: center; font-size: 28rpx; font-weight: 650; }
|
||||
.av.self { background: #1677FF; color: #fff; }
|
||||
.av image { width: 76rpx; height: 76rpx; }
|
||||
.av.self { background: #E8F1FF; color: #1677FF; }
|
||||
.face { width: 76rpx; height: 76rpx; display: block; }
|
||||
.who { font-size: 22rpx; color: #9CA3AF; margin: 0 4rpx 8rpx; }
|
||||
.ball {
|
||||
background: #fff;
|
||||
|
||||
+14
-12
@@ -8,7 +8,8 @@
|
||||
<view class="card">
|
||||
<view v-for="p in people" :key="p.id" class="item" @click="toggle(p.id)">
|
||||
<view class="box" :class="{ on: picked.includes(p.id) }" />
|
||||
<view class="av">{{ p.name.slice(0, 1) }}</view>
|
||||
<image v-if="p.avatar" class="av img" :src="p.avatar" mode="aspectFill" />
|
||||
<view v-else class="av">{{ (p.name || '?').slice(0, 1) }}</view>
|
||||
<view class="meta">
|
||||
<text class="n">{{ p.name }}</text>
|
||||
<text class="s">{{ p.title }} · {{ p.department }}</text>
|
||||
@@ -16,7 +17,7 @@
|
||||
</view>
|
||||
</view>
|
||||
<view class="pad">
|
||||
<view class="btn-primary" :class="{ off: !can }" @click="ok">创建并进入</view>
|
||||
<wd-button type="primary" block size="large" :disabled="!can" @click="ok">创建并进入</wd-button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
@@ -65,17 +66,18 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.field { margin: 24rpx; padding: 8rpx 24rpx; }
|
||||
.field input { height: 80rpx; font-size: 30rpx; }
|
||||
.hint { margin: 0 32rpx 12rpx; font-size: 22rpx; color: #6B7280; }
|
||||
.field { margin: 16rpx 24rpx; padding: 8rpx 24rpx; }
|
||||
.field input { height: 88rpx; font-size: 30rpx; color: #111827; }
|
||||
.hint { margin: 0 32rpx 12rpx; font-size: 24rpx; color: #6B7280; }
|
||||
.card { margin: 0 24rpx 24rpx; overflow: hidden; }
|
||||
.item { display: flex; align-items: center; padding: 20rpx 24rpx; }
|
||||
.box { width: 36rpx; height: 36rpx; border: 2rpx solid #D1D5DB; border-radius: 8rpx; margin-right: 16rpx; }
|
||||
.item { display: flex; align-items: center; padding: 0 24rpx; }
|
||||
.item + .item .meta { border-top: 1rpx solid #F0F2F5; }
|
||||
.box { width: 36rpx; height: 36rpx; border: 2rpx solid #D1D5DB; border-radius: 8rpx; margin-right: 16rpx; flex-shrink: 0; }
|
||||
.box.on { background: #1677FF; border-color: #1677FF; }
|
||||
.av { width: 72rpx; height: 72rpx; border-radius: 50%; background: #E8F1FF; color: #1677FF; display: flex; align-items: center; justify-content: center; font-weight: 600; }
|
||||
.meta { margin-left: 16rpx; }
|
||||
.n { display: block; font-size: 28rpx; font-weight: 600; }
|
||||
.s { font-size: 22rpx; color: #6B7280; }
|
||||
.av { width: 72rpx; height: 72rpx; border-radius: 18rpx; background: #E8F1FF; color: #1677FF; display: flex; align-items: center; justify-content: center; font-weight: 600; margin: 16rpx 0; flex-shrink: 0; overflow: hidden; }
|
||||
.av.img { display: block; }
|
||||
.meta { margin-left: 16rpx; flex: 1; min-width: 0; padding: 18rpx 0; }
|
||||
.n { display: block; font-size: 28rpx; font-weight: 600; color: #111827; }
|
||||
.s { display: block; margin-top: 4rpx; font-size: 22rpx; color: #6B7280; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.pad { padding: 0 24rpx 40rpx; }
|
||||
.off { opacity: 0.45; }
|
||||
</style>
|
||||
|
||||
+11
-4
@@ -3,7 +3,10 @@
|
||||
<fy-header title="群聊设置" back />
|
||||
<view class="card head">
|
||||
<view class="grid">
|
||||
<view v-for="p in members.slice(0, 4)" :key="p.id" class="cell">{{ (p.name || '?').slice(0, 1) }}</view>
|
||||
<view v-for="p in members.slice(0, 4)" :key="p.id" class="cell">
|
||||
<image v-if="p.avatar" class="cell-img" :src="p.avatar" mode="aspectFill" />
|
||||
<text v-else>{{ (p.name || '?').slice(0, 1) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="meta">
|
||||
<text class="gn">{{ title }}</text>
|
||||
@@ -17,7 +20,8 @@
|
||||
</view>
|
||||
<view class="mems">
|
||||
<view v-for="p in members" :key="p.id" class="mem" @click="open(p)">
|
||||
<view class="mav">{{ (p.name || '?').slice(0, 1) }}</view>
|
||||
<image v-if="p.avatar" class="mav img" :src="p.avatar" mode="aspectFill" />
|
||||
<view v-else class="mav">{{ (p.name || '?').slice(0, 1) }}</view>
|
||||
<text class="mn">{{ p.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
@@ -76,6 +80,7 @@ export default {
|
||||
this.members = ids.map((id) => store.person(id) || { id, name: id, title: '', department: '' })
|
||||
},
|
||||
open(p) {
|
||||
if (!p || !store.person(p.id)) return
|
||||
uni.navigateTo({ url: '/pages/contact/detail?id=' + encodeURIComponent(p.id) })
|
||||
},
|
||||
toggle(field) {
|
||||
@@ -106,7 +111,8 @@ export default {
|
||||
<style scoped>
|
||||
.head { margin: 24rpx; padding: 28rpx; display: flex; align-items: center; }
|
||||
.grid { width: 96rpx; height: 96rpx; background: #E8F1FF; border-radius: 22rpx; display: flex; flex-wrap: wrap; padding: 8rpx; box-sizing: border-box; }
|
||||
.cell { width: 36rpx; height: 36rpx; margin: 2rpx; background: #fff; color: #1677FF; font-size: 18rpx; font-weight: 700; display: flex; align-items: center; justify-content: center; border-radius: 8rpx; }
|
||||
.cell { width: 36rpx; height: 36rpx; margin: 2rpx; background: #fff; color: #1677FF; font-size: 18rpx; font-weight: 700; display: flex; align-items: center; justify-content: center; border-radius: 8rpx; overflow: hidden; }
|
||||
.cell-img { width: 36rpx; height: 36rpx; display: block; }
|
||||
.meta { margin-left: 20rpx; }
|
||||
.gn { font-size: 32rpx; font-weight: 700; display: block; }
|
||||
.gc { font-size: 22rpx; color: #6B7280; }
|
||||
@@ -114,7 +120,8 @@ export default {
|
||||
.cap { padding: 20rpx 24rpx 8rpx; font-size: 26rpx; font-weight: 700; }
|
||||
.mems { display: flex; flex-wrap: wrap; padding: 8rpx 16rpx 24rpx; }
|
||||
.mem { width: 20%; display: flex; flex-direction: column; align-items: center; margin-bottom: 16rpx; }
|
||||
.mav { width: 80rpx; height: 80rpx; border-radius: 18rpx; background: #E8F1FF; color: #1677FF; display: flex; align-items: center; justify-content: center; font-weight: 700; }
|
||||
.mav { width: 80rpx; height: 80rpx; border-radius: 18rpx; background: #E8F1FF; color: #1677FF; display: flex; align-items: center; justify-content: center; font-weight: 700; overflow: hidden; }
|
||||
.mav.img { display: block; }
|
||||
.mn { font-size: 20rpx; margin-top: 8rpx; }
|
||||
.row { display: flex; justify-content: space-between; align-items: center; padding: 28rpx 24rpx; font-size: 28rpx; border-bottom: 1rpx solid #F0F2F5; }
|
||||
.row:last-child { border-bottom: none; }
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<template>
|
||||
<view class="page">
|
||||
<fy-header title="同事资料" back />
|
||||
<view v-if="p" class="body">
|
||||
<wd-status-tip v-if="!p" image="content" tip="未找到这位同事" />
|
||||
<view v-else class="body">
|
||||
<view class="card profile">
|
||||
<image v-if="p.avatar" class="av img" :src="p.avatar" mode="aspectFill" />
|
||||
<view v-else class="av">{{ p.name.slice(0, 1) }}</view>
|
||||
|
||||
@@ -37,6 +37,9 @@
|
||||
<view class="av-wrap">
|
||||
<image v-if="c.avatar && c.type !== 'files'" class="av" :src="c.avatar" mode="aspectFill" />
|
||||
<view v-else-if="c.type === 'files'" class="av"><fy-file-mark /></view>
|
||||
<view v-else-if="facesOf(c).length" class="av mosaic">
|
||||
<image v-for="f in facesOf(c)" :key="f.id" class="tile" :src="f.avatar" mode="aspectFill" />
|
||||
</view>
|
||||
<view v-else class="av txt" :class="avClass(c)">{{ avText(c) }}</view>
|
||||
<text v-if="c.unread && !c.muted" class="badge abs">{{ c.unread > 99 ? '99+' : c.unread }}</text>
|
||||
<text v-else-if="c.unread && c.muted" class="dotu" />
|
||||
@@ -102,6 +105,10 @@ export default {
|
||||
reload() {
|
||||
store.refreshPeoplePhotos().finally(() => this.pull())
|
||||
},
|
||||
facesOf(c) {
|
||||
if (!c || c.type !== 'group' || c.avatar) return []
|
||||
return (c.memberIds || []).map((id) => store.person(id)).filter((p) => p && p.avatar).slice(0, 4)
|
||||
},
|
||||
avText(c) {
|
||||
if (c.type === 'work') return '工'
|
||||
if (c.type === 'group') return '群'
|
||||
@@ -187,6 +194,8 @@ export default {
|
||||
.av.work { background: #1677FF; color: #fff; }
|
||||
.av.file { background: #F3F6FB; color: #4B5563; }
|
||||
.av.plain { background: #E8F1FF; color: #1677FF; }
|
||||
.mosaic { display: flex; flex-wrap: wrap; align-content: center; justify-content: center; gap: 4rpx; background: #E8F1FF; padding: 6rpx; box-sizing: border-box; }
|
||||
.tile { width: 38rpx; height: 38rpx; border-radius: 8rpx; }
|
||||
.abs { position: absolute; top: -8rpx; right: -8rpx; }
|
||||
.dotu { position: absolute; top: -4rpx; right: -4rpx; width: 16rpx; height: 16rpx; border-radius: 50%; background: #DC2626; }
|
||||
.meta { flex: 1; margin-left: 20rpx; min-width: 0; padding: 8rpx 0 18rpx; border-bottom: 1rpx solid #F0F2F5; }
|
||||
|
||||
Reference in New Issue
Block a user