perf: 适配 onlyoffice JWT
This commit is contained in:
parent
b3d631eac5
commit
1ce18c8e10
@ -83,6 +83,21 @@ export default {
|
|||||||
url: '/user/setting/resetMenuAndRole',
|
url: '/user/setting/resetMenuAndRole',
|
||||||
method: 'put',
|
method: 'put',
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
// 获取office配置
|
||||||
|
getOfficeConfig: function() {
|
||||||
|
return request({
|
||||||
|
url: '/office/config',
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 更新office配置
|
||||||
|
updateOfficeConfig: function(data) {
|
||||||
|
return request({
|
||||||
|
url: '/office/config',
|
||||||
|
method: 'put',
|
||||||
|
data
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2206,7 +2206,7 @@ export default {
|
|||||||
},
|
},
|
||||||
extendedInfo(file) {
|
extendedInfo(file) {
|
||||||
if (!file.exif && !file.video) {
|
if (!file.exif && !file.video) {
|
||||||
return
|
return ''
|
||||||
}
|
}
|
||||||
return "\r\n" + formatExif(file.exif) + formatVideo(file.video)
|
return "\r\n" + formatExif(file.exif) + formatVideo(file.video)
|
||||||
},
|
},
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
<script>
|
<script>
|
||||||
|
|
||||||
import api from "@/api/file-api"
|
import api from "@/api/file-api"
|
||||||
|
import settingApi from "@/api/setting-api"
|
||||||
import fileConfig from "@/utils/file-config";
|
import fileConfig from "@/utils/file-config";
|
||||||
import SparkMD5 from 'spark-md5'
|
import SparkMD5 from 'spark-md5'
|
||||||
import HistoryPopover from "@/components/HistoryPopover/index.vue";
|
import HistoryPopover from "@/components/HistoryPopover/index.vue";
|
||||||
@ -79,7 +80,12 @@ export default {
|
|||||||
historyPageIndex: 1,
|
historyPageIndex: 1,
|
||||||
historyPageSize: 50,
|
historyPageSize: 50,
|
||||||
viewHistory: false,
|
viewHistory: false,
|
||||||
historyOperationLoading: false
|
historyOperationLoading: false,
|
||||||
|
officeServerConfig: {
|
||||||
|
documentServer: undefined,
|
||||||
|
callbackServer: undefined,
|
||||||
|
tokenEnabled: false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
@ -97,24 +103,9 @@ export default {
|
|||||||
if (!id) {
|
if (!id) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let officeApiUrl = fileConfig.officeApiUrl()
|
settingApi.getOfficeConfig().then(res => {
|
||||||
$J.loadScript($J.apiUrl(officeApiUrl), (e) => {
|
this.officeServerConfig = res.data
|
||||||
if (e !== null) {
|
this.loadOfficeApi()
|
||||||
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()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
immediate: true,
|
immediate: true,
|
||||||
@ -138,6 +129,27 @@ export default {
|
|||||||
destroyed() {
|
destroyed() {
|
||||||
},
|
},
|
||||||
methods: {
|
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}) {
|
viewHistoryFile({historyInfo}) {
|
||||||
const historyUrl = window.location.origin + fileConfig.previewHistoryUrl(historyInfo.id, this.$store.state.user.name, this.$store.state.user.token)
|
const historyUrl = window.location.origin + fileConfig.previewHistoryUrl(historyInfo.id, this.$store.state.user.name, this.$store.state.user.token)
|
||||||
this.onRequestHistoryData(null, historyInfo, historyUrl)
|
this.onRequestHistoryData(null, historyInfo, historyUrl)
|
||||||
@ -231,15 +243,23 @@ export default {
|
|||||||
this.destroyEditor()
|
this.destroyEditor()
|
||||||
|
|
||||||
const file_username = this.sharer ? this.sharer : this.$store.state.user.name
|
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)}`
|
let callbackServer = this.officeServerConfig.callbackServer
|
||||||
if (this.readOnly && window.shareId) {
|
if (callbackServer) {
|
||||||
this.fileUrl = window.location.origin + fileConfig.publicPreviewUrl(this.file, window.shareId, this.$store.getters.shareToken)
|
if (callbackServer.endsWith('/')) {
|
||||||
this.fileKey = `${new Date(this.file.updateDate).getTime()}-${SparkMD5.hash(window.shareId)}`
|
// 去掉最后的/
|
||||||
|
callbackServer = callbackServer.substring(0, this.officeServerConfig.callbackServer.length - 1)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callbackServer = window.location.origin
|
||||||
}
|
}
|
||||||
|
this.fileUrl = fileConfig.previewUrl(file_username, this.file, this.$store.getters.token, undefined, callbackServer)
|
||||||
let callbackUrl = fileConfig.officeCallBackUrl(this.$store.getters.token, this.$store.getters.name, this.file.id)
|
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 = {
|
this.docEditorConfig = {
|
||||||
document: {
|
document: {
|
||||||
fileType: this.fileType,
|
fileType: this.fileType,
|
||||||
@ -280,14 +300,20 @@ export default {
|
|||||||
this.loadOffice(res.data)
|
this.loadOffice(res.data)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
api.getOfficeJwt(this.docEditorConfig).then(res => {
|
if (this.officeServerConfig.tokenEnabled) {
|
||||||
this.loadOffice(res.data)
|
api.getOfficeJwt(this.docEditorConfig).then(res => {
|
||||||
})
|
this.loadOffice(res.data)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.loadOffice()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
loadOffice(token) {
|
loadOffice(token) {
|
||||||
this.docEditorConfig.token = token
|
if (token) {
|
||||||
|
this.docEditorConfig.token = token
|
||||||
|
}
|
||||||
if (!this.$pc) {
|
if (!this.$pc) {
|
||||||
this.docEditorConfig.type = 'mobile'
|
this.docEditorConfig.type = 'mobile'
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,17 +12,23 @@ export default {
|
|||||||
return window.location.origin + `/webDAV/${username}`
|
return window.location.origin + `/webDAV/${username}`
|
||||||
},
|
},
|
||||||
// office api url
|
// office api url
|
||||||
officeApiUrl: function() {
|
officeApiUrl: function(documentServer) {
|
||||||
const url = window._env_.API_OFFICE_URL || process.env.API_OFFICE_URL || `${window.location.origin}/office`
|
let serverUrl = documentServer || window._env_.API_URL || process.env.API_URL || `${window.location.origin}/office`
|
||||||
return `${url}/web-apps/apps/api/documents/api.js`
|
if (!serverUrl.endsWith('/')) {
|
||||||
|
serverUrl = serverUrl + "/"
|
||||||
|
}
|
||||||
|
return serverUrl + "web-apps/apps/api/documents/api.js"
|
||||||
},
|
},
|
||||||
// office回调url
|
// office回调url
|
||||||
officeCallBackUrl: function(token, username, fileId) {
|
officeCallBackUrl: function(callbackServer, token, username, fileId) {
|
||||||
const url = window._env_.API_URL || process.env.API_URL || 'http://jmalcloud:8088'
|
let callbackServerUrl = callbackServer || window._env_.API_URL || process.env.API_URL || 'http://jmalcloud:8088'
|
||||||
return `${url}/office/track?jmal-token=${token}&name=${username}&fileId=${fileId}`
|
if (!callbackServerUrl.endsWith('/')) {
|
||||||
|
callbackServerUrl = callbackServerUrl + "/"
|
||||||
|
}
|
||||||
|
return `${callbackServerUrl}office/track?jmal-token=${token}&name=${username}&fileId=${fileId}`
|
||||||
},
|
},
|
||||||
// 预览文件的url
|
// 预览文件的url
|
||||||
previewUrl: function(username, file, token, shareToken) {
|
previewUrl: function(username, file, token, shareToken, serverUrl) {
|
||||||
let owner = null
|
let owner = null
|
||||||
if (username !== store.getters.name || localStorage.getItem('mountFileOwner') !== null) {
|
if (username !== store.getters.name || localStorage.getItem('mountFileOwner') !== null) {
|
||||||
owner = localStorage.getItem('mountFileOwner')
|
owner = localStorage.getItem('mountFileOwner')
|
||||||
@ -32,7 +38,8 @@ export default {
|
|||||||
if (owner == null) {
|
if (owner == null) {
|
||||||
owner = store.getters.name
|
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, '/')
|
fileUrl = fileUrl.replace(/%5C/g, '/')
|
||||||
if (token) {
|
if (token) {
|
||||||
return `${fileUrl}?jmal-token=${token}&name=${username}`
|
return `${fileUrl}?jmal-token=${token}&name=${username}`
|
||||||
@ -80,11 +87,12 @@ export default {
|
|||||||
window.open(url, '_blank')
|
window.open(url, '_blank')
|
||||||
},
|
},
|
||||||
// 共享文件预览Url
|
// 共享文件预览Url
|
||||||
publicPreviewUrl: function(file, shareId, shareToken) {
|
publicPreviewUrl: function(file, shareId, shareToken, serverUrl) {
|
||||||
if (!shareToken) {
|
if (!shareToken) {
|
||||||
shareToken = "none"
|
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) {
|
publicPackageDownload: function(shareId, fileIds, shareToken) {
|
||||||
|
|||||||
@ -65,13 +65,18 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
</el-tab-pane>
|
</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">
|
<el-tab-pane label="视频转码" name="3" class="setting-tab-panel">
|
||||||
<div v-if="activeName === '3'">
|
<div v-if="activeName === '3'">
|
||||||
<transcode-config></transcode-config>
|
<transcode-config></transcode-config>
|
||||||
</div>
|
</div>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="LDAP认证" name="2" class="setting-tab-panel">
|
<el-tab-pane label="LDAP认证" name="4" class="setting-tab-panel">
|
||||||
<div v-if="activeName === '2'">
|
<div v-if="activeName === '4'">
|
||||||
<ldap-config></ldap-config>
|
<ldap-config></ldap-config>
|
||||||
</div>
|
</div>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
@ -91,11 +96,12 @@ import UploadImageInput from "@/components/input/UploadImageInput.vue";
|
|||||||
import {mapGetters, mapState} from "vuex";
|
import {mapGetters, mapState} from "vuex";
|
||||||
import store from "@/store";
|
import store from "@/store";
|
||||||
import TaskProgress from "@/components/TaskProgress/index.vue";
|
import TaskProgress from "@/components/TaskProgress/index.vue";
|
||||||
import LdapConfig from "@/views/setting/ldapConfig.vue";
|
import LdapConfig from "@/views/setting/cloudSetting/ldapConfig.vue";
|
||||||
import TranscodeConfig from "@/views/setting/transcodeConfig.vue";
|
import TranscodeConfig from "@/views/setting/cloudSetting/transcodeConfig.vue";
|
||||||
|
import OfficeConfig from "@/views/setting/cloudSetting/officeConfig.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {TranscodeConfig, LdapConfig, TaskProgress, UploadImageInput, Logo},
|
components: {OfficeConfig, TranscodeConfig, LdapConfig, TaskProgress, UploadImageInput, Logo},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
activeName: '1',
|
activeName: '1',
|
||||||
|
|||||||
83
src/views/setting/cloudSetting/officeConfig.vue
Normal file
83
src/views/setting/cloudSetting/officeConfig.vue
Normal 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>
|
||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container">
|
<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">
|
style="width: 520px" autocomplete="off">
|
||||||
<el-form-item label="功能状态" prop="enable">
|
<el-form-item label="功能状态" prop="enable">
|
||||||
<el-select v-model="configFormData.enable">
|
<el-select v-model="configFormData.enable">
|
||||||
@ -74,8 +74,12 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
saveConfig() {
|
saveConfig() {
|
||||||
|
this.saveConfigLoading = true
|
||||||
settingApi.setTranscodeConfig(this.configFormData).then(() => {
|
settingApi.setTranscodeConfig(this.configFormData).then(() => {
|
||||||
|
this.saveConfigLoading = false
|
||||||
this.$message.success('保存成功')
|
this.$message.success('保存成功')
|
||||||
|
}).catch(() => {
|
||||||
|
this.saveConfigLoading = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user