Compare commits

...

7 Commits
main ... xingyy

Author SHA1 Message Date
Phoenix
3ec981ea7f fix: 修复文件上传和编辑器相关问题
- 启用vueDevTools插件用于开发调试
- 移除调试用的console.error/log语句
- 修复文件扩展名获取可能导致的错误
- 优化文件上传逻辑,添加path字段
- 重构编辑器图片上传处理,支持直接发送
- 调整编辑器样式颜色
2025-06-06 16:57:02 +08:00
Phoenix
7067c42b2b feat(editor): 添加Ionicons4图标并优化编辑器功能
- 新增@vicons/ionicons4依赖用于编辑器发送按钮
- 优化提及列表滚动行为,保持选中项可见
- 支持Ctrl+Enter/Shift+Enter换行功能
- 添加发送按钮和编辑器placeholder提示
- 修复引用消息id字段不一致问题
2025-06-06 14:49:38 +08:00
Phoenix
1ff26564c7 refactor(editor): 优化引用消息的点击事件处理逻辑
使用事件委托统一处理引用消息的点击事件,包括关闭按钮点击和光标定位
移除重复的事件监听器,简化代码结构
修复引用消息ID字段从msg_id改为id的匹配问题
2025-06-06 13:43:39 +08:00
Phoenix
b18a6e5432 feat(编辑器): 添加清除事件常量并优化提及功能
在事件总线常量中添加 editor:clear 事件类型
优化提及功能,确保编辑器获得焦点后光标位置正确
2025-06-06 12:00:12 +08:00
Phoenix
17c1368346 feat: 优化消息发送逻辑和编辑器功能
- 在vite配置中启用vueDevTools工具
- 重构PanelFooter.vue中的图片消息发送逻辑,改为直接调用onSendMessage
- 修改CustomEditor.vue的消息发送逻辑,支持分类型处理消息内容
- 增加编辑器引用元素的检查逻辑,避免无效引用
- 优化图片上传后的URL替换逻辑,确保编辑器内容更新
2025-06-06 11:52:55 +08:00
Phoenix
f279248a51 feat(编辑器): 增强编辑器功能并优化图片处理
- 添加对粘贴图片的支持,自动触发上传流程
- 优化图片插入逻辑,保留原始尺寸信息并改进显示效果
- 重构消息内容解析逻辑,完善数据结构
- 移除冗余的文件插入功能,专注于图片处理优化
- 调整编辑器样式,改进图片显示效果
2025-06-06 10:44:17 +08:00
Phoenix
c89056d7f1 edit 2025-06-05 16:21:39 +08:00
9 changed files with 1907 additions and 66 deletions

View File

@ -20,6 +20,7 @@
"@kangc/v-md-editor": "^2.3.18",
"@onlyoffice/document-editor-vue": "^1.5.0",
"@vicons/fluent": "^0.13.0",
"@vicons/ionicons4": "^0.13.0",
"@vicons/ionicons5": "^0.13.0",
"@vueup/vue-quill": "^1.2.0",
"@vueuse/core": "^10.7.0",

View File

@ -26,6 +26,9 @@ importers:
'@vicons/fluent':
specifier: ^0.13.0
version: 0.13.0
'@vicons/ionicons4':
specifier: ^0.13.0
version: 0.13.0
'@vicons/ionicons5':
specifier: ^0.13.0
version: 0.13.0
@ -1002,6 +1005,9 @@ packages:
'@vicons/fluent@0.13.0':
resolution: {integrity: sha512-bYGZsOE3qzvm3Cm43e7tybgGlr5ZUpYqtRZq0g0Tfupe8jIzLolpvQLNUt1zS8Mgt6goTbUk5YH7Fkv16jkykg==}
'@vicons/ionicons4@0.13.0':
resolution: {integrity: sha512-5WHIl/4R5a4i9GONa+hIQWxg/WczrbsCdqxawHZvdd3drsEr+Q3yzlfS+NNRO4WS3uDW2uWLCwoW+yp5TgcKeQ==}
'@vicons/ionicons5@0.13.0':
resolution: {integrity: sha512-zvZKBPjEXKN7AXNo2Na2uy+nvuv6SP4KAMQxpKL2vfHMj0fSvuw7JZcOPCjQC3e7ayssKnaoFVAhbYcW6v41qQ==}
@ -4411,6 +4417,8 @@ snapshots:
'@vicons/fluent@0.13.0': {}
'@vicons/ionicons4@0.13.0': {}
'@vicons/ionicons5@0.13.0': {}
'@vitejs/plugin-vue-jsx@3.1.0(vite@6.3.5(@types/node@18.19.99)(jiti@1.21.7)(less@4.3.0)(sass@1.88.0)(terser@5.39.2))(vue@3.5.13(typescript@5.2.2))':

