tangning 5 月之前
父節點
當前提交
14d044b44e

二進制
src/assets/images/obj.jpg


二進制
src/assets/images/osgb.jpg


+ 11 - 0
src/request/urls.ts

@@ -261,4 +261,15 @@ export const caseaddOrUpdate = '/service/manage/case/addOrUpdate';
 export const getTips = "/s/api/gettips";
 export const getTipsName = "/s/api/gettips_name";
 
+export const getUrlByKeyList = "/fusion/dict/getByKey/media-library";
+export const dictFiledel = '/fusion/dictFile/del/media-library';
+export const getByKey = '/fusion/dict/getByKey/media-library';
+export const getpageList = '/fusion/dict/pageList/media-library';
+export const addOrUpdate = '/fusion/dict/addOrUpdate/media-library';
+export const del = '/fusion/dict/del/media-library';
+export const upload = '/fusion/common/upload/fileNew';
+export const getCaseNumByRyId = '/fusion/case/getCaseNumByRyId';
+export const mediaList = '/fusion/dictFile/pageList/media-library';
+
+
 

+ 12 - 0
src/router/config.ts

@@ -32,6 +32,12 @@ export const system: Routes = [
     component: () => import("@/view/system/index.vue"),
     meta: { title: "重置密码" },
   },
+  {
+    name: 'mediaLibrary',
+    path: "/mediaLibrary/:caseId",
+    component: () => import("@/view/mediaLibrary/index.vue"),
+    meta: { title: "媒体库" },
+  },
 ];
 
 export const routes: Routes = [
@@ -140,6 +146,12 @@ export const routes: Routes = [
         component: () => import("@/view/case/records/index.vue"),
         meta: { title: "现场勘验笔录" },
       },
+      {
+        name: 'homes',
+        path: "homes/:caseId",
+        component: () => import("@/view/vrmodel/index.vue"),
+        meta: { title: "场景管理", icon: "icon-shiyongwendang" },
+      },
     ],
   },
   {

+ 23 - 1
src/store/case.ts

@@ -36,7 +36,12 @@ import {
   caseaddOrUpdate,
   isdyrh,
   getTips,
-  getTipsName
+  getTipsName,
+  getUrlByKeyList,
+  mediaList,
+  dictFiledel,
+  del,
+  addOrUpdate,
 } from "@/request";
 import { router } from "@/router";
 import { ModelScene, QuoteScene, Scene, SceneType } from "./scene";
@@ -67,6 +72,23 @@ export const setCaseaddOrUpdate = (params) =>
 export const getCaseSharePWD = async (params: { caseId: number }) =>
   (await axios.get<string>(getCasePsw, { params })).data;
 
+export const getByKeyList = async (params: { caseId: number }) =>
+  (await axios.get<string>(getUrlByKeyList, { params })).data;
+
+export const getdictFiledel = async (params) =>
+  (await axios.post<string>(dictFiledel, params)).data;
+
+export const getaddOrUpdate = async (params) =>
+  (await axios.post<string>(addOrUpdate, params)).data;
+
+
+export const getfzdel = async (params) =>
+  (await axios.post<string>(del, params)).data;
+
+
+export const getmediaList = async (params) =>
+  (await axios.post<string>(mediaList, params)).data;
+
 export const addByMediaLiBrary = async (params) =>{
   const newUrl = params.uploadIds?.length ? addByMediaLibrarys : addByMediaLibrary
   return (await axios.post<string>(newUrl, params)).data;

+ 2 - 1
src/view/case/draw/selectFuseImage.vue

@@ -61,7 +61,8 @@ import { QuiskExpose } from "@/helper/mount";
 export type FuseImage = { blob: Blob | null; taggings: CaseTagging[] };
 const props = defineProps<{ caseId: number }>();
 
-const fuseUrl = computed(() => getQuery(props.caseId, true, true));
+const fuseUrl = 'http://192.168.0.25/code/index.html?caseId=528&app=2&share=1&single=1#show/summary'
+// computed(() => getQuery(props.caseId, true, true));
 
 const taggings = ref<CaseTagging[]>([]);
 const transferSource = computed(() =>

+ 6 - 19
src/view/layout/index.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="layer">
-    <ly-top class="top" />
+    <ly-top class="top" v-if="router.currentRoute.value.name != 'mediaLibrary'" />
     <div class="content">
       <router-view v-slot="{ Component }" v-if="isSystem">
         <component :is="Component" />
@@ -8,7 +8,7 @@
       <template v-else>
         <ly-slide class="slide" :names="menuRouteNames" v-if="!hiddenSlide" />
         <div class="view" :class="{ full: hiddenSlide }">
-          <div class="app-wrap m-4" v-if="!hiddenSlide">
+          <div class="app-wrap m-4" v-if="showScene || !hiddenSlide">
             <div
               class="app-scene"
               ref="sceneRef"
@@ -18,22 +18,6 @@
                 // display: showScene ? 'none' : 'block'
               }"
             >
-            <!-- <div class="poprs sceneList" v-if="sceneList.length">
-              <el-dropdown placement="bottom" style="width: 100%" trigger="click" @command="handleCommand">
-                <el-button >
-                  <div style="width: 200px;" class="truncate" :title="sceneListName">
-                    {{sceneListName}}
-                  </div>
-                  <el-icon class="el-icon--right"><arrow-down /></el-icon>
-                </el-button>
-              <template #dropdown>
-                <el-dropdown-menu>
-                  <el-dropdown-item class="truncate" style="max-width: 400px;" v-for="item,index in sceneList" :key="index" :command="item.id">{{ item.name || '多元融合' }}</el-dropdown-item>
-                </el-dropdown-menu>
-              </template>
-            </el-dropdown>
-            </div> -->
-            <!-- @load="setupSDK($event.target)" -->
               <iframe
                 v-if="caseId"
               :key="qpisceneList.length"
@@ -43,7 +27,7 @@
               ></iframe>
             </div>
           </div>
-          <div class="main p-4" :class="{ fullmain: hiddenSlide }">
+          <div class="main p-4" :class="{ fullmain: hiddenSlide && !showScene }">
             <router-view v-slot="{ Component }">
               <component :is="Component" />
             </router-view>
@@ -111,6 +95,9 @@ updateByTreeFileLists()
 const hiddenSlide = computed(
   () => !menuRouteNames.includes(router.currentRoute.value.name as string)
 );
+const showScene = computed(
+  () => ['homes'].includes(router.currentRoute.value.name as string)
+);
 const handleCommand = (command) => {
   let newid = command || sceneList.value[0].id;
   console.log('handleCommand', command, newid, sceneList.value);

+ 547 - 0
src/view/mediaLibrary/TableComponent.vue

@@ -0,0 +1,547 @@
+<template>
+  <div class="mymediaLibrary">
+    <!-- 表头搜索 -->
+    <el-form :inline="true" :model="searchForm">
+      <el-form-item class="formitem">
+        <el-input
+          v-model="searchForm.name"
+          @blur="submitClick"
+          @keydown.enter="submitClick"
+          placeholder="请输入搜索内容"
+          :prefix-icon="Search"
+        ></el-input>
+      </el-form-item>
+      <el-form-item>
+        <el-select
+          style="width: 120px"
+          v-model="searchForm.fileType"
+          @change="submitClick"
+          size="large"
+          placeholder="全部"
+        >
+          <el-option
+            v-for="(item, index) in [
+              '全部',
+              '图片',
+              '视频',
+              '音频',
+              '模型',
+              '其他',
+            ]"
+            :key="index"
+            :label="item"
+            :value="index"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-select
+          v-model="searchForm.dictId"
+          style="width: 120px"
+          @change="submitClick"
+          size="large"
+          placeholder="全部"
+        >
+          <el-option
+            v-for="(item, index) in [...allList,...dictIdList]"
+            :key="index"
+            :label="item.dictName"
+            :value="item.id"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item style="float: right; margin-right: 0">
+        <el-button type="primary" @click="handleAddfz">分组管理</el-button>
+        <el-button type="primary" @click="handleAdd">上传</el-button>
+      </el-form-item>
+    </el-form>
+    <!-- 表格 -->
+    <el-table
+      size="large"
+      :data="tableData"
+      style="width: 100%"
+      :row-class-name="tableRowClassName"
+    >
+      <el-table-column prop="name" label="名称">
+        <template #default="scope">
+          <a
+            style="color: #0960bd; cursor: pointer"
+            v-if="scope.row.fileUrl"
+            target="_blank"
+            :title="scope.row.name"
+            @click="floadileUrl(scope.row)"
+          >
+            {{ scope.row.name }}</a
+          >
+        </template>
+      </el-table-column>
+      <el-table-column
+        v-for="column in columns"
+        :key="column.prop"
+        :prop="column.prop"
+        align="center"
+        :label="column.label"
+      ></el-table-column>
+      <el-table-column align="center" label="操作" width="150">
+        <template #default="{ row }">
+          <el-button link type="primary" size="small" @click="handleEdit(row)">
+            编辑
+          </el-button>
+          <span
+            class="oper-span"
+            @click="del(row)"
+            style="color: var(--primaryColor)"
+          >
+            删除
+          </span>
+        </template>
+      </el-table-column>
+    </el-table>
+    <!-- 分页 -->
+    <el-pagination
+      class="mt-3"
+      @size-change="handleSizeChange"
+      @current-change="handleCurrentChange"
+      :current-page="currentPage"
+      :page-sizes="[10, 20, 30]"
+      :page-size="pageSize"
+      layout="total, sizes, prev, pager, next, jumper"
+      :total="total"
+    >
+    </el-pagination>
+    <!-- 弹窗 -->
+    <el-dialog v-model="dialogData.show" :title="dialogData.title" width="500">
+      <el-form :model="form" label-width="110">
+        <el-form-item
+          v-if="dialogData.title == '上传'"
+          label="文件"
+          :label-width="formLabelWidth"
+        >
+          <!-- <el-input v-model="addForm.name" autocomplete="off" /> -->
+          <el-upload
+            class="upload-demo"
+            style="width: 100%"
+            :multiple="false"
+            :limit="1"
+            :before-upload="beforeUpload"
+            :file-list="fileList"
+            :http-request="() => {}"
+            :on-preview="previewFile"
+            :accept="accept"
+            :before-remove="removeFile"
+          >
+            <el-button type="primary">
+              上传
+            </el-button>
+          </el-upload>
+        </el-form-item>
+        <el-form-item
+          :label="dialogData.title == '' ? '分组' : '修改分组'"
+          :label-width="formLabelWidth"
+        >
+          <el-select style="width: 180px" v-model="addForm.dictId" placeholder="请选择分组">
+            <el-option
+              v-for="(item, index) in dictIdList"
+              :key="index"
+              :label="item.dictName"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+        <div style="padding: 0 0 0 40px" v-if="dialogData.title == '上传'">
+          <div style="margin-bottom: 10px">
+            支持jpg、png、jpeg、mp4、wav、mp3 、shp格式文件上传。文件大小 ≤ 2G
+          </div>
+          <!-- <span>注意:模型需使用zip包上传。包含贴图、模型、mtl文件,包内不得包含文件夹。</span> -->
+          <div style="margin-bottom: 10px">
+            <div>
+              上传
+              obj:需使用zip包上传。包含贴图、模型、mtl文件,包内不得包含文件夹,文件名不得使用中文。如图:
+            </div>
+            <img style="width: 150px" :src="obj" alt="" />
+          </div>
+          <div style="margin-bottom: 10px">
+            <div>
+              上传 osgb:需使用zip包上传。包含 Data 文件夹、xml
+              文件,包内不得包含文件夹,文件名不得使用中文。如图:
+            </div>
+            <img style="width: 150px" :src="osgb" alt="" />
+          </div>
+        </div>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="dialogData.show = false">取消</el-button>
+          <el-button type="primary" @click="handleuploadAdd">
+            确定
+          </el-button>
+        </div>
+      </template>
+    </el-dialog>
+    <!-- 修改分组 -->
+    <el-dialog v-model="dialogData.fzshow" title="分组管理" width="500">
+    <el-form :model="form" label-width="50">
+      <el-form-item label="分组" :label-width="formLabelWidth">
+        <el-input v-model="dialogData.fzName" style="width: 300px;" />
+        <el-button style="margin-left: 20px" @click="handlefzAdd" type="primary">新增</el-button>
+      </el-form-item>
+      <div class="itemTitle">
+        <p>分组列表</p>
+        <div class="itemTitleList">
+          <div class="itemTitle-list" v-for="(item, index) in dictIdList" :key="index">
+            <span>{{ item.dictName }}</span>
+            <span @click="hanleFzDle(item)">删除</span>
+          </div>
+        </div>
+      </div>
+    </el-form>
+    <template #footer>
+      <div class="dialog-footer">
+          <el-button @click="dialogData.fzshow = false">取消</el-button>
+          <el-button type="primary" @click="handleuploadAdd">
+            确定
+          </el-button>
+      </div>
+    </template>
+  </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { Search } from "@element-plus/icons-vue";
+import { ref, watch, onMounted } from "vue";
+import { getByKeyList, getfzdel, getdictFiledel, getaddOrUpdate  } from "@/store/case";
+import dayjs from "dayjs";
+import obj from "@/assets/images/obj.jpg";
+import osgb from "@/assets/images/osgb.jpg";
+import { ElMessage, ElMessageBox } from "element-plus";
+
+// 定义 props
+const props = defineProps({
+  columns: {
+    type: Array,
+    default: () => [],
+  },
+  searchColumns: {
+    type: Array,
+    default: () => [],
+  },
+  getData: {
+    type: Function,
+    required: true,
+  },
+});
+// 定义响应式数据
+const searchForm = ref({
+  name: "",
+  fileType: 0,
+  dictId: "0",
+});
+const addForm = ref({
+  fileType: "",
+  dictId: "",
+  name: "",
+});
+const dialogData = ref({
+  show: false,
+  title: "上传",
+  data: {},
+  fzshow: false,
+  fzName: '',
+  fzList: [],
+});
+const file = ref(null);
+const accept = ".jpg,.png,.jpeg,.mp4,.wav,.mp3,.shp";
+const hanleFzDle = (item) => {
+  ElMessageBox.confirm("确定删除?", "提示", {
+    confirmButtonText: "确定",
+    cancelButtonText: "取消",
+    type: "warning",
+  }).then(async () => {
+    await getfzdel(item);
+    dictIdList.value = dictIdList.value.filter(item1 => item1.id !== item.id)
+    ElMessage({
+      type: "success",
+      message: "删除成功",
+    });
+  });
+  
+
+  console.log("upload", file);
+};
+const previewFile = (file) => {
+  console.log("previewFile", file);
+};
+const handleEdit = (data) => {
+  addForm.value.dictId = data.dictId;
+  dialogData.value = {
+    show: true,
+    title: "修改分组",
+    data,
+  };
+};
+
+const removeFile = () => {
+  return true;
+};
+const handleAdd = () => {
+  addForm.value.dictId = '';
+  dialogData.value = {
+    show: true,
+    title: "上传",
+  };
+};
+const handlefzAdd = async () => {
+  let params = {
+    dictName: dialogData.value.fzName,
+  };
+  if (!params.dictName) {
+    return ElMessage.error('请输入名称');
+  }
+  await getaddOrUpdate(params);
+  ElMessage({
+    type: "success",
+    message: "新增成功",
+  });
+  getFzlist();
+  dialogData.value.fzName = '';
+};
+const handleAddfz = () => {
+  dialogData.value.fzshow = true;
+};
+
+const handleuploadAdd = () => {
+  if (file.value) {
+    const formData = new FormData();
+    formData.append("file", file.value);
+    formData.append("dictId", addForm.value.dictId);
+    console.log(formData);
+  }
+};
+// 定义方法
+const del = (row) => {
+  console.log(file, "file");
+  ElMessageBox.confirm("确定删除?", "提示", {
+    confirmButtonText: "确定",
+    cancelButtonText: "取消",
+    type: "warning",
+  }).then(async () => {
+    await getdictFiledel({id: row.id});
+    initData();
+    ElMessage({
+      type: "success",
+      message: "删除成功",
+    });
+  });
+};
+const allList = ref([{ dictName: "全部", id: "0" }])
+const dictIdList = ref([]);
+const tableData = ref([]);
+const fileList = ref([]);
+const currentPage = ref(1);
+const pageSize = ref(10);
+const total = ref(0);
+onMounted(() => {
+  document.body.classList.toggle("dark-mode");
+});
+const getFzlist = () => {
+  getByKeyList({}).then((res) => {
+    console.log("getByKeyList", res);
+    dictIdList.value = res;
+  });
+};
+getFzlist();
+const submitClick = () => {
+  console.log("submitClick", searchForm.value);
+  currentPage.value = 1;
+  initData();
+};
+const tableRowClassName = ({ row, rowIndex }) => {
+  if (rowIndex === 1) {
+    return "warning-row";
+  } else if (rowIndex === 3) {
+    return "success-row";
+  }
+  return "";
+};
+
+// 初始化数据
+const initData = async () => {
+  const { list, totalCount } = await props.getData({
+    ...searchForm.value,
+    fileType:
+      searchForm.value.fileType == 0 ? "" : searchForm.value.fileType - 1,
+    dictId: searchForm.value.dictId == 0 ? "" : searchForm.value.dictId,
+    pageNum: currentPage.value,
+    pageSize: pageSize.value,
+  });
+  tableData.value = list.map((res) => {
+    return {
+      ...res,
+      statusStr:
+        res.status == -1 ? "上传失败" : res.status == 0 ? "上传中" : "上传成功",
+      createTime: dayjs(res.createTime).format("YYYY-MM-DD HH:mm:ss"),
+    };
+  });
+  total.value = totalCount;
+};
+const floadileUrl = (record) => {
+  if (record.fileType == 3) {
+    let url = `/code/index.html?title=${record.fileName}&type=${record.fileFormat}&fileUrl=${record.fileUrl}#/sign-model`;
+    return window.open(url);
+  } else {
+    return window.open(record.fileUrl);
+  }
+};
+const beforeUpload = (file) => {
+        console.log('beforeUpload', file);
+        const filetype = file.name.substring(file.name.lastIndexOf('.') + 1).toLowerCase();
+        const isExcel = ['jpg', 'jpg', 'png', 'jpeg', 'mp4', 'wav', 'mp3', 'shp', 'zip'].includes(
+          filetype,
+        ); // 调用上面代码
+        if (!isExcel) {
+          createMessage.error('支持jpg、png、jpeg、mp4、wav、mp3 、shp、zip格式文件上传');
+          fileList.value = [];
+          return false;
+        }
+        const isLt10M = file.size / 1024 / 1024 < 2000;
+        if (!isLt10M) {
+          fileList.value = [];
+          createMessage.error('上传文件不能超过 2G!');
+          return false;
+        }
+        fileList.value = [file];
+        return true;
+      };
+// 监听搜索表单变化
+watch(searchForm, () => {
+  currentPage.value = 1;
+  initData();
+});
+
+// 处理分页大小变化
+const handleSizeChange = (newSize) => {
+  pageSize.value = newSize;
+  initData();
+};
+
+// 处理当前页码变化
+const handleCurrentChange = (newPage) => {
+  currentPage.value = newPage;
+  initData();
+};
+
+// 处理搜索按钮点击
+const handleSearch = () => {
+  currentPage.value = 1;
+  initData();
+};
+
+// 重置搜索表单
+const resetSearch = () => {
+  Object.keys(searchForm.value).forEach((key) => {
+    searchForm.value[key] = "";
+  });
+  currentPage.value = 1;
+  initData();
+};
+
+// 初始化数据
+initData();
+</script>
+
+<style lang="scss">
+:root {
+  // --el-bg-color: #151515;
+  // --colorColor: #fff;
+}
+// /* 覆盖 Element Plus 的 CSS 变量 */
+// --el-color-primary: #1890ff;
+// --el-bg-color: #141414;
+// --el-text-color-primary: #ffffff;
+// /* 可以根据需要覆盖更多变量 */
+.mb-3 {
+  margin-bottom: 1rem;
+}
+.mt-3 {
+  margin-top: 1rem;
+}
+.mymediaLibrary {
+  text-align: left;
+  // .el-form-item{
+  //   margin-bottom: 30px;
+  // }
+  // .el-table th.el-table__cell{
+  //   background-color: #1d1d1d;
+  //   color: #fff;
+  // }
+  // width: 100%;
+  // --el-input-bg-color: #535353;
+  // .el-table{
+  //   background-color: #535353;
+  // }
+  // .el-form--inline .el-form-item{
+  //   margin-right: 10px;
+  // }
+  // .el-form-item, .el-select__wrapper{
+  //   background-color: #535353;
+  // }
+  // .el-input__wrapper, .el-select__wrapper{
+  //   background-color: #535353;
+  //   box-shadow: none;
+  // }
+  // .el-input__inner, .el-select__selected-item{
+  //   color: #fff;
+  // }
+  //     /* 局部修改具有 custom-table 类名的 el-table 的背景颜色 */
+  //     .custom-table.el-table {
+  //     background-color: #535353;
+  //   }
+
+  //   /* 修改表头背景颜色 */
+  //   .custom-table.el-table__header-wrapper th {
+  //     background-color: #535353;
+  //   }
+
+  //   /* 修改表格行的背景颜色 */
+  //   .el-table tr {
+  //     background-color: #535353;
+  //   }
+
+  //   /* 修改表格行悬停时的背景颜色 */
+  //   .custom-table.el-table__body tr:hover>td {
+  //     background-color: #535353;
+  //   }
+  //   .el-table th.el-table__cell{
+  //     background-color: #1d1d1d
+  //   }
+  //   .el-table .el-table__cell{
+  //     border-color: #303030 !important;
+  //   }
+  //   .el-table--fit .el-table__inner-wrapper:before{
+  //     background-color: none;
+  //   }
+  //   .el-table .warning-row {
+  //     --el-table-tr-bg-color: var(--el-color-warning-light-9);
+  //   }
+  //   .el-table .success-row {
+  //     --el-table-tr-bg-color: var(--el-color-success-light-9);
+  //   }
+  .itemTitle{
+    width: 400px;
+    margin: 0 8px;
+    .itemTitleList{
+      max-height: 240px;
+      overflow-y: scroll;
+      ::-webkit-scrollbar {
+        display: none; /* Chrome Safari */
+      }
+    }
+    .itemTitle-list{
+      line-height: 30px;
+      display: flex;
+      justify-content: space-between;
+    }
+  }
+}
+</style>

+ 62 - 0
src/view/mediaLibrary/index.vue

@@ -0,0 +1,62 @@
+<template>
+  <div id="mediaLibraryApp">
+    <TableComponent
+      :columns="columns"
+      :searchColumns="searchColumns"
+      :getData="getData"
+    />
+  </div>
+</template>
+
+<script setup>
+import TableComponent from './TableComponent.vue';
+import { getmediaList } from "@/store/case";
+import { ref } from 'vue';
+
+// 模拟接口数据
+const mockData = [
+  { id: 1, name: 'John', age: 20 },
+  { id: 2, name: 'Jane', age: 25 },
+  { id: 3, name: 'Bob', age: 30 },
+  // 更多数据...
+];
+
+// 定义表格列
+const columns = [
+  // { prop: 'name', label: '名称', width: 150, },
+  { prop: 'fileTypeStr', label: '文件类型', width: 100, },
+  { prop: 'fileFormat', label: '文件格式', width: 80, },
+  { prop: 'dictName', label: '分组', width: 100, },
+  { prop: 'statusStr', label: '状态', width: 100, },
+  { prop: 'createTime', label: '上传时间', width: 180, },
+];
+
+// 定义搜索列
+const searchColumns = ref([
+]);
+
+// 获取数据的函数
+const getData = async (params) => {
+  // 这里可以调用后端接口获取数据
+  const res =  await getmediaList(params)
+  return { list: res.list, totalCount: res.total }
+  // .then(res => {
+  //   searchColumns.value = res.list
+  //   const totalCount = res.total;
+  //   return { list, totalCount };
+  // });
+};
+</script>
+
+<style scoped>
+#mediaLibraryApp {
+  font-family: Avenir, Helvetica, Arial, sans-serif;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+  text-align: center;
+  /* color: #2c3e50; */
+  width: 100%;
+  padding: 20px;
+  /* background-color: rgba(58, 58, 58, 1); */
+}
+</style>

+ 2 - 2
vite.config.ts

@@ -46,12 +46,12 @@ export default defineConfig({
     host: "0.0.0.0",
     proxy: {
       "/api": {
-        target: dev ? "http://192.168.0.25" : "mix3d.4dkankan.com",
+        target: dev ? "http://192.168.0.43:8808" : "mix3d.4dkankan.com",
         changeOrigin: true,
         rewrite: (path) => path.replace(new RegExp(`^/api`), ""),
       },
       "/fusion": {
-        target: dev ? "http://192.168.0.25" : "mix3d.4dkankan.com",
+        target: dev ? "http://192.168.0.43:8808" : "mix3d.4dkankan.com",
         changeOrigin: true,
         rewrite: (path) => path.replace(new RegExp(`^/api`), "/fusion"),
       },