Commit ed4c035db03ced5adeb777f486059eda67ee0b61
Merge branch 'fix/teambition/10-17/2024' into 'main_dev'
fix(src/packages): 新增或者编辑3D模型编辑器,携带区分标识,云端大屏绑定摄像头点击全屏后,视频暂停了 See merge request yunteng/thingskit-view!294
Showing
16 changed files
with
197 additions
and
78 deletions
1 | 1 | <!DOCTYPE html> |
2 | 2 | <html lang="en"> |
3 | + <head> | |
4 | + <title>ThingsKit 3D Model Editor</title> | |
5 | + <meta charset="utf-8" /> | |
6 | + <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" /> | |
7 | + </head> | |
3 | 8 | |
4 | -<head> | |
5 | - <title>3D Model Editor</title> | |
6 | - <meta charset="utf-8"> | |
7 | - <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> | |
8 | -</head> | |
9 | - | |
10 | -<body> | |
11 | - <link rel="stylesheet" href="css/main.css"> | |
12 | - <link rel="stylesheet" href="js/libs/codemirror/codemirror.css"> | |
13 | - <link rel="stylesheet" href="js/libs/codemirror/theme/monokai.css"> | |
14 | - <link rel="stylesheet" href="js/libs/codemirror/addon/dialog.css"> | |
15 | - <link rel="stylesheet" href="js/libs/codemirror/addon/show-hint.css"> | |
16 | - <link rel="stylesheet" href="js/libs/codemirror/addon/tern.css"> | |
17 | - | |
18 | - <script type="module" src="./jsm/libs/draco/draco_encoder.js"></script> | |
19 | - <script type="module" src="./js/libs/codemirror/codemirror.js"></script> | |
20 | - <script type="module" src="./js/libs/codemirror/mode/javascript.js"></script> | |
21 | - <script type="module" src="./js/libs/codemirror/mode/glsl.js"></script> | |
22 | - <script type="module" src="./js/libs/esprima.js"></script> | |
23 | - <script type="module" src="./js/libs/jsonlint.js"></script> | |
24 | - <script type="module" src="./js/libs/ffmpeg/ffmpeg.min.js"></script> | |
25 | - <script type="module" src="./js/libs/codemirror/addon/dialog.js"></script> | |
26 | - <script type="module" src="./js/libs/codemirror/addon/show-hint.js"></script> | |
27 | - <script type="module" src="./js/libs/codemirror/addon/tern.js"></script> | |
28 | - <script type="module" src="./js/libs/acorn/acorn.js"></script> | |
29 | - <script type="module" src="./js/libs/acorn/acorn_loose.js"></script> | |
30 | - <script type="module" src="./js/libs/acorn/walk.js"></script> | |
31 | - <script type="module" src="./js/libs/ternjs/polyfill.js"></script> | |
32 | - <script type="module" src="./js/libs/ternjs/signal.js"></script> | |
33 | - <script type="module" src="./js/libs/ternjs/tern.js"></script> | |
34 | - <script type="module" src="./js/libs/ternjs/def.js"></script> | |
35 | - <script type="module" src="./js/libs/ternjs/comment.js"></script> | |
36 | - <script type="module" src="./js/libs/ternjs/infer.js"></script> | |
37 | - <script type="module" src="./js/libs/ternjs/doc_comment.js"></script> | |
38 | - <script type="module" src="./js/libs/tern-threejs/threejs.js"></script> | |
39 | - <script type="module" src="./js/libs/signals.min.js"></script> | |
40 | - <script type="module" src="./js/libs/axios.min.js"></script> | |
41 | - <script type="module" src="./js/libs/http/config.js"></script> | |
42 | - | |
43 | - <script src="./main.js" type="module"></script> | |
44 | -</body> | |
45 | - | |
9 | + <body> | |
10 | + <link rel="stylesheet" href="css/main.css" /> | |
11 | + <link rel="stylesheet" href="js/libs/codemirror/codemirror.css" /> | |
12 | + <link rel="stylesheet" href="js/libs/codemirror/theme/monokai.css" /> | |
13 | + <link rel="stylesheet" href="js/libs/codemirror/addon/dialog.css" /> | |
14 | + <link rel="stylesheet" href="js/libs/codemirror/addon/show-hint.css" /> | |
15 | + <link rel="stylesheet" href="js/libs/codemirror/addon/tern.css" /> | |
16 | + <script type="module" src="./jsm/libs/draco/draco_encoder.js"></script> | |
17 | + <script type="module" src="./js/libs/codemirror/codemirror.js"></script> | |
18 | + <script type="module" src="./js/libs/codemirror/mode/javascript.js"></script> | |
19 | + <script type="module" src="./js/libs/codemirror/mode/glsl.js"></script> | |
20 | + <script type="module" src="./js/libs/esprima.js"></script> | |
21 | + <script type="module" src="./js/libs/jsonlint.js"></script> | |
22 | + <script type="module" src="./js/libs/ffmpeg/ffmpeg.min.js"></script> | |
23 | + <script type="module" src="./js/libs/codemirror/addon/dialog.js"></script> | |
24 | + <script type="module" src="./js/libs/codemirror/addon/show-hint.js"></script> | |
25 | + <script type="module" src="./js/libs/codemirror/addon/tern.js"></script> | |
26 | + <script type="module" src="./js/libs/acorn/acorn.js"></script> | |
27 | + <script type="module" src="./js/libs/acorn/acorn_loose.js"></script> | |
28 | + <script type="module" src="./js/libs/acorn/walk.js"></script> | |
29 | + <script type="module" src="./js/libs/ternjs/polyfill.js"></script> | |
30 | + <script type="module" src="./js/libs/ternjs/signal.js"></script> | |
31 | + <script type="module" src="./js/libs/ternjs/tern.js"></script> | |
32 | + <script type="module" src="./js/libs/ternjs/def.js"></script> | |
33 | + <script type="module" src="./js/libs/ternjs/comment.js"></script> | |
34 | + <script type="module" src="./js/libs/ternjs/infer.js"></script> | |
35 | + <script type="module" src="./js/libs/ternjs/doc_comment.js"></script> | |
36 | + <script type="module" src="./js/libs/tern-threejs/threejs.js"></script> | |
37 | + <script type="module" src="./js/libs/signals.min.js"></script> | |
38 | + <script type="module" src="./js/libs/axios.min.js"></script> | |
39 | + <script type="module" src="./js/libs/http/config.js"></script> | |
40 | + <script type="module" src="./main.js"></script> | |
41 | + </body> | |
46 | 42 | </html> | ... | ... |
... | ... | @@ -51,6 +51,8 @@ editor.storage.init(async function () { |
51 | 51 | const paramsStr = window.location.search |
52 | 52 | const params = new URLSearchParams(paramsStr) |
53 | 53 | const file_uuid = params.get('three_file_uuid') |
54 | + const actionType = params.get('action_type') | |
55 | + if (actionType === 'create') return | |
54 | 56 | const fileData = await getThreeJsModel(file_uuid) |
55 | 57 | if (!fileData) return |
56 | 58 | if (!fileData['content']) return | ... | ... |
... | ... | @@ -5,12 +5,13 @@ |
5 | 5 | <meta charset="UTF-8" /> |
6 | 6 | <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> |
7 | 7 | <meta name="renderer" content="webkit" /> |
8 | - <meta name="description" content="GoView 是高效、高性能的拖拽式低代码数据可视化开发平台,将页面元素封装为基础组件,无需编写代码即可完成业务需求。"> | |
9 | - <meta name="keywords" content="GoView,goview,低代码,可视化"> | |
10 | - <meta name="author" content="奔跑的面条,面条"> | |
8 | + <meta name="description" content="ThingsKit View 是高效、高性能的拖拽式低代码数据可视化开发平台,将页面元素封装为基础组件,无需编写代码即可完成业务需求。"> | |
9 | + <meta name="keywords" content="ThingsKit View,低代码,可视化"> | |
10 | + <meta name="author" content="ThingsKit"> | |
11 | 11 | <meta name="viewport" |
12 | 12 | content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=0" /> |
13 | 13 | <link rel="icon" href="./favicon.ico" /> |
14 | + <title>大屏设计器</title> | |
14 | 15 | <!-- <link rel="stylesheet" href="./index.css" /> --> |
15 | 16 | <style> |
16 | 17 | * { | ... | ... |
1 | 1 | <template> |
2 | 2 | <div class="go-apple-control-btn"> |
3 | 3 | <template v-for="item in filterBtnList" :key="item.key"> |
4 | - <div | |
5 | - class="btn" | |
6 | - :class="[item.key, disabled && 'disabled', mini && 'mini']" | |
7 | - @click.stop="handleClick(item.key)" | |
8 | - > | |
9 | - <n-icon size="10" class="icon-base" :class="{ hover: !disabled }"> | |
10 | - <component :is="item.icon"></component> | |
11 | - </n-icon> | |
4 | + <div class="btn" :class="[item.key, disabled && 'disabled', mini && 'mini']" @click.stop="handleClick(item.key)"> | |
5 | + <n-tooltip trigger="hover"> | |
6 | + <template #trigger> | |
7 | + <n-icon size="10" class="icon-base" :class="{ hover: !disabled }"> | |
8 | + <component :is="item.icon"></component> | |
9 | + </n-icon> | |
10 | + </template> | |
11 | + {{ item.title }} | |
12 | + </n-tooltip> | |
12 | 13 | </div> |
13 | 14 | </template> |
14 | 15 | </div> |
... | ... | @@ -50,7 +51,7 @@ const props = defineProps({ |
50 | 51 | }) |
51 | 52 | const t = window['$t'] |
52 | 53 | |
53 | -const { CloseIcon, RemoveIcon, ResizeIcon } = icon.ionicons5 | |
54 | +const { CloseIcon, RemoveIcon, BrowsersOutlineIcon } = icon.ionicons5 | |
54 | 55 | |
55 | 56 | const filterBtnList = computed(() => { |
56 | 57 | const res = btnList.filter(e => { |
... | ... | @@ -69,19 +70,19 @@ const btnList: { |
69 | 70 | icon: any |
70 | 71 | }[] = [ |
71 | 72 | { |
72 | - title: t('common.closeText'), | |
73 | + title: t('common.delText'), | |
73 | 74 | key: 'close', |
74 | 75 | icon: CloseIcon |
75 | 76 | }, |
76 | 77 | { |
77 | - title: t('common.reduceText'), | |
78 | + title: t('common.reduceText'), | |
78 | 79 | key: 'remove', |
79 | 80 | icon: RemoveIcon |
80 | 81 | }, |
81 | 82 | { |
82 | - title: isFull.value ? t('common.reduceText') : t('common.amplifyText'), | |
83 | + title: isFull.value ? t('common.loadThreeModel') : t('common.loadThreeModel'), | |
83 | 84 | key: props.narrow ? 'fullResize' : 'resize', |
84 | - icon: ResizeIcon | |
85 | + icon: BrowsersOutlineIcon | |
85 | 86 | } |
86 | 87 | ] |
87 | 88 | ... | ... |
... | ... | @@ -6,6 +6,13 @@ import cloneDeep from 'lodash/cloneDeep' |
6 | 6 | |
7 | 7 | export const option = { |
8 | 8 | dataset: '', |
9 | + backgroundColor: '', //场景背景色 | |
10 | + backgroundAlpha: 0, //场景透明度 | |
11 | + borderConfig: { | |
12 | + color: 'grey', | |
13 | + size: 1, | |
14 | + show: false | |
15 | + } | |
9 | 16 | } |
10 | 17 | |
11 | 18 | export default class Config extends PublicConfigClass implements CreateComponentType { | ... | ... |
1 | 1 | <template> |
2 | - <!-- <collapse-item :name="t('component.treeConfig')" :expanded="true"> | |
2 | + <collapse-item :name="t('component.treeConfig')" :expanded="true"> | |
3 | 3 | <setting-item-box :name="t('component.borderConfig')"> |
4 | - <setting-item :name="t('common.colorText')"> </setting-item> | |
4 | + <setting-item :name="t('common.colorText')"> | |
5 | + <n-color-picker size="small" :show-alpha="false" v-model:value="optionData.borderConfig.color"></n-color-picker> | |
6 | + </setting-item> | |
7 | + <setting-item :name="t('component.openBorder')"> | |
8 | + <n-switch v-model:value="optionData.borderConfig.show" size="small" /> | |
9 | + </setting-item> | |
10 | + <setting-item :name="t('charts.chart.sizeText')"> | |
11 | + <n-input-number :min="0" v-model:value="optionData.borderConfig.size" size="small" /> | |
12 | + </setting-item> | |
5 | 13 | </setting-item-box> |
6 | - </collapse-item> --> | |
14 | + </collapse-item> | |
7 | 15 | </template> |
8 | 16 | |
9 | 17 | <script setup lang="ts"> |
10 | 18 | import { PropType } from 'vue' |
11 | 19 | import { option } from './config' |
12 | -// import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' | |
20 | +import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' | |
13 | 21 | |
14 | 22 | defineProps({ |
15 | 23 | optionData: { |
... | ... | @@ -18,7 +26,7 @@ defineProps({ |
18 | 26 | } |
19 | 27 | }) |
20 | 28 | |
21 | -// const t = window['$t'] | |
29 | +const t = window['$t'] | |
22 | 30 | </script> |
23 | 31 | |
24 | 32 | <style lang="scss" scoped></style> | ... | ... |
1 | 1 | <template> |
2 | - <div class="go-content-box"> | |
2 | + <div class="go-content-box" :style="{ border: !borderConfig.show ? 'none' : '' }"> | |
3 | 3 | <div> |
4 | 4 | <vue3dLoader |
5 | 5 | ref="vue3dLoaderRef" |
6 | 6 | :requestHeader="headers" |
7 | + :backgroundColor="backgroundColor" | |
8 | + :backgroundAlpha="backgroundAlpha" | |
7 | 9 | :webGLRendererOptions="webGLRendererOptions" |
8 | 10 | :height="h" |
9 | 11 | :width="w" |
... | ... | @@ -69,12 +71,15 @@ const onProcess = (event: Recordable) => { |
69 | 71 | |
70 | 72 | const { w, h } = toRefs(props.chartConfig.attr) |
71 | 73 | |
72 | -const { dataset } = toRefs(props.chartConfig.option) as Recordable | |
74 | +const { dataset, backgroundColor, backgroundAlpha,borderConfig } = toRefs(props.chartConfig.option) as Recordable | |
73 | 75 | </script> |
74 | 76 | |
75 | 77 | <style lang="scss" scoped> |
76 | 78 | .go-content-box { |
77 | 79 | height: 100%; |
80 | + border-width: v-bind('borderConfig.size + "px"'); | |
81 | + border-style: solid; | |
82 | + border-color: v-bind('borderConfig.color'); | |
78 | 83 | .process { |
79 | 84 | position: absolute; |
80 | 85 | top: 50%; | ... | ... |
... | ... | @@ -70,13 +70,14 @@ async function doPlaySource(params?: Dataset) { |
70 | 70 | } |
71 | 71 | |
72 | 72 | function handleOnUserAction(event: UserActionEventType) { |
73 | - const { from, to } = event | |
73 | + console.log(event) | |
74 | + const { from, to, pluginName } = event | |
74 | 75 | if (from && !to) { |
75 | 76 | doPlaySource(dataset?.value) |
76 | 77 | nextTick(() => { |
77 | 78 | XGPlayerRef.value?.getPlayerInstance()?.play() |
78 | 79 | }) |
79 | - } else if (!from && to) { | |
80 | + } else if (!from && to && pluginName !== "fullscreen") { | |
80 | 81 | nextTick(() => { |
81 | 82 | XGPlayerRef.value?.getPlayerInstance()?.pause() |
82 | 83 | }) | ... | ... |
1 | +<template> | |
2 | + <div class="go-content-box"> | |
3 | + <div> | |
4 | + <vue3dLoader | |
5 | + ref="vue3dLoaderRef" | |
6 | + :requestHeader="headers" | |
7 | + :webGLRendererOptions="webGLRendererOptions" | |
8 | + :height="200" | |
9 | + :width="400" | |
10 | + :filePath="threeModelPath" | |
11 | + @process="onProcess" | |
12 | + @load="onLoad" | |
13 | + :intersectRecursive="true" | |
14 | + /> | |
15 | + <div v-show="show" class="process"> | |
16 | + <span> 拼命加载中... </span> | |
17 | + <n-progress type="line" :color="themeColor" :percentage="process" :indicator-placement="'inside'" processing /> | |
18 | + </div> | |
19 | + </div> | |
20 | + </div> | |
21 | +</template> | |
22 | +<script setup lang="ts"> | |
23 | +import { ref, nextTick, computed } from 'vue' | |
24 | +import { vue3dLoader } from 'vue-3d-loader' | |
25 | +import { useDesignStore } from '@/store/modules/designStore/designStore' | |
26 | +import { getJwtToken } from '@/utils/external/auth' | |
27 | + | |
28 | +const designStore = useDesignStore() | |
29 | + | |
30 | +defineProps({ | |
31 | + threeModelPath: { | |
32 | + type: String, | |
33 | + default: '' | |
34 | + } | |
35 | +}) | |
36 | + | |
37 | +const themeColor = computed(() => { | |
38 | + return designStore.getAppTheme | |
39 | +}) | |
40 | + | |
41 | +const vue3dLoaderRef = ref(null) | |
42 | + | |
43 | +const headers = { | |
44 | + 'x-authorization': `Bearer ${getJwtToken()}` | |
45 | +} | |
46 | +const webGLRendererOptions = { | |
47 | + alpha: true, // 透明 | |
48 | + antialias: true, // 抗锯齿 | |
49 | + // fix: 预览三维图像需加上preserveDrawingBuffer: true | |
50 | + preserveDrawingBuffer: true //缩略图生效需开启 | |
51 | +} | |
52 | + | |
53 | +//三维模型加载 | |
54 | +const show = ref(false) | |
55 | + | |
56 | +const onLoad = async () => { | |
57 | + //加载完成 | |
58 | + await nextTick() | |
59 | + show.value = false | |
60 | +} | |
61 | + | |
62 | +//三维模型进度条 | |
63 | +const process = ref(0) | |
64 | + | |
65 | +const onProcess = (event: Recordable) => { | |
66 | + process.value = Math.floor((event.loaded / event.total) * 100) | |
67 | +} | |
68 | +</script> | |
69 | + | |
70 | +<style lang="scss" scoped> | |
71 | +.go-content-box { | |
72 | + height: 100%; | |
73 | + .process { | |
74 | + position: absolute; | |
75 | + top: 50%; | |
76 | + left: 50%; | |
77 | + width: 50%; | |
78 | + transform: translate(-50%, -50%); | |
79 | + } | |
80 | +} | |
81 | +</style> | ... | ... |
... | ... | @@ -8,15 +8,17 @@ |
8 | 8 | class="top-btn" |
9 | 9 | :hidden="['remove']" |
10 | 10 | @close="deleteHandle" |
11 | - @resize="resizeHandle" | |
11 | + @resize="handleLoadThreeModel" | |
12 | 12 | ></mac-os-control-btn> |
13 | 13 | </div> |
14 | 14 | <!-- 中间 --> |
15 | - <div class="list-content-img" @click="resizeHandle"> | |
15 | + <div class="list-content-img"> | |
16 | + <LoadThreeModelImage v-if="showThreeModel" :threeModelPath="cardData.threeModelFilePath" /> | |
16 | 17 | <n-image |
17 | 18 | object-fit="contain" |
18 | 19 | height="180" |
19 | 20 | preview-disabled |
21 | + v-else | |
20 | 22 | :src="requireUrl('ThreeModelDefault.svg')" |
21 | 23 | :fallback-src="requireErrorImg()" |
22 | 24 | ></n-image> |
... | ... | @@ -99,6 +101,7 @@ import { MacOsControlBtn } from '@/components/Tips/MacOsControlBtn' |
99 | 101 | import { ChartType } from '../..' |
100 | 102 | import { updateThreeJsModel } from '@/api/external/contentSave/content' |
101 | 103 | const { EllipsisHorizontalCircleSharpIcon, TrashIcon, HammerIcon, SendIcon } = icon.ionicons5 |
104 | +import LoadThreeModelImage from '../LoadThreeModelImage.vue' | |
102 | 105 | |
103 | 106 | const emit = defineEmits(['delete', 'resize', 'edit', 'release', 'inputUpdateCard']) |
104 | 107 | |
... | ... | @@ -112,6 +115,10 @@ const inputInstRef = ref(null) |
112 | 115 | |
113 | 116 | const title = ref<string>('') |
114 | 117 | |
118 | +const showThreeModel = ref(false) | |
119 | + | |
120 | +const handleLoadThreeModel = () => (showThreeModel.value = true) | |
121 | + | |
115 | 122 | // 处理url获取 |
116 | 123 | const requireUrl = (name: string) => { |
117 | 124 | return new URL(`../../../../../assets/images/${name}`, import.meta.url).href |
... | ... | @@ -172,10 +179,10 @@ const releaseHandle = () => { |
172 | 179 | emit('release', props.cardData) |
173 | 180 | } |
174 | 181 | |
175 | -// 放大处理 | |
176 | -const resizeHandle = () => { | |
177 | - emit('resize', props.cardData) | |
178 | -} | |
182 | +// // 放大处理 | |
183 | +// const resizeHandle = () => { | |
184 | +// emit('resize', props.cardData) | |
185 | +// } | |
179 | 186 | |
180 | 187 | const handleFocus = () => { |
181 | 188 | focus.value = true |
... | ... | @@ -186,7 +193,7 @@ const handleFocus = () => { |
186 | 193 | |
187 | 194 | const handleBlur = async () => { |
188 | 195 | focus.value = false |
189 | - if(!title.value) return | |
196 | + if (!title.value) return | |
190 | 197 | await updateThreeJsModel({ |
191 | 198 | id: props.cardData?.id as string, |
192 | 199 | name: title.value | ... | ... |
... | ... | @@ -28,9 +28,16 @@ export const useDataListInit = () => { |
28 | 28 | pageSize: pagination.pageSize |
29 | 29 | }) |
30 | 30 | if (res) { |
31 | + const { host, protocol } = location | |
32 | + const threeFilePath = `${protocol}//${host}` | |
33 | + const VITE_GLOB_API_URL = import.meta.env.VITE_GLOB_API_URL | |
34 | + const VITE_GLOB_API_URL_PREFIX = import.meta.env.VITE_GLOB_API_URL_PREFIX | |
31 | 35 | const { total, items } = res as PaginationResult<ChartType> |
32 | 36 | pagination.count = total |
33 | - list.value = items | |
37 | + list.value = items.map(item => ({ | |
38 | + ...item, | |
39 | + threeModelFilePath: `${threeFilePath}${VITE_GLOB_API_URL}${VITE_GLOB_API_URL_PREFIX}/3d_component/json/${item.id}/scene.json` | |
40 | + })) | |
34 | 41 | setTimeout(() => { |
35 | 42 | loading.value = false |
36 | 43 | }, 500) |
... | ... | @@ -60,7 +67,7 @@ export const useDataListInit = () => { |
60 | 67 | // eslint-disable-next-line @typescript-eslint/no-empty-function |
61 | 68 | onPositiveCallback: () => {}, |
62 | 69 | promiseResCallback: async () => { |
63 | - await threeJsDeleteApi([cardData.id] as string[]) | |
70 | + await threeJsDeleteApi([cardData.id] as string[]) | |
64 | 71 | window['$message'].success(window['$t']('common.deleteSuccessText')) |
65 | 72 | fetchList() |
66 | 73 | } | ... | ... |
... | ... | @@ -23,7 +23,7 @@ export const useModalDataInit = () => { |
23 | 23 | if (!cardData) return |
24 | 24 | if (!cardData?.id) return |
25 | 25 | const { host, protocol, pathname } = location |
26 | - window.open(`${protocol}//${host}${pathname}editor/?three_file_uuid=${cardData?.id}`) | |
26 | + window.open(`${protocol}//${host}${pathname}editor/?three_file_uuid=${cardData?.id}&action_type=update`) | |
27 | 27 | } |
28 | 28 | |
29 | 29 | return { | ... | ... |
... | ... | @@ -48,7 +48,7 @@ const modalShow = ref<boolean>(false) |
48 | 48 | const clickHandle = () => { |
49 | 49 | const { host, protocol, pathname } = location |
50 | 50 | const randomId = getUUID(32) |
51 | - window.open(`${protocol}//${host}${pathname}editor/?three_file_uuid=${randomId}`) | |
51 | + window.open(`${protocol}//${host}${pathname}editor/?three_file_uuid=${randomId}&action_type=create`) | |
52 | 52 | } |
53 | 53 | |
54 | 54 | const closeHandle = () => { | ... | ... |