Merge branch 'wyfMain-dev'
Some checks are pending
Check / lint (push) Waiting to run
Check / typecheck (push) Waiting to run
Check / build (build, 18.x, ubuntu-latest) (push) Waiting to run
Check / build (build, 18.x, windows-latest) (push) Waiting to run
Check / build (build:app, 18.x, ubuntu-latest) (push) Waiting to run
Check / build (build:app, 18.x, windows-latest) (push) Waiting to run
Check / build (build:mp-weixin, 18.x, ubuntu-latest) (push) Waiting to run
Check / build (build:mp-weixin, 18.x, windows-latest) (push) Waiting to run
Some checks are pending
Check / lint (push) Waiting to run
Check / typecheck (push) Waiting to run
Check / build (build, 18.x, ubuntu-latest) (push) Waiting to run
Check / build (build, 18.x, windows-latest) (push) Waiting to run
Check / build (build:app, 18.x, ubuntu-latest) (push) Waiting to run
Check / build (build:app, 18.x, windows-latest) (push) Waiting to run
Check / build (build:mp-weixin, 18.x, ubuntu-latest) (push) Waiting to run
Check / build (build:mp-weixin, 18.x, windows-latest) (push) Waiting to run
This commit is contained in:
commit
b7eea81200
@ -263,9 +263,20 @@
|
||||
@editorChange="onEditorChange"
|
||||
style="width: 100%; flex: 1; height: 100%;"
|
||||
@click="onEditorClick"
|
||||
v-if="state.canUseQuillEditor"
|
||||
/>
|
||||
<!-- <tm-input type=textarea autoHeight focusColor="#F9F9F9" color="#F9F9F9" :inputPadding="[12]"
|
||||
placeholder=""></tm-input> -->
|
||||
<tm-input
|
||||
type="textarea"
|
||||
autoHeight
|
||||
focusColor="#F9F9F9"
|
||||
color="#F9F9F9"
|
||||
:inputPadding="[12]"
|
||||
placeholder=""
|
||||
v-if="!state.canUseQuillEditor"
|
||||
@update:modelValue="onTextAreaChange"
|
||||
v-model="state.textAreaValue"
|
||||
@input="onTextAreaInput"
|
||||
></tm-input>
|
||||
<div class="quote-area" v-if="state?.quoteInfo">
|
||||
<span
|
||||
v-if="state?.quoteInfo?.msg_type === 1"
|
||||
@ -326,7 +337,17 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="state.isOpenEmojiPanel" class="mt-[50rpx]">
|
||||
<emojiPanel @on-select="onEmoticonEvent" />
|
||||
<emojiPanel
|
||||
@on-select="
|
||||
(data) => {
|
||||
if (!state.canUseQuillEditor) {
|
||||
onTextAreaEmoticon(data)
|
||||
} else {
|
||||
onEmoticonEvent(data)
|
||||
}
|
||||
}
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="state.isOpenFilePanel" class="mt-[16rpx]">
|
||||
<filePanel
|
||||
@ -629,6 +650,8 @@ const state = ref({
|
||||
lastMentionPosition: -1, // 添加新的状态来记录上一次@的位置
|
||||
isLoading: false, //发送按钮loading
|
||||
lastSelection: 0,
|
||||
canUseQuillEditor: true, //是否可以使用quill编辑器,如果版本不支持,则使用普通输入框
|
||||
textAreaValue: '', //普通输入框的值
|
||||
})
|
||||
|
||||
uniOnload(async (options) => {
|
||||
@ -728,7 +751,78 @@ const onSendMessage = (data = {}, callBack, showLoading = false) => {
|
||||
})
|
||||
}
|
||||
|
||||
const onTextAreaChange = (value) => {
|
||||
state.value.textAreaValue = value
|
||||
|
||||
// 更新mentionUserIds数组,确保与输入框中的@内容一致
|
||||
const atPattern = /@([^@\s]+)(?:\s|$)/g
|
||||
const matches = Array.from(value.matchAll(atPattern))
|
||||
const mentionedUsers = matches.map((match) => match[1].trim().toLowerCase())
|
||||
|
||||
// 获取当前对话中的所有成员信息
|
||||
const members = dialogueStore.members || []
|
||||
|
||||
// 根据@的用户名找到对应的user_id
|
||||
const newMentionUserIds = mentionedUsers
|
||||
.map((username) => {
|
||||
if (username === '所有人') {
|
||||
return 0 // 如果是@所有人,返回0
|
||||
}
|
||||
const member = members.find(
|
||||
(m) => m.nickname.trim().toLowerCase() === username,
|
||||
)
|
||||
return member ? member.id : null
|
||||
})
|
||||
.filter((id) => id !== null)
|
||||
|
||||
// 只有在输入框中有@内容时才更新mentionUserIds
|
||||
if (value.includes('@')) {
|
||||
state.value.mentionUserIds = newMentionUserIds
|
||||
} else {
|
||||
state.value.mentionUserIds = []
|
||||
}
|
||||
}
|
||||
|
||||
// 处理输入框输入事件
|
||||
const onTextAreaInput = (value) => {
|
||||
console.log(value, 'value')
|
||||
if (value.length > 0) {
|
||||
if (value[value.length - 1] === '@') {
|
||||
if (talkParams.type === 1) {
|
||||
return
|
||||
}
|
||||
state.value.isShowMentionSelect = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const onSendMessageClick = () => {
|
||||
if (!state.value.canUseQuillEditor) {
|
||||
// 处理普通输入框的发送消息
|
||||
if (state.value.textAreaValue.trim() === '') {
|
||||
return
|
||||
}
|
||||
if (state.value.textAreaValue.length > 1024) {
|
||||
return message.warning('发送内容超长,请分条发送')
|
||||
}
|
||||
let message = {
|
||||
type: 'text',
|
||||
content: state.value.textAreaValue,
|
||||
quote_id: state.value.quoteInfo ? state.value.quoteInfo.msg_id : null, // 添加quote_id
|
||||
mentions: state.value.mentionUserIds, // 使用最终的用户ID数组
|
||||
}
|
||||
console.log(message)
|
||||
onSendMessage(
|
||||
message,
|
||||
(ok) => {
|
||||
if (!ok) return
|
||||
state.value.textAreaValue = ''
|
||||
state.value.quoteInfo = null // 发送后清除引用信息
|
||||
},
|
||||
true,
|
||||
)
|
||||
return
|
||||
}
|
||||
// 发送前确保 mentionUserIds 是最新的
|
||||
updateMentionUserIds()
|
||||
|
||||
@ -879,8 +973,46 @@ const onEmoticonEvent = (data) => {
|
||||
emit('editor-event', fn)
|
||||
}
|
||||
}
|
||||
|
||||
let calcDelta = false
|
||||
const onEditorChange = () => {
|
||||
if(calcDelta){
|
||||
calcDelta = false
|
||||
return
|
||||
}
|
||||
// 以下逻辑是 光标与@之间存在其他内容时 不触发选人弹窗
|
||||
const qtext = getQuill().getText()
|
||||
let selectIdx = getQuill().getSelection().index
|
||||
const textBeforeCursor = qtext.substring(0, selectIdx)
|
||||
if (textBeforeCursor[0]?.charCodeAt(0) === 10) {
|
||||
const delta = getQuill().getContents()
|
||||
const ops = delta.ops || []
|
||||
if (ops[0].insert === '\n') {
|
||||
ops.splice(0, 1)
|
||||
getQuill().setContents(delta)
|
||||
getQuill().setSelection(getQuill().getText().length, 0)
|
||||
}
|
||||
// for (let i = 0; i < ops.length; i++) {
|
||||
// if (ops[i].insert === '\n') {
|
||||
// console.error('有空格')
|
||||
// ops.splice(i, 1)
|
||||
// calcDelta = true
|
||||
// }
|
||||
// }
|
||||
// getQuill().setContents(delta)
|
||||
// getQuill().setSelection(getQuill().getText().length, 0)
|
||||
}
|
||||
let endWithAt = false
|
||||
if (
|
||||
textBeforeCursor[textBeforeCursor.length - 1] === '@' ||
|
||||
textBeforeCursor[textBeforeCursor.length - 2]?.charCodeAt(0) === 64
|
||||
) {
|
||||
endWithAt = true
|
||||
}
|
||||
if (endWithAt) {
|
||||
state.value.cursorMention = true
|
||||
} else {
|
||||
state.value.cursorMention = false
|
||||
}
|
||||
if (getQuill().getText() !== state.value.lastMentionText) {
|
||||
state.value.lastMentionTriggered = false
|
||||
}
|
||||
@ -1350,6 +1482,11 @@ const clearMultiSelect = () => {
|
||||
|
||||
const initData = async () => {
|
||||
const dialogueList = getDialogueList(talkParams.index_name)
|
||||
let doLocalPaging = false
|
||||
if(dialogueList?.records?.length > 0){
|
||||
doLocalPaging = true
|
||||
}
|
||||
console.error('dialogueList', dialogueList)
|
||||
|
||||
let objT = {
|
||||
uid: talkParams.uid,
|
||||
@ -1360,7 +1497,9 @@ const initData = async () => {
|
||||
no_limit: dialogueList ? 1 : 0,
|
||||
}
|
||||
await onLoad({ ...objT })
|
||||
zpagingRef.value?.setLocalPaging(records.value)
|
||||
if(doLocalPaging){
|
||||
zpagingRef.value?.setLocalPaging(dialogueList.records)
|
||||
}
|
||||
}
|
||||
|
||||
//点击跳转到聊天设置页面
|
||||
@ -1404,6 +1543,10 @@ const confirmMentionSelect = () => {
|
||||
selectMemberByAlphabetRef.value.confirmSelectMembers()
|
||||
}
|
||||
hideMentionSelect()
|
||||
|
||||
// 重置选中人数和多选状态
|
||||
state.value.selectedMembersNum = 0
|
||||
state.value.mentionIsMulSelect = false
|
||||
}
|
||||
}
|
||||
|
||||
@ -1415,6 +1558,14 @@ const getSelectResult = (mentionSelect) => {
|
||||
|
||||
//处理要提醒人的消息样式
|
||||
const getMentionSelectLists = (mentionSelectList) => {
|
||||
if (!state.value.canUseQuillEditor) {
|
||||
if (mentionSelectList.length > 0) {
|
||||
mentionSelectList.forEach((item) => {
|
||||
onTextAreaMention(item)
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
const quill = getQuill()
|
||||
const mention = quill.getModule('mention')
|
||||
|
||||
@ -1648,7 +1799,11 @@ let currentPressItem = null
|
||||
const handleAvatarTouchStart = (item) => {
|
||||
currentPressItem = item
|
||||
avatarPressTimer = setTimeout(() => {
|
||||
doMentionUser(item)
|
||||
if (!state.value.canUseQuillEditor) {
|
||||
onTextAreaMention(item)
|
||||
} else {
|
||||
doMentionUser(item)
|
||||
}
|
||||
}, 500)
|
||||
}
|
||||
|
||||
@ -1661,6 +1816,13 @@ const handleAvatarTouchEnd = () => {
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
if (uni.getSystemInfoSync().osName === 'ios') {
|
||||
let versions = uni.getSystemInfoSync().osVersion.split('.')
|
||||
if (Number(versions[0]) < 17) {
|
||||
console.error('ios版本低于17')
|
||||
state.value.canUseQuillEditor = false
|
||||
}
|
||||
}
|
||||
if (typeof plus !== 'undefined') {
|
||||
const webview = plus.webview.currentWebview()
|
||||
webview.setStyle({
|
||||
@ -1716,23 +1878,9 @@ onUnmounted(() => {
|
||||
// 修改防抖函数的实现
|
||||
const showMentionSelectDebounced = (quill) => {
|
||||
const text = quill.getText()
|
||||
|
||||
// 以下逻辑是 光标与@之间存在其他内容时 不触发选人弹窗
|
||||
const selection = quill.getSelection()
|
||||
if (selection) {
|
||||
state.lastSelection = selection.index
|
||||
if (
|
||||
text[selection.index - 1].charCodeAt(0) !== 64 &&
|
||||
text[selection.index - 1].charCodeAt(0) !== 32 &&
|
||||
text[selection.index - 1].charCodeAt(0) !== 10
|
||||
) {
|
||||
uni.showToast({
|
||||
title: text[selection.index - 1],
|
||||
icon: 'none',
|
||||
})
|
||||
state.value.lastMentionTriggered = false
|
||||
return
|
||||
}
|
||||
// 光标不在@后第一位时,不触发选人弹窗
|
||||
if (!state.value.cursorMention) {
|
||||
return
|
||||
}
|
||||
// 以下逻辑是 记录触发@时,用户的输入框内容,下次一样内容得@不会再次触发
|
||||
if (text !== state.value.lastMentionText) {
|
||||
@ -1749,6 +1897,45 @@ const showMentionSelectDebounced = (quill) => {
|
||||
state.value.isShowMentionSelect = true
|
||||
// quill.blur()
|
||||
}
|
||||
|
||||
// 处理普通输入框的表情插入
|
||||
const onTextAreaEmoticon = (data) => {
|
||||
if (data.type == 1) {
|
||||
if (data.img) {
|
||||
// 如果是图片表情,插入对应的文本标记
|
||||
state.value.textAreaValue += `${data.value}`
|
||||
} else {
|
||||
// 如果是文本表情,直接插入
|
||||
state.value.textAreaValue += data.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理普通输入框的长按@功能
|
||||
const onTextAreaMention = (user) => {
|
||||
if (talkParams.type === 1) {
|
||||
return
|
||||
}
|
||||
if (state.value.textAreaValue.length > 0) {
|
||||
if (
|
||||
state.value.textAreaValue[state.value.textAreaValue.length - 1] === '@'
|
||||
) {
|
||||
state.value.textAreaValue = state.value.textAreaValue.slice(0, -1)
|
||||
}
|
||||
}
|
||||
state.value.textAreaValue += `@${user.nickname} `
|
||||
|
||||
// 先创建新数组,再赋值
|
||||
const newMentionUserIds = state.value.mentionUserIds
|
||||
? [...state.value.mentionUserIds]
|
||||
: []
|
||||
newMentionUserIds.push(user.nickname === '所有人' ? 0 : user.id)
|
||||
state.value.mentionUserIds = newMentionUserIds
|
||||
|
||||
if (state.value.isShowMentionSelect) {
|
||||
state.value.isShowMentionSelect = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.dialog-page {
|
||||
@ -2045,6 +2232,11 @@ const showMentionSelectDebounced = (quill) => {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.round-3) {
|
||||
max-height: 320rpx;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.wd-action-sheet) {
|
||||
|
@ -23,7 +23,7 @@ class WsSocket {
|
||||
lockReconnect: false,
|
||||
setTimeout: null, // 计时器对象
|
||||
time: 3000, // 重连间隔时间
|
||||
number: 10000000 // 重连次数
|
||||
number: 20 // 重连次数
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user