Compare commits

...

4 Commits

Author SHA1 Message Date
5b4ee3c677 处理代码冲突——恢复已读未读功能 2025-06-05 16:32:31 +08:00
Phoenix
ef0eb903a7 feat(消息组件): 优化图片消息上传体验并修复文件扩展名获取
1. 在图片消息组件中添加上传进度显示和加载状态
2. 重构图片上传逻辑,先显示本地预览再上传
3. 修复文件消息组件中从文件名获取扩展名改为从文件路径获取
4. 根据消息浮动方向调整提及文本颜色

重构了图片上传流程,现在会先显示本地预览图片,然后在上传过程中显示进度条。同时修复了文件扩展名获取逻辑,现在从文件路径而非文件名获取扩展名。优化了提及文本的颜色显示,使其根据消息浮动方向(左/右)显示不同颜色。
2025-06-05 14:13:50 +08:00
Phoenix
f511244d59 Merge branch 'xingyy'
# Conflicts:
#	src/views/message/inner/panel/PanelContent.vue   resolved by xingyy version
2025-06-05 11:42:46 +08:00
Phoenix
a5a70391a4 feat: 添加ERP用户ID字段并优化多处功能
- 在ISession接口中添加erp_user_id字段以支持ERP系统集成
- 更新.env.test环境变量添加VITE_PAGE_URL配置
- 启用vueDevTools插件用于开发调试
- 移除好友删除选项以限制用户操作
- 优化消息发送逻辑,过滤空白内容
- 调整头像右键菜单触发条件
- 更新文件消息打开链接使用环境变量
- 修改会话菜单中用户信息跳转使用erp_user_id
- 更新默认access token值
2025-06-05 11:41:06 +08:00
11 changed files with 106 additions and 41 deletions

1
env/.env.test vendored
View File

@ -8,4 +8,5 @@ VUE_APP_PREVIEW=false
VITE_BASE_API=http://114.218.158.24:8503
VITE_SOCKET_API=ws://114.218.158.24:8504
VITE_EPR_BASEURL=http://114.218.158.24:9020
VITE_PAGE_URL=http://172.16.100.93:9032
VUE_APP_WEBSITE_NAME=""

View File

@ -363,22 +363,9 @@ async function onUploadFile(e: any) {
console.log("文件类型"+file.type)
if (file.type.indexOf('image/') === 0) {
console.log("进入图片")
//
const quill = getQuill()
let index = getQuillSelectionIndex()
//
if (index == 1 && quill.getLength() == 1 && quill.getText(0, 1) == '\n') {
quill.deleteText(0, 1)
index = 0
}
//
let src = await onUploadImage(file)
if (src) {
quill.insertEmbed(index, 'image', src)
quill.setSelection(index + 1)
}
// -
let fn = emitCall('image_event', file, () => {})
emit('editor-event', fn)
return
}
@ -437,8 +424,7 @@ function onClipboardMatcher(node: any, Delta) {
function onSendMessage() {
var delta = getQuill().getContents()
let data = deltaToMessage(delta) // Delta
if (data.items.length === 0) {
if (data.items.length === 0||!data.items[0].content.trim()) {
return //
}

View File

@ -49,7 +49,7 @@ const PPT_EXTENSIONS = ['PPT', 'PPTX', 'PPS', 'PPSX']
//
const fileInfo = computed(() => {
const extension = getFileExtension(props.extra.name)
const extension = getFileExtension(props.extra.path)
if (EXCEL_EXTENSIONS.includes(extension)) {
return fileTypes.EXCEL
}
@ -63,8 +63,8 @@ const fileInfo = computed(() => {
})
//
function getFileExtension(filename) {
const parts = filename.split('.')
function getFileExtension(filepath) {
const parts = filepath.split('.')
return parts.length > 1 ? parts.pop().toUpperCase() : ''
}
@ -88,7 +88,7 @@ const strokeDashoffset = computed(() =>
const handleClick = () => {
if(!props.extra.is_uploading){
window.open(
`${window.location.origin}/office?url=${props.extra.path}`,
`${import.meta.env.VITE_PAGE_URL}/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'
);

View File

@ -1,9 +1,9 @@
<script lang="ts" setup>
import { NImage } from 'naive-ui'
import { NImage, NSpin } from 'naive-ui'
import { getImageInfo } from '@/utils/functions'
import { ITalkRecordExtraImage, ITalkRecord } from '@/types/chat'
defineProps<{
const props = defineProps<{
extra: ITalkRecordExtraImage
data: ITalkRecord
maxWidth?: Boolean
@ -35,7 +35,13 @@ const img = (src: string, width = 200) => {
:class="{ left: data.float === 'left' }"
:style="img(extra.url, 350)"
>
<n-image class="h-149px" :src="extra.url" />
<div class="image-container">
<n-image class="h-149px" :src="extra.url" />
<!-- 上传中的loading蒙版 -->
<div v-if="props.extra.is_uploading" class="loading-overlay">
<n-spin size="large" />
</div>
</div>
</section>
</template>
<style lang="less" scoped>
@ -44,11 +50,32 @@ const img = (src: string, width = 200) => {
padding: 5px;
border-radius: 5px;
background: var(--im-message-left-bg-color);
height:149px
height:149px;
&.left {
background: var(--im-message-right-bg-color);
}
.image-container {
position: relative;
width: 100%;
height: 100%;
}
.loading-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
border-radius: 5px;
z-index: 1;
}
:deep(.n-image img) {
width: 100%;
height: 100%;

View File

@ -17,7 +17,7 @@ let textContent = props.extra?.content || ''
textContent = textReplaceLink(textContent)
if (props.data.talk_type == 2) {
textContent = textReplaceMention(textContent, '#462AA0')
textContent = textReplaceMention(textContent, float==='right'?'#fff':'#462AA0')
}
textContent = textReplaceEmoji(textContent)

View File

@ -21,7 +21,7 @@ export function useFriendsMenu() {
dropdown.item = Object.assign({}, item)
dropdown.options = []
dropdown.options.push({ label: '删除好友', key: 'delete' })
// dropdown.options.push({ label: '删除好友', key: 'delete' })
dropdown.x = e.clientX
dropdown.y = e.clientY

View File

@ -71,11 +71,11 @@ export function useSessionMenu() {
})
if (item.talk_type == 1) {
options.push({
// options.push({
label: '删除好友',
key: 'delete_contact'
})
// label: '删除好友',
// key: 'delete_contact'
// })
} else {
options.push({
@ -107,9 +107,7 @@ export function useSessionMenu() {
}
const onUserInfo = (item: ISession) => {
console.error('item',item)
user(item.id)
user(item.erp_user_id)
}
// 移除会话

View File

@ -27,6 +27,7 @@ export interface ISession {
content?: string // 消息内容
last_message?: ISessionLastMessage
draft_text?: string // 草稿文本
erp_user_id:number
}
// 消息记录

View File

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

View File

@ -94,8 +94,60 @@ const onSendTextEvent = throttle((value: any) => {
}, 1000)
//
const onSendImageEvent = ({ data, callBack }) => {
onSendMessage({ type: 'image', ...data }, callBack)
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])
}
)
}
//

View File

@ -46,9 +46,9 @@ export default defineConfig(({ mode }) => {
vueJsx({}),
compressPlugin(),
UnoCSS(),
// vueDevTools({
// launchEditor: 'trae',
// })
vueDevTools({
launchEditor: 'trae',
})
],
define: {
__APP_ENV__: env.APP_ENV