瀏覽代碼

log: 主页布局配置部分

sunhongyao341504 2 年之前
父節點
當前提交
3b21113e02

+ 32 - 2
mock/login/routers.ts

@@ -63,7 +63,38 @@ const list = [
       },
     ],
   },
-
+  {
+    path: '/system-config',
+    name: 'system-config',
+    component: 'LAYOUT',
+    redirect: '/system-config/scene-layout',
+    meta: {
+      icon: 'ApartmentOutlined',
+      title: '系统设置',
+      noCache: false,
+      hidden: false,
+      isFrame: '1',
+      status: '0',
+      isRoot: false,
+      alwaysShow: false,
+    },
+    children: [
+      {
+        path: 'scene-layout',
+        name: 'scene-layout',
+        component: '/system-config/scene-layout/SceneLayout',
+        meta: {
+          title: '场景布局',
+          noCache: false,
+          hidden: false,
+          isFrame: '1',
+          status: '0',
+          isRoot: false,
+          alwaysShow: false,
+        },
+      },
+    ],
+  },
   {
     path: '/cameras',
     name: 'cameras',
@@ -96,7 +127,6 @@ const list = [
       },
     ],
   },
-
   {
     path: '/map-config',
     name: 'map_config',

+ 2 - 0
src/router/router-icons.ts

@@ -15,6 +15,7 @@ import {
   ToolOutlined,
   PictureOutlined,
   CameraOutlined,
+  ApartmentOutlined,
 } from '@vicons/antd';
 import {
   OptionsSharp,
@@ -44,4 +45,5 @@ export const constantRouterIcon = {
   ToolOutlined: renderIcon(ToolOutlined),
   PictureOutlined: renderIcon(PictureOutlined),
   CameraOutlined: renderIcon(CameraOutlined),
+  ApartmentOutlined: renderIcon(ApartmentOutlined),
 };

+ 271 - 0
src/views/system-config/scene-layout/SceneLayout.vue

@@ -0,0 +1,271 @@
+<template>
+  <div class="page">
+    <div class="page-head flex items-center">
+      <el-icon size="20"><ArrowLeft /></el-icon>
+      <div class="head-opt flex-1 flex justify-between items-center">
+        <el-space :size="20">
+          <div>
+            <span>公司:</span>
+            <el-select v-model="curCompany">
+              <el-option
+                v-for="item in workshopInfos"
+                :key="item.id"
+                :value="item.id"
+                :label="item.name"
+              />
+            </el-select>
+          </div>
+          <div>
+            <span>标签:</span>
+            <el-select v-model="curScene">
+              <el-option
+                v-for="item in workshopInfos.find((item) => item.id === curCompany)?.labelList"
+                :key="item.id"
+                :value="item.id"
+                :label="item.name"
+              />
+            </el-select>
+          </div>
+        </el-space>
+        <div class="flex">
+          <el-upload
+            class="avatar-uploader flex justify-center items-center"
+            action="/temp/api/layout/uploadPicture"
+            :show-file-list="false"
+            :on-success="handleAvatarSuccess"
+            :with-credentials="true"
+            name="file"
+          >
+            <el-button style="font-size: 12px" :icon="Refresh" :disabled="!hasBg">
+              替换照片
+            </el-button>
+          </el-upload>
+
+          <el-button @click="handleSave" style="margin-left: 40px" type="primary"
+            >保存为布局
+          </el-button>
+        </div>
+      </div>
+    </div>
+    <div class="paint-tool flex">
+      <div class="camera-list">
+        <div>
+          <span class="label-text flex">车间列表:</span>
+          <ElInput
+            class="search-put"
+            style="margin: 10px 0; width: 230px"
+            placeholder="请输入搜索内容"
+            v-model="searchKey"
+            :suffix-icon="Search"
+          />
+        </div>
+        <span class="ml-1" style="color: #3f3f3f"> 提示:请先选择相应公司和场景 </span>
+        <el-scrollbar style="position: relative; height: calc(100% - 90px)">
+          <div></div>
+        </el-scrollbar>
+      </div>
+      <div class="draw-container">
+        <div style="overflow: auto">
+          <canvas width="400" height="400" id="mapEditCanvas"></canvas>
+        </div>
+        <el-upload
+          v-if="!hasBg"
+          class="upload-icon flex justify-center items-center"
+          action="/temp/api/layout/uploadPicture"
+          :show-file-list="false"
+          :on-success="handleAvatarSuccess"
+          :with-credentials="true"
+          name="file"
+        >
+          <img src="~@/assets/images/img-upload.png" />
+        </el-upload>
+        <div class="tag-option">
+          <div>
+            <span>选项</span>
+          </div>
+          <div class="flex flex-col">
+            <div class="flex">
+              <span>背景色:</span>
+              <el-radio-group v-model="tagOption.backgroundColor" size="small">
+                <el-radio label="orange">
+                  <div
+                    style="width: 24px; height: 12px; background-color: orange; margin-right: 10px"
+                  ></div>
+                </el-radio>
+                <el-radio label="blue">
+                  <div
+                    style="width: 24px; height: 12px; background-color: aqua; margin-right: 10px"
+                  ></div>
+                </el-radio>
+                <el-radio label="yellow">
+                  <div
+                    style="width: 24px; height: 12px; background-color: yellow; margin-right: 10px"
+                  ></div>
+                </el-radio>
+              </el-radio-group>
+            </div>
+            <div class="flex">
+              <span>字体:</span>
+              <el-input v-model="tagOption.fontSize" style="width: 150px" />
+            </div>
+            <div class="flex">
+              <span>文字位置:</span>
+              <el-radio-group v-model="tagOption.textPosition" size="small">
+                <el-radio-button label="up">上</el-radio-button>
+                <el-radio-button label="bottom">下</el-radio-button>
+                <el-radio-button label="left">左</el-radio-button>
+                <el-radio-button label="right">右</el-radio-button>
+              </el-radio-group>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+  import { ref } from 'vue';
+  import { workshopInfos } from './tempConstant';
+
+  const curCompany = ref<number>();
+  const curScene = ref<string>('');
+
+  const tagOption = ref({
+    backgroundColor: 'orange',
+    fontSize: 14,
+    textPosition: 'right',
+  });
+
+  import { ElInput } from 'element-plus';
+  import urlJoin from 'url-join';
+  import { useGlobSetting } from '@/hooks/setting';
+  import { Search, ArrowLeft, Refresh } from '@element-plus/icons-vue';
+
+  const globSetting = useGlobSetting();
+
+  const searchKey = ref('');
+  // 是否已有背景图
+  const hasBg = ref(false);
+
+  const handleAvatarSuccess = (e) => {
+    const imgPath = e.data;
+    const imgUrl = urlJoin(globSetting.imgUrl!, imgPath);
+    hasBg.value = true;
+  };
+
+  const handleSave = () => {};
+</script>
+
+<style scoped>
+  .page {
+  }
+  .page-head {
+    height: 54px;
+    padding-left: 15px;
+    background-color: #ffffff;
+  }
+  .head-opt {
+    margin-left: 20px;
+    padding-right: 15px;
+    font-size: 14px;
+    color: #3f3f3f;
+  }
+
+  .avatar-uploader {
+    /* width: 120px; */
+    /* height: 30px; */
+    /* border: 1px solid #eee; */
+    border-radius: 4px;
+    margin-left: 30px;
+  }
+  .upload-icon {
+    position: absolute;
+    top: 0;
+    right: 0;
+    left: 0;
+    bottom: 0;
+    margin: auto;
+  }
+
+  .paint-tool {
+    position: relative;
+    height: calc(100vh - 138px);
+    margin-top: 2px;
+  }
+
+  .camera-list {
+    width: 250px;
+    padding: 0 10px;
+    background-color: #ffffff;
+  }
+  .label-text {
+    font-size: 14px;
+    font-weight: 600;
+    margin: 10px 0 5px 10px;
+  }
+  .camera-item {
+    height: 32px;
+    font-size: 14px;
+    font-weight: 400;
+    color: #404040;
+    line-height: 14px;
+    cursor: pointer;
+  }
+  .camera-item-disabled {
+    color: #c6c6c6;
+  }
+  .camera-id {
+    width: 110px;
+  }
+  .space-name {
+    width: 120px;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+  }
+
+  .draw-container {
+    position: relative;
+    width: calc(100% - 300px);
+    margin: 20px;
+  }
+
+  .tag-option {
+    position: absolute;
+    width: 264px;
+    height: 167px;
+    top: 24px;
+    right: 0px;
+    border-radius: 10px;
+    padding: 12px;
+    background-color: #ffffff;
+  }
+
+  :deep(.search-put .el-input__wrapper) {
+    background-color: #f0f2f5;
+  }
+  :deep(.el-popper__arrow) {
+    display: none;
+  }
+  :deep(.el-tree-node__content:hover) {
+    background: #e6f4ff;
+  }
+  :deep(.el-button--primary) {
+    --el-button-disabled-bg-color: #bfbfbf;
+  }
+  :deep(.el-popover) {
+    width: unset !important;
+    min-width: 110px;
+    text-align: center;
+    font-weight: 400;
+  }
+
+  :deep(.el-radio) {
+    margin-right: 0;
+  }
+
+  .isAdded {
+    color: #409eff;
+  }
+</style>

+ 27 - 0
src/views/system-config/scene-layout/tempConstant.ts

@@ -0,0 +1,27 @@
+export interface LabelItem {
+  code: string;
+  id: number;
+  name: string;
+}
+
+export interface WorkshopInfo {
+  code: string;
+  name: string;
+  id: number;
+  labelList: LabelItem[];
+}
+
+export const workshopInfos: WorkshopInfo[] = [
+  {
+    code: 'shangfei',
+    name: '上飞公司',
+    id: 2,
+    labelList: [
+      {
+        code: 'safe-production',
+        id: 0,
+        name: '生产安全-上飞公司安全模板',
+      },
+    ],
+  },
+];