Browse Source

热点瀑布流新增品牌

jinx 1 year ago
parent
commit
c343b547a2

+ 1 - 1
package.json

@@ -33,7 +33,7 @@
         "sdk:dev": "yarn workspace @kankan/sdk run dev",
         "sdk:serve": "npm-run-all --parallel serve sdk:dev",
         "sdk:build": "yarn workspace @kankan/sdk run build",
-        "editor:run": "yarn workspace @kankan/editor run serve",
+        "editor:run": "yarn workspace @app/cdfg run serve",
         "editor:dev": "npm-run-all --parallel sdk:serve editor:run",
         "editor:langs": "yarn workspace @kankan/editor run langs",
         "editor:build": "yarn workspace @kankan/editor run build",

+ 106 - 103
packages/app-cdfg/src/apis/scene-edit.js

@@ -1,103 +1,106 @@
-import { http } from '@/utils/request'
-/**
- * 场景发布
- * @param {object} data 传入的对象参数
- * @param {string} data.num 场景码
- * @returns {Promise}
- **/
-export const publicScene = data => {
-    return http.post('/api/scene/edit/publicScene', data)
-}
-/**
- * 场景编辑保存
- * @param {object} data 传入的对象参数
- * @param {string} data.num 场景码
- * @param {string} data.floorLogo 地面logo名称
- * @param {number} data.floorLogoSize 地面logo大小
- * @param {string} data.music  背景音乐名称
- * @param {string} data.scenePassword 加密浏览密码
- * @param {string} data.title 场景标题
- * @param {string} data.description 场景描述
- * @param {object} data.controls
- * @param {number} data.controls.showMap 是否展示小地图(0-否,1-是)
- * @param {number} data.controls.showLock 是否需要密码访问(0-否,1-是)
- * @param {number} data.controls.showTitle 是否展示标题(0-否,1-是)
- * @param {number} data.controls.showPanorama 是否展示漫游按钮(0-否,1-是)
- * @param {number} data.controls.showDollhouse 是否展示3D按钮(0-否,1-是)
- * @param {number} data.controls.showFloorplan 是否展示2D按钮(0-否,1-是)
- * @returns {Promise}
- **/
-export const saveScene = data => {
-    return http.post('/api/scene/edit/saveScene', data)
-}
-/**
- * 文件上传
- * @param {object} data 传入的对象参数
- * @param {text} data.base64 图片base64
- * @param {text} data.num 场景码
- * @param {text} data.type 0添加,1替换,默认为1
- * @param {file} data.files 文件数组
- * @param {text} data.fileName 文件名称
- * @param {text} data.bizType 业务类型
- * @returns {Promise}
- **/
-export const upload_files = data => {
-    return http.postFile('/api/scene/edit/upload/files', data)
-}
-/**
- * 文件上传后保存
- * @param {object} data 传入的对象参数
- * @param {string} data.num 场景码
- * @param {string} data.type 文件业务类型
- * @param {string} data.fileInfo 文件信息,json格式字符串
- * @returns {Promise}
- **/
-export const saveUpload = data => {
-    return http.post('/api/scene/edit/saveUpload', data)
-}
-/**
- * 获取场景详情-编辑页面
- * @param {object} data 传入的对象参数
- * @param {string} data.num 场景码
- * @param {number} data.reqType 请求来源(1-编辑页面 2-查看页面)
- * @returns {Promise}
- **/
-export const getInfo = data => {
-    return http.get('/api/scene/edit/getInfo', data)
-}
-
-/**
- * 添加热点/添加或修改热点
- * @param {object} data 传入的对象参数
- * @param {string} data.num 场景码
- * @param {array} data.hotDataList 热点数据集合
- * @param {array} data.icons icons集合
- * @returns {Promise}
- **/
-export const tag_save = data => {
-    return http.post('/service/scene/edit/tag/save', data)
-}
-
-export const get_goods_list = data => {
-    return http.post('/back/product/list', data)
-}
-
-export const get_hk_product_source = data => {
-    return http.get('/back/product/productSourceHK', data)
-}
-
-export const get_hk_goods_list = data => {
-    return http.post('/back/product/HKList', data)
-}
-
-export const get_category_list = data => {
-    return http.post('/back/category/allList', data)
-}
-
-export const get_scene_list = data => {
-    return http.post('/back/scene/allList', data)
-}
-
-export const get_qrCode = data => {
-    return http.get('/service/scene/edit/down/qrCode', data)
-}
+import { http } from '@/utils/request'
+/**
+ * 场景发布
+ * @param {object} data 传入的对象参数
+ * @param {string} data.num 场景码
+ * @returns {Promise}
+ **/
+export const publicScene = data => {
+    return http.post('/api/scene/edit/publicScene', data)
+}
+/**
+ * 场景编辑保存
+ * @param {object} data 传入的对象参数
+ * @param {string} data.num 场景码
+ * @param {string} data.floorLogo 地面logo名称
+ * @param {number} data.floorLogoSize 地面logo大小
+ * @param {string} data.music  背景音乐名称
+ * @param {string} data.scenePassword 加密浏览密码
+ * @param {string} data.title 场景标题
+ * @param {string} data.description 场景描述
+ * @param {object} data.controls
+ * @param {number} data.controls.showMap 是否展示小地图(0-否,1-是)
+ * @param {number} data.controls.showLock 是否需要密码访问(0-否,1-是)
+ * @param {number} data.controls.showTitle 是否展示标题(0-否,1-是)
+ * @param {number} data.controls.showPanorama 是否展示漫游按钮(0-否,1-是)
+ * @param {number} data.controls.showDollhouse 是否展示3D按钮(0-否,1-是)
+ * @param {number} data.controls.showFloorplan 是否展示2D按钮(0-否,1-是)
+ * @returns {Promise}
+ **/
+export const saveScene = data => {
+    return http.post('/api/scene/edit/saveScene', data)
+}
+/**
+ * 文件上传
+ * @param {object} data 传入的对象参数
+ * @param {text} data.base64 图片base64
+ * @param {text} data.num 场景码
+ * @param {text} data.type 0添加,1替换,默认为1
+ * @param {file} data.files 文件数组
+ * @param {text} data.fileName 文件名称
+ * @param {text} data.bizType 业务类型
+ * @returns {Promise}
+ **/
+export const upload_files = data => {
+    return http.postFile('/api/scene/edit/upload/files', data)
+}
+/**
+ * 文件上传后保存
+ * @param {object} data 传入的对象参数
+ * @param {string} data.num 场景码
+ * @param {string} data.type 文件业务类型
+ * @param {string} data.fileInfo 文件信息,json格式字符串
+ * @returns {Promise}
+ **/
+export const saveUpload = data => {
+    return http.post('/api/scene/edit/saveUpload', data)
+}
+/**
+ * 获取场景详情-编辑页面
+ * @param {object} data 传入的对象参数
+ * @param {string} data.num 场景码
+ * @param {number} data.reqType 请求来源(1-编辑页面 2-查看页面)
+ * @returns {Promise}
+ **/
+export const getInfo = data => {
+    return http.get('/api/scene/edit/getInfo', data)
+}
+
+/**
+ * 添加热点/添加或修改热点
+ * @param {object} data 传入的对象参数
+ * @param {string} data.num 场景码
+ * @param {array} data.hotDataList 热点数据集合
+ * @param {array} data.icons icons集合
+ * @returns {Promise}
+ **/
+export const tag_save = data => {
+    return http.post('/service/scene/edit/tag/save', data)
+}
+
+export const get_goods_list = data => {
+    return http.post('/back/product/list', data)
+}
+export const get_brands_list = data => {
+    return http.post('/back/brand/list', data)
+}
+
+export const get_hk_product_source = data => {
+    return http.get('/back/product/productSourceHK', data)
+}
+
+export const get_hk_goods_list = data => {
+    return http.post('/back/product/HKList', data)
+}
+
+export const get_category_list = data => {
+    return http.post('/back/category/allList', data)
+}
+
+export const get_scene_list = data => {
+    return http.post('/back/scene/allList', data)
+}
+
+export const get_qrCode = data => {
+    return http.get('/service/scene/edit/down/qrCode', data)
+}

+ 390 - 0
packages/app-cdfg/src/components/Tags/brand-list.vue