File diff suppressed because it is too large Load Diff

View File

@ -64,8 +64,8 @@ const fileInfo = computed(() => {
//
function getFileExtension(filepath) {
const parts = filepath.split('.')
return parts.length > 1 ? parts.pop().toUpperCase() : ''
const parts = filepath?.split('.')
return parts?.length > 1 ? parts?.pop()?.toUpperCase() : ''
}
//

View File

@ -5,5 +5,6 @@ export const enum ContactConst {
export const enum EditorConst {
Mention = 'editor:mention',
Quote = 'editor:quote',
Edit = 'editor:edit'
Edit = 'editor:edit',
Clear = 'editor:clear'
}

View File

@ -190,8 +190,6 @@ export const useTalkRecord = (uid: number) => {
loadConfig.receiver_id = params.receiver_id
loadConfig.talk_type = params.talk_type
console.error('onLoad', params, options)
// 新增:支持指定消息定位模式,参数以传入为准合并
if (options?.specifiedMsg?.cursor !== undefined) {
loadConfig.specialParams = { ...options.specifiedMsg } // 记录特殊参数,供分页加载用

View File

@ -18,7 +18,7 @@ export function isLoggedIn() {
*/
export function getAccessToken() {
// return storage.get(AccessToken) || ''
return JSON.parse(localStorage.getItem('token'))||'46d71a72d8d845ad7ed23eba9bdde260e635407190c2ce1bf7fd22088e41682ea07773ec65cae8946d2003f264d55961f96e0fc5da10eb96d3a348c1664e9644ce2108c311309f398ae8ea1b8200bfd490e5cb6e8c52c9e5d493cbabb163368f8351420451a631dbfa749829ee4cda49b77b5ed2d3dced5d0f2b7dd9ee76ba5465c84a17c23af040cd92b6b2a4ea48befbb5c729dcdad0a9c9668befe84074cc24f78899c1d947f8e7f94c7eda5325b8ed698df729e76febb98549ef3482ae942fb4f4a1c92d21836fa784728f0c5483aab2760a991b6b36e6b10c84f840a6433a6ecc31dee36e8f1c6158818bc89d22726726265e9af0db370a54ea5ee002b43662d571b84c8468ac15330f79503a5cd5e72282d8bee92749b1a3c1b7fd87ae70b64b90e437e84c1b558c64a35e181b2ecf5db3007680c3607eac1edee7f59d'
return JSON.parse(localStorage.getItem('token'))||'46d71a72d8d845ad7ed23eba9bdde260e635407190c2ce1bf7fd22088e41682ea07773ec65cae8946d2003f264d55961f96e0fc5da10eb96d3a348c1664e9644ce2108c311309f398ae8ea1b8200bfd490e5cb6e8c52c9e5d493cbabb163368f8351420451a631dbfa749829ee4cda49b77b5ed2d3dced5d0f2b7dd9ee76ba5465c84a17c23af040cd92b6b2a4ea48befbb5c729dcdad0a9c9668befe84074cc24f78899c1d947f8e7f94c7eda5325b8ed698df729e76febb98549ef3482ae942fb4f4a1c92d21836fa784728f0c5483aab2760a991b6b36e6b10c84f840a6433a6ecc31dee36e8f1c6158818bc89d22403363066ad3c046839f7b2cf8a6186da017388f197c0c3b219b1c04e7d986e9774b72664a22a6075cee77da3584b7a2131365913796a5fcabc8f4594284e480a592a84a40a9aa7f5f27c951a53a369c'
}
/**

View File

@ -289,7 +289,6 @@ watch(
async (newProps) => {
await nextTick()
let specialParams = undefined
console.error(newProps, 'newProps')
if (newProps.specifiedMsg) {
try {
const parsed = JSON.parse(decodeURIComponent(newProps.specifiedMsg))

View File

@ -16,6 +16,7 @@ import Editor from '@/components/editor/Editor.vue'
import MultiSelectFooter from './MultiSelectFooter.vue'
import HistoryRecord from '@/components/talk/HistoryRecord.vue'
import {scrollToBottom} from '@/utils/dom.ts'
import CustomEditor from '@/components/editor/CustomEditor.vue'
const userStore = useUserStore()
const talkStore = useTalkStore()
const editorStore = useEditorStore()
@ -60,11 +61,11 @@ const onSendMessage = (data = {}, callBack: any) => {
}
ServePublishMessage(message)
.then(({ code, message }) => {
.then(({ code, message, msg }) => {
if (code == 200) {
callBack(true)
} else {
window['$message'].warning(message)
window['$message'].warning(message || msg)
}
})
.catch(() => {
@ -94,65 +95,13 @@ const onSendTextEvent = throttle((value: any) => {
}, 1000)
//
const onSendImageEvent = ({ data }) => {
console.log('onSendImageEvent')
// ID
const uploadId = `image-${Date.now()}-${Math.floor(Math.random() * 1000)}`
// URL
const previewUrl = URL.createObjectURL(data)
//
const tempMessage = {
msg_id: uploadId,
sequence: Date.now(),
talk_type: props.talk_type,
msg_type: 3, //
user_id: props.uid,
receiver_id: props.receiver_id,
is_revoke: 0,
is_mark: 0,
is_read: 1,
content: '',
created_at: parseTime(new Date(), '{y}-{m}-{d} {h}:{i}'),
extra: {
url: previewUrl, // 使URL
size: data.size,
is_uploading: true,
upload_id: uploadId,
percentage: 0
},
isCheck: false,
send_status: 1,
float: 'right' //
}
//
dialogueStore.addDialogueRecord(tempMessage)
nextTick(()=>{
scrollToBottom()
})
uploadsStore.initUploadFile(
data,
props.talk_type,
props.receiver_id,
uploadId,
async (percentage) => {
dialogueStore.updateUploadProgress(uploadId, percentage)
},
async () => {
// URL
URL.revokeObjectURL(previewUrl)
dialogueStore.batchDelDialogueRecord([uploadId])
}
)
const onSendImageEvent = ({ data, callBack }) => {
onSendMessage({ type: 'image', ...data }, callBack)
}
//
const onSendVideoEvent = async ({ data }) => {
console.log('onSendVideoEvent')
//
// let resp = await getVideoImage(data)
@ -217,7 +166,6 @@ const onSendFileEvent = ({ data }) => {
return window['$message'].warning('上传文件不能超过100M!')
}
const clientUploadId = `file-${Date.now()}-${Math.floor(Math.random() * 1000)}`
const tempMessage = {
msg_id: clientUploadId,
sequence: Date.now(),
@ -233,6 +181,7 @@ const onSendFileEvent = ({ data }) => {
extra: {
name: data.name,
url: '',
path:data.name,
size: data.size,
is_uploading: true,
upload_id: clientUploadId,
@ -342,7 +291,8 @@ onMounted(() => {
<footer class="el-footer">
<MultiSelectFooter v-if="dialogueStore.isOpenMultiSelect" />
<Editor v-else @editor-event="onEditorEvent" :vote="talk_type == 2" :members="members" />
<!-- <Editor v-else @editor-event="onEditorEvent" :vote="talk_type == 2" :members="members" /> -->
<CustomEditor v-else @editor-event="onEditorEvent" :vote="talk_type == 2" :members="members" />
</footer>
<HistoryRecord