Compare commits
9 Commits
e3f2346d66
...
2c1ae41c3e
Author | SHA1 | Date | |
---|---|---|---|
|
2c1ae41c3e | ||
|
44a1dd0986 | ||
|
8ce7d143ce | ||
|
58b70f84d7 | ||
|
6d663d3d01 | ||
|
b117765bdc | ||
1edb639ad9 | |||
8ecee15180 | |||
efb410b657 |
@ -883,8 +883,8 @@ packages:
|
||||
'@types/ms@2.1.0':
|
||||
resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==}
|
||||
|
||||
'@types/node@18.19.101':
|
||||
resolution: {integrity: sha512-Ykg7fcE3+cOQlLUv2Ds3zil6DVjriGQaSN/kEpl5HQ3DIGM6W0F2n9+GkWV4bRt7KjLymgzNdTnSKCbFUUJ7Kw==}
|
||||
'@types/node@18.19.103':
|
||||
resolution: {integrity: sha512-hHTHp+sEz6SxFsp+SA+Tqrua3AbmlAw+Y//aEwdHrdZkYVRWdvWD3y5uPZ0flYOkgskaFWqZ/YGFm3FaFQ0pRw==}
|
||||
|
||||
'@types/node@18.19.99':
|
||||
resolution: {integrity: sha512-tNGqoGjjI4vY5jfm3lnqgR6yS8wyT76SfsWefLWRyh/cEK4UHmPVyqHZdafI/SNu1PQzfo2JLBWfG8eMmD7KrQ==}
|
||||
@ -3517,8 +3517,8 @@ packages:
|
||||
warning@4.0.3:
|
||||
resolution: {integrity: sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==}
|
||||
|
||||
watchpack@2.4.3:
|
||||
resolution: {integrity: sha512-adBYQLivcg1jbdKEJeqScJJFvgm4qY9+3tXw+jdG6lkVeqRJEtiQmSWjmth8GKmDZuX7sYM4YFxQsf0AzMfGGw==}
|
||||
watchpack@2.4.4:
|
||||
resolution: {integrity: sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
|
||||
web-worker@1.5.0:
|
||||
@ -3528,8 +3528,8 @@ packages:
|
||||
resolution: {integrity: sha512-BCfKo2YkDe2ByqkEWe1Rw+zko4LsyS75LVr29C6xIrxAg9JHJ4pl8kaIZ396SUSNp6b4815dRZPSTAS8LlURRQ==}
|
||||
deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
|
||||
|
||||
webpack-sources@3.2.3:
|
||||
resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==}
|
||||
webpack-sources@3.3.0:
|
||||
resolution: {integrity: sha512-77R0RDmJfj9dyv5p3bM5pOHa+X8/ZkO9c7kpDstigkC4nIDobadsfSGCwB4bKhMVxqAok8tajaoR8rirM7+VFQ==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
|
||||
webpack-virtual-modules@0.6.2:
|
||||
@ -4228,7 +4228,7 @@ snapshots:
|
||||
|
||||
'@types/ms@2.1.0': {}
|
||||
|
||||
'@types/node@18.19.101':
|
||||
'@types/node@18.19.103':
|
||||
dependencies:
|
||||
undici-types: 5.26.5
|
||||
|
||||
@ -5895,7 +5895,7 @@ snapshots:
|
||||
|
||||
jest-worker@27.5.1:
|
||||
dependencies:
|
||||
'@types/node': 18.19.101
|
||||
'@types/node': 18.19.103
|
||||
merge-stream: 2.0.0
|
||||
supports-color: 8.1.1
|
||||
|
||||
@ -7244,7 +7244,7 @@ snapshots:
|
||||
dependencies:
|
||||
loose-envify: 1.4.0
|
||||
|
||||
watchpack@2.4.3:
|
||||
watchpack@2.4.4:
|
||||
dependencies:
|
||||
glob-to-regexp: 0.4.1
|
||||
graceful-fs: 4.2.11
|
||||
@ -7256,7 +7256,7 @@ snapshots:
|
||||
deepmerge: 1.5.2
|
||||
javascript-stringify: 1.6.0
|
||||
|
||||
webpack-sources@3.2.3: {}
|
||||
webpack-sources@3.3.0: {}
|
||||
|
||||
webpack-virtual-modules@0.6.2: {}
|
||||
|
||||
@ -7284,8 +7284,8 @@ snapshots:
|
||||
schema-utils: 4.3.2
|
||||
tapable: 2.2.2
|
||||
terser-webpack-plugin: 5.3.14(webpack@5.99.8)
|
||||
watchpack: 2.4.3
|
||||
webpack-sources: 3.2.3
|
||||
watchpack: 2.4.4
|
||||
webpack-sources: 3.3.0
|
||||
transitivePeerDependencies:
|
||||
- '@swc/core'
|
||||
- esbuild
|
||||
|
@ -29,7 +29,7 @@ html {
|
||||
|
||||
// 黑色主题
|
||||
html[theme-mode='dark'] {
|
||||
--im-primary-color: #1890ff;
|
||||
--im-primary-color: #462AA0;
|
||||
--im-bg-color: #202124;
|
||||
--line-border-color: rgb(255 255 255 / 9%);
|
||||
--border-color: rgb(255 255 255 / 9%);
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
&:hover,
|
||||
&.dropsize-resizing {
|
||||
background-color: #1890ff;
|
||||
background-color: #462AA0;
|
||||
}
|
||||
|
||||
&.dropsize-line-top {
|
||||
|
@ -44,7 +44,7 @@
|
||||
font-feature-settings: 'tnum';
|
||||
position: absolute;
|
||||
display: none;
|
||||
color: #1890ff;
|
||||
color: #462AA0;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
opacity: 0;
|
||||
@ -177,7 +177,7 @@
|
||||
display: block;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
background-color: #1890ff;
|
||||
background-color: #462AA0;
|
||||
border-radius: 100%;
|
||||
-webkit-transform: scale(0.75);
|
||||
transform: scale(0.75);
|
||||
|
@ -143,6 +143,7 @@ const editorOption = {
|
||||
},
|
||||
// 数据源函数,过滤匹配的用户
|
||||
source: function (searchTerm: string, renderList: any) {
|
||||
console.log("source")
|
||||
if (!props.members.length) {
|
||||
return renderList([])
|
||||
}
|
||||
|
@ -236,6 +236,8 @@ const handleModalConfirm = (closeLoading) => {
|
||||
closeLoading()
|
||||
window['$message'].error(err.message)
|
||||
})
|
||||
} else if (state.chatSettingOperateType == 'quit'){
|
||||
//退出群聊
|
||||
}
|
||||
}
|
||||
|
||||
@ -988,7 +990,7 @@ const handleEditGroupNameConfirm = () => {
|
||||
margin: 3px 0;
|
||||
&:hover {
|
||||
.nickname {
|
||||
color: #1890ff;
|
||||
color: #462AA0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,17 @@
|
||||
<template>
|
||||
<div class="outer-layer search-by-condition-page">
|
||||
<n-infinite-scroll style="height: 455px;" :distance="10">
|
||||
<n-infinite-scroll style="height: 455px;" :distance="40" @load="loadMore">
|
||||
<div class="root">
|
||||
<div v-if="state.condition === 'dateTimePicker'" class="search-by-date">
|
||||
<n-date-picker
|
||||
<!-- <div v-if="state.condition === 'date'" class="search-by-date"> -->
|
||||
<!-- <n-date-picker
|
||||
:panel="true"
|
||||
type="datetime"
|
||||
:clearable="true"
|
||||
:first-day-of-week="6"
|
||||
:is-date-disabled="dateDisabled"
|
||||
:actions="['clear', 'confirm']"
|
||||
/>
|
||||
@confirm="onDatePickConfirm"
|
||||
/> -->
|
||||
<!-- <tm-time-picker
|
||||
:show="state.showMonthPicker"
|
||||
:showDetail="{
|
||||
@ -55,17 +56,24 @@
|
||||
@getDArray="getDArray"
|
||||
:showDefault="false"
|
||||
></tm-calendar-view> -->
|
||||
</div>
|
||||
<!-- </div> -->
|
||||
<div
|
||||
class="search-by-condition-input-list"
|
||||
v-if="
|
||||
state.condition === 'imgAndVideo' ||
|
||||
state.condition === 'file' ||
|
||||
state.condition === 'link' ||
|
||||
state.condition === 'member'
|
||||
state.condition === 'member' ||
|
||||
state.condition === 'all' ||
|
||||
state.condition === 'date'
|
||||
"
|
||||
:style="{
|
||||
padding: state.condition === 'imgAndVideo' ? '20px 38px' : ''
|
||||
padding:
|
||||
state.searchResultList.length > 0
|
||||
? state.condition === 'imgAndVideo'
|
||||
? '20px 38px'
|
||||
: ''
|
||||
: '0'
|
||||
}"
|
||||
>
|
||||
<!-- <div
|
||||
@ -117,7 +125,14 @@
|
||||
padding: state.condition === 'imgAndVideo' ? '' : ''
|
||||
}"
|
||||
>
|
||||
<div class="condition-result-member" v-if="state.condition === 'member'">
|
||||
<div
|
||||
class="condition-result-member"
|
||||
v-if="
|
||||
state.condition === 'member' ||
|
||||
state.condition === 'all' ||
|
||||
state.condition === 'date'
|
||||
"
|
||||
>
|
||||
<searchItem
|
||||
@click="toDialogueByMember(item)"
|
||||
:searchResultKey="'search_by_member_condition'"
|
||||
@ -216,7 +231,7 @@
|
||||
<span
|
||||
class="text-[14px] font-regular"
|
||||
v-if="state.condition === 'file'"
|
||||
style="color: #999999;"
|
||||
style="color: #999999; flex-shrink: 0; margin: 0 0 0 20px;"
|
||||
>
|
||||
{{ item.dateTime }}
|
||||
</span>
|
||||
@ -236,7 +251,11 @@
|
||||
<span class="text-[12px] font-regular" v-if="state.condition === 'file'">
|
||||
{{ item?.nickname }}
|
||||
</span>
|
||||
<span class="text-[12px] font-regular" v-if="state.condition === 'file'">
|
||||
<span
|
||||
class="text-[12px] font-regular"
|
||||
v-if="state.condition === 'file'"
|
||||
style="flex-shrink: 0; margin: 0 0 0 20px;"
|
||||
>
|
||||
{{ item?.extra?.fileSize }}
|
||||
</span>
|
||||
</div>
|
||||
@ -278,6 +297,10 @@
|
||||
</div>
|
||||
</teleport>
|
||||
</div>
|
||||
<div class="search-record-empty" v-if="state.searchResultList.length === 0">
|
||||
<img src="@/assets/image/chatList/search-empty.png" alt="" />
|
||||
<span>无内容</span>
|
||||
</div>
|
||||
</n-infinite-scroll>
|
||||
</div>
|
||||
</template>
|
||||
@ -304,6 +327,8 @@ import { parseTime } from '@/utils/datetime'
|
||||
import { fileFormatSize, fileSuffix } from '@/utils/strings'
|
||||
import { NImage, NInfiniteScroll, NScrollbar, NIcon, NDatePicker } from 'naive-ui'
|
||||
|
||||
const emits = defineEmits(['clearSearchMemberByAlphabet', 'getDisabledDateArray'])
|
||||
|
||||
const dialogueStore = useDialogueStore()
|
||||
// 当前对话参数
|
||||
const dialogueParams = reactive({
|
||||
@ -318,6 +343,26 @@ const props = defineProps({
|
||||
//搜索条件
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
searchMemberItem: {
|
||||
//搜索的群成员
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
searchRecordByConditionText: {
|
||||
//搜索关键字文本
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
selectedDateTime: {
|
||||
//选中的日期时间戳格式
|
||||
type: [Number, null],
|
||||
default: null
|
||||
},
|
||||
nowDateTime: {
|
||||
//当前日期时间
|
||||
type: Date,
|
||||
default: new Date()
|
||||
}
|
||||
})
|
||||
|
||||
@ -338,7 +383,10 @@ const state = reactive({
|
||||
cursor: 0, //上次查询的游标
|
||||
msg_type: 0, //查询的消息类型
|
||||
group_member_id: 0, //群成员id
|
||||
flatList: [] // 用于存储扁平化的数据
|
||||
flatList: [], // 用于存储扁平化的数据
|
||||
selectedDateTime: null, //选中的日期时间戳格式
|
||||
isLoadingChatRecord: false, // 添加加载状态标志
|
||||
hasNoMoreResults: false // 是否没有更多结果
|
||||
})
|
||||
|
||||
const videoContext = ref()
|
||||
@ -409,6 +457,7 @@ const ServeQueryTalkDate = (month) => {
|
||||
} else {
|
||||
state.disabledDateArray = state.dArray
|
||||
}
|
||||
emits('getDisabledDateArray', state.disabledDateArray)
|
||||
} else {
|
||||
}
|
||||
})
|
||||
@ -416,16 +465,6 @@ const ServeQueryTalkDate = (month) => {
|
||||
resp.catch(() => {})
|
||||
}
|
||||
|
||||
//禁用的日期
|
||||
const dateDisabled = (e) => {
|
||||
const date = new Date(e)
|
||||
const year = date.getFullYear()
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(date.getDate()).padStart(2, '0')
|
||||
const formattedDate = `${year}/${month}/${day}`
|
||||
return state.disabledDateArray.includes(formattedDate)
|
||||
}
|
||||
|
||||
//点击选择日期
|
||||
const selectDate = async (e) => {
|
||||
if (e == parseTime(state.nowDate, '{y}/{m}/{d}')) {
|
||||
@ -518,8 +557,6 @@ const getDArray = (selectedMonth) => {
|
||||
//输入搜索内容
|
||||
const inputSearchText = (e) => {
|
||||
state.searchText = e
|
||||
state.cursor = 0
|
||||
queryAllSearch()
|
||||
}
|
||||
|
||||
//点击取消搜索
|
||||
@ -546,28 +583,32 @@ const queryAllSearch = () => {
|
||||
limit: 10, //数据行数
|
||||
no_limit: '', //1不限制
|
||||
direction: 'up', //down向下查最新,up向上查老数据
|
||||
start_time: '',
|
||||
end_time: '',
|
||||
start_time: state.selectedDateTime
|
||||
? parseTime(new Date(state.selectedDateTime), '{y}-{m}-{d}')
|
||||
: '',
|
||||
end_time: state.selectedDateTime
|
||||
? parseTime(new Date(state.selectedDateTime), '{y}-{m}-{d}')
|
||||
: '',
|
||||
group_member_user_id: state.group_member_id, //群成员id,当查询群历史消息的时候,需要指定群成员的时候送
|
||||
file_name: state.msg_type === 6 ? state.searchText : ''
|
||||
file_name: props?.searchRecordByConditionText
|
||||
}
|
||||
console.log(params)
|
||||
const resp = ServeFindTalkRecords(params)
|
||||
console.log(resp)
|
||||
resp.then(({ code, data }) => {
|
||||
resp
|
||||
.then(({ code, data }) => {
|
||||
console.log(data)
|
||||
if (code == 200) {
|
||||
// 当cursor为0时,清空searchResultList
|
||||
let dateList = state.cursor === 0 ? [] : state.searchResultList
|
||||
let noMore = false
|
||||
if (data?.items?.length > 0) {
|
||||
data.items.forEach((item) => {
|
||||
item.dateTime = parseTime(item?.created_at, '{m}/{d}')
|
||||
if (item?.extra) {
|
||||
if (item?.extra && typeof item.extra === 'object') {
|
||||
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)
|
||||
// console.log(item.extra.type)
|
||||
}
|
||||
let year = new Date(item.created_at).getFullYear()
|
||||
let month = new Date(item.created_at).getMonth() + 1
|
||||
@ -597,8 +638,6 @@ const queryAllSearch = () => {
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
noMore = true
|
||||
}
|
||||
|
||||
// 保存分组数据用于显示
|
||||
@ -615,6 +654,11 @@ const queryAllSearch = () => {
|
||||
// zPaging.value?.completeByNoMore(state.flatList, noMore)
|
||||
}
|
||||
state.cursor = data?.cursor
|
||||
if (data?.cursor === 0) {
|
||||
state.hasNoMoreResults = true
|
||||
} else {
|
||||
state.hasNoMoreResults = false
|
||||
}
|
||||
} else {
|
||||
if (state.cursor === 0) {
|
||||
state.searchResultList = []
|
||||
@ -623,6 +667,9 @@ const queryAllSearch = () => {
|
||||
// zPaging.value?.complete([])
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
state.isLoadingChatRecord = false // 无论成功失败,都重置加载状态
|
||||
})
|
||||
|
||||
resp.catch(() => {
|
||||
if (state.cursor === 0) {
|
||||
@ -630,6 +677,7 @@ const queryAllSearch = () => {
|
||||
state.flatList = []
|
||||
}
|
||||
// zPaging.value?.complete([])
|
||||
state.isLoadingChatRecord = false // 发生错误时也要重置加载状态
|
||||
})
|
||||
}
|
||||
|
||||
@ -699,22 +747,45 @@ const toDialogueByMember = async (msgInfo) => {
|
||||
})
|
||||
}
|
||||
|
||||
//重置部分搜索条件
|
||||
const resetSearchConditions = (newVal) => {
|
||||
state.cursor = 0
|
||||
state.searchResultList = []
|
||||
state.flatList = []
|
||||
if (newVal !== 'member') {
|
||||
state.group_member_id = 0
|
||||
emits('clearSearchMemberByAlphabet')
|
||||
}
|
||||
}
|
||||
|
||||
//触底加载更多数据
|
||||
const loadMore = () => {
|
||||
if (state.isLoadingChatRecord || state.hasNoMoreResults) return // 如果正在加载中,或者没有更多结果,直接返回
|
||||
state.isLoadingChatRecord = true
|
||||
queryAllSearch()
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props?.conditionType,
|
||||
(newVal, oldVal) => {
|
||||
console.log(newVal, oldVal)
|
||||
state.condition = newVal
|
||||
if (newVal) {
|
||||
resetSearchConditions(newVal)
|
||||
if (newVal === 'member') {
|
||||
//没选日期前,也等同于倒序查询全部
|
||||
state.showPageTitle = true
|
||||
state.pageTitle = '按群成员查找'
|
||||
// state.group_member_id = options.groupMemberId
|
||||
state.msg_type = 0
|
||||
queryAllSearch()
|
||||
} else if (newVal === 'dateTimePicker') {
|
||||
} else if (newVal === 'date') {
|
||||
//没选日期前,也等同于倒序查询全部
|
||||
state.showPageTitle = true
|
||||
state.pageTitle = '按日期查找'
|
||||
state.msg_type = 0
|
||||
ServeQueryTalkDate(parseTime(state.nowDate, '{y}{m}'))
|
||||
getDArray(parseTime(state.nowDate, '{y}-{m}'))
|
||||
queryAllSearch()
|
||||
} else if (newVal === 'imgAndVideo') {
|
||||
state.showPageTitle = true
|
||||
state.pageTitle = '图片与视频'
|
||||
@ -744,6 +815,10 @@ watch(
|
||||
)
|
||||
state.msg_type = 14
|
||||
queryAllSearch()
|
||||
} else if (newVal === 'all') {
|
||||
//查询全部,即重置所有条件
|
||||
state.msg_type = 0
|
||||
queryAllSearch()
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -752,13 +827,48 @@ watch(
|
||||
deep: true
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => props?.searchMemberItem,
|
||||
(newVal, oldVal) => {
|
||||
const memberItem = newVal ? JSON.parse(decodeURIComponent(newVal)) : ''
|
||||
state.group_member_id = memberItem?.user_id
|
||||
resetSearchConditions('member')
|
||||
queryAllSearch()
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
deep: true
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => props?.searchRecordByConditionText,
|
||||
(newVal, oldVal) => {
|
||||
resetSearchConditions(state.condition)
|
||||
queryAllSearch()
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => props?.selectedDateTime,
|
||||
(newVal, oldVal) => {
|
||||
state.selectedDateTime = newVal
|
||||
resetSearchConditions('date')
|
||||
queryAllSearch()
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => props?.nowDateTime,
|
||||
(newVal, oldVal) => {
|
||||
ServeQueryTalkDate(parseTime(newVal, '{y}{m}'))
|
||||
getDArray(parseTime(newVal, '{y}-{m}'))
|
||||
}
|
||||
)
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.search-by-date {
|
||||
:deep(.n-date-panel-header) {
|
||||
display: none;
|
||||
}
|
||||
.search-date-picker {
|
||||
.search-date-picker {
|
||||
padding: 10px 16px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
@ -773,9 +883,7 @@ watch(
|
||||
height: 6px;
|
||||
margin: 0 0 0 13px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
body:deep(.text-overflow-1) {
|
||||
color: #666666 !important;
|
||||
line-height: 22px !important;
|
||||
@ -963,11 +1071,6 @@ body:deep(.round-3) {
|
||||
}
|
||||
}
|
||||
}
|
||||
.condition-dimensionality-each:nth-child(1) {
|
||||
.condition-each-result-attachments {
|
||||
padding: 0 0 14px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -990,4 +1093,23 @@ body:deep(.round-3) {
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.search-record-empty {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 455px;
|
||||
box-sizing: border-box;
|
||||
img {
|
||||
width: 160px;
|
||||
height: 104px;
|
||||
}
|
||||
span {
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
font-weight: 400;
|
||||
margin: 13px 0 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -334,6 +334,7 @@ const resultDetail = computed(() => {
|
||||
.searchRecordDetail-fastLocal {
|
||||
display: none;
|
||||
line-height: 20px;
|
||||
flex-shrink: 0;
|
||||
span {
|
||||
color: #46299d;
|
||||
font-size: 12px;
|
||||
|
@ -89,7 +89,7 @@ const onContextMenu = (e:any,item: ITalkRecord) => {
|
||||
<Loading v-if="items.length === 0" />
|
||||
|
||||
<div v-for="item in items" :key="item.msg_id" class="message-item">
|
||||
<div class="left-box pointer" @click="showUserInfoModal(item.user_id)">
|
||||
<div class="left-box pointer" @click="showUserInfoModal(item.erp_user_id)">
|
||||
<im-avatar :src="item.avatar" :size="38" :username="item.nickname" />
|
||||
</div>
|
||||
|
||||
|
@ -86,12 +86,14 @@ const strokeDashoffset = computed(() =>
|
||||
|
||||
// 处理文件点击事件
|
||||
const handleClick = () => {
|
||||
console.log('handleClick')
|
||||
if(!props.extra.is_uploading){
|
||||
window.open(
|
||||
`${window.location.origin}/office?url=${props.extra.path}`,
|
||||
'_blank',
|
||||
'width=1200,height=900,left=200,top=200,toolbar=no,menubar=no,scrollbars=yes,resizable=yes,location=no,status=no'
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function downloadFileWithProgress(resourceUrl, filename) {
|
||||
|
@ -27,7 +27,7 @@ let textContent = props.extra?.content || ''
|
||||
textContent = textReplaceLink(textContent)
|
||||
|
||||
if (props.data.talk_type == 2) {
|
||||
textContent = textReplaceMention(textContent, '#1890ff')
|
||||
textContent = textReplaceMention(textContent, '#462AA0')
|
||||
}
|
||||
|
||||
textContent = textReplaceEmoji(textContent)
|
||||
|
@ -17,7 +17,7 @@ let textContent = props.extra?.content || ''
|
||||
textContent = textReplaceLink(textContent)
|
||||
|
||||
if (props.data.talk_type == 2) {
|
||||
textContent = textReplaceMention(textContent, '#1890ff')
|
||||
textContent = textReplaceMention(textContent, '#462AA0')
|
||||
}
|
||||
|
||||
textContent = textReplaceEmoji(textContent)
|
||||
|
@ -121,7 +121,7 @@ onMounted(() => {
|
||||
:height="5"
|
||||
:show-indicator="false"
|
||||
:percentage="parseInt(option.progress)"
|
||||
color="#1890ff"
|
||||
color="#462AA0"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
|
@ -28,7 +28,7 @@
|
||||
font-weight: 400;
|
||||
|
||||
&:hover {
|
||||
color: #1890ff;
|
||||
color: #462AA0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1514,7 +1514,7 @@ const numWidth = computed(() => {
|
||||
|
||||
.x-upload-preview-button:hover {
|
||||
background-color: #e6f7ff;
|
||||
color: #1890ff;
|
||||
color: #462AA0;
|
||||
}
|
||||
|
||||
.x-upload-download-button:hover {
|
||||
|
@ -45,7 +45,7 @@
|
||||
font-feature-settings: 'tnum';
|
||||
position: absolute;
|
||||
display: none;
|
||||
color: #1890ff;
|
||||
color: #462AA0;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
opacity: 0;
|
||||
@ -103,7 +103,7 @@
|
||||
display: block;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
background-color: #1890ff;
|
||||
background-color: #462AA0;
|
||||
border-radius: 100%;
|
||||
transform: scale(0.75);
|
||||
transform-origin: 50% 50%;
|
||||
|
@ -7,6 +7,7 @@ import { formatTalkItem, palyMusic, formatTalkRecord } from '@/utils/talk'
|
||||
import { isElectronMode } from '@/utils/common'
|
||||
import { ServeClearTalkUnreadNum, ServeCreateTalkList } from '@/api/chat'
|
||||
import { useTalkStore, useDialogueStore, useSettingsStore } from '@/store'
|
||||
import { isScrollAtBottom, scrollToBottom } from '@/utils/dom'
|
||||
|
||||
/**
|
||||
* 好友状态事件
|
||||
@ -189,12 +190,10 @@ class Talk extends Base {
|
||||
if (!el) return
|
||||
|
||||
// 判断的滚动条是否在底部
|
||||
const isBottom = Math.ceil(el.scrollTop) + el.clientHeight >= el.scrollHeight
|
||||
const isBottom = isScrollAtBottom(el)
|
||||
|
||||
if (isBottom || record.user_id == this.getAccountId()) {
|
||||
nextTick(() => {
|
||||
el.scrollTop = el.scrollHeight + 1000
|
||||
})
|
||||
scrollToBottom()
|
||||
} else {
|
||||
useDialogueStore().setUnreadBubble()
|
||||
}
|
||||
|
@ -108,8 +108,8 @@ export function useSessionMenu() {
|
||||
|
||||
const onUserInfo = (item: ISession) => {
|
||||
console.error('item',item)
|
||||
debugger
|
||||
user(item.receiver_id)
|
||||
|
||||
user(item.id)
|
||||
}
|
||||
|
||||
// 移除会话
|
||||
|
@ -3,7 +3,7 @@ import { ServeTalkRecords } from '@/api/chat'
|
||||
import { useDialogueStore } from '@/store'
|
||||
import { ITalkRecord } from '@/types/chat'
|
||||
import { formatTalkRecord } from '@/utils/talk'
|
||||
import { addClass, removeClass } from '@/utils/dom'
|
||||
import { addClass, removeClass, scrollToBottom, isScrollAtBottom } from '@/utils/dom'
|
||||
|
||||
interface Params {
|
||||
receiver_id: number
|
||||
@ -14,7 +14,8 @@ interface Params {
|
||||
interface SpecialParams extends Params {
|
||||
msg_id?: string
|
||||
cursor?: number
|
||||
direction?: 'up' | 'down'
|
||||
direction?: 'up' | 'down',
|
||||
sort_sequence?: string
|
||||
}
|
||||
|
||||
interface LoadOptions {
|
||||
@ -136,16 +137,8 @@ export const useTalkRecord = (uid: number) => {
|
||||
|
||||
if (el) {
|
||||
if (request.cursor == 0) {
|
||||
el.scrollTop = el.scrollHeight
|
||||
|
||||
setTimeout(() => {
|
||||
console.log('el.scrollHeight',el.scrollHeight)
|
||||
console.log('request.cursor == 0')
|
||||
el.scrollTop = el.scrollHeight + 1000
|
||||
|
||||
}, 500)
|
||||
scrollToBottom()
|
||||
} else {
|
||||
console.log('request.cursor !== 0')
|
||||
el.scrollTop = el.scrollHeight - scrollHeight
|
||||
}
|
||||
}
|
||||
@ -201,9 +194,9 @@ export const useTalkRecord = (uid: number) => {
|
||||
loadConfig.status = 2
|
||||
return
|
||||
}
|
||||
dialogueStore.clearDialogueRecord()
|
||||
// dialogueStore.clearDialogueRecord()
|
||||
const items = (data.items || []).map((item: ITalkRecord) => formatTalkRecord(uid, item))
|
||||
dialogueStore.unshiftDialogueRecord(items.reverse())
|
||||
dialogueStore.unshiftDialogueRecord(contextParams.direction === 'down' ? items : items.reverse())
|
||||
loadConfig.status = items.length >= contextParams.limit ? 1 : 2
|
||||
loadConfig.cursor = data.cursor
|
||||
nextTick(() => {
|
||||
@ -221,7 +214,7 @@ export const useTalkRecord = (uid: number) => {
|
||||
addClass(target, 'border')
|
||||
setTimeout(() => removeClass(target, 'border'), 3000)
|
||||
} else if (el) {
|
||||
el.scrollTop = el.scrollHeight
|
||||
scrollToBottom()
|
||||
}
|
||||
}, 50)
|
||||
})
|
||||
@ -255,6 +248,7 @@ export const useTalkRecord = (uid: number) => {
|
||||
specifiedMsg: {
|
||||
...loadConfig.specialParams,
|
||||
direction: 'up',
|
||||
sort_sequence: '',
|
||||
cursor: getMinSequence()
|
||||
}
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ const isActive = (menu) => {
|
||||
<component
|
||||
:is="nav.icon"
|
||||
:theme="isActive(nav) ? 'filled' : 'outline'"
|
||||
:fill="isActive(nav) ? '#1890ff' : color"
|
||||
:fill="isActive(nav) ? '#462AA0' : color"
|
||||
:strokeWidth="2"
|
||||
:size="22"
|
||||
/>
|
||||
|
@ -54,6 +54,8 @@ export const useDialogueStore = defineStore('dialogue', {
|
||||
groupInfo: {} ,
|
||||
// 群成员列表
|
||||
members: [],
|
||||
// 群成员列表按字母分组
|
||||
membersByAlphabet: {},
|
||||
|
||||
// 对话记录
|
||||
items: {
|
||||
@ -101,6 +103,7 @@ export const useDialogueStore = defineStore('dialogue', {
|
||||
// }
|
||||
|
||||
this.members = []
|
||||
this.membersByAlphabet = []
|
||||
if (data.talk_type == 2) {
|
||||
this.updateGroupMembers()
|
||||
this.getGroupInfo()
|
||||
@ -126,6 +129,17 @@ export const useDialogueStore = defineStore('dialogue', {
|
||||
online: false,
|
||||
value: o.nickname
|
||||
}))
|
||||
const groupMap = {};
|
||||
data.sortItems.forEach(member => {
|
||||
const alpha = (member.key || member.nickname?.[0] || '#').toUpperCase();
|
||||
if (!groupMap[alpha]) groupMap[alpha] = [];
|
||||
groupMap[alpha].push(member);
|
||||
});
|
||||
const alphabets = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
|
||||
this.membersByAlphabet = alphabets.map(alpha => ({
|
||||
alphabet: alpha,
|
||||
members: groupMap[alpha] || []
|
||||
})).filter(group => group.members.length > 0);
|
||||
},
|
||||
|
||||
// 清空对话记录
|
||||
|
@ -18,7 +18,7 @@ export function isLoggedIn() {
|
||||
*/
|
||||
export function getAccessToken() {
|
||||
// return storage.get(AccessToken) || ''
|
||||
return JSON.parse(localStorage.getItem('token'))||'46d71a72d8d845ad7ed23eba9bdde260e635407190c2ce1bf7fd22088e41682ea07773ec65cae8946d2003f264d55961f96e0fc5da10eb96d3a348c1664e9644ce2108c311309f398ae8ea1b8200bfd490e5cb6e8c52c9e5d493cbabb163368f8351420451a631dbfa749829ee4cda49b77b5ed2d3dced5d0f2b7dd9ee76ba5465c84a17c23af040cd92b6b2a4ea48befbb5c729dcdad0a9c9668befe84074cc24f78899c1d947f8e7f94c7eda5325b8ed698df729e76febb98549ef3482ae942fb4f4a1c92d21836fa784728f0c5483aab2760a991b6b36e6b10c84f840a6433a6ecc31dee36e8f1c6158818bc89d22ab23a552e0c3f606946dcb914a52b692e10d823cc7f43027127359e7ee8555d956e7e095946931ceaa3877675584b0a0a4fc690c8018712b306050ebbdea92037aea31d66d65004be26d3c696abc4c29'
|
||||
return JSON.parse(localStorage.getItem('token'))||'46d71a72d8d845ad7ed23eba9bdde260e635407190c2ce1bf7fd22088e41682ea07773ec65cae8946d2003f264d55961f96e0fc5da10eb96d3a348c1664e9644ce2108c311309f398ae8ea1b8200bfd490e5cb6e8c52c9e5d493cbabb163368f8351420451a631dbfa749829ee4cda49b77b5ed2d3dced5d0f2b7dd9ee76ba5465c84a17c23af040cd92b6b2a4ea48befbb5c729dcdad0a9c9668befe84074cc24f78899c1d947f8e7f94c7eda5325b8ed698df729e76febb98549ef3482ae942fb4f4a1c92d21836fa784728f0c5483aab2760a991b6b36e6b10c84f840a6433a6ecc31dee36e8f1c6158818bc89d227de310c4e6f5d7ff11a9e1ea73aba3f6c749f75a50a2aeaed07b14bc0d8b1db6428caf891f0a0b0c84a49697f4a4e7c8b87d972340ecbf02ddbc4d4f1e51b057c822f8351524e19d52a3ec5ce8c83e2f'
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -52,7 +52,12 @@ export function throttle(fn, delay, call = function () {}) {
|
||||
* @param {Function} callback 复制成功回调方法
|
||||
*/
|
||||
export function clipboard(text, callback) {
|
||||
navigator.clipboard
|
||||
// 在wujie环境下使用主应用的clipboard
|
||||
const clipboardObj = window.__POWERED_BY_WUJIE__
|
||||
? window.parent.navigator.clipboard
|
||||
: navigator.clipboard
|
||||
|
||||
clipboardObj
|
||||
.writeText(text)
|
||||
.then(() => {
|
||||
callback && callback()
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { nextTick } from 'vue'
|
||||
|
||||
function trim(string: string) {
|
||||
return (string || '').replace(/^[\s\uFEFF]+|[\s\uFEFF]+$/g, '')
|
||||
}
|
||||
@ -54,3 +56,26 @@ export function removeClass(el: Element, cls: string) {
|
||||
el.className = trim(curClass)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断容器是否已在底部
|
||||
* @param el DOM元素
|
||||
* @returns boolean
|
||||
*/
|
||||
export function isScrollAtBottom(el: HTMLElement): boolean {
|
||||
return Math.ceil(el.scrollTop) + el.clientHeight >= el.scrollHeight
|
||||
}
|
||||
|
||||
/**
|
||||
* 滚动指定容器到底部
|
||||
* @param id 容器的DOM id,默认 'imChatPanel'
|
||||
* @param offset 偏移量,默认 0
|
||||
*/
|
||||
export function scrollToBottom(id = 'imChatPanel', offset = 0) {
|
||||
nextTick(() => {
|
||||
const el = document.getElementById(id)
|
||||
if (el) {
|
||||
el.scrollTop = el.scrollHeight + offset
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ export function fileFormatSize(value) {
|
||||
return '0'
|
||||
}
|
||||
|
||||
let unitArr = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
|
||||
let unitArr = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
|
||||
let index = 0
|
||||
let srcsize = parseFloat(value)
|
||||
index = Math.floor(Math.log(srcsize) / Math.log(1000))
|
||||
|
@ -1,6 +1,6 @@
|
||||
<script lang="ts" setup>
|
||||
import { reactive, computed, watch } from 'vue'
|
||||
import { NDrawer, NCard, NTag } from 'naive-ui'
|
||||
import { reactive, computed, watch, ref } from 'vue'
|
||||
import { NDrawer, NCard, NTag, NInput, NDatePicker } from 'naive-ui'
|
||||
import { useUserStore, useDialogueStore, useUploadsStore } from '@/store'
|
||||
import PanelHeader from './panel/PanelHeader.vue'
|
||||
import PanelContent from './panel/PanelContent.vue'
|
||||
@ -16,9 +16,31 @@ import avatarModule from '@/components/avatar-module/index.vue'
|
||||
const userStore = useUserStore()
|
||||
const dialogueStore = useDialogueStore()
|
||||
const uploadsStore = useUploadsStore()
|
||||
console.log('dialogueStore',dialogueStore);
|
||||
console.log('dialogueStore', dialogueStore)
|
||||
|
||||
const members = computed(() => dialogueStore.members)
|
||||
const membersByAlphabet = computed(() => {
|
||||
if (state.searchMemberByAlphabet) {
|
||||
// 过滤分组,并且只保留匹配成员
|
||||
return (
|
||||
(dialogueStore.membersByAlphabet as any)
|
||||
.map((group: any) => {
|
||||
// 只保留匹配的成员
|
||||
const filteredMembers = group.members.filter(
|
||||
(member) => member.nickname && member.nickname.includes(state.searchMemberByAlphabet)
|
||||
)
|
||||
return {
|
||||
...group,
|
||||
members: filteredMembers
|
||||
}
|
||||
})
|
||||
// 只保留有成员的分组
|
||||
.filter((group) => group.members.length > 0)
|
||||
)
|
||||
}
|
||||
return dialogueStore.membersByAlphabet
|
||||
})
|
||||
|
||||
const isShowEditor = computed(() => dialogueStore.isShowEditor)
|
||||
|
||||
// 当前对话参数
|
||||
@ -31,7 +53,7 @@ const talkParams = reactive({
|
||||
online: computed(() => dialogueStore.online),
|
||||
keyboard: computed(() => dialogueStore.keyboard),
|
||||
num: computed(() => dialogueStore.members.length),
|
||||
avatar:computed(() => dialogueStore.talk.avatar),
|
||||
avatar: computed(() => dialogueStore.talk.avatar),
|
||||
specifiedMsg: computed(() => dialogueStore.specifiedMsg)
|
||||
})
|
||||
|
||||
@ -46,8 +68,8 @@ const state = reactive({
|
||||
backgroundColor: '#F9F9FD'
|
||||
}, //按条件搜索记录弹窗样式
|
||||
searchRecordByConditionText: '', //按条件搜索记录文本
|
||||
conditionTag: '', //当前条件标签
|
||||
conditionType: '', //当前条件类型
|
||||
conditionTag: 'all', //当前条件标签
|
||||
conditionType: 'all', //当前条件类型
|
||||
isShowGroupNoticeModal: false, //是否显示群公告模态框
|
||||
customGroupNoticeModalStyle: {
|
||||
width: '997px',
|
||||
@ -81,7 +103,14 @@ const state = reactive({
|
||||
content: ''
|
||||
}, //群公告信息
|
||||
isAdmin: false, //当前登录用户是否是该群管理员
|
||||
groupNoticeContentChange: '' //群公告内容变化
|
||||
groupNoticeContentChange: '', //群公告内容变化
|
||||
searchMemberByAlphabet: '', //群成员搜索文本
|
||||
searchMemberItem: '', //群成员搜索item
|
||||
showMemberListByAlphabetPopover: false, // 控制群成员弹窗显示
|
||||
disabledDateArray: [] as string[], // 被禁用的日期数组
|
||||
selectedDateTime: null, // 选中的日期时间戳格式
|
||||
nowDateTime: new Date(), // 当前日期时间
|
||||
showDateConditionPopover: false // 控制日期条件弹窗显示
|
||||
})
|
||||
|
||||
const events = {
|
||||
@ -118,7 +147,7 @@ const changeConditionTag = (tag) => {
|
||||
} else if (tag === 'member') {
|
||||
state.conditionTag = '群成员'
|
||||
} else {
|
||||
state.conditionTag = ''
|
||||
state.conditionTag = 'all'
|
||||
}
|
||||
}
|
||||
|
||||
@ -370,13 +399,94 @@ const handleGroupNoticeModalShow = (isAdmin) => {
|
||||
state.isShowGroupNoticeModal = true
|
||||
getGroupNotices()
|
||||
}
|
||||
//点击群成员类型搜索聊天记录下的群成员item
|
||||
const handleMemberItemClick = (memberItem) => {
|
||||
state.searchMemberItem = encodeURIComponent(JSON.stringify(memberItem))
|
||||
state.showMemberListByAlphabetPopover = false // 关闭弹窗
|
||||
state.searchMemberByAlphabet = ''
|
||||
}
|
||||
//清空按A-Z排序下搜索群成员关键字
|
||||
const clearSearchMemberByAlphabet = () => {
|
||||
state.searchMemberByAlphabet = ''
|
||||
}
|
||||
|
||||
// 搜索记录模态框关闭事件
|
||||
const handleSearchRecordByConditionModalClose = () => {
|
||||
state.isShowSearchRecordByConditionModal = false
|
||||
resetSearchRecordByCondition()
|
||||
}
|
||||
|
||||
// 重置搜索记录模态框
|
||||
const resetSearchRecordByCondition = () => {
|
||||
state.searchRecordByConditionText = ''
|
||||
state.conditionType = 'all'
|
||||
state.conditionTag = 'all'
|
||||
state.searchMemberItem = ''
|
||||
state.showMemberListByAlphabetPopover = false
|
||||
state.searchMemberByAlphabet = ''
|
||||
}
|
||||
|
||||
//禁用的日期
|
||||
const dateDisabled = (e) => {
|
||||
const date = new Date(e)
|
||||
const year = date.getFullYear()
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(date.getDate()).padStart(2, '0')
|
||||
const formattedDate = `${year}/${month}/${day}`
|
||||
return state.disabledDateArray.includes(formattedDate)
|
||||
}
|
||||
|
||||
// 获取禁用日期
|
||||
const getDisabledDateArray = (disabledDateArray) => {
|
||||
state.disabledDateArray = disabledDateArray
|
||||
}
|
||||
|
||||
// 日期选择器确认事件
|
||||
const onDatePickConfirm = (datePicker) => {
|
||||
console.log(datePicker)
|
||||
state.selectedDateTime = datePicker
|
||||
state.showDateConditionPopover = false
|
||||
}
|
||||
|
||||
// 日期选择器清除事件
|
||||
const onDatePickClear = () => {
|
||||
state.selectedDateTime = null
|
||||
state.showDateConditionPopover = false
|
||||
state.nowDateTime = new Date()
|
||||
}
|
||||
|
||||
// 日期选择器前一个月事件
|
||||
const onPrevMonth = () => {
|
||||
state.nowDateTime = new Date(state.nowDateTime.getFullYear(), state.nowDateTime.getMonth() - 1, 1)
|
||||
}
|
||||
|
||||
// 日期选择器后一个月事件
|
||||
const onNextMonth = () => {
|
||||
state.nowDateTime = new Date(state.nowDateTime.getFullYear(), state.nowDateTime.getMonth() + 1, 1)
|
||||
}
|
||||
|
||||
// 日期选择器前一年事件
|
||||
const onPrevYear = () => {
|
||||
state.nowDateTime = new Date(state.nowDateTime.getFullYear() - 1, state.nowDateTime.getMonth(), 1)
|
||||
}
|
||||
|
||||
// 日期选择器后一年事件
|
||||
const onNextYear = () => {
|
||||
state.nowDateTime = new Date(state.nowDateTime.getFullYear() + 1, state.nowDateTime.getMonth(), 1)
|
||||
}
|
||||
|
||||
// 日期选择器显示事件(其实是popover显示事件)
|
||||
const onDatePickShow = (show) => {
|
||||
if (show) {
|
||||
// state.nowDateTime = new Date()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section id="drawer-container" class="el-container is-vertical">
|
||||
<!-- 头部区域 -->
|
||||
<header class="el-header bdr-b">
|
||||
|
||||
<PanelHeader
|
||||
:type="talkParams.type"
|
||||
:username="talkParams.username"
|
||||
@ -468,6 +578,8 @@ const handleGroupNoticeModalShow = (isAdmin) => {
|
||||
:style="state.customSearchRecordByConditionModalStyle"
|
||||
:customCloseBtn="true"
|
||||
:closable="false"
|
||||
:customCloseEvent="true"
|
||||
@customCloseModal="handleSearchRecordByConditionModalClose"
|
||||
>
|
||||
<template #content>
|
||||
<div class="search-record-modal-searchArea">
|
||||
@ -484,7 +596,11 @@ const handleGroupNoticeModalShow = (isAdmin) => {
|
||||
<img src="@/assets/image/icon/close-btn-grey-line.png" alt="close" />
|
||||
</template>
|
||||
<template #prefix>
|
||||
<n-tag closable v-if="state.conditionTag" @close="changeConditionTag('')">
|
||||
<n-tag
|
||||
closable
|
||||
v-if="state.conditionTag && state.conditionTag !== 'all'"
|
||||
@close="changeConditionTag('all')"
|
||||
>
|
||||
{{ state.conditionTag }}
|
||||
</n-tag>
|
||||
</template>
|
||||
@ -493,23 +609,87 @@ const handleGroupNoticeModalShow = (isAdmin) => {
|
||||
<div class="search-area-condition">
|
||||
<span @click="changeConditionTag('file')">文件</span>
|
||||
<span @click="changeConditionTag('imgAndVideo')">图片与视频</span>
|
||||
<n-popover trigger="click" placement="bottom-start" style="height: 312px; padding: 0;">
|
||||
<n-popover
|
||||
v-model:show="state.showDateConditionPopover"
|
||||
trigger="click"
|
||||
placement="bottom-start"
|
||||
style="height: 312px; padding: 0;"
|
||||
@update:show="onDatePickShow"
|
||||
>
|
||||
<template #trigger>
|
||||
<span id="date-condition" @click="changeConditionTag('date')">日期</span>
|
||||
</template>
|
||||
<historyRecord conditionType="dateTimePicker" v-if="state.conditionType === 'date'" />
|
||||
<div class="search-by-date">
|
||||
<n-date-picker
|
||||
:panel="true"
|
||||
type="datetime"
|
||||
:clearable="true"
|
||||
:first-day-of-week="6"
|
||||
:is-date-disabled="dateDisabled"
|
||||
:actions="['clear', 'confirm']"
|
||||
@confirm="onDatePickConfirm"
|
||||
@clear="onDatePickClear"
|
||||
@prev-month="onPrevMonth"
|
||||
@next-month="onNextMonth"
|
||||
@prev-year="onPrevYear"
|
||||
@next-year="onNextYear"
|
||||
v-model:value="state.selectedDateTime"
|
||||
/>
|
||||
</div>
|
||||
</n-popover>
|
||||
<n-popover
|
||||
v-model:show="state.showMemberListByAlphabetPopover"
|
||||
trigger="click"
|
||||
placement="bottom-start"
|
||||
style="height: 505px; padding: 0;"
|
||||
style="width: 290px; height: 505px; padding: 0;"
|
||||
v-if="talkParams.type === 2"
|
||||
>
|
||||
<template #trigger>
|
||||
<span @click="changeConditionTag('member')">群成员</span>
|
||||
</template>
|
||||
<div>
|
||||
<text>这里是memberList</text>
|
||||
<div class="member-list-by-alphabet-container">
|
||||
<n-input
|
||||
placeholder="请输入群成员"
|
||||
style="margin: 0 0 17px;"
|
||||
v-model:value="state.searchMemberByAlphabet"
|
||||
/>
|
||||
<n-scrollbar style="height: 430px;">
|
||||
<div
|
||||
class="member-list-by-alphabet"
|
||||
v-for="(alphabetMembersItem, alphabetMembersIndex) in membersByAlphabet"
|
||||
:key="alphabetMembersIndex"
|
||||
>
|
||||
<div class="member-list-each-alphabet-header">
|
||||
<span>{{ (alphabetMembersItem as any).alphabet }}</span>
|
||||
</div>
|
||||
<div class="member-list-each-alphabet">
|
||||
<div
|
||||
class="member-item-each-alphabet"
|
||||
v-for="(memberItem, memberItemIndex) in (alphabetMembersItem as any).members"
|
||||
:key="memberItemIndex"
|
||||
@click="handleMemberItemClick(memberItem)"
|
||||
>
|
||||
<avatarModule
|
||||
:mode="1"
|
||||
:avatar="memberItem.avatar"
|
||||
:userName="memberItem.nickname"
|
||||
:groupType="0"
|
||||
:customStyle="{
|
||||
width: '38px',
|
||||
height: '38px'
|
||||
}"
|
||||
:customTextStyle="{
|
||||
fontSize: '12px',
|
||||
fontWeight: 'bold',
|
||||
color: '#fff',
|
||||
lineHeight: '17px'
|
||||
}"
|
||||
></avatarModule>
|
||||
<span>{{ memberItem.nickname }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</n-scrollbar>
|
||||
</div>
|
||||
</n-popover>
|
||||
</div>
|
||||
@ -517,18 +697,16 @@ const handleGroupNoticeModalShow = (isAdmin) => {
|
||||
</div>
|
||||
<div class="search-record-modal-content">
|
||||
<n-card>
|
||||
<div
|
||||
class="search-record-card"
|
||||
v-if="state.searchRecordByConditionText || state.conditionType"
|
||||
>
|
||||
<historyRecord :conditionType="state.conditionType" />
|
||||
</div>
|
||||
<div
|
||||
class="search-record-empty"
|
||||
v-if="!state.searchRecordByConditionText && !state.conditionType"
|
||||
>
|
||||
<img src="@/assets/image/chatList/search-empty.png" alt="" />
|
||||
<span>无内容</span>
|
||||
<div class="search-record-card">
|
||||
<historyRecord
|
||||
:conditionType="state.conditionType"
|
||||
:searchMemberItem="state.searchMemberItem"
|
||||
@clearSearchMemberByAlphabet="clearSearchMemberByAlphabet"
|
||||
:searchRecordByConditionText="state.searchRecordByConditionText"
|
||||
@getDisabledDateArray="getDisabledDateArray"
|
||||
:selectedDateTime="state.selectedDateTime"
|
||||
:nowDateTime="state.nowDateTime"
|
||||
/>
|
||||
</div>
|
||||
</n-card>
|
||||
</div>
|
||||
@ -663,6 +841,11 @@ const handleGroupNoticeModalShow = (isAdmin) => {
|
||||
}
|
||||
}
|
||||
}
|
||||
.search-by-date {
|
||||
:deep(.n-date-panel-header) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.search-record-modal-content {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
@ -677,24 +860,6 @@ const handleGroupNoticeModalShow = (isAdmin) => {
|
||||
}
|
||||
.search-record-card {
|
||||
}
|
||||
.search-record-empty {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 455px;
|
||||
box-sizing: border-box;
|
||||
img {
|
||||
width: 160px;
|
||||
height: 104px;
|
||||
}
|
||||
span {
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
font-weight: 400;
|
||||
margin: 13px 0 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
.group-notice-modal-content {
|
||||
.group-notice-text-area {
|
||||
@ -772,4 +937,43 @@ const handleGroupNoticeModalShow = (isAdmin) => {
|
||||
color: #1f2225;
|
||||
}
|
||||
}
|
||||
|
||||
.member-list-by-alphabet-container {
|
||||
padding: 12px;
|
||||
width: 290px;
|
||||
.member-list-by-alphabet {
|
||||
.member-list-each-alphabet-header {
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
span {
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
font-weight: 400;
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
.member-list-each-alphabet {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
padding: 12px 0;
|
||||
.member-item-each-alphabet {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
gap: 10px;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
span {
|
||||
font-size: 12px;
|
||||
color: #000;
|
||||
font-weight: 400;
|
||||
line-height: 17px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -298,13 +298,6 @@ const items = computed((): ISession[] => {
|
||||
|
||||
return [...topItems, ...normalItems]
|
||||
})
|
||||
watch(
|
||||
() => talkStore,
|
||||
(newValue, oldValue) => {
|
||||
// console.log(newValue)
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
)
|
||||
watch(
|
||||
() => state.addressBookSearchNickName,
|
||||
(newValue, oldValue) => {
|
||||
|
@ -95,7 +95,6 @@ const onPanelScroll = (e: any) => {
|
||||
if (!skipBottom.value && dialogueStore.unreadBubble) {
|
||||
dialogueStore.setUnreadBubble(0)
|
||||
}
|
||||
|
||||
// 检测是否到达底部
|
||||
if (skipBottom.value == false) {
|
||||
let len = dialogueStore.records.length
|
||||
@ -232,7 +231,7 @@ const onClickNickname = (data: ITalkRecord) => {
|
||||
|
||||
// 会话列表右键显示菜单
|
||||
const onContextMenu = (e: any, item: ITalkRecord) => {
|
||||
console.log('item',item)
|
||||
|
||||
if (!dialogueStore.isShowEditor || dialogueStore.isOpenMultiSelect) {
|
||||
return e.preventDefault()
|
||||
}
|
||||
@ -243,7 +242,7 @@ const onContextMenu = (e: any, item: ITalkRecord) => {
|
||||
}
|
||||
|
||||
const onConvertText = async (data: ITalkRecord) => {
|
||||
console.log('data', data)
|
||||
|
||||
data.is_convert_text = 1
|
||||
const res = await voiceToText({ msgId: data.msg_id, voiceUrl: data.extra.url })
|
||||
if (res.code == 200) {
|
||||
@ -324,13 +323,14 @@ const retry=(item:any)=>{
|
||||
}
|
||||
|
||||
const onContextMenuAvatar=(e:any,item:any)=>{
|
||||
console.log('item',item)
|
||||
e.preventDefault()
|
||||
if(item.float!=='right'){
|
||||
bus.emit(EditorConst.Mention, {
|
||||
id: item.user_id,
|
||||
value: item.nickname
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { ref, onMounted, nextTick } from 'vue'
|
||||
import {
|
||||
useTalkStore,
|
||||
useDialogueStore,
|
||||
@ -15,7 +15,8 @@ import { parseTime } from '@/utils/datetime'
|
||||
import Editor from '@/components/editor/Editor.vue'
|
||||
import MultiSelectFooter from './MultiSelectFooter.vue'
|
||||
import HistoryRecord from '@/components/talk/HistoryRecord.vue'
|
||||
import { uploadImg } from '@/api/upload'
|
||||
import {scrollToBottom} from '@/utils/dom.ts'
|
||||
import SimpleEditorExample from '@/components/editor/SimpleEditorExample.vue'
|
||||
const userStore = useUserStore()
|
||||
const talkStore = useTalkStore()
|
||||
const editorStore = useEditorStore()
|
||||
@ -135,6 +136,9 @@ const onSendVideoEvent = async ({ data }) => {
|
||||
|
||||
// 直接添加到对话记录中
|
||||
dialogueStore.addDialogueRecord(tempMessage)
|
||||
nextTick(()=>{
|
||||
scrollToBottom()
|
||||
})
|
||||
uploadsStore.initUploadFile(
|
||||
data,
|
||||
props.talk_type,
|
||||
@ -145,6 +149,7 @@ const onSendVideoEvent = async ({ data }) => {
|
||||
},
|
||||
async () => {
|
||||
dialogueStore.batchDelDialogueRecord([uploadId])
|
||||
|
||||
}
|
||||
)
|
||||
}
|
||||
@ -185,13 +190,16 @@ const onSendFileEvent = ({ data }) => {
|
||||
float: 'right'
|
||||
}
|
||||
dialogueStore.addDialogueRecord(tempMessage)
|
||||
|
||||
nextTick(()=>{
|
||||
scrollToBottom()
|
||||
})
|
||||
uploadsStore.initUploadFile(data, props.talk_type, props.receiver_id,clientUploadId,
|
||||
async (percentage) => {
|
||||
dialogueStore.updateUploadProgress(clientUploadId, percentage)
|
||||
},
|
||||
async () => {
|
||||
dialogueStore.batchDelDialogueRecord([clientUploadId])
|
||||
|
||||
}
|
||||
)
|
||||
}
|
||||
@ -282,6 +290,7 @@ onMounted(() => {
|
||||
<template>
|
||||
<footer class="el-footer">
|
||||
<MultiSelectFooter v-if="dialogueStore.isOpenMultiSelect" />
|
||||
|
||||
<Editor v-else @editor-event="onEditorEvent" :vote="talk_type == 2" :members="members" />
|
||||
</footer>
|
||||
|
||||
|
@ -156,7 +156,7 @@ const onSetMenu = () => {
|
||||
text-align: center;
|
||||
|
||||
&.color {
|
||||
color: #1890ff;
|
||||
color: #462AA0;
|
||||
}
|
||||
|
||||
.online-status {
|
||||
@ -168,7 +168,7 @@ const onSetMenu = () => {
|
||||
vertical-align: middle;
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
background-color: #1890ff;
|
||||
background-color: #462AA0;
|
||||
margin-right: 5px;
|
||||
|
||||
&:after {
|
||||
@ -177,7 +177,7 @@ const onSetMenu = () => {
|
||||
left: -1px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 1px solid #1890ff;
|
||||
border: 1px solid #462AA0;
|
||||
border-radius: 50%;
|
||||
-webkit-animation: antStatusProcessing 1.2s ease-in-out infinite;
|
||||
animation: antStatusProcessing 1.2s ease-in-out infinite;
|
||||
|
@ -1,6 +1,8 @@
|
||||
<script lang="ts" setup>
|
||||
import { useDialogueStore } from '@/store'
|
||||
import { DoubleDown } from '@icon-park/vue-next'
|
||||
import { scrollToBottom } from '@/utils/dom'
|
||||
|
||||
defineProps(['modelValue'])
|
||||
|
||||
const dialogueStore = useDialogueStore()
|
||||
@ -8,13 +10,7 @@ const dialogueStore = useDialogueStore()
|
||||
// 聊天版本滚动到底部
|
||||
const onSkipBottom = () => {
|
||||
console.log('onSkipBottom')
|
||||
let el = document.getElementById('imChatPanel')
|
||||
if (el) {
|
||||
el.scrollTo({
|
||||
top: el.scrollHeight + 1000,
|
||||
behavior: 'smooth'
|
||||
})
|
||||
}
|
||||
scrollToBottom()
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -35,7 +31,7 @@ const onSkipBottom = () => {
|
||||
min-width: 100px;
|
||||
height: 28px;
|
||||
font-size: 12px;
|
||||
background-color: #1ebafc;
|
||||
background-color: #462AA0;
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
@ -47,7 +47,7 @@ export default defineConfig(({ mode }) => {
|
||||
compressPlugin(),
|
||||
UnoCSS(),
|
||||
vueDevTools({
|
||||
launchEditor: 'cursor',
|
||||
launchEditor: 'trae',
|
||||
})
|
||||
],
|
||||
define: {
|
||||
|
Loading…
Reference in New Issue
Block a user