@@ -0,0 +1,390 @@
+<!--  -->
+<template>
+    <teleport to="body">
+        <div class="brand-layer">
+            <div class="brand-info">
+                <div class="brand-header">
+                    <span>選擇品牌</span>
+                    <ui-icon @click.stop="close" class="close-btn" type="close"></ui-icon>
+                </div>
+
+                <div class="brand-con">
+                    <div class="g-search">
+                        <ui-input type="text" width="260px" placeholder="輸入關鍵字" v-model="searchKey">
+                            <template v-slot:preIcon>
+                                <ui-icon type="search" class="icon" />
+                            </template>
+                        </ui-input>
+                    </div>
+                    <div
+                        v-show="showListPanel"
+                        class="table-layer"
+                        v-infinite-scroll="getData"
+                        infinite-scroll-disabled="disabled_x"
+                        :infinite-scroll-throttle-delay="500"
+                        :infinite-scroll-immediate-check="false"
+                        infinite-scroll-distance="30"
+                    >
+                        <table class="list">
+                            <thead>
+                                <tr>
+                                    <th width="10px"></th>
+                                    <th>序號</th>
+                                    <th>品牌名稱</th>
+                                    <th>品牌Logo</th>
+                                    <th>品牌邊框</th>
+                                </tr>
+                            </thead>
+                            <tbody>
+                                <tr v-for="(i, index) in brands" :key="index" @click="chooseItem(i)">
+                                    <td>
+                                        <div class="checkbox" :class="{ active: brand?.id == i.id }">
+                                            <!-- <input type="radio" /> -->
+                                            <!-- <span></span> -->
+                                        </div>
+                                    </td>
+                                    <td>{{ index + 1 }}</td>
+                                    <td>
+                                        <span class="brand-name">{{ i.zhName }}</span>
+                                    </td>
+                                    <td><img style="width: 100px" :src="i.brandLogo" alt="" /></td>
+                                    <td><img style="width: 100px" :src="i.outlineImage" alt="" /></td>
+                                </tr>
+                                <tr class="nodata" v-if="brands.length === 0">
+                                    <td colspan="7">暫無數據</td>
+                                </tr>
+                            </tbody>
+                        </table>
+                    </div>
+                </div>
+                <div class="brand-footer">
+                    <ui-button @click.stop="close" type="cancel">取消</ui-button>
+                    <ui-button @click.stop="saveBrand" type="primary">保存</ui-button>
+                </div>
+            </div>
+        </div></teleport
+    >
+</template>
+
+<script setup>
+import { reactive, ref, toRefs, onBeforeMount, onMounted, watch, defineEmits, computed } from 'vue'
+const emits = defineEmits(['close'])
+import common from '@/utils/common'
+import { useStore } from 'vuex'
+const store = useStore()
+const showListPanel = ref(false)
+const searchKey = ref('')
+const productSource = ref(null)
+const hotData = computed(() => store.getters['tag/hotData'])
+const brands = computed(() => {
+    return store.getters['tag/brandsList'] || []
+})
+const brand = ref(null)
+// const brands = ref([
+//     {
+//         id: 1,
+//         cdfBrandId: 1,
+//         zhName: '阿迪达斯',
+//         ftName: '阿迪達斯',
+//         enName: 'adidas',
+//         brandLogo: 'https://tm-image.tianyancha.com/tm/1bf31ff81eb5e59a51db1a51600693e2.jpg',
+//         outlineId: '',
+//         outlineName: '',
+//         outlineImage: 'https://pic.90sheji.com/original_origin_pic/18/12/14/8691dccadcecf039f60540135bb4a5e5.png%21/fw/315/quality/90/unsharp/true/compress/true/canvas/315x315a0a0/cvscolor/FFFFFFFF',
+//     },
+//     {
+//         id: 2,
+//         cdfBrandId: 2,
+//         zhName: '耐克',
+//         ftName: '耐克',
+//         enName: 'nike',
+//         brandLogo: 'https://pan.kanfeidie.com/wp-content/uploads/2020/08/20200809012925603.png',
+//         outlineId: '',
+//         outlineName: '',
+//         outlineImage: 'https://pic.90sheji.com/original_origin_pic/18/12/14/8691dccadcecf039f60540135bb4a5e5.png%21/fw/315/quality/90/unsharp/true/compress/true/canvas/315x315a0a0/cvscolor/FFFFFFFF',
+//     },
+//     {
+//         id: 3,
+//         cdfBrandId: 3,
+//         zhName: '李宁',
+//         ftName: '李寧',
+//         enName: 'li-ning',
+//         brandLogo: 'https://www.bjxku.com/uploads/images/img/2021/1013/1634090167152732.png',
+//         outlineId: '',
+//         outlineName: '',
+//         outlineImage: 'https://pic.90sheji.com/original_origin_pic/18/12/14/8691dccadcecf039f60540135bb4a5e5.png%21/fw/315/quality/90/unsharp/true/compress/true/canvas/315x315a0a0/cvscolor/FFFFFFFF',
+//     },
+//     {
+//         id: 4,
+//         cdfBrandId: 4,
+//         zhName: '安踏',
+//         ftName: '安踏',
+//         enName: 'ANTA',
+//         brandLogo:
+//             'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2F97cc9fb1-55e4-43a6-a19e-9b29c30771ac%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1704946045&t=b6f477348b8e188ae95b0fb522395aa0',
+//         outlineId: '',
+//         outlineName: '',
+//         outlineImage: 'https://pic.90sheji.com/original_origin_pic/18/12/14/8691dccadcecf039f60540135bb4a5e5.png%21/fw/315/quality/90/unsharp/true/compress/true/canvas/315x315a0a0/cvscolor/FFFFFFFF',
+//     },
+// ])
+const chooseItem = item => {
+    brand.value = item
+}
+const saveBrand = () => {
+    hotData.value.brandId = brand.value.cdfBrandId
+    hotData.value.brand = brand.value
+    emits('close')
+}
+const pageNum = ref(1)
+const getData = common.debounce(
+    (reset = false) => {
+        store
+            .dispatch('tag/getBrandsList', {
+                keyword: searchKey.value,
+                reset,
+                // pageNum: Math.floor(brands.value.length / 20) + 1,
+                pageNum: pageNum.value,
+                pageSize: 20,
+            })
+            .then(res => {
+                pageNum.value++
+            })
+            .catch(err => {
+                console.error(err)
+            })
+        if (!showListPanel.value) {
+            showListPanel.value = true
+        }
+    },
+    700,
+    false
+)
+const close = () => {
+    emits('close')
+}
+const selectGood = (item, isSelect) => {
+    item.isCheck = isSelect
+    let index = select.value.findIndex(i => i.id == item.id)
+    if (isSelect) {
+        !~index && select.value.push(item)
+    } else {
+        ~index && select.value.splice(index, 1)
+    }
+}
+watch(
+    () => searchKey.value,
+    (newval, old) => {
+        getData(true)
+    }
+)
+onMounted(() => {
+    showListPanel.value = true
+    getData(true)
+})
+</script>
+<style lang="scss" scoped>
+.brand-layer {
+    width: 100vw;
+    height: 100vh;
+    z-index: 100000;
+    top: 0;
+    position: fixed;
+    left: 0;
+    // padding: calc(var(--editor-head-height) + 20px) calc(var(--editor-toolbox-width) + 20px) 60px calc(var(--editor-menu-width) + 20px);
+    // background-color: rgba(255, 255, 255, 0.7);
+    z-index: 999;
+    .brand-info {
+        color: #fff;
+        width: 800px;
+        height: 760px;
+        margin: 5% auto;
+        user-select: none;
+        filter: var(--editor-menu-filter);
+        background-color: var(--editor-menu-back);
+        backdrop-filter: blur(4px);
+        border: solid 1px #000;
+        border-radius: 4px;
+        overflow: hidden;
+        &::after {
+            position: absolute;
+            top: 0;
+            left: 0;
+            content: '';
+            width: 100%;
+            height: 100%;
+            z-index: -1;
+            border: solid 1px rgba(255, 255, 255, 0.16);
+        }
+
+        .brand-header {
+            width: 100%;
+            padding: 22px 20px;
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+            border-bottom: 1px solid rgba(255, 255, 255, 0.16);
+            .close-btn {
+                font-size: 16px;
+                cursor: pointer;
+            }
+        }
+
+        .brand-con {
+            padding: 20px;
+            height: calc(100% - 142px);
+            .g-search {
+            }
+
+            .table-layer {
+                overflow-y: auto;
+                height: calc(100% - 54px);
+                flex: 1;
+                margin-top: 20px;
+                background: rgba(176, 176, 176, 0.16);
+                border: 1px solid rgba(255, 255, 255, 0.1);
+                .list {
+                    border-collapse: collapse;
+                    width: 100%;
+                }
+
+                .list td,
+                .list th {
+                    .brand-name {
+                        max-width: 150px;
+                        display: inline-block;
+                        overflow: hidden;
+                        white-space: nowrap;
+                        text-overflow: ellipsis;
+                    }
+                    font-size: 14px;
+                    line-height: 20px;
+                    text-align: left;
+
+                    padding: 15px;
+                    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
+                    &:not(&:first-of-type) {
+                        // min-width: 90px;
+                    }
+                }
+
+                .list th {
+                    color: rgba(255, 255, 255, 0.6);
+                    font-weight: normal;
+                    background: rgba(27, 27, 28, 0.8);
+                }
+                tr {
+                    cursor: pointer;
+                }
+
+                .nodata td,
+                .nodata th {
+                    text-align: center;
+                }
+
+                .list-info {
+                    height: 28px;
+                    padding-left: 33px;
+                    line-height: 28px;
+                    position: relative;
+                    text-align: left;
+                }
+
+                .list-info > img {
+                    position: absolute;
+                    left: 0;
+                    top: 0;
+                    width: 28px;
+                    height: 28px;
+                }
+            }
+        }
+
+        .brand-footer {
+            width: 100%;
+            padding: 22px 20px;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            > button {
+                width: 105px;
+                margin: 0 10px;
+            }
+        }
+    }
+    .checkbox {
+        position: relative;
+        width: 14px;
+        height: 14px;
+        border-radius: 2px;
+        &.disabled {
+            opacity: 0.3;
+            > input {
+                cursor: default;
+            }
+        }
+    }
+
+    // .checkbox > input,
+    // .checkbox > span {
+    //     width: 100%;
+    //     height: 100%;
+    //     position: absolute;
+    //     left: 0;
+    //     top: 0;
+    //     border: 1px solid rgba(176, 176, 176, 0.5);
+    // }
+
+    // .checkbox > input {
+    //     z-index: 1;
+    //     opacity: 0;
+    //     cursor: pointer;
+    // }
+
+    // .checkbox > span {
+    //     z-index: 2;
+    //     pointer-events: none;
+    //     border-radius: 2px;
+    // }
+
+    // .checkbox span {
+    // }
+    .checkbox {
+        position: absolute;
+        left: 0;
+        top: 0;
+        border: 1px solid rgba(176, 176, 176, 0.5);
+        position: relative;
+        width: 14px;
+        height: 14px;
+        border-radius: 2px;
+        cursor: pointer;
+        &.disabled {
+            opacity: 0.3;
+            > input {
+                cursor: default;
+            }
+        }
+
+        &.active {
+            background: #00c8af;
+            border: 1px solid #00c8af;
+            &::after {
+                position: absolute;
+                display: table;
+                border: 2px solid #fff;
+                border-top: 0;
+                border-left: 0;
+                -webkit-transform: rotate(45deg) scale(0.6) translate(-50%, -50%);
+                transform: rotate(45deg) scale(0.6) translate(-50%, -50%);
+                opacity: 1;
+                -webkit-transition: all 0.2s cubic-bezier(0.12, 0.4, 0.29, 1.46) 0.1s;
+                transition: all 0.2s cubic-bezier(0.12, 0.4, 0.29, 1.46) 0.1s;
+                content: ' ';
+                width: 9px;
+                height: 16px;
+                top: 20%;
+            }
+        }
+    }
+}
+</style>

+ 244 - 229
packages/app-cdfg/src/components/Tags/index.vue

