解决搜索页面查看聊天记录中的详细内容时分页错误的问题;新增聊天设置页面

This commit is contained in:
wangyifeng 2025-01-02 16:01:36 +08:00
parent bfde37b111
commit 3824ab7638
16 changed files with 647 additions and 7 deletions

View File

@ -82,6 +82,14 @@
"navigationStyle": "custom",
"enablePullDownRefresh": false
}
},
{
"path": "pages/chatSettings/index",
"type": "page",
"style": {
"navigationStyle": "custom",
"enablePullDownRefresh": false
}
}
],
"globalStyle": {

View File

@ -0,0 +1,73 @@
<template>
<div class="setting-form-item">
<div class="item-main">
<div class="item-main-label">
<span class="text-[32rpx] font-regular">{{ item.label }}</span>
</div>
<div class="item-main-value">
<span class="text-[32rpx] font-regular" v-if="item.value">
{{ item.value }}
</span>
<img
v-if="item.hasPointer"
src="/src/static/image/chatSettings/pointer.png"
/>
<tm-switch
v-if="item.customInfo && item.customInfo === 'switch'"
barIcon=""
color="#46299D"
unCheckedColor="#EEEEEE"
></tm-switch>
</div>
</div>
<div class="item-sub" v-if="item.subValue">
<span class="text-[32rpx] font-regular">{{ item.subValue }}</span>
</div>
</div>
</template>
<script setup>
import { defineProps } from 'vue'
const props = defineProps({
item: {
type: Object,
default() {
return {}
},
},
})
</script>
<style lang="scss" scoped>
.setting-form-item {
.item-main {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
.item-main-label {
span {
line-height: 44rpx;
color: $theme-text;
}
}
.item-main-value {
span {
line-height: 44rpx;
color: #747474;
}
img {
width: 11rpx;
height: 18rpx;
margin: 0 0 0 32rpx;
}
}
}
.item-sub {
margin: 28rpx 0 0;
span {
line-height: 44rpx;
color: #747474;
}
}
}
</style>

View File

@ -0,0 +1,494 @@
<template>
<div class="outer-layer chat-settings-page">
<div class="root">
<ZPaging ref="zPaging" :show-scrollbar="false">
<template #top>
<tm-navbar :hideBack="false" hideHome title="" :leftWidth="220">
<div class="navBar-title flex flex-col items-center justify-center">
<span class="text-[34rpx] font-medium">
{{ $t('index.chat.settings') }}
</span>
</div>
</tm-navbar>
</template>
<div class="chat-settings">
<div class="chat-group-base-infos chat-settings-card">
<div class="base-info-avatar">
<img :src="groupAvatar" />
</div>
<div class="base-info">
<div class="base-info-name">
<span class="text-[32rpx] font-medium">{{ groupName }}</span>
<span class="base-info_num text-[32rpx] font-medium">
{{ '' + groupNum + '' }}
</span>
</div>
<div class="base-info-tag">
<span class="text-[24rpx] font-medium">{{ groupType }}</span>
</div>
</div>
<div class="base-info-edit">
<img src="/src/static/image/chatSettings/edit-btn.png" />
</div>
</div>
<div class="chat-group-members chat-group-infos chat-settings-card">
<div
class="chat-group-infos-each"
v-for="(item, index) in state.chatGroupMembers"
:key="index"
>
<settingFormItem :item="item"></settingFormItem>
<div class="group-member-list">
<div
class="group-member-list-each"
v-for="(memberItem, memberIndex) in item?.memberList"
>
<div class="group-member-each" v-if="memberIndex < 15">
<div class="group-member-avatar">
<img />
<span class="text-[24rpx] font-bold">
{{ memberItem.avatar }}
</span>
</div>
<div class="group-member-tag" v-if="memberIndex < 3">
<span class="text-[16rpx] font-regular">
{{ $t('group.identify.admin') }}
</span>
</div>
<div class="group-member-name">
<span class="text-[24rpx] font-regular">
{{ memberItem.name }}
</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="chat-group-infos chat-settings-card">
<div
class="chat-group-infos-each"
v-for="(item, index) in state.chatGroupInfos"
:key="index"
>
<settingFormItem :item="item"></settingFormItem>
</div>
</div>
<div class="chat-records-search chat-settings-card">
<tm-input
class="searchRoot_input"
:placeholder="$t('search.chat.record')"
color="#F9F9FD"
:round="1"
prefix="tmicon-search"
prefixColor="#46299D"
></tm-input>
<div class="record-search-types">
<div
class="record-search-types-each"
v-for="(item, index) in state.recordSearchTypeList"
:key="index"
>
<img class="record-search-types-icon" :src="item.typeIcon" />
<span class="text-[24rpx] font-regular">{{ item.value }}</span>
</div>
</div>
</div>
<div class="chat-group-infos chat-settings-card">
<div
class="chat-group-infos-each"
v-for="(item, index) in state.chatSettings"
:key="index"
>
<settingFormItem :item="item"></settingFormItem>
</div>
</div>
<div class="chat-group-infos chat-settings-card">
<div
class="chat-group-infos-each"
v-for="(item, index) in state.chatManagement"
:key="index"
>
<settingFormItem :item="item"></settingFormItem>
</div>
</div>
<div class="clear-chat-record-btn chat-settings-card">
<div class="clear-chat-record-btn-each">
<span class="text-[32rpx] font-regular">
{{ $t('chat.settings.clearChatRecord') }}
</span>
</div>
<div class="clear-chat-record-btn-each">
<span class="text-[32rpx] font-regular">
{{ $t('group.disband.btn') }}
</span>
</div>
<div class="clear-chat-record-btn-each">
<span class="text-[32rpx] font-regular">
{{ $t('group.quit.btn') }}
</span>
</div>
</div>
</div>
</ZPaging>
</div>
</div>
</template>
<script setup>
import recordSearchTypeIcon_groupMember from '@/static/image/chatSettings/recordSearchTypeGroupMembers.png'
import recordSearchTypeIcon_date from '@/static/image/chatSettings/recordSearchTypeDate.png'
import recordSearchTypeIcon_imgAndVideo from '@/static/image/chatSettings/recordSearchTypeImgAndVideo.png'
import recordSearchTypeIcon_files from '@/static/image/chatSettings/recordSearchTypeFiles.png'
import recordSearchTypeIcon_link from '@/static/image/chatSettings/recordSearchTypeLink.png'
import ZPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue'
import settingFormItem from './components/settingFormItem.vue'
import { computed, onMounted, reactive } from 'vue'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const state = reactive({
chatGroupMembers: [], //
chatGroupInfos: [], //
recordSearchTypeList: [], //
chatSettings: [], //
chatManagement: [], //
})
onMounted(() => {
let memberList = []
for (let i = 0; i < 18; i++) {
memberList.push({
name: '姜雪辞',
avatar: '雪辞',
})
}
state.chatGroupMembers = [
{
label: t('chat.settings.groupMember'),
hasPointer: true,
value: '全部(' + groupNum.value + '',
subValue: '',
customInfo: '',
memberList: memberList,
},
]
state.chatGroupInfos = [
{
label: t('chat.settings.groupName'),
hasPointer: true,
value: '泰丰国际',
subValue: '',
customInfo: '',
},
{
label: t('chat.settings.groupNotice'),
hasPointer: true,
value: '',
subValue: '数字科技中心啊撒salads阿萨达撒的啊撒…',
customInfo: '',
},
{
label: t('chat.settings.groupType'),
hasPointer: false,
value: '公司群',
subValue: '',
customInfo: '',
},
]
state.recordSearchTypeList = [
{
value: t('chat.settings.groupMember'),
typeIcon: recordSearchTypeIcon_groupMember,
},
{
value: t('record.searchType.date'),
typeIcon: recordSearchTypeIcon_date,
},
{
value: t('record.searchType.imgAndVideo'),
typeIcon: recordSearchTypeIcon_imgAndVideo,
},
{
value: t('record.searchType.files'),
typeIcon: recordSearchTypeIcon_files,
},
{
value: t('record.searchType.link'),
typeIcon: recordSearchTypeIcon_link,
},
]
state.chatSettings = [
{
label: t('chat.settings.topSession'),
hasPointer: false,
value: '',
subValue: '',
customInfo: 'switch',
},
{
label: t('chat.settings.messageNoDisturb'),
hasPointer: false,
value: '',
subValue: '',
customInfo: 'switch',
},
]
state.chatManagement = [
{
label: t('chat.settings.groupGag'),
hasPointer: true,
value: '',
subValue: '',
customInfo: '',
},
{
label: t('chat.settings.groupAdmin'),
hasPointer: true,
value: '',
subValue: '总经理室-总经理,苏州站-出纳,常熟站…',
customInfo: '',
},
]
})
//
const groupAvatar = computed(() => {
return ''
})
//
const groupName = computed(() => {
return '泰丰国际'
})
//
const groupNum = computed(() => {
return 600
})
//
const groupType = computed(() => {
return '公司'
})
</script>
<style scoped lang="scss">
.outer-layer {
flex: 1;
background-image: url('@/static/image/clockIn/z3280@3x.png');
background-size: cover;
background-repeat: no-repeat;
}
.chat-settings-page {
.navBar-title {
span {
line-height: 48rpx;
}
}
.chat-settings {
padding: 0 32rpx 36rpx;
width: 100%;
.chat-settings-card {
width: 100%;
background-color: #fff;
margin: 20rpx 0 0;
border-radius: 8rpx;
box-shadow: 0 6px 12px 2px rgba(188, 188, 188, 0.08);
}
.chat-group-base-infos {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
padding: 32rpx 40rpx 32rpx 20rpx;
.base-info-avatar {
width: 96rpx;
height: 96rpx;
flex-shrink: 0;
border-radius: 50%;
overflow: hidden;
img {
width: 100%;
height: 100%;
}
}
.base-info {
width: 100%;
margin: 0 30rpx;
.base-info-name {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
span {
line-height: 44rpx;
color: $theme-text;
}
.base-info_num {
line-height: 44rpx;
}
}
.base-info-tag {
border: 2rpx solid #7a58de;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 2rpx 14rpx;
margin: 10rpx 0 0;
border-radius: 8rpx;
width: 80rpx;
span {
flex-shrink: 0;
color: #7a58de;
line-height: 34rpx;
}
}
}
.base-info-edit {
width: 36rpx;
height: 36rpx;
flex-shrink: 0;
img {
width: 100%;
height: 100%;
}
}
}
.chat-group-members {
.group-member-list {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
flex-wrap: wrap;
.group-member-list-each {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: calc(100% / 5);
.group-member-each {
margin: 32rpx 0 0;
position: relative;
.group-member-avatar {
width: 72rpx;
height: 72rpx;
border-radius: 50%;
background: linear-gradient(to right, #674bbc, #46299d);
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
img {
}
span {
line-height: 34rpx;
color: #fff;
}
}
.group-member-tag {
position: absolute;
top: 58rpx;
left: 0;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
background-color: #cf3050;
border-radius: 16rpx;
padding: 0 12rpx;
span {
line-height: 22rpx;
color: #fff;
}
}
.group-member-name {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
margin: 8rpx 0 0;
span {
line-height: 34rpx;
color: #919191;
}
}
}
}
}
}
.chat-group-infos {
padding: 0 16rpx;
.chat-group-infos-each {
padding: 32rpx 14rpx;
border-bottom: 1px solid $theme-border-color;
}
.chat-group-infos-each:last-child {
border-bottom: 0;
}
}
.chat-records-search {
padding: 22rpx 16rpx;
.record-search-types {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
flex-wrap: wrap;
.record-search-types-each {
width: calc(100% / 4);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin: 36rpx 0 0;
.record-search-types-icon {
width: 106rpx;
height: 106rpx;
border-radius: 50%;
background-color: #f9f9f9;
}
span {
line-height: 34px;
color: #666666;
}
}
}
}
.clear-chat-record-btn {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.clear-chat-record-btn-each {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 32rpx 16rpx;
width: calc(100% - 32rpx);
border-bottom: 1px solid $theme-border-color;
span {
line-height: 44rpx;
color: #cf3050;
}
}
.clear-chat-record-btn-each:last-child {
border-bottom: 0;
}
}
}
}
</style>

View File

@ -8,7 +8,7 @@
</div>
<template v-slot:right>
<div class="mr-[36rpx]">
<tm-icon color="rgb(51, 51, 51)" :font-size="36" name="tmicon-gengduo"></tm-icon>
<tm-icon color="rgb(51, 51, 51)" :font-size="36" name="tmicon-gengduo" @click="toChatSettingsPage"></tm-icon>
</div>
</template>
</tm-navbar>
@ -680,6 +680,13 @@ const initData = async () => {
zpagingRef.value?.complete(records.value)
}
//
const toChatSettingsPage = () => {
uni.navigateTo({
url: '/pages/chatSettings/index'
})
}
onMounted(async () => {
initData()
})

View File

@ -228,7 +228,7 @@ const resultDetail = computed(() => {
result_detail = t('search.result.include') + result_detail
break
case 'extra':
result_detail = JSON.parse(props.searchItem?.extra).content
result_detail = props.searchItem?.extra
break
default:
result_detail = ''

View File

@ -29,8 +29,11 @@
:round="1"
prefix="tmicon-search"
prefixColor="#46299D"
:prefixLabel="state?.first_talk_record_infos?.receiver_name"
v-model.lazy="state.searchText"
@input="inputSearchText"
:showClear="true"
@clear="clearInput"
></tm-input>
<span
class="searchRoot_cancelBtn text-[32rpx] font-medium"
@ -156,6 +159,11 @@ onMounted(() => {
}
})
//
const clearInput = () => {
inputSearchText('')
}
//
const inputSearchText = (e) => {
// console.log(e)
@ -254,7 +262,11 @@ const queryAllSearch = (pageNum, searchResultPageSize) => {
data.last_group_id,
data.last_member_id,
)
zPaging.value?.completeByTotal([data], data.count)
let total = data.count
if (props.searchRecordDetail) {
total = data.group_record_count
}
zPaging.value?.completeByTotal([data], total)
} else {
zPaging.value?.complete([data])
}
@ -377,6 +389,11 @@ const clickSearchItem = (searchResultKey, searchItem) => {
width: 100%;
}
.searchRoot_input::v-deep .tmicon-times-circle-fill::before {
content: '\e82a';
color: #d2d2d5;
}
.searchRoot_cancelBtn {
line-height: 44rpx;
color: $theme-primary;

View File

@ -28,11 +28,13 @@ const state = reactive({
apiRequest: Function,
apiParams: String,
searchText: String,
searchResultKey: String,
})
onLoad((options) => {
console.log(options)
if (options.searchResultKey) {
state.searchResultKey = options.searchResultKey
if (options.searchResultKey === 'user_infos') {
state.apiParams = encodeURIComponent(
JSON.stringify({
@ -85,9 +87,11 @@ const lastIdChange = (last_id, last_group_id, last_member_id) => {
//
const clickSearchItem = (searchText) => {
if (state.searchResultKey === 'general_infos') {
uni.navigateTo({
url: '/pages/search/moreResult/moreResultDetail?searchText=' + searchText,
})
}
}
</script>
<style scoped lang="scss"></style>

View File

@ -9,6 +9,7 @@
:searchText="state.searchText"
:isPagination="true"
:searchRecordDetail="true"
@lastIdChange="lastIdChange"
></searchList>
</div>
</div>
@ -48,5 +49,23 @@ onLoad((options) => {
console.log(JSON.parse(decodeURIComponent(state.apiParams)))
})
//id
const lastIdChange = (last_id, last_group_id, last_member_id) => {
let idChanges = {
last_id,
last_group_id,
last_member_id,
}
state.apiParams = encodeURIComponent(
JSON.stringify(
Object.assign(
{},
JSON.parse(decodeURIComponent(state.apiParams)),
idChanges,
),
),
)
}
</script>
<style scoped lang="scss"></style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 519 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 370 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -82,5 +82,23 @@
"search.result.include": "包含:",
"has_more": "更多",
"index.type.company": "公司",
"search.result.relevant": "相关"
"search.result.relevant": "相关",
"index.chat.settings": "聊天设置",
"chat.settings.clearChatRecord": "清空聊天记录",
"chat.settings.groupName": "群名称",
"chat.settings.groupNotice": "群公告",
"chat.settings.groupType": "群类型",
"chat.settings.topSession": "置顶会话",
"chat.settings.messageNoDisturb": "消息免打扰",
"chat.settings.groupGag": "群内禁言",
"chat.settings.groupAdmin": "群管理员",
"chat.settings.groupMember": "群成员",
"search.chat.record": "搜索聊天记录",
"record.searchType.date": "日期",
"record.searchType.imgAndVideo": "图片及视频",
"record.searchType.files": "文件",
"record.searchType.link": "链接",
"group.identify.admin": "管理员",
"group.disband.btn": "解散该群",
"group.quit.btn": "退出群聊"
}