diff --git a/.env.development b/.env.development index 91dc563..97d26e7 100644 --- a/.env.development +++ b/.env.development @@ -8,5 +8,6 @@ VITE_APP_PORT = 9999 VITE_APP_BASE_API = '/dev-api' VITE_APP_BASE_URL = 'http://myvuetest.net' VITE_APP_TOKEN_KEY = 'offlineAccessSystemAppToken' -VITE_APP_SJZT_URL = 'http://172.20.5.120/prod-api' -VITE_OFFICE_HOST="http://192.168.56.101:8012" +VITE_APP_SJZT_URL = 'http://172.20.5.86/prod-api' +VITE_OFFICE_HOST='http://myvuetest.net/kkapi' +VITE_ONLYOFFICE_HOST = 'http://myvuetest.net/onlyoffice' \ No newline at end of file diff --git a/.env.production b/.env.production index a4dfe4b..1acc738 100644 --- a/.env.production +++ b/.env.production @@ -5,4 +5,5 @@ VITE_APP_PORT = 17777 VITE_APP_BASE_API = '' VITE_APP_TOKEN_KEY = 'onlineAccessSystemAppToken' VITE_APP_SJZT_URL = 'http://120.224.6.6:29911/prod-api' -VITE_OFFICE_HOST='https://gyhlw.hxgk.group/kkapi' \ No newline at end of file +VITE_OFFICE_HOST='https://gyhlw.hxgk.group/kkapi' +VITE_ONLYOFFICE_HOST = 'https://gyhlw.hxgk.group/onlyoffice' \ No newline at end of file diff --git a/package.json b/package.json index 432dd50..8a81892 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "dependencies": { "@dnd-kit/core": "^6.1.0", "@element-plus/icons-vue": "^2.3.1", + "@onlyoffice/document-editor-vue": "^1.5.0", "@tinymce/tinymce-vue": "^5.1.1", "@vitejs/plugin-vue": "^4.2.3", "@vueup/vue-quill": "^1.2.0", diff --git a/src/api/doc/type.ts b/src/api/doc/type.ts index 7472d70..a423475 100644 --- a/src/api/doc/type.ts +++ b/src/api/doc/type.ts @@ -31,6 +31,19 @@ export interface matterInfo{ expireTime?:string; } +export interface shareItem{ + name?:string; + updateTime?:string; + uuid:string; //文件uuid + code:string; + userUuid?:string; //owner uuid + puuid?:string; // parent dir uuid + path?:string; + expireInfinity?:boolean; + expireTime?:string; + permitList?:string; +} + export interface matterTree extends matterInfo { children:matterTree[] } diff --git a/src/router/index.ts b/src/router/index.ts index d068ba1..6267e9b 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -33,6 +33,12 @@ export const constantRoutes: RouteRecordRaw[] = [ meta: { hidden: true }, }, + { + path: "/onlyoffice", + component: () => import("@/views/doc/onlyoffice.vue"), + meta: { hidden: true }, + }, + { path: "/", component: Layout, diff --git a/src/views/doc/manage.vue b/src/views/doc/manage.vue index 365fdc9..d98c36b 100644 --- a/src/views/doc/manage.vue +++ b/src/views/doc/manage.vue @@ -12,6 +12,7 @@ import { matterPage,matterInfo,respCreateShare,matterTree } from "@/api/doc/type import { h } from 'vue' import { Delete, + View, Download, Share, Search, @@ -22,6 +23,7 @@ import { } from '@element-plus/icons-vue' import {ElSelect,ElOption, ElText,ElInput,TableInstance,ElMessage,UploadFile,UploadFiles,ElPagination,ElTree,TreeInstance} from "element-plus"; import type { TreeNode } from 'element-plus/es/components/tree/src/tree.type' +import preview from './preview.vue'; //TODO: add file icons done! //TODO: click on table-item, 1)preview on file ..................... @@ -51,7 +53,8 @@ const tabSelected=ref([]) //table组件多选数据维护 const treeData=ref([{name:'root',uuid:'root',children:[]}]) const treeRef = ref(); const currentNode=ref({}) //打开的路径层次 - +const officeHost=import.meta.env.VITE_OFFICE_HOST +const dynamicVNode = ref(null) //permission 组件的父组件 const multipleTableRef = ref() const paginInfo = ref({ page: 0, total: 0 }) const formHeaders=ref({ @@ -373,6 +376,22 @@ function onNodeClick(data:matterTree,node:TreeNode,self:any,env:any){ }) } +//文件预览 +function onPrivateView(row:matterInfo){ + let a = `${row.uuid}${row.name}` + let _token=document.cookie.match(/hxpan=([\w-]*)/) + if (_token&&_token.length>1){ + _token=_token[1] + } + + let _url=`${siteHost}${apiURL}/alien/download/${row.uuid}/${row.name}?access_token=${_token}&fullfilename=${a}` + + dynamicVNode.value=h(preview,{ + url:`${officeHost}/kkpreview/onlinePreview?url=`+window.btoa(unescape(encodeURIComponent(_url))), + closeFunc:()=>dynamicVNode.value=null + }) +} + function handleMouseEnter(row:any){ currentHoverRow.value=row.name } @@ -481,9 +500,10 @@ const handleSelectionChange = (val:matterInfo[]) => { @@ -503,6 +523,9 @@ const handleSelectionChange = (val:matterInfo[]) => { +
+ +
diff --git a/src/views/doc/onlyoffice.vue b/src/views/doc/onlyoffice.vue new file mode 100644 index 0000000..5520fbf --- /dev/null +++ b/src/views/doc/onlyoffice.vue @@ -0,0 +1,89 @@ + + + + \ No newline at end of file diff --git a/src/views/doc/recentVisited.vue b/src/views/doc/recentVisited.vue new file mode 100644 index 0000000..031a1ff --- /dev/null +++ b/src/views/doc/recentVisited.vue @@ -0,0 +1,160 @@ + + + + \ No newline at end of file diff --git a/src/views/doc/share.vue b/src/views/doc/share.vue index b1f46c1..e80c42c 100644 --- a/src/views/doc/share.vue +++ b/src/views/doc/share.vue @@ -14,14 +14,16 @@ import { h } from 'vue' import { Delete, Folder, + Edit, Share, Avatar, View, } from '@element-plus/icons-vue' -import {ElText } from "element-plus"; -import {getFileIcon,checkExpirTime } from "./tools" +import {ElText,ElButton } from "element-plus"; +import {getFileIcon,checkExpirTime,fileType } from "./tools" import sharePermission from './sharePermission.vue'; import preview from './preview.vue'; +import recentVisited from './recentVisited.vue'; const route = useRoute() const userStore = useUserStore(); @@ -40,7 +42,6 @@ import type { VNode } from 'vue' const dynamicVNode = ref(null) //permission 组件的父组件 - function showShareMessage(row:{uuid:string,code:string,name:string,expireTime:string}){ let _shareURL=`${siteHost}/#/doc/share?uuid=${row.uuid}&code=${row.code}` ElMessageBox({ @@ -71,6 +72,7 @@ function showShareMessage(row:{uuid:string,code:string,name:string,expireTime:st confirmButtonText: '复制分享链接', showCancelButton: true }).then(()=>{ + if(!navigator.clipboard) alert("clipboard 不可用") navigator.clipboard.writeText(_shareURL) }).catch(() => { if (browerMode.value){ @@ -113,23 +115,59 @@ function onShareMember(row:matterInfo){ //文件预览 function onShareView(row:matterInfo){ - let a = row.name ?? ''; - if(a.endsWith('...')){ - a=`${row.uuid}-${row.code}.zip` - } - - //由于预览服务在缓存文件时,直接按文件名缓存,所以同名文件就会出现覆盖错乱的问题 - a=a.match("(\.[a-zA-Z]+)$") - if (a && a.length>0) { - a=`${row.uuid}-${row.code}${a[0]}` + const _type=fileType(row.name!) + if(_type!==""){ //office file + const info =btoa(encodeURIComponent(`${row.name}`)) //预览模式不需要绝对路径,只核对一下文件名即可 + const _url=`${siteHost}${apiURL}/share/zip?shareUuid=${row.uuid}&code=${row.code}&uid=${uid}&dprt=${udprt}&puuid=root&rootUuid=root` + window.open(`/#/onlyoffice?name=${row.name}&dtype=${_type}&info=${info}&fileurl=`+encodeURIComponent(_url),"_blank") }else{ - a=`${row.uuid}${row.name}` + //by kkFilePreview + let a = row.name ?? ''; + if(a.endsWith('...')){ + a=`${row.uuid}-${row.code}.zip` + } + + //由于预览服务在缓存文件时,直接按文件名缓存,所以同名文件就会出现覆盖错乱的问题 + a=a.match("(\.[a-zA-Z]+)$") + if (a && a.length>0) { + a=`${row.uuid}-${row.code}${a[0]}` + }else{ + a=`${row.uuid}${row.name}` + } + + let _url=`${siteHost}${apiURL}/share/zip?shareUuid=${row.uuid}&code=${row.code}&uid=${uid}&dprt=${udprt}&puuid=root&rootUuid=root&fullfilename=${a}` + //window.open(`${officeHost}/kkpreview/onlinePreview?url=`+window.btoa(encodeURIComponent(_url)),"_blank") + dynamicVNode.value=h(preview,{ + url:`${officeHost}/kkpreview/onlinePreview?url=`+window.btoa(encodeURIComponent(_url)), + closeFunc:()=>dynamicVNode.value=null + }) + } +} - let _url=`${siteHost}${apiURL}/share/zip?shareUuid=${row.uuid}&code=${row.code}&uid=${uid}&dprt=${udprt}&puuid=root&rootUuid=root&fullfilename=${a}` - dynamicVNode.value=h(preview,{ - url:`${officeHost}/kkpreview/onlinePreview?url=`+window.btoa(unescape(encodeURIComponent(_url))), - closeFunc:()=>dynamicVNode.value=null +//onlyoffice在线编辑 +async function onlyOfficeEdit(row:matterInfo){ + const _type=fileType(row.name!) + if(_type===""){ + alert("暂不支持该类型编辑") + return + } + let filepath="" + await getShareBrowse("",{shareUuid:row.uuid,code:row.code,puuid:'root',rootUuid:'root',dprt:udprt}).then((resp)=>{ + console.log(resp.data,"<<<<<<<<<<<") + filepath= resp.data.matters[0].path + }) + ElMessageBox.confirm("线上资源有限,确定继续线上编辑吗", "提示", { + confirmButtonText: "确定", + cancelButtonText: "取消", + type: "warning", + }).then(()=>{ + //office file + //base64 encode for MASK + const _verify = btoa(row.uuid.match(/(\w+-\w+)/)![0]+"true") //增加一个权限验证的标记 + const info =btoa(encodeURIComponent(`${row.userUuid}/root${filepath}`)) //编辑模式必须要全路径 + const _url=`${siteHost}${apiURL}/share/zip?shareUuid=${row.uuid}&code=${row.code}&uid=${uid}&dprt=${udprt}&puuid=root&rootUuid=root` + window.open(`/#/onlyoffice?name=${row.name}&dtype=${_type}&info=${info}&verify=${_verify}&fileurl=`+encodeURIComponent(_url),"_blank") }) } @@ -164,9 +202,17 @@ onMounted(() => { browerMode.value=true getShareBrowse("",{shareUuid:query.uuid,code:query.code,puuid:'root',rootUuid:'root',dprt:udprt}).then((resp)=>{ showShareMessage(resp.data) - return + const request = indexedDB.open('visitList') + request.onsuccess = (e) => { + const db = e.target.result; + const store = db.transaction('vlist','readwrite').objectStore("vlist"); + store.put(resp.data) + db.close() + } }) + return } + browerMode.value=false onLoadShareList() }) @@ -175,6 +221,7 @@ onMounted(() => {