Skip to content

Commit

Permalink
feat: 文件在线预览支持更多的文件类型 #2765
Browse files Browse the repository at this point in the history
  • Loading branch information
lannoy0523 committed Jan 6, 2025
1 parent b1d844a commit a9ef42f
Show file tree
Hide file tree
Showing 9 changed files with 189 additions and 16 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/frontend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ jobs:

steps:
- uses: actions/checkout@v2

- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: '18' # 或者您需要的其他版本

- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
Expand Down
26 changes: 26 additions & 0 deletions src/frontend/devops-repository/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<script src="/ui/libs/vuex.min.js"></script>
<script src="/ui/libs/vue-router.min.js"></script>
<script src="/ui/libs/jsencrypt.min.js"></script>
<script src="/ui/watermark.js"></script>
<link rel='preload' as='script' href="/ui/libs/bk-magic-vue/bk-magic-vue.min.js" />
<link href="/ui/libs/bk-magic-vue/bk-magic-vue.min.css" rel="stylesheet">
<link href="/ui/iconfont.css" rel="stylesheet">
Expand Down Expand Up @@ -167,6 +168,31 @@
+ '</div>'
)
}

function initWaterMark (param) {
watermark.init({
watermark_txt: param.watermarkTxt,
watermark_x: 0,
watermark_y: 0,
watermark_rows: 0,
watermark_cols: 0,
watermark_x_space: Number(param.watermarkXSpace),
watermark_y_space: Number(param.watermarkYSpace),
watermark_font: param.watermarkFont,
watermark_fontsize: param.watermarkFontsize,
watermark_color: param.watermarkColor,
watermark_alpha: param.watermarkAlpha,
watermark_width: Number(param.watermarkWidth),
watermark_height: Number(param.watermarkHeight),
watermark_angle: Number(param.watermarkAngle)
})
}

function resetWaterMark() {
watermark.init({
watermark_txt: ' '
})
}
</script>
<script src="/ui/libs/bk-magic-vue/bk-magic-vue.min.js"></script>
</body>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,21 @@
<span class="mt5 error-data-title">{{ $t('previewErrorTip') }}</span>
</div>
</div>
<div v-if="loading" class="mainBody">
<div class="iconBody">
<Icon name="loading" size="80" class="svg-loading" />
<span class="mainMessage">{{ $t('fileLoadingTip') }}</span>
</div>
</div>
</div>
</template>
<script>
import VueOfficeExcel from '@vue-office/excel'
import {
customizePreviewLocalOfficeFile, customizePreviewOfficeFile, customizePreviewRemoteOfficeFile
customizePreviewLocalOfficeFile,
customizePreviewOfficeFile,
customizePreviewRemoteOfficeFile,
getPreviewLocalOfficeFileInfo, getPreviewRemoteOfficeFileInfo
} from '@/utils/previewOfficeFile'
import { mapActions } from 'vuex'
import { Base64 } from 'js-base64'
Expand Down Expand Up @@ -63,7 +72,8 @@
basicFileText: '',
hasError: false,
pageUrl: '',
showFrame: true
showFrame: false,
loading: false
}
},
computed: {
Expand All @@ -72,6 +82,7 @@
}
},
async created () {
this.loading = true
if (this.filePath.endsWith('txt')
|| this.filePath.endsWith('sh')
|| this.filePath.endsWith('bat')
Expand All @@ -89,20 +100,24 @@
repoName: this.repoName,
path: '/' + this.filePath
}).then(res => {
this.loading = false
this.previewBasic = true
this.basicFileText = res
}).catch((e) => {
this.loading = false
this.hasError = true
})
} else if (this.filePath.endsWith('.xlsx')
) {
} else if (this.filePath.endsWith('.xlsx')) {
customizePreviewOfficeFile(this.projectId, this.repoName, '/' + this.filePath).then(res => {
this.loading = false
this.previewExcel = true
this.dataSource = res.data
}).catch((e) => {
this.loading = false
this.hasError = true
})
} else if (this.filePath.endsWith('docx')
|| this.filePath.endsWith('pdf')
|| this.filePath.endsWith('wps')
|| this.filePath.endsWith('doc')
|| this.filePath.endsWith('docm')
Expand Down Expand Up @@ -142,23 +157,38 @@
|| this.filePath.endsWith('pages')
|| this.filePath.endsWith('eps')) {
if (this.repoType === 'local') {
getPreviewLocalOfficeFileInfo(this.projectId, this.repoName, '/' + this.filePath).then(res => {
if (res.data.data.watermark && res.data.data.watermark.watermarkTxt && res.data.data.watermark.watermarkTxt != null) {
this.initWaterMark(res.data.data.watermark)
}
})
customizePreviewLocalOfficeFile(this.projectId, this.repoName, '/' + this.filePath).then(async res => {
const url = URL.createObjectURL(res.data)
this.loading = false
const url = URL.createObjectURL(res.data) + '#toolbar=0&navpanes=0'
this.showFrame = true
this.pageUrl = url
}).catch(() => {
this.loading = false
this.hasError = true
})
} else {
getPreviewRemoteOfficeFileInfo(Base64.encode(Base64.decode(this.extraParam))).then(res => {
if (res.data.data.watermark && res.data.data.watermark.watermarkTxt && res.data.data.watermark.watermarkTxt != null) {
this.initWaterMark(res.data.data.watermark)
}
})
customizePreviewRemoteOfficeFile(Base64.encode(Base64.decode(this.extraParam))).then(res => {
const url = URL.createObjectURL(res.data)
this.loading = false
const url = URL.createObjectURL(res.data)+ '#toolbar=0&navpanes=0'
this.showFrame = true
this.pageUrl = url
}).catch(() => {
this.loading = false
this.hasError = true
})
}
} else {
this.loading = false
this.hasError = true
}
},
Expand All @@ -176,6 +206,9 @@
this.showFrame = false
this.pageUrl = ''
this.hasError = false
},
initWaterMark (param) {
window.initWaterMark(param)
}
}
}
Expand All @@ -201,4 +234,31 @@
font-size: 24px;
line-height: 32px;
}
.mainBody {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
.svg-loading {
margin-right: 10px;
animation: rotate-loading 1s linear infinite;
}
.iconBody{
display: flex;
align-items: center;
justify-content: center;
}
.mainMessage{
font-size: 16px;
}
@keyframes rotate-loading {
0% {
transform: rotateZ(0);
}
100% {
transform: rotateZ(360deg);
}
}
}
</style>
25 changes: 24 additions & 1 deletion src/frontend/devops-repository/src/utils/previewOfficeFile.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,32 @@ export function customizePreviewOfficeFile (projectId, repoName, fullPath) {
})
}

