新增按文件类型搜索聊天记录静态页面,并接入真实数据

This commit is contained in:
wangyifeng 2025-01-13 16:56:13 +08:00
parent b93183eec3
commit a3c1b56d27
12 changed files with 380 additions and 13 deletions

View File

@ -20,7 +20,7 @@
}} }}
</span> </span>
</div> </div>
<div class="group-member-tag" v-if="memberIndex < 3"> <div class="group-member-tag" v-if="memberItem?.leader === 1">
<span class="text-[16rpx] font-regular"> <span class="text-[16rpx] font-regular">
{{ $t('group.identify.admin') }} {{ $t('group.identify.admin') }}
</span> </span>

View File

@ -34,11 +34,16 @@ import ZPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue'
import { onLoad } from '@dcloudio/uni-app' import { onLoad } from '@dcloudio/uni-app'
import { computed, onMounted, reactive } from 'vue' import { computed, onMounted, reactive } from 'vue'
import { useGroupTypeStore } from '@/store/groupType'
import { useGroupStore, useDialogueStore } from '@/store' import { useGroupStore, useDialogueStore } from '@/store'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
const { t } = useI18n() const { t } = useI18n()
const groupTypeStore = useGroupTypeStore()
const groupTypeParams = reactive({
postTreeList: computed(() => groupTypeStore.postTreeList),
})
const groupStore = useGroupStore() const groupStore = useGroupStore()
const dialogueStore = useDialogueStore() const dialogueStore = useDialogueStore()
@ -54,8 +59,10 @@ onLoad((options) => {
console.log(options) console.log(options)
}) })
onMounted(() => { onMounted(async () => {
console.log(dialogueParams.adminList) console.log(dialogueParams.adminList)
await groupTypeStore.getPositionsTree()
console.log(groupTypeParams)
}) })
// //

View File

