Commit b2c6363f075d7ea72db9fb4c9bef6bc93fef42c1

Authored by fengwotao
1 parent 0d4c0edf

perf(external/Composes): 三维模型新增可以自定义上传

1   -import { defHttp } from "@/utils/external/http/axios";
2   -import { DictItem, UploadResponse } from "./model";
  1 +import { defHttp } from '@/utils/external/http/axios'
  2 +import { DictItem, UploadResponse } from './model'
3 3
4 4 enum Api {
5 5 GET_DICT = '/dict_item',
6   - UPLOAD = '/oss/upload'
  6 + UPLOAD = '/oss/upload',
  7 + DOWNLOAD = '/oss/download_file/'
7 8 }
8 9
9 10 export const getDictItemByCode = (value: string) => {
... ... @@ -21,3 +22,7 @@ export const upload = (file: FormData) => {
21 22 params: file
22 23 })
23 24 }
  25 +
  26 +export const downloadFile = (fileName: string) => {
  27 + return defHttp.get({ url: `${Api.DOWNLOAD}${fileName}` })
  28 +}
... ...
... ... @@ -6,7 +6,7 @@ import { chartInitConfig } from '@/settings/designSetting'
6 6
7 7 export const option = {
8 8 //vue3dLoader支持数组或字符串,暂且绑定字符串,这个插件可以加载多个模型
9   - dataset: 'src/assets/external/models/fbx/宿舍楼.fbx',
  9 + dataset: '',
10 10 backgroundColor: '', //场景背景色
11 11 backgroundAlpha: 0, //场景透明度
12 12 enableDamping: false, //是否启用阻尼
... ...
1 1 <template>
2   - <collapse-item name="三维静态路径" :expanded="true">
3   - <setting-item-box>
4   - <setting-item name="路径">
  2 + <collapse-item name="三维配置" :expanded="true">
  3 + <setting-item-box name="文件上传" :alone="true">
  4 + <setting-item :name="fileSizeMsg">
  5 + <n-upload
  6 + :max="1"
  7 + :customRequest="customRequest"
  8 + :onBeforeUpload="beforeUploadHandle"
  9 + :default-file-list="defaultFileList"
  10 + >
  11 + <n-button> 上传文件</n-button>
  12 + </n-upload>
  13 + </setting-item>
  14 + </setting-item-box>
  15 + <setting-item-box name="静态路径">
  16 + <setting-item>
5 17 <n-select
6 18 @change="handlePathChange"
7 19 style="width: 12vw"
... ... @@ -12,9 +24,7 @@
12 24 ></n-select>
13 25 </setting-item>
14 26 </setting-item-box>
15   - </collapse-item>
16   - <collapse-item name="三维配置属性" :expanded="true">
17   - <setting-item-box>
  27 + <setting-item-box name="属性配置">
18 28 <setting-item name="场景色(需要这种格式HEX #000000,否则失效)">
19 29 <n-color-picker size="small" :show-alpha="false" v-model:value="optionData.backgroundColor"></n-color-picker>
20 30 </setting-item>
... ... @@ -24,19 +34,6 @@
24 34 <SettingItem name="启用阻尼">
25 35 <n-switch v-model:value="optionData.enableDamping" size="small" />
26 36 </SettingItem>
27   - <!-- <SettingItem name="选择灯光">
28   - <setting-item name="灯光">
29   - <n-select
30   - @change="handleLightChange"
31   - v-model:value="selectLight"
32   - size="small"
33   - :options="lightList"
34   - ></n-select>
35   - </setting-item>
36   - <setting-item name="灯光颜色选择">
37   - <n-color-picker size="small" :show-alpha="false" v-model:value="lightColor"></n-color-picker>
38   - </setting-item>
39   - </SettingItem> -->
40 37 <SettingItem v-if="optionData.enableDamping" name="阻尼值">
41 38 <n-input-number v-model:value="optionData.dampingFactor" :min="0" :max="1" size="small"></n-input-number>
42 39 </SettingItem>
... ... @@ -54,10 +51,13 @@
54 51 </template>
55 52
56 53 <script setup lang="ts">
57   -import { PropType, h, ref, watch } from 'vue'
  54 +import { PropType, h, ref, nextTick } from 'vue'
58 55 import { option } from './config'
59 56 import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
60   -import { NEllipsis, NInputNumber, NSelect, NSpace, SelectOption } from 'naive-ui'
  57 +import { NEllipsis, NInputNumber, NSelect, NSpace, SelectOption, NCard } from 'naive-ui'
  58 +import { uploadFile } from '@/api/external/contentSave/content'
  59 +import { downloadFile } from '@/api/external/common'
  60 +import { UploadCustomRequestOptions } from 'naive-ui'
61 61
62 62 const props = defineProps({
63 63 optionData: {
... ... @@ -66,6 +66,11 @@ const props = defineProps({
66 66 }
67 67 })
68 68
  69 +const defaultFileList = ref([])
  70 +
  71 +//文件限制大小
  72 +const fileSizeConst = ref(15)
  73 +
69 74 const handleChange = (e: boolean) => {
70 75 if (e) props.optionData.dataset = ''
71 76 }
... ... @@ -79,44 +84,6 @@ const encodinghList = [
79 84 { label: 'sRGB ', value: 'sRGB ' }
80 85 ]
81 86
82   -/**
83   -环境光(AmbientLight) | 方向光(DirectionalLight) | 点光(PointLight) | 半球光(HemisphereLight)
84   -暂且支持 环境光
85   - */
86   -const lightList = [
87   - {
88   - type: 'AmbientLight',
89   - value: 'AmbientLight',
90   - label: '环境光'
91   - }
92   -]
93   -
94   -const selectLight = ref('')
95   -
96   -const lightColor = ref('')
97   -
98   -const lightChange = (type: string, color: string) => {
99   - props.optionData.lights = [
100   - {
101   - type,
102   - color
103   - }
104   - ] as any
105   -}
106   -
107   -const handleLightChange = (e: string) => {
108   - selectLight.value = e
109   - lightChange(e, lightColor.value)
110   -}
111   -
112   -watch(
113   - () => lightColor.value,
114   - newValue => {
115   - lightChange(selectLight.value, newValue)
116   - }
117   -)
118   -
119   -//TODO:三维静态路径地址,无法通过import.meta.globEager来引入,要报错,待优化
120 87 const pathList = [
121 88 {
122 89 label: '猫模型',
... ... @@ -167,4 +134,55 @@ const renderOption = (option: SelectOption) => {
167 134 h(NEllipsis, null, () => option.label)
168 135 ])
169 136 }
  137 +
  138 +const fileSizeMsg = ref(`文件需小于 ${fileSizeConst.value}M ,格式为${threeSupportFileFormat.join(',')}的文件`)
  139 +
  140 +const extname = (filename: string) => {
  141 + if (!filename || typeof filename != 'string') {
  142 + return false
  143 + }
  144 + let a = filename.split('').reverse().join('')
  145 + let b = a.substring(0, a.search(/\./)).split('').reverse().join('')
  146 + return b
  147 +}
  148 +
  149 +// 上传图片前置处理
  150 +// eslint-disable-next-line @typescript-eslint/ban-ts-comment
  151 +//@ts-ignore
  152 +const beforeUploadHandle = async ({ file }) => {
  153 + defaultFileList.value = []
  154 + const type = extname(file.file.name) as string
  155 + const size = file.file.size
  156 + if (size / (1024 * 1024) > fileSizeConst.value) {
  157 + window['$message'].warning(`文件超出 ${fileSizeConst.value}M限制,请重新上传!`)
  158 + return false
  159 + }
  160 + if (!threeSupportFileFormat.includes(type)) {
  161 + window['$message'].warning('文件格式不符合,请重新上传!')
  162 + return false
  163 + }
  164 + return true
  165 +}
  166 +
  167 +// 自定义上传操作
  168 +const customRequest = (options: UploadCustomRequestOptions) => {
  169 + const { file } = options
  170 + nextTick(async () => {
  171 + if (file.file) {
  172 + const formData = new FormData()
  173 + formData.append('file', file.file)
  174 + const uploadRes = await uploadFile(formData)
  175 + if (uploadRes) {
  176 + props.optionData.dataset = uploadRes?.fileStaticUri
  177 + const res = await downloadFile(uploadRes?.fileName)
  178 + console.log(res)
  179 + window['$message'].success('上传文件成功!')
  180 + }
  181 + } else {
  182 + window['$message'].error('上传文件失败,请稍后重试!')
  183 + }
  184 + })
  185 +}
170 186 </script>
  187 +
  188 +<style lang="scss" scoped></style>
... ...
1 1 <template>
2 2 <div class="go-content-box">
3   - <!-- fix: 预览三维图像需加上preserveDrawingBuffer: true -->
4 3 <div v-if="supportWebGL">
5 4 <vue3dLoader
6 5 ref="vue3dLoaderRef"
... ... @@ -15,7 +14,7 @@
15 14 :outputEncoding="outputEncoding"
16 15 :clearScene="clearScene"
17 16 :dampingFactor="dampingFactor"
18   - :labels="labels"
  17 + :intersectRecursive="true"
19 18 @process="onProcess"
20 19 @load="onLoad"
21 20 @click="onClick"
... ... @@ -54,48 +53,10 @@ const vue3dLoaderRef = ref(null)
54 53 const webGLRendererOptions = {
55 54 alpha: true, // 透明
56 55 antialias: true, // 抗锯齿
  56 + // fix: 预览三维图像需加上preserveDrawingBuffer: true
57 57 preserveDrawingBuffer: true //缩略图生效需开启
58 58 }
59 59
60   -//标注示例可以多个支持图片和文字
61   -const labels = ref()
62   -labels.value = [
63   - {
64   - text: 'co2浓度:44',
65   - position: { x: 0, y: 18, z: 0 },
66   - scale: { x: 11.5, y: 10.8, z: 30.5 },
67   - textStyle: {
68   - fontFamily: 'Arial',
69   - fontSize: 12,
70   - fontWeight: 600,
71   - lineHeight: 1,
72   - color: '#ffffff',
73   - borderWidth: 8,
74   - borderRadius: 0,
75   - borderColor: '#000000',
76   - backgroundColor: 'rgba(0,0,0,1)'
77   - },
78   - sid: 3 // 自定义标识,可有可无
79   - },
80   - {
81   - text: '氧气浓度:100',
82   - position: { x: 10, y: 18, z: 0 },
83   - scale: { x: 11.5, y: 10.8, z: 30.5 },
84   - textStyle: {
85   - fontFamily: 'Arial',
86   - fontSize: 12,
87   - fontWeight: 600,
88   - lineHeight: 1,
89   - color: '#ffffff',
90   - borderWidth: 8,
91   - borderRadius: 0,
92   - borderColor: '#000000',
93   - backgroundColor: 'rgba(0,0,0,1)'
94   - },
95   - sid: 4 // 自定义标识,可有可无
96   - }
97   -]
98   -
99 60 //三维模型加载
100 61 const show = ref(true)
101 62
... ... @@ -109,7 +70,7 @@ const onLoad = async () => {
109 70 const process = ref(0)
110 71
111 72 const onProcess = (event: any) => {
112   - process.value= Math.floor((event.loaded / event.total) * 100)
  73 + process.value = Math.floor((event.loaded / event.total) * 100)
113 74 }
114 75
115 76 const onClick = (event: any) => {
... ...