@@ -1,229 +1,244 @@
-<template>
-    <teleport :to="tags$" v-if="tags$">
-        <template :key="index" v-for="(tag, index) in tags">
-            <div @mouseenter="onMouseEnter(tag, index)" @mouseleave="onMouseLeave($event, tag)" :style="{ left: tag.x + 'px', top: tag.y + 'px' }" :class="{ visible: tag.visible }">
-                <span @click.stop="goTag(tag, index)" class="point zoom" :style="{ 'background-image': 'url(' + getUrl(tag.icon) + ')' }"></span>
-                <!-- <div class="content"> -->
-                <div class="content">
-                    <div class="trans" :class="{ active: (isFixed && tag.sid == hotData.sid) || showInfo }">
-                        <template v-if="hotData && tag.sid == hotData.sid && !showMsg">
-                            <div class="arrow" :id="`arrow_${tag.sid}`"></div>
-                            <TagInfo v-if="isEdit && hotData" />
-                            <ShowTag @click.stop="" v-if="!isEdit && hotData" @open="openInfo" />
-                        </template>
-                    </div>
-                </div>
-                <TagView @click.stop="" v-if="showMsg && toggleIndex == index" @close="closeInfo" />
-            </div>
-        </template>
-    </teleport>
-    <GoodsList v-if="isShowGoodList" @close="closeGoodsList" />
-    <SceneList v-if="isShowSceneList" @close="closeSceneList" />
-</template>
-<script setup>
-import { ref, onMounted, computed, watch, watchEffect, onActivated, onDeactivated, getCurrentInstance, nextTick } from 'vue'
-import { getApp, useApp } from '@/app'
-import { useStore } from 'vuex'
-import common from '../../utils/common'
-import TagView from './tag-view.vue'
-import GoodsList from './goods-list.vue'
-import SceneList from './scene-list.vue'
-
-import TagInfo from './tag-info.vue'
-import ShowTag from './show-tag.vue'
-import { useRoute } from 'vue-router'
-import { useMusicPlayer } from '@/utils/sound'
-const musicPlayer = useMusicPlayer()
-// const route = useRoute()
-let init = true
-const hotData = computed(() => {
-    let data = store.getters['tag/hotData']
-    if (!data) {
-        // musicPlayer.play()
-        // musicPlayer.pause(true)
-        // if (!getApp().Scene.isCurrentPanoHasVideo) {
-        //     console.log('resume')
-        //     console.log(init)
-        //     musicPlayer.resume()
-        // }
-    }
-    return data
-})
-const isPlay = computed(() => store.getters['tour/isPlay'])
-const router = computed(() => store.getters['router'])
-const flying = computed(() => store.getters['flying'])
-const leaveId = computed(() => store.getters['tag/leaveId'])
-const isEdit = computed(() => store.getters['tag/isEdit'])
-const isShowGoodList = computed(() => store.getters['tag/isShowGoodList'])
-const isShowSceneList = computed(() => store.getters['tag/isShowSceneList'])
-
-const isFixed = computed(() => store.getters['tag/isFixed'])
-const enterVisible = computed(() => store.getters['tag/enterVisible'])
-const editPosition = computed(() => store.getters['tag/editPosition'])
-const toggleIndex = computed(() => store.getters['tag/toggleIndex'])
-const isClick = computed(() => store.getters['tag/isClick'])
-const editModule = computed(() => store.getters['editModule'])
-const positionInfo = computed(() => store.getters['tag/positionInfo'])
-const store = useStore()
-const tags$ = ref(null)
-const tags = computed(() => {
-    return store.getters['tag/tags'] || []
-})
-
-watch(
-    () => router.value.name,
-    (val, old) => {
-        // console.log(val)
-        if (val !== 'tag') {
-            store.commit('tag/setFixed', false)
-        }
-    }
-)
-
-const showInfo = ref(false)
-const showMsg = ref(false)
-
-// const toggleIndex = ref(null)
-const openInfo = () => {
-    showMsg.value = true
-    store.commit('tag/setFixed', false)
-    showInfo.value = false
-}
-const closeInfo = () => {
-    showMsg.value = false
-    if (isClick.value) {
-        //只有点击定位的才恢复显示
-        store.commit('tag/show', toggleIndex.value)
-        store.commit('tag/setFixed', true)
-        // showInfo.value = true
-        showInfo.value = false
-    }
-    store.commit('tag/setClick', false)
-}
-
-const closeGoodsList = () => {
-    store.commit('tag/setShowGoodsList', false)
-}
-
-const closeSceneList = () => {
-    store.commit('tag/setShowSceneList', false)
-}
-
-const closeTag = async () => {
-    const app = getApp()
-    const player = await app.TourManager.player
-    //关闭热点面板时候,继续播放之前暂停的音频
-    if (!app.Scene.isCurrentPanoHasVideo && !player.isPlaying) {
-        if (hotData.value.type == 'audio' || hotData.value.type == 'video') {
-            // console.log('resume')
-            musicPlayer.resume()
-        }
-    }
-
-    store.commit('tag/setFixed', false)
-    store.commit('tag/closeTag')
-    showInfo.value = false
-}
-const goTag = async (item, index) => {
-    let player = await getApp().TourManager.player
-    if (isPlay.value) {
-        player.pause()
-        store.commit('tour/setData', { isPlay: false })
-    }
-    if (flying.value) {
-        return
-    }
-    if (isFixed.value && !isEdit.value && hotData.value.sid == item.sid && !positionInfo.value) {
-        closeTag()
-    } else {
-        if (!enterVisible.value && !editPosition.value) {
-            if (!isEdit.value && !positionInfo.value) {
-                store.commit('tag/show', index)
-                store.commit('tag/setFixed', true)
-                showInfo.value = true
-                store.commit('tag/setToggleIndex', index)
-                store.commit('tag/gotoTag', item)
-            }
-            store.commit('tag/setClick', true)
-        } else {
-            //热点可视操作
-            getApp().TagManager.edit.setTagVisi(item.sid)
-        }
-    }
-}
-
-onMounted(async () => {
-    const app = await useApp()
-    await app.TagManager.tag()
-    init = false
-
-    tags$.value = '[xui_tags]'
-    app.TagManager.updatePosition(tags.value)
-    if (app.config.mobile) {
-        nextTick(() => {
-            let player = document.querySelector('.player')
-            player.addEventListener('touchstart', onClickHandler)
-        })
-    } else {
-        window.addEventListener('click', onClickHandler)
-    }
-})
-const getUrl = icon => {
-    let url = icon == '' || !icon ? getApp().resource.getAppURL('images/tag_icon_default.svg') : icon
-
-    return common.changeUrl(url)
-}
-const onMouseEnter = (tag, index) => {
-    if (!getApp().config.mobile) {
-        if (flying.value || isPlay.value) {
-            return
-        }
-        if (!enterVisible.value && !editPosition.value && !isEdit.value && !positionInfo.value) {
-            // console.log('onMouseEnter')
-
-            showInfo.value = true
-            store.commit('tag/show', index)
-
-            store.commit('tag/setToggleIndex', index)
-            if (leaveId.value != tag.sid) {
-                //聚焦后 移到其他热点取消fixed
-                store.commit('tag/setFixed', false)
-            }
-        }
-    }
-}
-
-const onMouseLeave = (event, tag) => {
-    if (!getApp().config.mobile) {
-        if (flying.value) {
-            return
-        }
-        if (event.relatedTarget != null) {
-            // if (!isEdit.value) {
-            showInfo.value = false
-            // }
-            store.commit('tag/setLeaveId', tag.sid)
-            if (!enterVisible.value && !isFixed.value && !showMsg.value && !editPosition.value && !positionInfo.value) {
-                closeTag()
-            }
-        }
-    }
-}
-
-const onClickHandler = () => {
-    // if (flying.value) {
-    //     return
-    // }
-
-    if (!isEdit.value && !positionInfo.value && isFixed.value) {
-        closeTag()
-        store.commit('tag/setClick', false)
-    }
-}
-</script>
-
-<style lang="scss" scoped>
-[xui_tags] .content .trans {
-    min-width: 525px;
-}
-</style>
+<template>
+    <teleport :to="tags$" v-if="tags$">
+        <template :key="index" v-for="(tag, index) in tags">
+            <div @mouseenter="onMouseEnter(tag, index)" @mouseleave="onMouseLeave($event, tag)" :style="{ left: tag.x + 'px', top: tag.y + 'px' }" :class="{ visible: tag.visible }">
+                <span @click.stop="goTag(tag, index)" class="point zoom" :style="{ 'background-image': 'url(' + getUrl(tag.icon) + ')' }"></span>
+                <!-- <div class="content"> -->
+                <div class="content">
+                    <div :id="`trans_${tag.sid}`" :style="isEdit ? transStyle : ''" class="trans" :class="{ active: (isFixed && tag.sid == hotData.sid) || showInfo }">
+                        <template v-if="hotData && tag.sid == hotData.sid && !showMsg">
+                            <div class="arrow" :id="`arrow_${tag.sid}`"></div>
+                            <TagInfo v-if="isEdit && hotData" />
+                            <ShowTag @click.stop="" v-if="!isEdit && hotData" @open="openInfo" />
+                        </template>
+                    </div>
+                </div>
+                <TagView @click.stop="" v-if="showMsg && toggleIndex == index" @close="closeInfo" />
+            </div>
+        </template>
+    </teleport>
+    <GoodsList v-if="isShowGoodList" @close="closeGoodsList" />
+    <SceneList v-if="isShowSceneList" @close="closeSceneList" />
+</template>
+<script setup>
+import { ref, onMounted, computed, watch, watchEffect, onActivated, onDeactivated, getCurrentInstance, nextTick } from 'vue'
+import { getApp, useApp } from '@/app'
+import { useStore } from 'vuex'
+import common from '../../utils/common'
+import TagView from './tag-view.vue'
+import GoodsList from './goods-list.vue'
+import SceneList from './scene-list.vue'
+
+import TagInfo from './tag-info.vue'
+import ShowTag from './show-tag.vue'
+import { useRoute } from 'vue-router'
+import { useMusicPlayer } from '@/utils/sound'
+const musicPlayer = useMusicPlayer()
+// const route = useRoute()
+let init = true
+const transRef = ref(null)
+const hotData = computed(() => {
+    let data = store.getters['tag/hotData']
+    if (!data) {
+        // musicPlayer.play()
+        // musicPlayer.pause(true)
+        // if (!getApp().Scene.isCurrentPanoHasVideo) {
+        //     console.log('resume')
+        //     console.log(init)
+        //     musicPlayer.resume()
+        // }
+    }
+    return data
+})
+const isPlay = computed(() => store.getters['tour/isPlay'])
+const router = computed(() => store.getters['router'])
+const flying = computed(() => store.getters['flying'])
+const leaveId = computed(() => store.getters['tag/leaveId'])
+const isEdit = computed(() => store.getters['tag/isEdit'])
+const isShowGoodList = computed(() => store.getters['tag/isShowGoodList'])
+const isShowSceneList = computed(() => store.getters['tag/isShowSceneList'])
+
+const isFixed = computed(() => store.getters['tag/isFixed'])
+const enterVisible = computed(() => store.getters['tag/enterVisible'])
+const editPosition = computed(() => store.getters['tag/editPosition'])
+const toggleIndex = computed(() => store.getters['tag/toggleIndex'])
+const isClick = computed(() => store.getters['tag/isClick'])
+const editModule = computed(() => store.getters['editModule'])
+const positionInfo = computed(() => store.getters['tag/positionInfo'])
+const store = useStore()
+const tags$ = ref(null)
+const tags = computed(() => {
+    return store.getters['tag/tags'] || []
+})
+
+watch(
+    () => router.value.name,
+    (val, old) => {
+        // console.log(val)
+        if (val !== 'tag') {
+            store.commit('tag/setFixed', false)
+        }
+    }
+)
+const transStyle = ref('')
+watch(
+    () => isEdit.value,
+    (val, old) => {
+        // console.log(val)
+        if (val) {
+            nextTick(() => {
+                // let transEle = document.getElementById(`trans_${hotData.value.sid}`)
+                // let transOffsetHeight = transEle.offsetHeight
+                // transStyle.value = `transform:translateY(0) scale(1);margin-top:-${transOffsetHeight / 2}px;transition:none;`
+            })
+        }
+    }
+)
+
+const showInfo = ref(false)
+const showMsg = ref(false)
+
+// const toggleIndex = ref(null)
+const openInfo = () => {
+    showMsg.value = true
+    store.commit('tag/setFixed', false)
+    showInfo.value = false
+}
+const closeInfo = () => {
+    showMsg.value = false
+    if (isClick.value) {
+        //只有点击定位的才恢复显示
+        store.commit('tag/show', toggleIndex.value)
+        store.commit('tag/setFixed', true)
+        // showInfo.value = true
+        showInfo.value = false
+    }
+    store.commit('tag/setClick', false)
+}
+
+const closeGoodsList = () => {
+    store.commit('tag/setShowGoodsList', false)
+}
+
+const closeSceneList = () => {
+    store.commit('tag/setShowSceneList', false)
+}
+
+const closeTag = async () => {
+    const app = getApp()
+    const player = await app.TourManager.player
+    //关闭热点面板时候,继续播放之前暂停的音频
+    if (!app.Scene.isCurrentPanoHasVideo && !player.isPlaying) {
+        if (hotData.value.type == 'audio' || hotData.value.type == 'video') {
+            // console.log('resume')
+            musicPlayer.resume()
+        }
+    }
+
+    store.commit('tag/setFixed', false)
+    store.commit('tag/closeTag')
+    showInfo.value = false
+}
+const goTag = async (item, index) => {
+    let player = await getApp().TourManager.player
+    if (isPlay.value) {
+        player.pause()
+        store.commit('tour/setData', { isPlay: false })
+    }
+    if (flying.value) {
+        return
+    }
+    if (isFixed.value && !isEdit.value && hotData.value.sid == item.sid && !positionInfo.value) {
+        closeTag()
+    } else {
+        if (!enterVisible.value && !editPosition.value) {
+            if (!isEdit.value && !positionInfo.value) {
+                store.commit('tag/show', index)
+                store.commit('tag/setFixed', true)
+                showInfo.value = true
+                store.commit('tag/setToggleIndex', index)
+                store.commit('tag/gotoTag', item)
+            }
+            store.commit('tag/setClick', true)
+        } else {
+            //热点可视操作
+            getApp().TagManager.edit.setTagVisi(item.sid)
+        }
+    }
+}
+
+onMounted(async () => {
+    const app = await useApp()
+    await app.TagManager.tag()
+    init = false
+
+    tags$.value = '[xui_tags]'
+    app.TagManager.updatePosition(tags.value)
+    if (app.config.mobile) {
+        nextTick(() => {
+            let player = document.querySelector('.player')
+            player.addEventListener('touchstart', onClickHandler)
+        })
+    } else {
+        window.addEventListener('click', onClickHandler)
+    }
+})
+const getUrl = icon => {
+    let url = icon == '' || !icon ? getApp().resource.getAppURL('images/tag_icon_default.svg') : icon
+
+    return common.changeUrl(url)
+}
+const onMouseEnter = (tag, index) => {
+    if (!getApp().config.mobile) {
+        if (flying.value || isPlay.value) {
+            return
+        }
+        if (!enterVisible.value && !editPosition.value && !isEdit.value && !positionInfo.value) {
+            // console.log('onMouseEnter')
+
+            showInfo.value = true
+            store.commit('tag/show', index)
+
+            store.commit('tag/setToggleIndex', index)
+            if (leaveId.value != tag.sid) {
+                //聚焦后 移到其他热点取消fixed
+                store.commit('tag/setFixed', false)
+            }
+        }
+    }
+}
+
+const onMouseLeave = (event, tag) => {
+    if (!getApp().config.mobile) {
+        if (flying.value) {
+            return
+        }
+        if (event.relatedTarget != null) {
+            // if (!isEdit.value) {
+            showInfo.value = false
+            // }
+            store.commit('tag/setLeaveId', tag.sid)
+            if (!enterVisible.value && !isFixed.value && !showMsg.value && !editPosition.value && !positionInfo.value) {
+                closeTag()
+            }
+        }
+    }
+}
+
+const onClickHandler = () => {
+    // if (flying.value) {
+    //     return
+    // }
+
+    if (!isEdit.value && !positionInfo.value && isFixed.value) {
+        closeTag()
+        store.commit('tag/setClick', false)
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+[xui_tags] .content .trans {
+    min-width: 525px;
+}
+</style>

+ 400 - 259
packages/app-cdfg/src/components/Tags/tag-info.vue

@@ -1,259 +1,400 @@
-<!--  -->
-<template>
-    <div class="hot-editor" :id="`tagBox_${hotData.sid}`">
-        <div class="header">
-            <div class="header-title">{{ $t('tag.toolbox.hotspot') }}</div>
-            <!-- <ui-icon class="close" type="close"></ui-icon> -->
-        </div>
-        <div class="hot-content">
-            <StyleIcon />
-            <ui-input
-                require
-                class="input"
-                width="100%"
-                :placeholder="$t('tag.toolbox.hotspotTitleTips')"
-                type="text"
-                :modelValue="title"
-                @update:modelValue="value => (title = value)"
-                maxlength="30"
-            />
-
-            <div class="desc-box" v-if="info.showDesc" :class="{ border: showBorder }">
-                <div class="edit-box">
-                    <Editor
-                        @click="showBorder = true"
-                        :placeholder="$t('tag.toolbox.hotspotDescTips')"
-                        :maxlength="descriptionMax"
-                        :html="content"
-                        ref="editor$"
-                        @change="onDescriptionChange"
-                        @blur="onEditDescription"
-                    />
-                </div>
-                <div class="desc-link">
-                    <!-- <LinkManage :show="!!(inInsertLink && maxTextLen)" :textlen="maxTextLen" @close="inInsertLink = false" @add="insertel" /> -->
-                    <LinkManage v-if="showLink" @close="closeLink" @confirm="insertText" />
-                    <ui-icon type="link" class="icon" @click="showLink = true" />
-
-                    <span>
-                        <span class="theme-color">{{ descriptionLength }}</span>
-                        /
-                        <span>{{ descriptionMax }}</span>
-                    </span>
-                </div>
-            </div>
-
-            <div class="tag-metas" v-if="info.showDesc">
-                <MetasUpload :type="info.type" />
-            </div>
-
-            <MetasUploadCustomized v-else :type="info.type" />
-
-            <div class="submit-ctrl">
-                <div class="radio-group">
-                    <!-- <ui-input
-                        v-for="(item, type) in custom"
-                        :key="type"
-                        class="radio"
-                        type="radio"
-                        :modelValue="info.type === type"
-                        @update:modelValue="changeType(type)"
-                        :tip="item.name"
-                        :icon="item.icon"
-                    /> -->
-                    <ui-input v-for="(item, type) in customized" :key="type" class="radio" type="radio" :modelValue="info.type === type" @update:modelValue="changeType(type)" :tip="item.name">
-                        <span>{{ item.name }}</span>
-                    </ui-input>
-                </div>
-            </div>
-        </div>
-    </div>
-</template>
-
-<script setup>
-import { reactive, toRefs, ref, onBeforeMount, onMounted, defineProps, computed, nextTick } from 'vue'
-import MetasUpload from './metas-upload.vue'
-import MetasUploadCustomized from './metas-upload-customized.vue'
-import StyleIcon from './style-icon.vue'
-import LinkManage from './link-manage.vue'
-import { custom, customized } from './constant.js'
-import Editor from '../shared/Editor'
-import { useStore } from 'vuex'
-const store = useStore()
-
-const editor$ = ref(null)
-const descriptionMax = 200
-const descriptionLength = ref(0)
-const showLink = ref(false)
-const hotData = computed(() => store.getters['tag/hotData'])
-const whichDept = computed(() => store.getters['scene/whichDept'])
-
-if (whichDept.value == 'HK') {
-    delete customized['applet_link']
-} else {
-    delete customized['exhibits']
-    delete customized['point_jump']
-}
-
-const info = computed(() => {
-    // let showDesc = hotData.value.type == 'image' || hotData.value.type == 'audio' || hotData.value.type == 'video' || hotData.value.type == 'link'
-    let data = {
-        type: hotData.value.type || 'commodity'
-    }
-    return data
-})
-const title = computed({
-    get() {
-        if (hotData.value.title && hotData.value.title != void 0) {
-            return hotData.value.title
-        }
-        return hotData.value.title || ''
-    },
-    set(value) {
-        store.commit('tag/setTitle', value)
-    }
-})
-const content = computed({
-    get() {
-        if (editor$.value) {
-            descriptionLength.value = editor$.value.getLength()
-            if (hotData.value.content && hotData.value.content != void 0) {
-                return hotData.value.content
-            } else {
-                editor$.value.setHtml(hotData.value.content)
-            }
-        }
-        return hotData.value.content || ''
-    },
-    set(value) {
-        // console.log(value)
-        store.commit('tag/setContent', { value })
-    }
-})
-
-const closeLink = () => {
-    showLink.value = false
-}
-const insertText = data => {
-    editor$.value.insertLink(data.text.value, data.link.value)
-    nextTick(() => {
-        store.commit('tag/update', { content: editor$.value.getHtml() })
-    })
-    closeLink()
-}
-const onDescriptionChange = ({ length, html, init }) => {
-    // // alert(1)
-    // console.log(length, html, init)
-    // if (init) {
-    //     return (descriptionLength.value = length)
-    // }
-
-    content.value = html
-    descriptionLength.value = length
-}
-const showBorder = ref(false)
-const onEditDescription = () => {
-    showBorder.value = false
-}
-
-const changeType = type => {
-    console.log(type)
-    info.value.type = type
-    store.commit('tag/setMetaType', type)
-}
-const maxContentLen = ref(10)
-</script>
-<style lang="scss" scoped>
-.hot-editor {
-    background: rgba(27, 27, 28, 0.8);
-    border-radius: 4px;
-    pointer-events: auto;
-    // backdrop-filter: blur(4px);
-    // min-width: 400px;
-    .hot-content {
-        width: 100%;
-        padding: 30px 20px;
-        .submit-ctrl {
-            margin-top: 20px;
-            display: flex;
-
-            .radio-group {
-                flex: 1;
-                display: inline-flex;
-                white-space: nowrap;
-                > .radio {
-                    margin-right: 18px;
-                    > span {
-                        margin-left: 8px;
-                    }
-                }
-            }
-
-            .submit {
-                flex: none;
-                cursor: pointer;
-            }
-        }
-        .desc-box {
-            width: 100%;
-            height: 158px;
-            background: rgba(255, 255, 255, 0.1);
-            border-radius: 4px;
-            border: 1px solid rgba(255, 255, 255, 0.2);
-            margin-bottom: 10px;
-            &.border {
-                border: 1px solid var(--editor-main-color);
-            }
-            .edit-box {
-                height: 128px;
-                padding: 10px;
-                box-sizing: border-box;
-            }
-        }
-        .tag-metas {
-            width: 100%;
-            height: 225px;
-            background: rgba(255, 255, 255, 0.1);
-            border-radius: 4px;
-            overflow: hidden;
-        }
-        .desc-link {
-            position: relative;
-            display: flex;
-            align-items: center;
-            justify-content: space-between;
-            background: rgba(255, 255, 255, 0.1);
-            border-radius: 0px 0px 4px 4px;
-            height: 30px;
-            padding: 0 10px;
-            .iconfont {
-                font-size: 16px;
-                cursor: pointer;
-            }
-            span {
-                font-size: 12px;
-            }
-        }
-        .input {
-            margin-bottom: 10px;
-        }
-    }
-    .header {
-        height: 60px;
-        display: flex;
-        align-items: center;
-        justify-content: space-between;
-        padding: 0 20px;
-        box-sizing: border-box;
-        color: #999;
-        border-bottom: 1px solid rgba(255, 255, 255, 0.16);
-        .header-title {
-            font-size: 16px;
-            font-weight: bold;
-        }
-        .close {
-            cursor: pointer;
-        }
-    }
-}
-</style>
+<!--  -->
+<template>
+    <div class="hot-editor" :id="`tagBox_${hotData.sid}`">
+        <div class="header">
+            <div class="header-title">{{ $t('tag.toolbox.hotspot') }}</div>
+            <!-- <ui-icon class="close" type="close"></ui-icon> -->
+        </div>
+        <div class="hot-content">
+            <StyleIcon v-if="info.type != 'waterfall'" />
+            <div v-else class="brand-item">
+                <div class="brand-info" v-if="hotData.brand">
+                    <div class="brand-logo" :style="`background-image:url(${hotData.brand.brandLogo});`">
+                        <div class="brand-frame" :style="`background-image:url(${hotData.brand.outlineImage});`">
+                            <div class="close-btn" @click.stop="delBrand">
+                                <ui-icon type="close"></ui-icon>
+                            </div>
+                        </div>
+                    </div>
+                    <span>{{ hotData.brand.zhName }}</span>
+                </div>
+                <div v-else class="add-brand" @click="showBrandList = true">
+                    <div class="button">
+                        <ui-icon type="add"></ui-icon>
+                    </div>
+                    <span>{{ $t('tag.toolbox.chooseBrand') }}</span>
+                </div>
+
+                <!-- <ui-input type="select" :options="brands" width="100%" placeholder="请选择品牌" v-model="brand" stop-el="i">
+                    <template v-slot:option="{ raw }">
+                        <div :class="{ 'music-user': raw.user }">
+                            <div>{{ raw.label }}</div>
+                        </div>
+                    </template>
+                </ui-input> -->
+            </div>
+            <ui-input
+                require
+                class="input"
+                width="100%"
+                :placeholder="$t('tag.toolbox.hotspotTitleTips')"
+                type="text"
+                :modelValue="title"
+                @update:modelValue="value => (title = value)"
+                maxlength="30"
+            />
+
+            <div class="desc-box" v-if="info.showDesc" :class="{ border: showBorder }">
+                <div class="edit-box">
+                    <Editor
+                        @click="showBorder = true"
+                        :placeholder="$t('tag.toolbox.hotspotDescTips')"
+                        :maxlength="descriptionMax"
+                        :html="content"
+                        ref="editor$"
+                        @change="onDescriptionChange"
+                        @blur="onEditDescription"
+                    />
+                </div>
+                <div class="desc-link">
+                    <!-- <LinkManage :show="!!(inInsertLink && maxTextLen)" :textlen="maxTextLen" @close="inInsertLink = false" @add="insertel" /> -->
+                    <LinkManage v-if="showLink" @close="closeLink" @confirm="insertText" />
+                    <ui-icon type="link" class="icon" @click="showLink = true" />
+
+                    <span>
+                        <span class="theme-color">{{ descriptionLength }}</span>
+                        /
+                        <span>{{ descriptionMax }}</span>
+                    </span>
+                </div>
+            </div>
+
+            <div class="tag-metas" v-if="info.showDesc">
+                <MetasUpload :type="info.type" />
+            </div>
+
+            <MetasUploadCustomized v-else :type="info.type" />
+
+            <div class="submit-ctrl">
+                <div class="radio-group">
+                    <!-- <ui-input
+                        v-for="(item, type) in custom"
+                        :key="type"
+                        class="radio"
+                        type="radio"
+                        :modelValue="info.type === type"
+                        @update:modelValue="changeType(type)"
+                        :tip="item.name"
+                        :icon="item.icon"
+                    /> -->
+                    <ui-input v-for="(item, type) in customized" :key="type" class="radio" type="radio" :modelValue="info.type === type" @update:modelValue="changeType(type)" :tip="item.name">
+                        <span>{{ item.name }}</span>
+                    </ui-input>
+                </div>
+            </div>
+        </div>
+    </div>
+    <brandList v-if="showBrandList" @close="showBrandList = false"></brandList>
+</template>
+
+<script setup>
+import { reactive, toRefs, ref, onBeforeMount, onMounted, defineProps, computed, nextTick } from 'vue'
+import MetasUpload from './metas-upload.vue'
+import MetasUploadCustomized from './metas-upload-customized.vue'
+import StyleIcon from './style-icon.vue'
+import LinkManage from './link-manage.vue'
+import brandList from './brand-list.vue'
+import { custom, customized } from './constant.js'
+import Editor from '../shared/Editor'
+import { useStore } from 'vuex'
+import { useI18n } from '@/i18n'
+
+const { t } = useI18n({ useScope: 'global' })
+const store = useStore()
+const metadata = computed(() => store.getters['info/metadata'])
+const editor$ = ref(null)
+const descriptionMax = 200
+const descriptionLength = ref(0)
+const showLink = ref(false)
+const hotData = computed(() => store.getters['tag/hotData'])
+const whichDept = computed(() => store.getters['scene/whichDept'])
+
+const showBrandList = ref(false)
+if (whichDept.value == 'HK') {
+    delete customized['applet_link']
+} else {
+    delete customized['exhibits']
+    delete customized['point_jump']
+}
+
+const info = computed(() => {
+    // let showDesc = hotData.value.type == 'image' || hotData.value.type == 'audio' || hotData.value.type == 'video' || hotData.value.type == 'link'
+    let data = {
+        type: hotData.value.type || 'commodity',
+    }
+    return data
+})
+const title = computed({
+    get() {
+        if (hotData.value.title && hotData.value.title != void 0) {
+            return hotData.value.title
+        }
+        return hotData.value.title || ''
+    },
+    set(value) {
+        store.commit('tag/setTitle', value)
+    },
+})
+const content = computed({
+    get() {
+        if (editor$.value) {
+            descriptionLength.value = editor$.value.getLength()
+            if (hotData.value.content && hotData.value.content != void 0) {
+                return hotData.value.content
+            } else {
+                editor$.value.setHtml(hotData.value.content)
+            }
+        }
+        return hotData.value.content || ''
+    },
+    set(value) {
+        // console.log(value)
+        store.commit('tag/setContent', { value })
+    },
+})
+//删除品牌信息
+const delBrand = () => {
+    if (hotData.value.brand && hotData.value.brandId) {
+        delete hotData.value.brand
+        delete hotData.value.brandId
+    }
+}
+const closeLink = () => {
+    showLink.value = false
+}
+const insertText = data => {
+    editor$.value.insertLink(data.text.value, data.link.value)
+    nextTick(() => {
+        store.commit('tag/update', { content: editor$.value.getHtml() })
+    })
+    closeLink()
+}
+const onDescriptionChange = ({ length, html, init }) => {
+    // // alert(1)
+    // console.log(length, html, init)
+    // if (init) {
+    //     return (descriptionLength.value = length)
+    // }
+
+    content.value = html
+    descriptionLength.value = length
+}
+const showBorder = ref(false)
+const onEditDescription = () => {
+    showBorder.value = false
+}
+
+const changeType = type => {
+    console.log(type)
+    info.value.type = type
+    store.commit('tag/setMetaType', type)
+}
+const maxContentLen = ref(10)
+onMounted(() => {})
+</script>
+<style lang="scss" scoped>
+.hot-editor {
+    background: rgba(27, 27, 28, 0.8);
+    border-radius: 4px;
+    pointer-events: auto;
+    // backdrop-filter: blur(4px);
+    // min-width: 400px;
+    .hot-content {
+        width: 100%;
+        padding: 30px 20px;
+        .brand-item {
+            display: flex;
+            align-items: flex-start;
+            justify-content: flex-start;
+            position: relative;
+            margin-bottom: 20px;
+            &::before {
+                content: '*';
+                position: absolute;
+                top: 50%;
+                transform: translateY(-50%);
+                right: 100%;
+                margin-right: 2px;
+                color: #fa3f48;
+                line-height: 1.5em;
+            }
+            .brand-info {
+                .brand-logo {
+                    background-repeat: no-repeat;
+                    background-size: cover;
+                    background-position: center center;
+                    width: 80px;
+                    height: 80px;
+
+                    .brand-frame {
+                        width: 100%;
+                        height: 100%;
+                        background-repeat: no-repeat;
+                        background-size: 100% 100%;
+                        position: relative;
+                        cursor: pointer;
+                        .close-btn {
+                            width: 16px;
+                            height: 16px;
+                            border-radius: 50%;
+                            position: absolute;
+                            display: flex;
+                            align-items: center;
+                            justify-content: center;
+                            background: #fa3f48;
+                            cursor: pointer;
+                            opacity: 0.8;
+                            right: -6px;
+                            top: -6px;
+                            z-index: 101;
+                            display: none;
+                            i {
+                                font-size: 12px;
+                                color: #fff;
+                                transform: scale(0.8);
+                            }
+                        }
+                        &:hover {
+                            .close-btn {
+                                display: flex;
+                                i {
+                                    font-size: 12px;
+                                    color: #fff;
+                                    transform: scale(0.8);
+                                }
+                            }
+                        }
+                    }
+                }
+                > span {
+                    width: 100px;
+                    overflow: hidden;
+                    text-overflow: ellipsis;
+                    white-space: nowrap;
+                    font-size: 12px;
+                    margin-top: 6px;
+                    text-align: center;
+                    display: inline-block;
+                    text-align: center;
+                    color: rgba(255, 255, 255, 0.3);
+                }
+            }
+        }
+        .add-brand {
+            color: rgba(255, 255, 255, 0.3);
+            margin-right: 8px;
+            width: 80px;
+            .button {
+                cursor: pointer;
+                width: 80px;
+                height: 80px;
+                border: 1px solid rgba(255, 255, 255, 0.2);
+                background: rgba(255, 255, 255, 0.1);
+                border-radius: 4px;
+                text-align: center;
+                display: flex;
+                flex-direction: column;
+                justify-content: center;
+            }
+            > span {
+                font-size: 12px;
+                margin-top: 6px;
+                text-align: center;
+                width: 100%;
+                display: inline-block;
+            }
+        }
+        .submit-ctrl {
+            margin-top: 20px;
+            display: flex;
+
+            .radio-group {
+                flex: 1;
+                display: inline-flex;
+                white-space: nowrap;
+                > .radio {
+                    margin-right: 18px;
+                    > span {
+                        margin-left: 8px;
+                    }
+                }
+            }
+
+            .submit {
+                flex: none;
+                cursor: pointer;
+            }
+        }
+        .desc-box {
+            width: 100%;
+            height: 158px;
+            background: rgba(255, 255, 255, 0.1);
+            border-radius: 4px;
+            border: 1px solid rgba(255, 255, 255, 0.2);
+            margin-bottom: 10px;
+            &.border {
+                border: 1px solid var(--editor-main-color);
+            }
+            .edit-box {
+                height: 128px;
+                padding: 10px;
+                box-sizing: border-box;
+            }
+        }
+        .tag-metas {
+            width: 100%;
+            height: 225px;
+            background: rgba(255, 255, 255, 0.1);
+            border-radius: 4px;
+            overflow: hidden;
+        }
+        .desc-link {
+            position: relative;
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
+            background: rgba(255, 255, 255, 0.1);
+            border-radius: 0px 0px 4px 4px;
+            height: 30px;
+            padding: 0 10px;
+            .iconfont {
+                font-size: 16px;
+                cursor: pointer;
+            }
+            span {
+                font-size: 12px;
+            }
+        }
+        .input {
+            margin-bottom: 10px;
+        }
+    }
+    .header {
+        height: 60px;
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        padding: 0 20px;
+        box-sizing: border-box;
+        color: #999;
+        border-bottom: 1px solid rgba(255, 255, 255, 0.16);
+        .header-title {
+            font-size: 16px;
+            font-weight: bold;
+        }
+        .close {
+            cursor: pointer;
+        }
+    }
+}
+</style>

+ 1 - 0
packages/app-cdfg/src/locales/en.json

@@ -168,6 +168,7 @@
             "deleteTips": "Click to delete",
             "hotspot": "Hotspot",
             "hotspotTitleTips": "Please enter the hotspot title. ",
+            "chooseBrand": "Please select a brand.",
             "hotspotDescTips": "Please enter the content.",
             "addLink": "Insert a link",
             "continueAdd": "Continue to add",

+ 1 - 0
packages/app-cdfg/src/locales/zh.json

@@ -169,6 +169,7 @@
             "deleteTips": "確定刪除?",
             "hotspot": "熱點",
             "hotspotTitleTips": "請輸入熱點標題",
+            "chooseBrand": "請先選擇品牌",
             "hotspotDescTips": "請輸入內容",
             "addLink": "添加鏈接",
             "continueAdd": "繼續添加",

+ 45 - 46
packages/app-cdfg/src/pages/editorPC.js

@@ -1,46 +1,45 @@
-import '@/assets/theme.editor.scss'
-import Delegate from '../utils/fns/Delegate'
-import ClickOutSide from '../utils/fns/ClickOutSide'
-import checkVip from '../utils/fns/v-check-vip'
-import Components from '@kankan/components'
-import { createApp } from 'vue'
-import store from '../store'
-import router from '../router'
-import i18n, { getLocale, setI18nLanguage, loadLocaleMessages } from '../i18n'
-
-import App from './EditorPC.vue'
-import { getApp } from '../app'
-import infiniteScroll from 'vue3-infinite-scroll-good'
-
-const local = getLocale()
-
-loadLocaleMessages(i18n, local).then(() => {
-    setI18nLanguage(i18n, local)
-
-    const app = (window.__app = createApp(App))
-    app.use(i18n)
-    app.use(store)
-    app.use(router)
-    app.use(Components)
-    app.use(infiniteScroll)
-    app.directive('click-outside', ClickOutSide)
-    app.directive('vip', checkVip)
-    app.mount('#app')
-
-    const handleUserInputFocus = () => {
-        setTimeout(() => {
-            getApp().config.useShortcutKeys = false
-        }, 200)
-    }
-
-    const handleUserInputBlur = () => {
-        setTimeout(() => {
-            getApp().config.useShortcutKeys = true
-        }, 200)
-    }
-
-    Delegate(document, 'focus', 'input', () => handleUserInputFocus())
-    Delegate(document, 'focus', '[contenteditable]', () => handleUserInputFocus())
-    Delegate(document, 'blur', 'input', () => handleUserInputBlur())
-    Delegate(document, 'blur', '[contenteditable]', () => handleUserInputBlur())
-})
+import '@/assets/theme.editor.scss'
+import Delegate from '../utils/fns/Delegate'
+import ClickOutSide from '../utils/fns/ClickOutSide'
+import checkVip from '../utils/fns/v-check-vip'
+import Components from '@kankan/components'
+import { createApp } from 'vue'
+import store from '../store'
+import router from '../router'
+import i18n, { getLocale, setI18nLanguage, loadLocaleMessages } from '../i18n'
+
+import App from './EditorPC.vue'
+import { getApp } from '../app'
+import infiniteScroll from 'vue3-infinite-scroll-good'
+
+const local = getLocale()
+loadLocaleMessages(i18n, local).then(() => {
+    setI18nLanguage(i18n, local)
+
+    const app = (window.__app = createApp(App))
+    app.use(i18n)
+    app.use(store)
+    app.use(router)
+    app.use(Components)
+    app.use(infiniteScroll)
+    app.directive('click-outside', ClickOutSide)
+    app.directive('vip', checkVip)
+    app.mount('#app')
+
+    const handleUserInputFocus = () => {
+        setTimeout(() => {
+            getApp().config.useShortcutKeys = false
+        }, 200)
+    }
+
+    const handleUserInputBlur = () => {
+        setTimeout(() => {
+            getApp().config.useShortcutKeys = true
+        }, 200)
+    }
+
+    Delegate(document, 'focus', 'input', () => handleUserInputFocus())
+    Delegate(document, 'focus', '[contenteditable]', () => handleUserInputFocus())
+    Delegate(document, 'blur', 'input', () => handleUserInputBlur())
+    Delegate(document, 'blur', '[contenteditable]', () => handleUserInputBlur())
+})

+ 213 - 214
packages/app-cdfg/src/store/modules/settings.js

@@ -1,214 +1,213 @@
-import { getApp, getNum } from '@/app'
-import { blobToDataURL, convertBlob2File } from '@/utils/file'
-import { useI18n, getLocale } from '@/i18n'
-export default {
-    namespaced: true,
-    state() {
-        return {
-            metadata: {
-                num: null,
-                thumb: null,
-                entry: null,
-                controls: null,
-                floorLogo: null,
-                floorLogoSize: null,
-                floorLogoFile: null,
-                loadingLogo: null,
-                loadingLogoFile: null,
-                scenePassword: null,
-            },
-            controls: null,
-        }
-    },
-    getters: {
-        metadata: (state, getters, rootState, rootGetters) => {
-            const metadata = rootGetters['scene/metadata']
-            for (let key in state.metadata) {
-                if (state.metadata[key] == void 0) {
-                    state.metadata[key] = metadata[key]
-                }
-                // 要特殊处理
-                if (key === 'thumb' && state.metadata.entry) {
-                    if (!state.metadata[key]) {
-                        state.metadata[key] = getApp().resource.getUserResourceURL('thumb-1k.jpg')
-                    } else if (state.metadata.files && state.metadata.files[key]) {
-                        state.metadata[key] = state.metadata.files[key]
-                    } else {
-                        state.metadata[key] = getApp().resource.getUserResourceURL('thumb-1k.jpg', true)
-                    }
-                }
-            }
-            return state.metadata
-        },
-        controls: (state, getters, rootState, rootGetters) => {
-            if (!state.controls) {
-                state.controls = getters.metadata.controls && Object.assign({}, getters.metadata.controls)
-            }
-            return state.controls || {}
-        },
-        loadingLogoFile: (state, getters, rootState, rootGetters) => {
-            if (state.metadata.files && state.metadata.files.loadingLogo) {
-                return state.metadata.loadingLogoFile
-            } else if (state.metadata.loadingLogoFile) {
-                return getApp().resource.getUserResourceURL(state.metadata.loadingLogoFile, true)
-            }
-
-            return null
-        },
-        floorLogoFile: (state, getters, rootState, rootGetters) => {
-            if (state.metadata.floorLogoFile) {
-                if (state.metadata.files && state.metadata.files.floorLogo) {
-                    return state.metadata.floorLogoFile
-                } else if (state.metadata.floorLogoFile) {
-                    return getApp().resource.getUserResourceURL(state.metadata.floorLogoFile, true)
-                }
-            }
-            return null
-        },
-    },
-    mutations: {
-        controls(state, payload) {
-            if (typeof payload === 'object') {
-                state.controls = Object.assign(state.controls || {}, payload)
-            } else {
-                if (payload) {
-                    state.controls = state.controls || {}
-                    state.controls[payload] = state.controls[payload] ? 0 : 1
-                } else {
-                    state.metadata.controls = null
-                    state.controls = null
-                }
-            }
-        },
-        update(state, payload = {}) {
-            let metadata = state.metadata || {}
-            if (metadata.files && payload.files) {
-                Object.assign(metadata.files, payload.files)
-                delete payload.files
-            }
-            state.metadata = Object.assign(metadata, payload)
-            this.commit('enterEdit')
-        },
-        cancel(state) {
-            for (let key in state.metadata) {
-                let value = state.metadata[key]
-                if (typeof value === 'string' && value.indexOf('blob:') === 0) {
-                    // 释放对象
-                    URL.revokeObjectURL(value)
-                }
-                state.metadata[key] = null
-            }
-            // 清空缓存
-            state.controls = null
-            state.metadata.controls = null
-            // 清空文件对象
-            state.metadata.files = null
-            this.commit('leaveEdit')
-        },
-        save(state, payload) {
-            this.commit('scene/update', payload || state.metadata)
-            this.commit('settings/cancel')
-        },
-    },
-    actions: {
-        async update({ state, commit }, payload) {
-            debugger
-            if (payload.entry) {
-                // 初始画面截图
-                const camera = getApp().Camera
-                payload.entry = camera.getScreenshotInfo()
-                payload.thumbs = await camera.screenshot()
-                // 更新初始点
-                let panos = getApp().core.get('Player').model.panos
-                getApp().core.get('Scene').firstView.updateByEntry(payload.entry, panos)
-                // 创建访问对象
-                //payload.thumb = URL.createObjectURL(payload.thumbs[0].data)
-                payload.files = {
-                    thumb: URL.createObjectURL(payload.thumbs[0].data),
-                }
-            }
-            commit('update', payload)
-        },
-        async save({ state, commit, dispatch }) {
-            let files = state.metadata.files
-            if (files) {
-                for (let biz in files) {
-                    let file = convertBlob2File(files[biz])
-                    let filename = `${biz}-user.${file.type.replace('image/', '')}`
-                    try {
-                        await getApp().remote_editor.upload_files({
-                            num: getNum(),
-                            files: [{ file, filename }],
-                            bizType: biz,
-                        })
-                        if (state.metadata.hasOwnProperty([biz + 'File'])) {
-                            state.metadata[biz + 'File'] = filename
-                        } else {
-                            state.metadata[biz] = filename
-                        }
-                        delete state.metadata.files
-                    } catch (error) {
-                        return Promise.reject({ type: 'toast', tips: 'error', msg: 'info.toolbox.uploadFail' })
-                        // return Promise.reject('文件上传失败')
-                    }
-                }
-            }
-
-            // 保存封面图
-            if (state.metadata.entry && state.metadata.thumbs) {
-                await dispatch('saveEntry', state.metadata)
-            }
-
-            // 对浏览设置进行关联处理
-            if (state.metadata.controls.showLock !== void 0) {
-                if (state.metadata.controls.showLock) {
-                    if (state.metadata.scenePassword && state.metadata.scenePassword.length < 4) {
-                        commit('setError', { type: 'password' }, { root: true })
-                        return Promise.reject()
-                    }
-                    if (!state.metadata.scenePassword) {
-                        state.metadata.controls.showLock = 0
-                    }
-                } else {
-                    state.metadata.scenePassword = ''
-                }
-            }
-
-            return getApp()
-                .remote_editor.base_save({
-                    ...state.metadata,
-                })
-                .then(result => {
-                    commit('save')
-                    return result
-                })
-        },
-        async saveEntry({ state, commit }) {
-            try {
-                const thumbs = {
-                    num: getNum(),
-                    bizType: 'settings-thumb',
-                    files: [],
-                }
-                state.metadata.thumbs.forEach(item => {
-                    thumbs.files.push(convertBlob2File(item.data, `thumb-${item.name}.jpg`))
-                })
-
-                await getApp().remote_editor.upload_files(thumbs)
-
-                const result = await getApp().remote_editor.saveInitialPage({
-                    num: getNum(),
-                    fileName: `thumb-1k.jpg`,
-                    data: JSON.stringify(state.metadata.entry),
-                })
-
-                delete state.metadata.thumbs
-
-                commit('save')
-                return Promise.resolve(result)
-            } catch (error) {
-                return Promise.reject(error)
-            }
-        },
-    },
-}
+import { getApp, getNum } from '@/app'
+import { blobToDataURL, convertBlob2File } from '@/utils/file'
+import { useI18n, getLocale } from '@/i18n'
+export default {
+    namespaced: true,
+    state() {
+        return {
+            metadata: {
+                num: null,
+                thumb: null,
+                entry: null,
+                controls: null,
+                floorLogo: null,
+                floorLogoSize: null,
+                floorLogoFile: null,
+                loadingLogo: null,
+                loadingLogoFile: null,
+                scenePassword: null,
+            },
+            controls: null,
+        }
+    },
+    getters: {
+        metadata: (state, getters, rootState, rootGetters) => {
+            const metadata = rootGetters['scene/metadata']
+            for (let key in state.metadata) {
+                if (state.metadata[key] == void 0) {
+                    state.metadata[key] = metadata[key]
+                }
+                // 要特殊处理
+                if (key === 'thumb' && state.metadata.entry) {
+                    if (!state.metadata[key]) {
+                        state.metadata[key] = getApp().resource.getUserResourceURL('thumb-1k.jpg')
+                    } else if (state.metadata.files && state.metadata.files[key]) {
+                        state.metadata[key] = state.metadata.files[key]
+                    } else {
+                        state.metadata[key] = getApp().resource.getUserResourceURL('thumb-1k.jpg', true)
+                    }
+                }
+            }
+            return state.metadata
+        },
+        controls: (state, getters, rootState, rootGetters) => {
+            if (!state.controls) {
+                state.controls = getters.metadata.controls && Object.assign({}, getters.metadata.controls)
+            }
+            return state.controls || {}
+        },
+        loadingLogoFile: (state, getters, rootState, rootGetters) => {
+            if (state.metadata.files && state.metadata.files.loadingLogo) {
+                return state.metadata.loadingLogoFile
+            } else if (state.metadata.loadingLogoFile) {
+                return getApp().resource.getUserResourceURL(state.metadata.loadingLogoFile, true)
+            }
+
+            return null
+        },
+        floorLogoFile: (state, getters, rootState, rootGetters) => {
+            if (state.metadata.floorLogoFile) {
+                if (state.metadata.files && state.metadata.files.floorLogo) {
+                    return state.metadata.floorLogoFile
+                } else if (state.metadata.floorLogoFile) {
+                    return getApp().resource.getUserResourceURL(state.metadata.floorLogoFile, true)
+                }
+            }
+            return null
+        },
+    },
+    mutations: {
+        controls(state, payload) {
+            if (typeof payload === 'object') {
+                state.controls = Object.assign(state.controls || {}, payload)
+            } else {
+                if (payload) {
+                    state.controls = state.controls || {}
+                    state.controls[payload] = state.controls[payload] ? 0 : 1
+                } else {
+                    state.metadata.controls = null
+                    state.controls = null
+                }
+            }
+        },
+        update(state, payload = {}) {
+            let metadata = state.metadata || {}
+            if (metadata.files && payload.files) {
+                Object.assign(metadata.files, payload.files)
+                delete payload.files
+            }
+            state.metadata = Object.assign(metadata, payload)
+            this.commit('enterEdit')
+        },
+        cancel(state) {
+            for (let key in state.metadata) {
+                let value = state.metadata[key]
+                if (typeof value === 'string' && value.indexOf('blob:') === 0) {
+                    // 释放对象
+                    URL.revokeObjectURL(value)
+                }
+                state.metadata[key] = null
+            }
+            // 清空缓存
+            state.controls = null
+            state.metadata.controls = null
+            // 清空文件对象
+            state.metadata.files = null
+            this.commit('leaveEdit')
+        },
+        save(state, payload) {
+            this.commit('scene/update', payload || state.metadata)
+            this.commit('settings/cancel')
+        },
+    },
+    actions: {
+        async update({ state, commit }, payload) {
+            if (payload.entry) {
+                // 初始画面截图
+                const camera = getApp().Camera
+                payload.entry = camera.getScreenshotInfo()
+                payload.thumbs = await camera.screenshot()
+                // 更新初始点
+                let panos = getApp().core.get('Player').model.panos
+                getApp().core.get('Scene').firstView.updateByEntry(payload.entry, panos)
+                // 创建访问对象
+                //payload.thumb = URL.createObjectURL(payload.thumbs[0].data)
+                payload.files = {
+                    thumb: URL.createObjectURL(payload.thumbs[0].data),
+                }
+            }
+            commit('update', payload)
+        },
+        async save({ state, commit, dispatch }) {
+            let files = state.metadata.files
+            if (files) {
+                for (let biz in files) {
+                    let file = convertBlob2File(files[biz])
+                    let filename = `${biz}-user.${file.type.replace('image/', '')}`
+                    try {
+                        await getApp().remote_editor.upload_files({
+                            num: getNum(),
+                            files: [{ file, filename }],
+                            bizType: biz,
+                        })
+                        if (state.metadata.hasOwnProperty([biz + 'File'])) {
+                            state.metadata[biz + 'File'] = filename
+                        } else {
+                            state.metadata[biz] = filename
+                        }
+                        delete state.metadata.files
+                    } catch (error) {
+                        return Promise.reject({ type: 'toast', tips: 'error', msg: 'info.toolbox.uploadFail' })
+                        // return Promise.reject('文件上传失败')
+                    }
+                }
+            }
+
+            // 保存封面图
+            if (state.metadata.entry && state.metadata.thumbs) {
+                await dispatch('saveEntry', state.metadata)
+            }
+
+            // 对浏览设置进行关联处理
+            if (state.metadata.controls.showLock !== void 0) {
+                if (state.metadata.controls.showLock) {
+                    if (state.metadata.scenePassword && state.metadata.scenePassword.length < 4) {
+                        commit('setError', { type: 'password' }, { root: true })
+                        return Promise.reject()
+                    }
+                    if (!state.metadata.scenePassword) {
+                        state.metadata.controls.showLock = 0
+                    }
+                } else {
+                    state.metadata.scenePassword = ''
+                }
+            }
+
+            return getApp()
+                .remote_editor.base_save({
+                    ...state.metadata,
+                })
+                .then(result => {
+                    commit('save')
+                    return result
+                })
+        },
+        async saveEntry({ state, commit }) {
+            try {
+                const thumbs = {
+                    num: getNum(),
+                    bizType: 'settings-thumb',
+                    files: [],
+                }
+                state.metadata.thumbs.forEach(item => {
+                    thumbs.files.push(convertBlob2File(item.data, `thumb-${item.name}.jpg`))
+                })
+
+                await getApp().remote_editor.upload_files(thumbs)
+
+                const result = await getApp().remote_editor.saveInitialPage({
+                    num: getNum(),
+                    fileName: `thumb-1k.jpg`,
+                    data: JSON.stringify(state.metadata.entry),
+                })
+
+                delete state.metadata.thumbs
+
+                commit('save')
+                return Promise.resolve(result)
+            } catch (error) {
+                return Promise.reject(error)
+            }
+        },
+    },
+}

File diff suppressed because it is too large
+ 1089 - 1033
packages/app-cdfg/src/store/modules/tag.js


+ 81 - 81
packages/app-cdfg/vue.config.js

@@ -1,81 +1,81 @@
-const pkg = require('./package.json')
-const path = require('path')
-const localIP = require('ip').address()
-const isPord = process.env.NODE_ENV !== 'development'
-const isDev = process.env.NODE_ENV === 'development'
-if (isDev) {
-    process.env.VUE_APP_VERSION = pkg.version
-} else {
-    process.env.VUE_APP_VERSION = pkg.version
-}
-
-module.exports = {
-    assetsDir: 'editor',
-    publicPath: process.env.VUE_APP_CDN_URL,
-    outputDir: isDev ? 'dist' : path.resolve('../../dist/editor'),
-    pages: {
-        epg: {
-            entry: 'src/pages/editorPC.js',
-            title: '四维看看'
-        },
-        show: {
-            entry: 'src/pages/show.js',
-            title: '四维看看'
-        }
-    },
-    css: {
-        extract: false,
-        loaderOptions: {
-            scss: {
-                // prependData: '@import "~@/assets/scss/_variables.editor.scss";',
-            }
-        }
-    },
-    devServer: {
-        headers: {
-            'Cache-Control': 'no-store'
-        },
-        proxy: {
-            '/service': {
-                // target: 'http://vr-admin.cdfmembers.com/',
-                target: 'https://zhongmian.4dage.com/',
-                changeOrigin: true
-            },
-            '/back': {
-                // target: 'http://vr-admin.cdfmembers.com/',
-                target: 'https://zhongmian.4dage.com/',
-                changeOrigin: true
-            },
-            '/sdk': {
-                // target: `http://${localIP}:3099/dist/`,
-                target: `https://eurs3.4dkankan.com/v4/cdfg/`,
-                changeOrigin: true
-            }
-        }
-    },
-    configureWebpack: {
-        resolve: {
-            alias: {
-                '@editor': path.resolve(__dirname, '..', 'kankan-editor', 'src')
-            },
-            extensions: ['.js', '.vue', '.json']
-        }
-    },
-    chainWebpack: config => {
-        // for(let key in this.pages){
-        //     config.plugins.delete(`preload-${key}`)
-        //     config.plugins.delete(`prefetch-${key}`)
-        // }
-
-        config.module
-            .rule('vue-i18n-loader')
-            .test(/\.(json5?|ya?ml)$/)
-            .type('javascript/auto')
-            .pre()
-            .include.add(path.resolve(__dirname, './src/locales'))
-            .end()
-            .use('@intlify/vue-i18n-loader')
-            .loader('@intlify/vue-i18n-loader')
-            .end()
-    }
-}
+const pkg = require('./package.json')
+const path = require('path')
+const localIP = require('ip').address()
+const isPord = process.env.NODE_ENV !== 'development'
+const isDev = process.env.NODE_ENV === 'development'
+if (isDev) {
+    process.env.VUE_APP_VERSION = pkg.version
+} else {
+    process.env.VUE_APP_VERSION = pkg.version
+}
+
+module.exports = {
+    assetsDir: 'editor',
+    publicPath: process.env.VUE_APP_CDN_URL,
+    outputDir: isDev ? 'dist' : path.resolve('../../dist/editor'),
+    pages: {
+        epg: {
+            entry: 'src/pages/editorPC.js',
+            title: '四维看看',
+        },
+        show: {
+            entry: 'src/pages/show.js',
+            title: '四维看看',
+        },
+    },
+    css: {
+        extract: false,
+        loaderOptions: {
+            scss: {
+                // prependData: '@import "~@/assets/scss/_variables.editor.scss";',
+            },
+        },
+    },
+    devServer: {
+        headers: {
+            'Cache-Control': 'no-store',
+        },
+        proxy: {
+            '/service': {
+                // target: 'http://vr-admin.cdfmembers.com/',
+                target: 'https://zhongmian.4dage.com/',
+                changeOrigin: true,
+            },
+            '/back': {
+                // target: 'http://vr-admin.cdfmembers.com/',
+                target: 'https://zhongmian.4dage.com/',
+                changeOrigin: true,
+            },
+            '/sdk': {
+                target: `http://${localIP}:3099/dist/`,
+                // target: `https://eurs3.4dkankan.com/v4/cdfg/`,
+                changeOrigin: true,
+            },
+        },
+    },
+    configureWebpack: {
+        resolve: {
+            alias: {
+                '@editor': path.resolve(__dirname, '..', 'kankan-editor', 'src'),
+            },
+            extensions: ['.js', '.vue', '.json'],
+        },
+    },
+    chainWebpack: config => {
+        // for(let key in this.pages){
+        //     config.plugins.delete(`preload-${key}`)
+        //     config.plugins.delete(`prefetch-${key}`)
+        // }
+
+        config.module
+            .rule('vue-i18n-loader')
+            .test(/\.(json5?|ya?ml)$/)
+            .type('javascript/auto')
+            .pre()
+            .include.add(path.resolve(__dirname, './src/locales'))
+            .end()
+            .use('@intlify/vue-i18n-loader')
+            .loader('@intlify/vue-i18n-loader')
+            .end()
+    },
+}

+ 1 - 21
yarn.lock

@@ -2872,14 +2872,6 @@
     estree-walker "^2.0.1"
     picomatch "^2.2.2"
 
-"@simaq/core@1.1.2-beta.4":
-  version "1.1.2-beta.4"
-  resolved "http://192.168.0.47:4873/@simaq/core/-/core-1.1.2-beta.4.tgz#98bd1c29f04444ef43092147eecd09c2006d413e"
-  integrity sha512-6A05/1UlQ7MVkZek6aVazbPXFYZagY/rh5zsnAERJbcPj1bTht+IZlL2jdMuuF477B/yIVTFxuiKk3qxJpXsbg==
-  dependencies:
-    eventemitter3 "^4.0.7"
-    rxjs "~7.5.7"
-
 "@soda/friendly-errors-webpack-plugin@^1.7.1":
   version "1.8.0"
   resolved "https://registry.npm.taobao.org/@soda/friendly-errors-webpack-plugin/download/@soda/friendly-errors-webpack-plugin-1.8.0.tgz?cache=0&sync_timestamp=1607927438775&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40soda%2Ffriendly-errors-webpack-plugin%2Fdownload%2F%40soda%2Ffriendly-errors-webpack-plugin-1.8.0.tgz#84751d82a93019d5c92c0cf0e45ac59087cd2240"
@@ -6047,11 +6039,6 @@ dotenv@^8.2.0:
   resolved "https://registry.nlark.com/dotenv/download/dotenv-8.6.0.tgz?cache=0&sync_timestamp=1621627076012&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fdotenv%2Fdownload%2Fdotenv-8.6.0.tgz#061af664d19f7f4d8fc6e4ff9b584ce237adcb8b"
   integrity sha1-Bhr2ZNGff02PxuT/m1hM4jety4s=
 
-driver.js@^0.9.8:
-  version "0.9.8"
-  resolved "https://registry.npmmirror.com/driver.js/-/driver.js-0.9.8.tgz#4b327f4537b1c9b9fb19419de86174be821ae32a"
-  integrity sha512-bczjyKdX6XmFyCDkwtRmlaORDwfBk1xXmRO0CAe5VwNQTM98aWaG2LAIiIdTe53iV/B7W5lXlIy2xYtf0JRb7Q==
-
 duplexer@^0.1.1:
   version "0.1.2"
   resolved "https://registry.npm.taobao.org/duplexer/download/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6"
@@ -6354,7 +6341,7 @@ eventemitter3@^2.0.3:
   resolved "https://registry.npm.taobao.org/eventemitter3/download/eventemitter3-2.0.3.tgz?cache=0&sync_timestamp=1598517820291&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Feventemitter3%2Fdownload%2Feventemitter3-2.0.3.tgz#b5e1079b59fb5e1ba2771c0a993be060a58c99ba"
   integrity sha1-teEHm1n7XhuidxwKmTvgYKWMmbo=
 
-eventemitter3@^4.0.0, eventemitter3@^4.0.4, eventemitter3@^4.0.7:
+eventemitter3@^4.0.0, eventemitter3@^4.0.4:
   version "4.0.7"
   resolved "https://registry.npm.taobao.org/eventemitter3/download/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
   integrity sha1-Lem2j2Uo1WRO9cWVJqG0oHMGFp8=
@@ -11487,13 +11474,6 @@ rxjs@^6.6.0, rxjs@^6.6.7:
   dependencies:
     tslib "^1.9.0"
 
-rxjs@~7.5.7:
-  version "7.5.7"
-  resolved "http://192.168.0.47:4873/rxjs/-/rxjs-7.5.7.tgz#2ec0d57fdc89ece220d2e702730ae8f1e49def39"
-  integrity sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==
-  dependencies:
-    tslib "^2.1.0"
-
 safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
   version "5.1.2"
   resolved "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.1.2.tgz?cache=0&sync_timestamp=1599054209520&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsafe-buffer%2Fdownload%2Fsafe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"