export function getPreviewLocalOfficeFileInfo (projectId, repoName, fullPath) {
const url = projectId + '/' + repoName + fullPath
return axios({
url: `${location.origin}/web/preview/api/file/getPreviewInfo/` + url,
method: 'get',
withCredentials: true,
xsrfCookieName: (MODE_CONFIG === 'ci' || MODE_CONFIG === 'saas') ? 'bk_token' : 'bkrepo_ticket', // 注入csrfToken
xsrfHeaderName: 'X-CSRFToken' // 注入csrfToken
})
}

export function getPreviewRemoteOfficeFileInfo(extraParam) {
return axios({
url: `${location.origin}/web/preview/api/file/getPreviewInfo/`,
method: 'get',
params: {
extraParam: extraParam
},
withCredentials: true,
xsrfCookieName: (MODE_CONFIG === 'ci' || MODE_CONFIG === 'saas') ? 'bk_token' : 'bkrepo_ticket', // 注入csrfToken
xsrfHeaderName: 'X-CSRFToken' // 注入csrfToken
})
}

export function customizePreviewLocalOfficeFile (projectId, repoName, fullPath) {
const url = projectId + '/' + repoName + fullPath
console.log(url)
return axios({
url: `${location.origin}/web/preview/api/file/onlinePreview/` + url,
method: 'get',
Expand Down
1 change: 1 addition & 0 deletions src/frontend/devops-repository/src/views/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
menuList () {
const routerName = this.$route.name
if (routerName === '440' || routerName === 'filePreview') this.routerStatus = false
if (routerName !== 'filePreview') window.resetWaterMark()
if (MODE_CONFIG === 'ci' || this.projectList.length) {
const showRepoScan = RELEASE_MODE !== 'community' || SHOW_ANALYST_MENU
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,23 @@
:options="excelOptions"
style="height: 100vh;"
/>
<div v-if="loading" class="mainBody">
<div class="iconBody">
<Icon name="loading" size="80" class="svg-loading" />
<span class="mainMessage">{{ $t('fileLoadingTip') }}</span>
</div>
</div>
</div>
</bk-dialog>
</template>

<script>
import VueOfficeExcel from '@vue-office/excel'
import {
customizePreviewLocalOfficeFile, customizePreviewOfficeFile, customizePreviewRemoteOfficeFile
customizePreviewLocalOfficeFile,
customizePreviewOfficeFile,
customizePreviewRemoteOfficeFile,
getPreviewLocalOfficeFileInfo, getPreviewRemoteOfficeFileInfo
} from '@repository/utils/previewOfficeFile'
export default {
Expand Down Expand Up @@ -57,7 +66,8 @@
pageUrl: '',
extraParam: '',
repoType: '',
showFrame: false
showFrame: false,
loading: false
}
},
methods: {
Expand All @@ -77,11 +87,18 @@
})
})
} else {
this.loading = true
this.$refs.showData.style.height = '800px'
if (this.repoType === 'local') {
customizePreviewLocalOfficeFile(this.projectId, this.repoName, '/' + this.filePath).then(res => {
getPreviewLocalOfficeFileInfo(this.projectId, this.repoName, '/' + this.filePath).then(res => {
if (res.data.data.watermark && res.data.data.watermark.watermarkTxt && res.data.data.watermark.watermarkTxt != null) {
this.initWaterMark(res.data.data.watermark)
}
})
customizePreviewLocalOfficeFile(this.projectId, this.repoName, this.filePath).then(res => {
this.loading = false
this.showFrame = true
const url = URL.createObjectURL(res.data)
const url = URL.createObjectURL(res.data) + '#toolbar=0&navpanes=0'
this.pageUrl = url
}).catch((e) => {
this.cancel()
Expand All @@ -92,9 +109,15 @@
})
})
} else {
getPreviewRemoteOfficeFileInfo(this.extraParam).then(res => {
if (res.data.data.watermark && res.data.data.watermark.watermarkTxt && res.data.data.watermark.watermarkTxt != null) {
this.initWaterMark(res.data.data.watermark)
}
})
customizePreviewRemoteOfficeFile(this.extraParam).then(res => {
this.loading = false
this.showFrame = true
const url = URL.createObjectURL(res.data)
const url = URL.createObjectURL(res.data)+ '#toolbar=0&navpanes=0'
this.pageUrl = url
}).catch((e) => {
this.cancel()
Expand All @@ -113,16 +136,19 @@
}
},
cancel () {
this.loading = false
this.previewDialog.show = false
this.filePath = ''
this.projectId = ''
this.repoName = ''
this.dataSource = ''
this.previewDocx = false
this.previewExcel = false
this.previewPdf = false
this.pageUrl = ''
this.showFrame = false
window.resetWaterMark()
},
initWaterMark (param) {
window.initWaterMark(param)
}
}
}
Expand All @@ -135,4 +161,32 @@
margin-bottom: 10px;
color: #707070;
}
.mainBody {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
.svg-loading {
margin-right: 10px;
animation: rotate-loading 1s linear infinite;
}
.iconBody{
display: flex;
align-items: center;
justify-content: center;
}
.mainMessage{
font-size: 16px;
}
@keyframes rotate-loading {
0% {
transform: rotateZ(0);
}
100% {
transform: rotateZ(360deg);
}
}
}
</style>
1 change: 1 addition & 0 deletions src/frontend/devops-repository/static/watermark.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion src/frontend/locale/repository/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -903,5 +903,6 @@
"conanCreditGuideSubTitle2":"2、Execute the following command on the command line to configure artifact repository credentials(conan1.x)",
"conanRecipePlaceholder":"The format of RECIPE is <NAME>/VERSION>@<USER>/CHANNEL>",
"conanPullGuideSubTitle":"Please execute the following command on the command line to pull(conan1.x):",
"projectNoPermissionTip": "Request project {0} has no permission and has been switched"
"projectNoPermissionTip": "Request project {0} has no permission and has been switched",
"fileLoadingTip": "File loading,Please wait"
}
3 changes: 2 additions & 1 deletion src/frontend/locale/repository/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -906,5 +906,6 @@
"conanCreditGuideSubTitle2":"2、在命令行执行以下命令配置制品仓库凭据(conan1.x)",
"conanRecipePlaceholder":"RECIPE的格式为<NAME>/VERSION>@<USER>/CHANNEL>",
"conanPullGuideSubTitle":"请在命令行执行以下命令进行拉取(conan1.x):",
"projectNoPermissionTip": "请求项目{0}无权限,已切换"
"projectNoPermissionTip": "请求项目{0}无权限,已切换",
"fileLoadingTip": "文件加载中,请稍后"
}

0 comments on commit a9ef42f

Please sign in to comment.