@ -426,6 +426,12 @@ const toSearchByConditionPage = (flag) => {
} else { } else {
if (flag == 1) { if (flag == 1) {
condition = 'date' condition = 'date'
} else if (flag == 2) {
condition = 'imgAndVideo'
} else if (flag == 3) {
condition = 'file'
} else if (flag == 4) {
condition = 'link'
} }
uni.navigateTo({ uni.navigateTo({
url: url:

View File

@ -1,6 +1,7 @@
<template> <template>
<div <div
class="search-item" class="search-item"
:class="props?.conditionType ? 'search-item-condition' : ''"
v-if="resultName" v-if="resultName"
:style=" :style="
props.searchResultKey === 'talk_record_infos_receiver' props.searchResultKey === 'talk_record_infos_receiver'
@ -8,7 +9,10 @@
: '' : ''
" "
> >
<div class="avatar-img"> <div
class="avatar-img"
:class="props?.conditionType ? 'avatar-img-condition' : ''"
>
<img v-if="avatarImg !== 'textImg'" :src="avatarImg" /> <img v-if="avatarImg !== 'textImg'" :src="avatarImg" />
<span v-if="avatarImg === 'textImg'" class="text-[32rpx] font-bold"> <span v-if="avatarImg === 'textImg'" class="text-[32rpx] font-bold">
{{ imgText }} {{ imgText }}
@ -21,7 +25,9 @@
> >
<HighlightText <HighlightText
:class=" :class="
searchRecordDetail props?.conditionType
? 'text-[28rpx] font-medium'
: searchRecordDetail
? 'text-[24rpx] font-medium' ? 'text-[24rpx] font-medium'
: 'text-[32rpx] font-medium' : 'text-[32rpx] font-medium'
" "
@ -92,6 +98,7 @@ const props = defineProps({
searchText: String, // searchText: String, //
searchRecordDetail: Boolean, // searchRecordDetail: Boolean, //
pointerIconSrc: String, // pointerIconSrc: String, //
conditionType: Number, //
}) })
// - // -
const keyMapping = { const keyMapping = {
@ -163,11 +170,21 @@ const avatarImg = computed(() => {
if (!avatar) { if (!avatar) {
avatar = groupTypeMapping[props.searchItem?.group_type]?.defaultImg avatar = groupTypeMapping[props.searchItem?.group_type]?.defaultImg
} }
if (props?.conditionType) {
avatar = props.searchItem.avatar
if (!avatar) {
avatar = groupTypeMapping[0]?.defaultImg
}
}
return avatar return avatar
}) })
// //
const resultName = computed(() => { const resultName = computed(() => {
return getKeyValue(keyMapping[props.searchResultKey]?.name) let result_name = getKeyValue(keyMapping[props.searchResultKey]?.name)
if (props?.conditionType) {
result_name = props.searchItem.nickname
}
return result_name
}) })
// //
const imgText = computed(() => { const imgText = computed(() => {
@ -237,9 +254,6 @@ const resultDetail = computed(() => {
}) })
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.search-item:nth-child(1) {
border-top: 1px solid $theme-border-color;
}
.search-item { .search-item {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@ -269,6 +283,11 @@ const resultDetail = computed(() => {
line-height: 44rpx; line-height: 44rpx;
} }
} }
.avatar-img-condition {
width: 64rpx;
height: 64rpx;
margin: 0 18rpx 0 0;
}
.result-info { .result-info {
width: 100%; width: 100%;
.info-name { .info-name {
@ -328,4 +347,7 @@ const resultDetail = computed(() => {
} }
} }
} }
.search-item-condition {
border: 0;
}
</style> </style>

View File

@ -399,6 +399,7 @@ const clickSearchItem = (searchResultKey, searchItem) => {
.result-title { .result-title {
padding: 0 0 10rpx; padding: 0 0 10rpx;
border-bottom: 1px solid $theme-border-color;
span { span {
line-height: 40rpx; line-height: 40rpx;
color: $theme-hint-text; color: $theme-hint-text;

View File

@ -1,8 +1,16 @@
<template> <template>
<div class="outer-layer search-by-condition-page"> <div class="outer-layer search-by-condition-page">
<div class="root"> <div class="root">
<ZPaging ref="zPaging" :show-scrollbar="false"> <ZPaging
<template #top> ref="zPaging"
:show-scrollbar="false"
@query="queryAllSearch"
:refresher-enabled="false"
:auto="false"
:loading-more-default-as-loading="true"
:inside-more="true"
>
<template #top v-if="state.showPageTitle">
<tm-navbar :hideBack="false" hideHome title="" :leftWidth="220"> <tm-navbar :hideBack="false" hideHome title="" :leftWidth="220">
<div class="navBar-title flex flex-col items-center justify-center"> <div class="navBar-title flex flex-col items-center justify-center">
<span class="text-[34rpx] font-medium"> <span class="text-[34rpx] font-medium">
@ -57,20 +65,115 @@
:showDefault="false" :showDefault="false"
></tm-calendar-view> ></tm-calendar-view>
</div> </div>
<div
class="search-by-condition-input-list"
v-if="state.condition === 'file' || state.condition === 'link'"
>
<div class="search-by-condition-input">
<customInput
:searchText="state.searchText"
:first_talk_record_infos="state.first_talk_record_infos"
@inputSearchText="inputSearchText"
></customInput>
<span
@click="cancelSearch"
class="search-by-condition-input-text text-[32rpx] font-medium"
>
{{ $t('cancel') }}
</span>
</div>
<div class="search-by-condition-list">
<div class="condition-dimensionality">
<div
class="condition-dimensionality-each"
v-for="(conditionItem,
conditionIndex) in state.searchResultList"
:key="conditionIndex"
>
<div class="condition-dimensionality-each-month">
<span class="text-[28rpx] font-regular">
{{ conditionItem.dateMonth }}
</span>
</div>
<div class="condition-each-resultList">
<div
class="condition-each-resultList-each"
v-for="(item, index) in conditionItem.monthResultList"
:key="index"
>
<div class="condition-each-result-main">
<searchItem
:searchItem="item"
:conditionType="state.msg_type"
></searchItem>
<span
class="text-[24rpx] font-medium condition-each-result-main-date"
>
{{ item.dateTime }}
</span>
</div>
<div class="condition-each-result-attachments">
<div class="attachment-avatar">
<img :src="item?.extra?.file_avatar" />
</div>
<div class="attachment-info">
<div class="attachment-info-title">
<span class="text-[28rpx] font-regular">
{{ item?.extra?.name }}
</span>
</div>
<div class="attachment-sub-info">
<span class="text-[24rpx] font-regular">
{{ item?.extra?.typeText }}
</span>
<span
class="text-[24rpx] font-regular"
style="margin: 0 0 0 20rpx;"
>
{{ item?.extra?.fileSize }}
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</ZPaging> </ZPaging>
</div> </div>
</div> </div>
</template> </template>
<script setup> <script setup>
import fileType_PPT from '@/static/image/search/fileType_PPT.png'
import fileType_EXCEL from '@/static/image/search/fileType_EXCEL.png'
import fileType_WORD from '@/static/image/search/fileType_WORD.png'
import fileType_PDF from '@/static/image/search/fileType_PDF.png'
import fileType_Files from '@/static/image/search/fileType_Files.png'
import { fileFormatSize, fileSuffix } from '@/utils/strings'
import searchItem from '../components/searchItem.vue'
import customInput from '@/components/custom-input/custom-input.vue'
import ZPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue' import ZPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue'
import searchList from '../components/searchList.vue' import useZPaging from '@/uni_modules/z-paging/components/z-paging/js/hooks/useZPaging.js'
import { parseTime } from '@/utils/datetime' import { parseTime } from '@/utils/datetime'
import { onMounted, reactive } from 'vue' import { onMounted, reactive, computed, ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app' import { onLoad } from '@dcloudio/uni-app'
import { ServeTalkDate } from '@/api/search/index' import { ServeTalkDate } from '@/api/search/index'
import { ServeFindTalkRecords } from '@/api/chat/index'
import { useDialogueStore } from '@/store'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
const { t } = useI18n() const { t } = useI18n()
const zPaging = ref()
useZPaging(zPaging)
const dialogueStore = useDialogueStore()
const dialogueParams = reactive({
talk_type: computed(() => dialogueStore.talk.talk_type),
receiver_id: computed(() => dialogueStore.talk.receiver_id),
})
let nowDay = new Date().setHours(0, 0, 0, 0) let nowDay = new Date().setHours(0, 0, 0, 0)
const state = reactive({ const state = reactive({
@ -84,6 +187,12 @@ const state = reactive({
selectedMonth: new Date(nowDay), // selectedMonth: new Date(nowDay), //
disabledDateArray: [], // disabledDateArray: [], //
dArray: [], // dArray: [], //
showPageTitle: false, //
searchText: '', //
first_talk_record_infos: Object,
searchResultList: [], //
cursor: 0, //
msg_type: 0, //
}) })
onLoad((options) => { onLoad((options) => {
@ -94,8 +203,33 @@ onLoad((options) => {
if (options.condition) { if (options.condition) {
state.condition = options.condition state.condition = options.condition
if (options.condition === 'date') { if (options.condition === 'date') {
state.showPageTitle = true
state.pageTitle = t('search.condition.date') state.pageTitle = t('search.condition.date')
ServeQueryTalkDate(parseTime(state.nowDate, '{y}{m}')) ServeQueryTalkDate(parseTime(state.nowDate, '{y}{m}'))
} else if (options.condition === 'file') {
console.log(dialogueParams)
let first_talk_record_infos = {
receiver_name: t('record.searchType.files'),
}
state.first_talk_record_infos = Object.assign(
{},
state.first_talk_record_infos,
first_talk_record_infos,
)
state.msg_type = 6
queryAllSearch()
} else if (options.condition === 'link') {
console.log(dialogueParams)
let first_talk_record_infos = {
receiver_name: t('record.searchType.link'),
}
state.first_talk_record_infos = Object.assign(
{},
state.first_talk_record_infos,
first_talk_record_infos,
)
state.msg_type = 0
queryAllSearch()
} }
} }
}) })
@ -204,6 +338,109 @@ const confirmSelectedMonth = (e) => {
const getDArray = (dArray) => { const getDArray = (dArray) => {
state.dArray = dArray state.dArray = dArray
} }
//
const inputSearchText = (e) => {
state.searchText = e
}
//
const cancelSearch = () => {}
//
const queryAllSearch = () => {
let params = {
talk_type: dialogueParams.talk_type, //12
receiver_id: dialogueParams.receiver_id, //idid
msg_type: state.msg_type, //0:;2:;3:;4:;5:;6:;7:;9:;11;12
cursor: state.cursor, //
limit: 10, //
no_limit: '', //1
direction: 'up', //downup
start_time: '',
end_time: '',
group_member_user_id: 0, //id
}
console.log(params)
const resp = ServeFindTalkRecords(params)
console.log(resp)
resp.then(({ code, data }) => {
console.log(data)
if (code == 200) {
let dateList = state.searchResultList
let noMore = false
if (data?.items?.length > 0) {
data.items.forEach((item) => {
item.dateTime = parseTime(item?.created_at, '{m}/{d}')
item.extra.fileSize = fileFormatSize(item?.extra?.size)
item.extra.typeText = item?.extra?.name
? fileSuffix(item?.extra?.name)
: ''
item.extra.file_avatar = fileTypeAvatar(item?.extra?.typeText)
console.log(item.extra.type)
let year = new Date(item.created_at).getFullYear()
let month = new Date(item.created_at).getMonth() + 1
let dateMonth =
year == state.nowDate.getFullYear() &&
month == state.nowDate.getMonth() + 1
? t('result.date.nowMonth')
: year + '年' + month + '月'
if (dateList.length > 0) {
let hasAdd = false
dateList.forEach((dateItem) => {
if (dateItem.dateMonth === dateMonth) {
dateItem.monthResultList.push(item)
hasAdd = true
}
})
if (!hasAdd) {
console.log(dateList)
dateList.push({
dateMonth: dateMonth,
monthResultList: [item],
})
}
} else {
dateList.push({
dateMonth: dateMonth,
monthResultList: [item],
})
}
})
} else {
noMore = true
}
console.log(dateList)
state.cursor = data?.cursor
zPaging.value?.completeByNoMore(dateList, noMore)
} else {
zPaging.value?.complete([])
}
})
resp.catch(() => {
zPaging.value?.complete([])
})
}
//
const fileTypeAvatar = (fileType) => {
let file_type_avatar = fileType_Files
if (fileType) {
if (fileType === 'ppt' || fileType === 'pptx') {
file_type_avatar = fileType_PPT
} else if (fileType === 'pdf') {
file_type_avatar = fileType_PDF
} else if (fileType === 'doc' || fileType === 'docx') {
file_type_avatar = fileType_WORD
} else if (fileType === 'xls' || fileType === 'xlsx') {
file_type_avatar = fileType_EXCEL
} else {
file_type_avatar = fileType_Files
}
}
return file_type_avatar
}
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.search-by-date { .search-by-date {
@ -238,4 +475,97 @@ body::v-deep .tmicon-times-circle-fill {
body::v-deep .round-3 { body::v-deep .round-3 {
background: linear-gradient(to right, #674bbc, #46299d); background: linear-gradient(to right, #674bbc, #46299d);
} }
.search-by-condition-input-list {
padding: 20rpx 48rpx 0 42rpx;
.search-by-condition-input {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
.search-by-condition-input-text {
flex-shrink: 0;
margin: 0 0 0 20rpx;
color: $theme-primary;
}
}
.search-by-condition-list {
.condition-dimensionality {
.condition-dimensionality-each {
.condition-dimensionality-each-month {
padding: 24rpx 0 10rpx;
span {
line-height: 40rpx;
color: $theme-hint-text;
}
}
.condition-each-resultList {
.condition-each-resultList-each {
border-bottom: 1px solid $theme-border-color;
padding: 0 0 20rpx;
.condition-each-result-main {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
.condition-each-result-main-date {
line-height: 34rpx;
color: $theme-hint-text;
}
}
.condition-each-result-attachments {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
padding: 24rpx 30rpx;
background-color: #f3f3f3;
border-radius: 8rpx;
.attachment-avatar {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
flex-shrink: 0;
img {
width: 96rpx;
height: 96rpx;
}
}
.attachment-info {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
margin: 0 0 0 22rpx;
.attachment-info-title {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
span {
line-height: 40rpx;
color: $theme-text;
}
}
.attachment-sub-info {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
margin: 20rpx 0 0;
span {
line-height: 34rpx;
color: $theme-hint-text;
}
}
}
}
}
}
}
}
}
}
</style> </style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -116,5 +116,6 @@
"chatSettings.btn.undoSilence": "解禁", "chatSettings.btn.undoSilence": "解禁",
"silence.tag.hasDone": "已禁言", "silence.tag.hasDone": "已禁言",
"chat.manage.addAdmin": "添加管理员", "chat.manage.addAdmin": "添加管理员",
"search.condition.member": "按群成员查找" "search.condition.member": "按群成员查找",
"result.date.nowMonth": "这个月"
} }