重构部分聊天选择页面

This commit is contained in:
wangyifeng 2025-02-08 17:09:57 +08:00
parent df07c953bf
commit 5c55411aa3
4 changed files with 198 additions and 120 deletions

View File

@ -40,7 +40,10 @@
</div>
</div>
<div
v-if="state.chooseMode === 1 || state.chooseMode === 2"
v-if="
(state.chooseMode === 1 || state.chooseMode === 2) &&
(currentCrumbs?.sons?.length > 0 || currentMembers?.length > 0)
"
class="pl-[32rpx] bg-[#FFFFFF] mt-[20rpx] h-[110rpx] flex items-center"
@click="() => allCheck(allCheckStatus)"
>
@ -55,7 +58,7 @@
</div>
</div>
<div
v-if="currentCrumbs?.sons?.length"
v-if="currentCrumbs?.sons?.length > 0"
v-for="item in currentCrumbs?.sons"
@click="
state.chooseMode === 1 || state.chooseMode === 2
@ -522,7 +525,7 @@ const buildDepsMap = (departments) => {
}
const allCheckStatus = computed(() => {
if (!currentCrumbs.value.sons) {
if (currentCrumbs?.value?.sons?.length === 0) {
return 'noChecked'
}
const allChecked = currentCrumbs.value.sons.every(
@ -837,6 +840,7 @@ const toUserDetail = (userItem) => {
background-position: bottom center;
padding: 20rpx 0;
background-attachment: fixed;
width: 100%;
}
}

View File

@ -1,36 +1,58 @@
<template>
<div>
<div @click="cellClick" :class="['chatItem', props.data.is_top === 1 ? 'isTop' : '']">
<div
@click="cellClick"
:class="['chatItem', props.data.is_top === 1 ? 'isTop' : '']"
>
<div>
<tm-checkbox v-if="props.isMultiSelect" :round="10" :modelValue="props.data.isCheck"
@update:modelValue="props.data.isCheck = !props.data.isCheck" :size="42" :color="props.data.isCheck ? '#46299D' : '#BABABA'"></tm-checkbox>
<tm-checkbox
v-if="props.isMultiSelect"
:round="10"
:modelValue="props.data.isCheck"
@update:modelValue="props.data.isCheck = !props.data.isCheck"
:size="32"
:color="props.data.isCheck ? '#46299D' : '#BABABA'"
class="pr-[4rpx]"
></tm-checkbox>
</div>
<div class="avatarImg">
<tm-image :width="96" :height="96" :round="12" :src="props.data.avatar"></tm-image>
<avatarModule
:mode="2"
:avatar="props?.data?.avatar"
:groupType="props?.data?.group_type"
:customStyle="{ width: '96rpx', height: '96rpx' }"
></avatarModule>
</div>
<div class="chatInfo">
<div class="chatInfo_1">
<div class="flex items-center">
<div class="text-[#000000] text-[32rpx] font-bold opacity-90">{{ props.data.name }}</div>
<div
class="text-[#171717] text-[32rpx] font-medium leading-[44rpx]"
>
<span>{{ props.data.name }}</span>
<span>{{ props.data.group_member_num }}</span>
</div>
</div>
</div>
</div>
<div v-if="props.index !== talkStore.talkItems.length - 1" class="divider"></div>
</div>
<div
v-if="props.index !== talkStore.talkItems.length - 1"
class="divider"
></div>
</div>
</template>
<script setup>
import { ref, reactive, defineProps, defineEmits } from "vue"
import dayjs from "dayjs";
import avatarModule from '@/components/avatar-module/index.vue'
import { ref, reactive, defineProps, defineEmits } from 'vue'
import dayjs from 'dayjs'
import { beautifyTime } from '@/utils/datetime'
import { ServeClearTalkUnreadNum } from '@/api/chat'
import { useTalkStore, useDialogueStore } from '@/store'
import { useSessionMenu } from '@/hooks'
const talkStore = useTalkStore()
const {
onToTopTalk
} = useSessionMenu()
const { onToTopTalk } = useSessionMenu()
const dialogueStore = useDialogueStore()
const emit = defineEmits(['itemClick'])
const props = defineProps({
@ -48,25 +70,22 @@ const props = defineProps({
type: Boolean,
default: false,
},
});
})
const cellClick = () => {
emit('itemClick', props.data)
}
</script>
<style lang="scss" scoped>
.chatItem {
width: 100%;
height: 154rpx;
padding: 30rpx 16rpx;
padding: 24rpx 18rpx;
display: flex;
align-items: center;
&.isTop {
background-color: #F3F3F3;
background-color: #f3f3f3;
}
}
@ -77,7 +96,7 @@ const cellClick = () => {
.chatInfo {
flex: 1;
margin-left: 20rpx;
margin-left: 16rpx;
}
.chatInfo_1 {
@ -97,17 +116,16 @@ const cellClick = () => {
font-size: 28rpx;
color: #000000;
opacity: 40%;
}
.companyTag {
width: 76rpx;
height: 38rpx;
border: 1px solid #7A58DE;
border: 1px solid #7a58de;
font-size: 24rpx;
text-align: center;
border-radius: 6rpx;
color: #7A58DE;
color: #7a58de;
font-weight: bold;
margin-left: 12rpx;
}

View File

@ -1,74 +1,123 @@
<template>
<div class="outer-layer">
<div>
<tm-navbar :hideBack="true" hideHome :leftWidth="320">
<template v-slot:left>
<div @click="handleClose" class="ml-[48rpx] text-[34rpx] leading-[40rpx]">
关闭
<div class="choose-chat-page">
<ZPaging ref="zPaging" :show-scrollbar="false">
<template #top>
<customNavbar
:title="$t('pageTitle.select.shareChat')"
:hideBack="true"
>
<template #left>
<div
@click="handleClose"
class="ml-[42rpx] text-[34rpx] leading-[48rpx] font-regular"
>
{{ $t('button.text.close') }}
</div>
</template>
<template v-slot:default>
<div class="text-[34rpx] font-bold ml-[-80rpx] leading-[40rpx]">
选择一个聊天
</div>
</template>
<template v-slot:right>
<div v-if="!isMultiSelect" @click="isMultiSelect = true" class="mr-[36rpx] text-[34rpx] leading-[40rpx]">
多选
<template #right>
<div
v-if="!isMultiSelect"
@click="isMultiSelect = true"
class="mr-[36rpx] text-[34rpx] leading-[48rpx] font-regular"
>
{{ $t('button.multiple.choice') }}
</div>
<div v-else class="mr-[36rpx] btnBox">
<tm-button @click="handleFinish" color="#5B3FB1" :fontSize="34" :disabled="!selectItems.length"
:margin="[10]" :shadow="0" size="small" :width="selectItems.length ? 162 : 116"
:label="selectItems.length ? `完成(${selectItems.length})` : '完成'">
</tm-button>
<customBtn
:btnText="
selectItems.length
? $t('button.text.done') + `(${selectItems.length})`
: $t('button.text.done')
"
:disabled="!selectItems.length"
@clickBtn="handleFinish"
></customBtn>
</div>
</template>
</tm-navbar>
</div>
<div class="root">
</customNavbar>
</template>
<div class="choose-chat">
<div class="searchRoot">
<tm-input placeholder="请输入…" color="#F9F9FD" :round="1" prefix="tmicon-search" prefixColor="#46299D"></tm-input>
<customInput></customInput>
</div>
<div class="contentRoot">
<chatItem v-for="(item, index) in items" :key="item.index_name" :index="index" :data="item"
:isMultiSelect="isMultiSelect" @itemClick="itemClick" />
<chatItem
v-for="(item, index) in items"
:key="item.index_name"
:index="index"
:data="item"
:isMultiSelect="isMultiSelect"
@itemClick="itemClick"
/>
</div>
</div>
<tm-modal v-model:show="showWin" :height="forwardModalHeight" :round="4" okColor="#FFFFFF" @ok="handleOk"
@cancel="handleCancel">
<tm-modal
v-model:show="showWin"
:height="forwardModalHeight"
:round="4"
okColor="#FFFFFF"
@ok="handleOk"
@cancel="handleCancel"
>
<template v-slot:title>
<div class="w-full pl-[30rpx] leading-[48rpx] mt-[30rpx] font-bold text-[32rpx]">
<div
class="w-full pl-[30rpx] leading-[48rpx] mt-[30rpx] font-bold text-[32rpx]"
>
发送给:
</div>
</template>
<template v-slot:default>
<div class="pl-[22rpx] pr-[32rpx] pt-[10rpx] flex items-center justify-start flex-wrap">
<div v-if="selectItemsModal.length > 1" v-for="item in selectItemsModal"
class="w-1/4 mt-[20rpx] flex flex-col items-center justify-center">
<div
class="pl-[22rpx] pr-[32rpx] pt-[10rpx] flex items-center justify-start flex-wrap"
>
<div
v-if="selectItemsModal.length > 1"
v-for="item in selectItemsModal"
class="w-1/4 mt-[20rpx] flex flex-col items-center justify-center"
>
<div class="w-[96rpx] h-[96rpx] rounded-[60rpx] flex-center">
<tm-image :width="96" :height="96" :round="12" :src="item.avatar"></tm-image>
<tm-image
:width="96"
:height="96"
:round="12"
:src="item.avatar"
></tm-image>
</div>
<div
class="mt-[8rpx] text-[#666666] text-[24rpx] w-[94rpx] truncate"
>
{{ item.name }}
</div>
<div class="mt-[8rpx] text-[#666666] text-[24rpx] w-[94rpx] truncate">{{ item.name }}</div>
</div>
<div v-else class="w-full flex items-center justify-start">
<div class="w-[96rpx] h-[96rpx] rounded-[60rpx] flex-center">
<tm-image :width="96" :height="96" :round="12" :src="selectItemsModal[0].avatar"></tm-image>
<avatarModule
:mode="2"
:avatar="selectItemsModal[0].avatar"
:groupType="selectItemsModal[0].group_type"
:customStyle="{ width: '96rpx', height: '96rpx' }"
></avatarModule>
<div class="ml-[16rpx] text-[#161616] text-[32rpx] font-bold">
{{ selectItemsModal[0].name }}
</div>
<div class="ml-[16rpx] text-[#161616] text-[32rpx] font-bold ">{{ selectItemsModal[0].name }}</div>
</div>
</div>
</template>
</tm-modal>
</ZPaging>
</div>
</template>
<script setup>
import { ref, watch, computed, onMounted, onUnmounted } from 'vue';
import { onShow, onLoad } from "@dcloudio/uni-app";
import { useChatList } from "@/store/chatList/index.js";
import { useAuth } from "@/store/auth";
import customInput from '@/components/custom-input/custom-input.vue'
import avatarModule from '@/components/avatar-module/index.vue'
import ZPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue'
import customBtn from '@/components/custom-btn/custom-btn.vue'
import { ref, watch, computed, onMounted, onUnmounted } from 'vue'
import { onShow, onLoad } from '@dcloudio/uni-app'
import { useChatList } from '@/store/chatList/index.js'
import { useAuth } from '@/store/auth'
import { useTalkStore, useUserStore, useDialogueStore } from '@/store'
import chatItem from './components/chatItem.vue';
import addCircle from "@/static/image/chatList/addCircle.png";
import chatItem from './components/chatItem.vue'
import addCircle from '@/static/image/chatList/addCircle.png'
import lodash from 'lodash'
const talkStore = useTalkStore()
@ -87,13 +136,13 @@ const items = ref([])
// })
const selectItems = computed(() => {
return items.value.filter(item => item.isCheck)
return items.value.filter((item) => item.isCheck)
})
const selectItemsModal = ref([])
const itemClick = (item) => {
console.log(item);
console.log(item)
if (isMultiSelect.value) {
item.isCheck = !item.isCheck
return false
@ -104,7 +153,7 @@ const itemClick = (item) => {
}
const handleFinish = () => {
console.log(selectItems.value);
console.log(selectItems.value)
selectItemsModal.value = selectItems.value
if (selectItemsModal.value.length > 4) {
forwardModalHeight.value = 560
@ -123,7 +172,6 @@ const handleClose = () => {
const handleOk = () => {
let msg_ids = dialogueStore.forwardMessages.map((item) => item.msg_id)
let user_ids = []
let group_ids = []
@ -139,23 +187,27 @@ const handleOk = () => {
mode: dialogueStore.forwardType,
message_ids: msg_ids,
uids: user_ids,
gids: group_ids
gids: group_ids,
})
uni.navigateBack()
}
const handleCancel = () => {
console.log('cancel');
console.log('cancel')
}
watch(() => talkStore, (newValue, oldValue) => {
console.log(talkStore);
}, { deep: true, immediate: true })
watch(
() => talkStore,
(newValue, oldValue) => {
console.log(talkStore)
},
{ deep: true, immediate: true },
)
onMounted(() => {
talkStore.loadTalkList()
console.log(talkStore.talkItems)
items.value = lodash.cloneDeep(talkStore.talkItems)
})
onUnmounted(() => {
@ -164,24 +216,20 @@ onUnmounted(() => {
})
</script>
<style scoped lang="scss">
uni-page-body,
page {
::v-deep .zp-paging-container-content {
height: 100%;
display: flex;
}
.outer-layer {
overflow-y: auto;
.choose-chat {
flex: 1;
background-image: url("@/static/image/clockIn/z3280@3x.png");
background-size: cover;
padding: 0 32rpx 20rpx 32rpx;
padding: 20rpx 32rpx;
display: flex;
flex-direction: column;
}
.root {
flex: 1;
padding: 20rpx 0;
background-image: url('@/static/image/clockIn/z3280@3x.png');
background-size: cover;
background-position: bottom center;
background-attachment: fixed;
}
.searchRoot {
@ -195,33 +243,38 @@ page {
}
.btnBox {
:deep(.button) {
&[disabled="true"] {
background-color: #F3F3F3 !important;
color: #BABABA !important;
::v-deep .custom-btn-class {
padding: 6rpx 24rpx !important;
width: unset !important;
min-width: unset !important;
height: unset !important;
}
::v-deep .wd-button__text {
font-size: 34rpx !important;
font-weight: 400 !important;
line-height: 48rpx !important;
}
}
:deep(.noNvueBorder.round-bl-4) {
border-top: 1rpx solid #E7E7E7 !important;
background-color: #FFFFFF !important;
border-top: 1rpx solid #e7e7e7 !important;
background-color: #ffffff !important;
uni-text {
color: #1A1A1A !important;
color: #1a1a1a !important;
font-size: 32rpx !important;
line-height: 48rpx !important;
}
}
:deep(.noNvueBorder.round-br-4) {
border-top: 1rpx solid #E7E7E7 !important;
border-left: 1rpx solid #E7E7E7 !important;
background-color: #FFFFFF !important;
border-top: 1rpx solid #e7e7e7 !important;
border-left: 1rpx solid #e7e7e7 !important;
background-color: #ffffff !important;
uni-text {
font-weight: bold;
color: #46299D !important;
color: #46299d !important;
font-size: 32rpx !important;
line-height: 48rpx !important;
}

View File

@ -144,5 +144,8 @@
"choose.deps.nextLevel": "下级",
"statistics.selected.deps": "已选择的部门数",
"chat.manage.addMembers": "添加群成员",
"pageTitle.select.groupType": "选择群类型"
"pageTitle.select.groupType": "选择群类型",
"pageTitle.select.shareChat": "选择一个聊天",
"button.multiple.choice": "多选",
"button.text.close": "关闭"
}