更新组件声明,新增NDropdown支持;调整ForwardRecord.vue中的模态框逻辑,优化文件点击事件处理,修复ContactModal.vue中的数据提交逻辑,更新路由配置以支持新页面。
This commit is contained in:
parent
b65f38f02e
commit
579fed2e69
1
components.d.ts
vendored
1
components.d.ts
vendored
@ -52,6 +52,7 @@ declare module 'vue' {
|
||||
NAvatar: typeof import('naive-ui')['NAvatar']
|
||||
NButton: typeof import('naive-ui')['NButton']
|
||||
NCheckbox: typeof import('naive-ui')['NCheckbox']
|
||||
NDropdown: typeof import('naive-ui')['NDropdown']
|
||||
NEmpty: typeof import('naive-ui')['NEmpty']
|
||||
NIcon: typeof import('naive-ui')['NIcon']
|
||||
NImage: typeof import('naive-ui')['NImage']
|
||||
|
@ -21,7 +21,7 @@ html {
|
||||
// message
|
||||
--im-message-bg-color: #f7f7f7;
|
||||
--im-message-border-color: #efeff5;
|
||||
--im-message-left-bg-color: #F4F4FC;
|
||||
--im-message-left-bg-color: #fff;
|
||||
--im-message-left-text-color: #333;
|
||||
--im-message-right-bg-color: #46299D;
|
||||
--im-message-right-text-color: #fff;
|
||||
|
@ -5,22 +5,21 @@ import { ServeGetForwardRecords } from '@/api/chat'
|
||||
import { MessageComponents } from '@/constant/message'
|
||||
import { ITalkRecord } from '@/types/chat'
|
||||
import { useInject } from '@/hooks'
|
||||
|
||||
const emit = defineEmits(['close'])
|
||||
import customModal from '@/components/common/customModal.vue'
|
||||
import { voiceToText } from '@/api/chat.js'
|
||||
const props = defineProps({
|
||||
msgId: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
const isShow=defineModel<boolean>('show')
|
||||
const { showUserInfoModal } = useInject()
|
||||
const isShow = ref(true)
|
||||
const items = ref<ITalkRecord[]>([])
|
||||
const title = ref('会话记录')
|
||||
|
||||
const onMaskClick = () => {
|
||||
emit('close')
|
||||
isShow.value=false
|
||||
}
|
||||
|
||||
const onLoadData = () => {
|
||||
@ -30,18 +29,92 @@ const onLoadData = () => {
|
||||
if (res.code == 200) {
|
||||
items.value = res.data.items || []
|
||||
|
||||
title.value = `会话记录(${items.value.length})`
|
||||
// title.value = `会话记录(${items.value.length})`
|
||||
}
|
||||
})
|
||||
}
|
||||
const dropdown=ref({
|
||||
show:false,
|
||||
x:'',
|
||||
y:'',
|
||||
options:[] as any,
|
||||
item:{} as ITalkRecord,
|
||||
})
|
||||
const onConvertText =async (data: ITalkRecord) => {
|
||||
data.is_convert_text = 1
|
||||
const res = await voiceToText({msgId:data.msg_id,voiceUrl:data.extra.url})
|
||||
if(res.code == 200){
|
||||
data.extra.content = res.data.convText
|
||||
|
||||
}
|
||||
}
|
||||
const onloseConvertText=(data: ITalkRecord)=>{
|
||||
data.is_convert_text = 0
|
||||
}
|
||||
const evnets = {
|
||||
convertText: onConvertText,
|
||||
closeConvertText:onloseConvertText
|
||||
}
|
||||
|
||||
const onContextMenuHandle=(key:string)=>{
|
||||
evnets[key] && evnets[key](dropdown.value.item)
|
||||
closeDropdownMenu()
|
||||
}
|
||||
const closeDropdownMenu=()=>{
|
||||
dropdown.value.show=false
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
onLoadData()
|
||||
})
|
||||
const onContextMenu = (e:any,item: ITalkRecord) => {
|
||||
dropdown.value.show=true
|
||||
|
||||
dropdown.value.x=e.clientX
|
||||
dropdown.value.y=e.clientY
|
||||
if(item.is_convert_text === 1){
|
||||
dropdown.value.options=[{ label: '关闭转文字', key: 'closeConvertText' }]
|
||||
}else{
|
||||
dropdown.value.options=[{ label: '转文字', key: 'convertText' }]
|
||||
}
|
||||
|
||||
dropdown.value.item=item
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<n-modal
|
||||
<customModal :closable="false" customCloseBtn v-model:show="isShow" :title="title" style="width: 997px;background-color: #F9F9FD;" :on-after-leave="onMaskClick">
|
||||
<template #content>
|
||||
<div class="main-box bg-#fff me-scrollbar me-scrollbar-thumb">
|
||||
<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)">
|
||||
<im-avatar :src="item.avatar" :size="38" :username="item.nickname" />
|
||||
</div>
|
||||
|
||||
<div class="right-box">
|
||||
<div class="msg-header">
|
||||
<span class="name">{{ item.nickname }}</span>
|
||||
<span class="time"> {{ item.created_at }}</span>
|
||||
</div>
|
||||
|
||||
<component
|
||||
@contextmenu.prevent="onContextMenu($event,item)"
|
||||
:is="MessageComponents[item.msg_type] || 'unknown-message'"
|
||||
:extra="item.extra"
|
||||
:data="item"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 右键菜单 -->
|
||||
<n-dropdown :show="dropdown.show" :x="dropdown.x" :y="dropdown.y" style="width: 142px;" :options="dropdown.options"
|
||||
@select="onContextMenuHandle" @clickoutside="closeDropdownMenu" />
|
||||
</template>
|
||||
|
||||
</customModal>
|
||||
<!-- <n-modal
|
||||
v-model:show="isShow"
|
||||
preset="card"
|
||||
:title="title"
|
||||
@ -80,7 +153,7 @@ onMounted(() => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</n-modal>
|
||||
</n-modal> -->
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@ -94,10 +167,10 @@ onMounted(() => {
|
||||
min-height: 38px;
|
||||
display: flex;
|
||||
margin-bottom: 10px;
|
||||
padding: 5px 15px;
|
||||
padding: 24px 42px;
|
||||
|
||||
.left-box {
|
||||
width: 30px;
|
||||
width: 38px;
|
||||
display: flex;
|
||||
user-select: none;
|
||||
padding-top: 8px;
|
||||
|
@ -86,12 +86,10 @@ const strokeDashoffset = computed(() =>
|
||||
|
||||
// 处理文件点击事件
|
||||
const handleClick = () => {
|
||||
console.log('props.extra', props.extra);
|
||||
|
||||
window.open(
|
||||
`http://localhost:5500/?url=${props.extra.path}`,
|
||||
`${window.location.origin}/office?url=${props.extra.path}`,
|
||||
'_blank',
|
||||
'width=800,height=600,left=200,top=200,toolbar=no,menubar=no,scrollbars=yes,resizable=yes,location=no,status=no'
|
||||
'width=1200,height=900,left=200,top=200,toolbar=no,menubar=no,scrollbars=yes,resizable=yes,location=no,status=no'
|
||||
);
|
||||
}
|
||||
</script>
|
||||
|
@ -33,7 +33,7 @@ const onClick = () => {
|
||||
<span>转发:聊天会话记录 ({{ extra.msg_ids.length }}条)</span>
|
||||
</div>
|
||||
|
||||
<ForwardRecord v-if="isShowRecord" :msg-id="data.msg_id" @close="isShowRecord = false" />
|
||||
<ForwardRecord v-model:show="isShowRecord" :msg-id="data.msg_id" @close="isShowRecord = false" />
|
||||
</section>
|
||||
</template>
|
||||
|
||||
|
@ -13,6 +13,7 @@ const { showUserInfoModal } = useInject()
|
||||
<template>
|
||||
<div class="im-message-sys-text">
|
||||
<div class="sys-text">
|
||||
|
||||
<a @click="showUserInfoModal(extra.owner_id)">
|
||||
{{ extra.owner_name }}
|
||||
</a>
|
||||
|
@ -127,11 +127,12 @@ const onCancel = () => {
|
||||
const onSubmit = () => {
|
||||
let data = checkedFilter.value.map((item: any) => {
|
||||
return {
|
||||
id: item.id,
|
||||
type: item.type
|
||||
receiver_id: item.receiver_id,
|
||||
talk_type: item.talk_type
|
||||
}
|
||||
})
|
||||
|
||||
console.log('data', data);
|
||||
console.log('checkedFilter.value', checkedFilter.value);
|
||||
emit('on-submit', data)
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,11 @@ const routes = [
|
||||
path: '/:pathMatch(.*)*',
|
||||
name: '404 NotFound',
|
||||
component: () => import('@/views/other/not-found.vue')
|
||||
},
|
||||
{
|
||||
path: '/office',
|
||||
name: 'office',
|
||||
component: () => import('@/views/office/index.vue')
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -18,7 +18,7 @@ export function isLoggedIn() {
|
||||
*/
|
||||
export function getAccessToken() {
|
||||
// return storage.get(AccessToken) || ''
|
||||
return JSON.parse(localStorage.getItem('token'))||'6e0b0a00c35d0e1613d8f9ce2303067e46a0c2d9941c959848ccf7c91e7eb0fe14690f485ae6b5e932196267c2af8a6089bda35a715c44ad565de15114eb2c82fddcba958dd35b80cd0980f7d6fa4dde04e3c5f1407e39ac1073432c4e9dc0031afbe520e8a6528eeba7e79cf2c97f4c6e07e4a466460ee50fc28b2f05ca5215db9ea522a4d76911dbdd5d863c107f1cb073da0c94091ce81c59c9bd2faba1de9552a38a8c9ac69bb4a8d562b41b127a1e92468d4b8a5749adf7c899a65c748940eda0d6c8834cdd8995b527ab6f56cf9a6ede9de78ce7938190030708b576238d62f018abb0d363ee4cb4c1a8235487c20938760bece6caaf5f3573f888d15a0f9e79c4b09bd5214c704c135be67de9b475e24addc92d662768128eef05ddc67d68d8c0f16b5293888508c2f7f87bd0766fa7609726c18f814f04551f6f54d7'
|
||||
return JSON.parse(localStorage.getItem('token'))||'46d71a72d8d845ad7ed23eba9bdde260e635407190c2ce1bf7fd22088e41682ea07773ec65cae8946d2003f264d55961f96e0fc5da10eb96d3a348c1664e9644ce2108c311309f398ae8ea1b8200bfd490e5cb6e8c52c9e5d493cbabb163368f8351420451a631dbfa749829ee4cda49b77b5ed2d3dced5d0f2b7dd9ee76ba5465c84a17c23af040cd92b6b2a4ea48befbb5c729dcdad0a9c9668befe84074cc24f78899c1d947f8e7f94c7eda5325b8ed698df729e76febb98549ef3482ae942fb4f4a1c92d21836fa784728f0c5483aab2760a991b6b36e6b10c84f840a6433a6ecc31dee36e8f1c6158818bc89d22201760cb2a37a6703ccf06c9d5a5752e0c3798b552c606065aa0079caa2737c431030be4871e931d3dcb27c239d70b4ba5f2e533a36a0b9b784388409ccd3ad8c62c1de535f4fd865b4f3bf37d260ccc'
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -39,20 +39,20 @@ const onMultiDelete = () => {
|
||||
dialogueStore.ApiDeleteRecord(msgIds)
|
||||
}
|
||||
|
||||
const onContactModal = (data: { id: number; type: number }[]) => {
|
||||
const onContactModal = (data: { receiver_id: number; talk_type: number }[]) => {
|
||||
let msg_ids = dialogueStore.selectItems.map((item: any) => item.msg_id)
|
||||
|
||||
let user_ids: number[] = []
|
||||
let group_ids: number[] = []
|
||||
|
||||
for (let o of data) {
|
||||
if (o.type == 1) {
|
||||
user_ids.push(o.id)
|
||||
if (o.talk_type == 1) {
|
||||
user_ids.push(o.receiver_id)
|
||||
} else {
|
||||
group_ids.push(o.id)
|
||||
group_ids.push(o.receiver_id)
|
||||
}
|
||||
}
|
||||
|
||||
console.log('user_ids',user_ids)
|
||||
dialogueStore.ApiForwardRecord({
|
||||
mode: forwardMode.value,
|
||||
message_ids: msg_ids,
|
||||
|
99
src/views/office/index.vue
Normal file
99
src/views/office/index.vue
Normal file
@ -0,0 +1,99 @@
|
||||
<template>
|
||||
<div id="office-div" ></div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
// 动态加载 OnlyOffice API 脚本(防止重复加载)
|
||||
function loadScript(src) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (document.querySelector(`script[src="${src}"]`)) {
|
||||
resolve()
|
||||
return
|
||||
}
|
||||
const script = document.createElement('script')
|
||||
script.type = 'text/javascript'
|
||||
script.src = src
|
||||
script.onload = resolve
|
||||
script.onerror = reject
|
||||
document.head.appendChild(script)
|
||||
})
|
||||
}
|
||||
|
||||
// 判断文件类型
|
||||
function getDocumentTypes(url) {
|
||||
const extension = url.split('.').pop().toLowerCase()
|
||||
const types = {
|
||||
'docx': { fileType: 'docx', documentType: 'word' },
|
||||
'doc': { fileType: 'doc', documentType: 'word' },
|
||||
'xlsx': { fileType: 'xlsx', documentType: 'cell' },
|
||||
'xls': { fileType: 'xls', documentType: 'cell' },
|
||||
'pptx': { fileType: 'pptx', documentType: 'slide' },
|
||||
'ppt': { fileType: 'ppt', documentType: 'slide' },
|
||||
'pdf': { fileType: 'pdf', documentType: 'word' }
|
||||
}
|
||||
return types[extension] || { fileType: 'docx', documentType: 'word' }
|
||||
}
|
||||
|
||||
// 动态插入 CSP meta
|
||||
function insertCSPMeta() {
|
||||
if (!document.querySelector('meta[http-equiv="Content-Security-Policy"]')) {
|
||||
const meta = document.createElement('meta')
|
||||
meta.httpEquiv = 'Content-Security-Policy'
|
||||
meta.content = 'upgrade-insecure-requests'
|
||||
document.head.appendChild(meta)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
insertCSPMeta()
|
||||
await loadScript('https://onlyoffice.fontree.cn/web-apps/apps/api/documents/api.js')
|
||||
const url = route.query.url
|
||||
if (!url) {
|
||||
alert('请提供文档 URL 参数')
|
||||
return
|
||||
}
|
||||
const fileName = url.split('/').pop()
|
||||
const { fileType, documentType } = getDocumentTypes(url)
|
||||
// eslint-disable-next-line no-undef
|
||||
new window.DocsAPI.DocEditor('office-div', {
|
||||
document: {
|
||||
fileType,
|
||||
key: `doc_${fileName}_${Date.now()}`,
|
||||
title: fileName,
|
||||
url
|
||||
},
|
||||
documentType,
|
||||
editorConfig: {
|
||||
mode: 'view',
|
||||
lang: 'zh-CN',
|
||||
user: {
|
||||
id: 'user_' + Date.now(),
|
||||
name: '访客用户'
|
||||
},
|
||||
customization: {
|
||||
chat: false,
|
||||
commentAuthorOnly: false,
|
||||
compactToolbar: true,
|
||||
hideRightMenu: false,
|
||||
compatibility: true,
|
||||
showReviewChanges: false
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
</script>
|
||||
<style>
|
||||
iframe[name="frameEditor"] {
|
||||
width: 100% !important;
|
||||
height: 100vh !important;
|
||||
min-height: 100vh !important;
|
||||
border: none !important;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
|
Loading…
Reference in New Issue
Block a user