perf: 适配 onlyoffice JWT

This commit is contained in:
jmal 2024-06-08 23:52:24 +08:00
parent b3d631eac5
commit 1ce18c8e10
8 changed files with 190 additions and 48 deletions

View File

@ -83,6 +83,21 @@ export default {
url: '/user/setting/resetMenuAndRole',
method: 'put',
})
},
// 获取office配置
getOfficeConfig: function() {
return request({
url: '/office/config',
method: 'get'
})
},
// 更新office配置
updateOfficeConfig: function(data) {
return request({
url: '/office/config',
method: 'put',
data
})
}
}

View File

@ -2206,7 +2206,7 @@ export default {
},
extendedInfo(file) {
if (!file.exif && !file.video) {
return
return ''
}
return "\r\n" + formatExif(file.exif) + formatVideo(file.video)
},

View File

@ -22,6 +22,7 @@
<script>
import api from "@/api/file-api"
import settingApi from "@/api/setting-api"
import fileConfig from "@/utils/file-config";
import SparkMD5 from 'spark-md5'
import HistoryPopover from "@/components/HistoryPopover/index.vue";
@ -79,7 +80,12 @@ export default {
historyPageIndex: 1,
historyPageSize: 50,
viewHistory: false,
historyOperationLoading: false
historyOperationLoading: false,
officeServerConfig: {
documentServer: undefined,
callbackServer: undefined,
tokenEnabled: false
}
}
},
beforeDestroy() {
@ -97,24 +103,9 @@ export default {
if (!id) {
return
}
let officeApiUrl = fileConfig.officeApiUrl()
$J.loadScript($J.apiUrl(officeApiUrl), (e) => {
if (e !== null) {
this.$emit('onClose')
this.$store.dispatch('updateMessage', { event: 'loadFileFailed'})
return
}
if (this.shareId) {
api.getPublicFileInfoById({fileId: this.file.id, shareId: this.shareId}).then(res => {
this.file = res.data
this.loadFile()
})
} else {
api.getFileInfoById({id: this.file.id}).then(res => {
this.file = res.data
this.loadFile()
})
}
settingApi.getOfficeConfig().then(res => {
this.officeServerConfig = res.data
this.loadOfficeApi()
})
},
immediate: true,
@ -138,6 +129,27 @@ export default {
destroyed() {
},
methods: {
loadOfficeApi() {
let officeApiUrl = fileConfig.officeApiUrl(this.officeServerConfig.documentServer)
$J.loadScript($J.apiUrl(officeApiUrl), (e) => {
if (e !== null) {
this.$emit('onClose')
this.$store.dispatch('updateMessage', { event: 'loadFileFailed'})
return
}
if (this.shareId) {
api.getPublicFileInfoById({fileId: this.file.id, shareId: this.shareId}).then(res => {
this.file = res.data
this.loadFile()
})
} else {
api.getFileInfoById({id: this.file.id}).then(res => {
this.file = res.data
this.loadFile()
})
}
})
},
viewHistoryFile({historyInfo}) {
const historyUrl = window.location.origin + fileConfig.previewHistoryUrl(historyInfo.id, this.$store.state.user.name, this.$store.state.user.token)
this.onRequestHistoryData(null, historyInfo, historyUrl)
@ -231,15 +243,23 @@ export default {
this.destroyEditor()
const file_username = this.sharer ? this.sharer : this.$store.state.user.name
this.fileUrl = window.location.origin + fileConfig.previewUrl(file_username, this.file, this.$store.getters.token)
this.fileKey = `${new Date(this.file.updateDate).getTime()}-${SparkMD5.hash(this.file.id)}`
if (this.readOnly && window.shareId) {
this.fileUrl = window.location.origin + fileConfig.publicPreviewUrl(this.file, window.shareId, this.$store.getters.shareToken)
this.fileKey = `${new Date(this.file.updateDate).getTime()}-${SparkMD5.hash(window.shareId)}`
let callbackServer = this.officeServerConfig.callbackServer
if (callbackServer) {
if (callbackServer.endsWith('/')) {
// 去掉最后的/
callbackServer = callbackServer.substring(0, this.officeServerConfig.callbackServer.length - 1)
}
} else {
callbackServer = window.location.origin
}
let callbackUrl = fileConfig.officeCallBackUrl(this.$store.getters.token, this.$store.getters.name, this.file.id)
this.fileUrl = fileConfig.previewUrl(file_username, this.file, this.$store.getters.token, undefined, callbackServer)
this.fileKey = `${new Date(this.file.updateDate).getTime()}-${SparkMD5.hash(this.file.id + callbackServer)}`
if (this.readOnly && window.shareId) {
this.fileUrl = fileConfig.publicPreviewUrl(this.file, window.shareId, this.$store.getters.shareToken, callbackServer)
this.fileKey = `${new Date(this.file.updateDate).getTime()}-${SparkMD5.hash(window.shareId + callbackServer)}`
}
let callbackUrl = fileConfig.officeCallBackUrl(this.officeServerConfig.callbackServer, this.$store.getters.token, this.$store.getters.name, this.file.id)
this.docEditorConfig = {
document: {
fileType: this.fileType,
@ -280,14 +300,20 @@ export default {
this.loadOffice(res.data)
})
} else {
api.getOfficeJwt(this.docEditorConfig).then(res => {
this.loadOffice(res.data)
})
if (this.officeServerConfig.tokenEnabled) {
api.getOfficeJwt(this.docEditorConfig).then(res => {
this.loadOffice(res.data)
})
} else {
this.loadOffice()
}
}
},
loadOffice(token) {
this.docEditorConfig.token = token
if (token) {
this.docEditorConfig.token = token
}
if (!this.$pc) {
this.docEditorConfig.type = 'mobile'
}

View File

@ -12,17 +12,23 @@ export default {
return window.location.origin + `/webDAV/${username}`
},
// office api url
officeApiUrl: function() {
const url = window._env_.API_OFFICE_URL || process.env.API_OFFICE_URL || `${window.location.origin}/office`
return `${url}/web-apps/apps/api/documents/api.js`
officeApiUrl: function(documentServer) {
let serverUrl = documentServer || window._env_.API_URL || process.env.API_URL || `${window.location.origin}/office`
if (!serverUrl.endsWith('/')) {
serverUrl = serverUrl + "/"
}
return serverUrl + "web-apps/apps/api/documents/api.js"
},
// office回调url
officeCallBackUrl: function(token, username, fileId) {
const url = window._env_.API_URL || process.env.API_URL || 'http://jmalcloud:8088'
return `${url}/office/track?jmal-token=${token}&name=${username}&fileId=${fileId}`
officeCallBackUrl: function(callbackServer, token, username, fileId) {
let callbackServerUrl = callbackServer || window._env_.API_URL || process.env.API_URL || 'http://jmalcloud:8088'
if (!callbackServerUrl.endsWith('/')) {
callbackServerUrl = callbackServerUrl + "/"
}
return `${callbackServerUrl}office/track?jmal-token=${token}&name=${username}&fileId=${fileId}`
},
// 预览文件的url
previewUrl: function(username, file, token, shareToken) {
previewUrl: function(username, file, token, shareToken, serverUrl) {
let owner = null
if (username !== store.getters.name || localStorage.getItem('mountFileOwner') !== null) {
owner = localStorage.getItem('mountFileOwner')
@ -32,7 +38,8 @@ export default {
if (owner == null) {
owner = store.getters.name
}
let fileUrl = `${this.baseUrl}/file/${owner}${encodeURI(file.path)}${encodeURI(file.name)}`
let baseUrl = serverUrl || this.baseUrl
let fileUrl = `${baseUrl}/file/${owner}${encodeURI(file.path)}${encodeURI(file.name)}`
fileUrl = fileUrl.replace(/%5C/g, '/')
if (token) {
return `${fileUrl}?jmal-token=${token}&name=${username}`
@ -80,11 +87,12 @@ export default {
window.open(url, '_blank')
},
// 共享文件预览Url
publicPreviewUrl: function(file, shareId, shareToken) {
publicPreviewUrl: function(file, shareId, shareToken, serverUrl) {
if (!shareToken) {
shareToken = "none"
}
return `${this.baseUrl}/public/s/preview/${file.name}?fileId=${file.id}&shareId=${shareId}&shareToken=${shareToken}`
let baseUrl = serverUrl || this.baseUrl
return `${baseUrl}/public/s/preview/${file.name}?fileId=${file.id}&shareId=${shareId}&shareToken=${shareToken}`
},
// 共享文件打包下载
publicPackageDownload: function(shareId, fileIds, shareToken) {

View File

@ -65,13 +65,18 @@
</div>
</el-tab-pane>
<el-tab-pane label="OnlyOffice" name="2" class="setting-tab-panel">
<div v-if="activeName === '2'">
<office-config></office-config>
</div>
</el-tab-pane>
<el-tab-pane label="视频转码" name="3" class="setting-tab-panel">
<div v-if="activeName === '3'">
<transcode-config></transcode-config>
</div>
</el-tab-pane>
<el-tab-pane label="LDAP认证" name="2" class="setting-tab-panel">
<div v-if="activeName === '2'">
<el-tab-pane label="LDAP认证" name="4" class="setting-tab-panel">
<div v-if="activeName === '4'">
<ldap-config></ldap-config>
</div>
</el-tab-pane>
@ -91,11 +96,12 @@ import UploadImageInput from "@/components/input/UploadImageInput.vue";
import {mapGetters, mapState} from "vuex";
import store from "@/store";
import TaskProgress from "@/components/TaskProgress/index.vue";
import LdapConfig from "@/views/setting/ldapConfig.vue";
import TranscodeConfig from "@/views/setting/transcodeConfig.vue";
import LdapConfig from "@/views/setting/cloudSetting/ldapConfig.vue";
import TranscodeConfig from "@/views/setting/cloudSetting/transcodeConfig.vue";
import OfficeConfig from "@/views/setting/cloudSetting/officeConfig.vue";
export default {
components: {TranscodeConfig, LdapConfig, TaskProgress, UploadImageInput, Logo},
components: {OfficeConfig, TranscodeConfig, LdapConfig, TaskProgress, UploadImageInput, Logo},
data() {
return {
activeName: '1',

View File

@ -0,0 +1,83 @@
<template>
<div class="container">
<el-form :rules="rules" ref="officeConfigForm" :model="configFormData" label-width="150px" size="small"
style="width: 520px" autocomplete="off">
<el-form-item label="OnlyOffice地址" prop="documentServer">
<el-input placeholder="OnlyOffice Server 地址, 一般不用填" v-model.number="configFormData.documentServer"></el-input>
</el-form-item>
<el-form-item label="密钥" prop="secret">
<el-input type="password" placeholder="OnlyOffice JWT (留空为不使用密钥)" v-model="configFormData.secret"></el-input>
</el-form-item>
<el-form-item label="回调服务地址" prop="callbackServer">
<el-input placeholder="JmalCloud Server 地址, 一般不用填" v-model.number="configFormData.callbackServer"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" v-loading="saveConfigLoading" @click="saveConfig">保存配置</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import settingApi from "@/api/setting-api";
export default {
name: 'OfficeConfig',
props: {
data: {
type: Array,
default: []
},
},
computed: {
},
data() {
return {
saveConfigLoading: false,
configFormData: {
documentServer: undefined,
secret: undefined,
tokenEnabled: false,
callbackServer: undefined
},
rules: {
// documentServer: [
// {required: true, message: '请输入文档服务器地址', trigger: 'blur'}
// ]
}
}
},
mounted() {
this.getOfficeConfig()
},
methods: {
getOfficeConfig() {
settingApi.getOfficeConfig().then(res => {
this.configFormData = res.data
})
},
saveConfig() {
this.saveConfigLoading = true
if (this.configFormData.documentServer === '') {
this.configFormData.documentServer = undefined
}
if (this.configFormData.callbackServer === '') {
this.configFormData.callbackServer = undefined
}
settingApi.updateOfficeConfig(this.configFormData).then(() => {
this.saveConfigLoading = false
this.$message.success('保存成功')
}).catch(() => {
this.saveConfigLoading = false
})
}
}
}
</script>
<style lang="scss" scoped>
.container {
padding: 0 !important;
}
</style>

View File

@ -1,6 +1,6 @@
<template>
<div class="container">
<el-form :rules="rules" ref="transcodeConfigform" :model="configFormData" label-width="120px" size="small"
<el-form :rules="rules" ref="transcodeConfigForm" :model="configFormData" label-width="120px" size="small"
style="width: 520px" autocomplete="off">
<el-form-item label="功能状态" prop="enable">
<el-select v-model="configFormData.enable">
@ -74,8 +74,12 @@ export default {
})
},
saveConfig() {
this.saveConfigLoading = true
settingApi.setTranscodeConfig(this.configFormData).then(() => {
this.saveConfigLoading = false
this.$message.success('保存成功')
}).catch(() => {
this.saveConfigLoading = false
})
}
}