diff --git a/frontend/package.json b/frontend/package.json index f2fc11ddf0..878dfb942d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -45,6 +45,7 @@ "js-cookie": "2.2.0", "jsencrypt": "^3.0.0-rc.1", "jspdf": "^2.3.1", + "jszip": "^3.10.1", "lodash": "^4.17.21", "lodash.isboolean": "^3.0.3", "lodash.isempty": "^4.4.0", diff --git a/frontend/src/lang/en.js b/frontend/src/lang/en.js index 93d33ac9c0..db216eed33 100644 --- a/frontend/src/lang/en.js +++ b/frontend/src/lang/en.js @@ -2640,8 +2640,13 @@ export default { dataset_group: 'Dataset group', panel: 'Panel', log_delete_tips: 'Are you sure to delete this application record?', - log_resource_delete_tips: 'Delete related resources (irrecoverable after deletion)' - + log_resource_delete_tips: 'Delete related resources (irrecoverable after deletion)', + file_error_tips: 'The relevant data file is not found. The current file may not be a DataEase application file, or the file may be damaged ', + app_export: 'Application export', + app_version: 'Application version', + program_version: 'DataEase minimum version', + creator: 'Author', + export: 'Export' }, logout: { diff --git a/frontend/src/lang/tw.js b/frontend/src/lang/tw.js index 8ce8d0a586..5b22d42f9d 100644 --- a/frontend/src/lang/tw.js +++ b/frontend/src/lang/tw.js @@ -2630,7 +2630,6 @@ export default { search_by_keyword: '通過關鍵字搜索', apply_logs: '應用記錄', app_group_delete_tips: '確定刪除該應用分類嗎?', - app_group_delete_content: '刪除後,該分類中所有的應用模板也將被刪除。', panel_position: '儀表板位置', panel_name: '儀表板名稱', @@ -2641,8 +2640,13 @@ export default { dataset_group: '數據集分組', panel: '儀表板', log_delete_tips: '確定刪除該條應用記錄嗎?', - log_resource_delete_tips: '刪除相關資源(刪除後不可恢復)' - + log_resource_delete_tips: '刪除相關資源(刪除後不可恢復)', + file_error_tips: '未找到相關數據文件,當前文件可能不是DataEase應用文件,或者文件已經損壞', + app_export: '应用导出', + app_version: '应用版本', + program_version: 'DataEase最低版本', + creator: '作者', + export: '导出' }, logout: { diff --git a/frontend/src/lang/zh.js b/frontend/src/lang/zh.js index 40b73f8d17..71ae979218 100644 --- a/frontend/src/lang/zh.js +++ b/frontend/src/lang/zh.js @@ -2630,7 +2630,6 @@ export default { search_by_keyword: '通过关键字搜索', apply_logs: '应用记录', app_group_delete_tips: '确定删除该应用分类吗?', - app_group_delete_content: '删除后,该分类中所有的应用模板也将被删除。', panel_position: '仪表板位置', panel_name: '仪表板名称', @@ -2641,8 +2640,13 @@ export default { dataset_group: '数据集分组', panel: '仪表板', log_delete_tips: '确定删除该条应用记录吗?', - log_resource_delete_tips: '删除相关资源(删除后不可恢复)' - + log_resource_delete_tips: '删除相关资源(删除后不可恢复)', + file_error_tips: '未找到相关数据文件,当前文件可能不是DataEase应用文件,或者文件已经损坏', + app_export: '應用導出', + app_version: '應用版本', + program_version: 'DataEase最低版本', + creator: '作者', + export: '導出' }, logout: { diff --git a/frontend/src/store/index.js b/frontend/src/store/index.js index cb392e68eb..43c23ebf9f 100644 --- a/frontend/src/store/index.js +++ b/frontend/src/store/index.js @@ -259,7 +259,7 @@ const data = { } else { state.componentData.push(component) } - this.commit('setCurComponent', { component: component, index: index ? index : state.componentData.length - 1 }) + this.commit('setCurComponent', { component: component, index: index || state.componentData.length - 1 }) }, removeViewFilter(state, componentId) { state.componentData = state.componentData.map(item => { diff --git a/frontend/src/views/panel/appTemplate/component/TemplateImport.vue b/frontend/src/views/panel/appTemplate/component/TemplateImport.vue index fefb319acc..6220dde404 100644 --- a/frontend/src/views/panel/appTemplate/component/TemplateImport.vue +++ b/frontend/src/views/panel/appTemplate/component/TemplateImport.vue @@ -31,7 +31,7 @@ id="input" ref="files" type="file" - accept=".DEAPP" + accept=".zip" hidden @change="handleFileChange" > @@ -47,14 +47,16 @@ secondary @click="cancel()" >{{ - $t("commons.cancel") - }} + $t('commons.cancel') + }} + {{ - $t("commons.confirm") - }} + $t('commons.confirm') + }} + @@ -64,6 +66,7 @@ import { save, update, nameCheck } from '@/api/system/appTemplate' import msgCfm from '@/components/msgCfm/index' import { find } from '@/api/system/template' import { imgUrlTrans } from '@/components/canvas/utils/utils' +import JSZip from 'jszip' export default { mixins: [msgCfm], @@ -186,22 +189,31 @@ export default { }) }, handleFileChange(e) { + const jsZip = new JSZip() const file = e.target.files[0] - const reader = new FileReader() const _this = this - reader.onload = (res) => { - _this.appResultInfo = JSON.parse(res.target.result) - _this.importTemplateInfo = JSON.parse(this.appResultInfo.panelInfo) - _this.templateInfo.name = this.importTemplateInfo.name - _this.templateInfo.templateStyle = this.importTemplateInfo.panelStyle - _this.templateInfo.templateData = this.importTemplateInfo.panelData - _this.templateInfo.snapshot = this.importTemplateInfo.snapshot - _this.templateInfo.dynamicData = this.importTemplateInfo.dynamicData - _this.templateInfo.staticResource = - _this.importTemplateInfo.staticResource - _this.templateInfo.nodeType = 'template' - } - reader.readAsText(file) + jsZip.loadAsync(file).then(function(file) { + jsZip.file('DATA_RELATION.DE').async('string').then(function(content) { + _this.appResultInfo = { ...JSON.parse(content), ..._this.appResultInfo } + }) + jsZip.file('APP.json').async('string').then(function(content) { + _this.appResultInfo['applicationInfo'] = content + const appInfo = JSON.parse(content) + _this.templateInfo.name = appInfo.appName + }) + jsZip.file('TEMPLATE.DET').async('string').then(function(content) { + _this.appResultInfo['panelInfo'] = content + _this.importTemplateInfo = JSON.parse(content) + _this.templateInfo.templateStyle = _this.importTemplateInfo.panelStyle + _this.templateInfo.templateData = _this.importTemplateInfo.panelData + _this.templateInfo.snapshot = _this.importTemplateInfo.snapshot + _this.templateInfo.dynamicData = _this.importTemplateInfo.dynamicData + _this.templateInfo.staticResource = _this.importTemplateInfo.staticResource + _this.templateInfo.nodeType = 'template' + }) + }).catch(() => { + _this.$warning(this.$t('app_template.file_error_tips')) + }) }, goFile() { this.$refs.files.click() @@ -216,10 +228,12 @@ export default { border: none; padding: 0 0; } + .my_table ::v-deep .el-table th.is-leaf { /* 去除上边框 */ border: none; } + .my_table ::v-deep .el-table::before { /* 去除下边框 */ height: 0; @@ -229,6 +243,7 @@ export default { margin-top: 24px; text-align: right; } + .preview { margin-top: -12px; border: 1px solid #e6e6e6; @@ -237,6 +252,7 @@ export default { background-size: 100% 100% !important; border-radius: 4px; } + .preview-show { border-left: 1px solid #e6e6e6; height: 300px; @@ -250,6 +266,7 @@ export default { display: flex; align-items: center; justify-content: space-between; + .el-input { margin-right: 2px; flex: 1; diff --git a/frontend/src/views/panel/list/AppExportForm.vue b/frontend/src/views/panel/list/AppExportForm.vue new file mode 100644 index 0000000000..565b21f96b --- /dev/null +++ b/frontend/src/views/panel/list/AppExportForm.vue @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + {{ $t('commons.cancel') }} + + + {{ $t('app_template.export') }} + + + + + + + + diff --git a/frontend/src/views/panel/list/PanelViewShow.vue b/frontend/src/views/panel/list/PanelViewShow.vue index f4c4072332..fe6ff3bac8 100644 --- a/frontend/src/views/panel/list/PanelViewShow.vue +++ b/frontend/src/views/panel/list/PanelViewShow.vue @@ -120,7 +120,7 @@ >{{ $t('panel.export_to_img') }} {{ $t('panel.export_to_app') }} @@ -278,6 +278,48 @@ @closePreExport="closePreExport" /> + + + + + + + + + + + + + +