Переглянути джерело

处理弹窗的放大缩小

MTrun 3 роки тому
батько
коміт
8dc4769b64

+ 3 - 2
package.json

@@ -12,15 +12,16 @@
     "mockjs": "^1.1.0",
     "naive-ui": "^2.19.9",
     "pinia": "^2.0.6",
+    "screenfull": "^6.0.0",
     "vue": "^3.2.16",
     "vue-i18n": "^9.2.0-beta.23",
     "vue-router": "4.0.12"
   },
   "devDependencies": {
-    "@vicons/ionicons5": "~0.11.0",
     "@types/node": "^16.11.1",
     "@typescript-eslint/eslint-plugin": "^5.6.0",
     "@typescript-eslint/parser": "^5.6.0",
+    "@vicons/ionicons5": "~0.11.0",
     "@vitejs/plugin-vue": "^1.9.3",
     "@vitejs/plugin-vue-jsx": "^1.2.0",
     "@vue/compiler-sfc": "^3.2.20",
@@ -31,7 +32,7 @@
     "eslint-plugin-import": "^2.25.3",
     "eslint-plugin-prettier": "^4.0.0",
     "eslint-plugin-vue": "^8.2.0",
-    "lodash": "^4.17.21",
+    "lodash": "~4.17.21",
     "prettier": "^2.5.1",
     "sass": "^1.43.2",
     "sass-loader": "^12.2.0",

+ 12 - 3
pnpm-lock.yaml

@@ -16,13 +16,14 @@ specifiers:
   eslint-plugin-import: ^2.25.3
   eslint-plugin-prettier: ^4.0.0
   eslint-plugin-vue: ^8.2.0
-  lodash: ^4.17.21
+  lodash: ~4.17.21
   mockjs: ^1.1.0
   naive-ui: ^2.19.9
   pinia: ^2.0.6
   prettier: ^2.5.1
   sass: ^1.43.2
   sass-loader: ^12.2.0
+  screenfull: ^6.0.0
   typescript: ^4.4.4
   vite: ^2.6.10
   vite-plugin-importer: ^0.2.5
@@ -34,11 +35,11 @@ specifiers:
   vue-tsc: ^0.28.7
 
 dependencies:
-  '@vicons/ionicons5': rg.cnpmjs.org/@vicons/ionicons5/0.11.0
   axios: rg.cnpmjs.org/axios/0.23.0
   mockjs: rg.cnpmjs.org/mockjs/1.1.0
   naive-ui: rg.cnpmjs.org/naive-ui/2.21.5_vue@3.2.24
   pinia: rg.cnpmjs.org/pinia/2.0.6_typescript@4.5.2+vue@3.2.24
+  screenfull: rg.cnpmjs.org/screenfull/6.0.0
   vue: rg.cnpmjs.org/vue/3.2.24
   vue-i18n: rg.cnpmjs.org/vue-i18n/9.2.0-beta.23_vue@3.2.24
   vue-router: rg.cnpmjs.org/vue-router/4.0.12_vue@3.2.24
@@ -47,6 +48,7 @@ devDependencies:
   '@types/node': rg.cnpmjs.org/@types/node/16.11.12
   '@typescript-eslint/eslint-plugin': rg.cnpmjs.org/@typescript-eslint/eslint-plugin/5.6.0_16d83f5c41c3abb1061a82b07c18e4f3
   '@typescript-eslint/parser': rg.cnpmjs.org/@typescript-eslint/parser/5.6.0_eslint@8.4.1+typescript@4.5.2
+  '@vicons/ionicons5': rg.cnpmjs.org/@vicons/ionicons5/0.11.0
   '@vitejs/plugin-vue': rg.cnpmjs.org/@vitejs/plugin-vue/1.10.2_vite@2.7.1
   '@vitejs/plugin-vue-jsx': rg.cnpmjs.org/@vitejs/plugin-vue-jsx/1.3.1
   '@vue/compiler-sfc': rg.cnpmjs.org/@vue/compiler-sfc/3.2.24
@@ -877,7 +879,7 @@ packages:
     resolution: {integrity: sha1-VBhb+lcqCd9wCU2xlU8ov78TY+0=, registry: http://r.cnpmjs.org/, tarball: https://rg.cnpmjs.org/@vicons/ionicons5/download/@vicons/ionicons5-0.11.0.tgz}
     name: '@vicons/ionicons5'
     version: 0.11.0
-    dev: false
+    dev: true
 
   rg.cnpmjs.org/@vitejs/plugin-vue-jsx/1.3.1:
     resolution: {integrity: sha512-Ku0pnlG0CuFfkvwOe3TEHS7noqBIBR61JbdvH6F6i3IqJv8+0+tcyusR+EoFwi7YrA2vdP26oorWyGv3wDt5kg==, registry: http://r.cnpmjs.org/, tarball: https://rg.cnpmjs.org/@vitejs/plugin-vue-jsx/download/@vitejs/plugin-vue-jsx-1.3.1.tgz}
@@ -3729,6 +3731,13 @@ packages:
       immutable: rg.cnpmjs.org/immutable/4.0.0
     dev: true
 
+  rg.cnpmjs.org/screenfull/6.0.0:
+    resolution: {integrity: sha1-b383v+GcXuUJMaxDjB/jgNW1/0Q=, registry: http://r.cnpmjs.org/, tarball: https://rg.cnpmjs.org/screenfull/download/screenfull-6.0.0.tgz}
+    name: screenfull
+    version: 6.0.0
+    engines: {node: ^14.13.1 || >=16.0.0}
+    dev: false
+
   rg.cnpmjs.org/seemly/0.3.3:
     resolution: {integrity: sha512-mAyqemz41e9HiZPMXAn7NtTExJgztwco5cdZjrt/iViU/oFeav+Q8K1c93M/tIZZ00QkT65JMr4xXQk7Vv5hWQ==, registry: http://r.cnpmjs.org/, tarball: https://rg.cnpmjs.org/seemly/download/seemly-0.3.3.tgz}
     name: seemly

+ 37 - 9
src/components/AppleControlBtn/index.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="go-apple-control-btn">
-    <template v-for="item in btnList" :key="item.key">
+    <template v-for="item in filterBtnList" :key="item.key">
       <div
         class="btn"
         :class="[item.key, disabled && 'disabled']"
@@ -14,13 +14,28 @@
   </div>
 </template>
 <script lang="ts" setup>
-import { renderIcon } from '@/utils/index'
 import { icon } from '@/plugins'
+import { computed } from 'vue'
+import { screenfullFn } from '@/utils'
 
-const emit = defineEmits(['close', 'remove', 'resize'])
+const emit = defineEmits(['close', 'remove', 'resize', 'fullResize'])
 
 const props = defineProps({
+  // 禁用所有按钮
   disabled: {
+    request: false,
+    type: Boolean,
+    default: false
+  },
+  // 要隐藏的按钮
+  hidden: {
+    request: false,
+    type: Array,
+    default: []
+  },
+  // 使用全屏功能
+  narrow: {
+    request: false,
     type: Boolean,
     default: false
   }
@@ -28,6 +43,16 @@ const props = defineProps({
 
 const { CloseIcon, RemoveIcon, ResizeIcon } = icon.ionicons5
 
+const filterBtnList = computed(() => {
+  const res = btnList.filter(e => {
+    return props.hidden.findIndex(p => e.key == p) === -1
+  })
+  return res
+})
+
+const isFull = computed(() => {
+  return props.narrow && screenfullFn(true)
+})
 const btnList = [
   {
     title: '关闭',
@@ -40,14 +65,16 @@ const btnList = [
     icon: RemoveIcon
   },
   {
-    title: '放大',
-    key: 'resize',
+    title: isFull ? '缩小' : '放大',
+    key: props.narrow ? 'fullResize' : 'resize',
     icon: ResizeIcon
   }
 ]
 
-const handleClick = (key: 'close' | 'remove' | 'resize') => {
-  console.log(key)
+const handleClick = (key: 'close' | 'remove' | 'resize' | 'fullResize') => {
+  if (key === 'fullResize') screenfullFn()
+  // 缩小并关闭全屏
+  if (key === 'remove') screenfullFn(true) && screenfullFn()
   emit(key)
 }
 </script>
@@ -74,7 +101,7 @@ const handleClick = (key: 'close' | 'remove' | 'resize') => {
     font-weight: bold;
     border-radius: 50%;
     &.disabled {
-      pointer-events:none;
+      pointer-events: none;
     }
     .icon-base {
       opacity: 0;
@@ -89,7 +116,8 @@ const handleClick = (key: 'close' | 'remove' | 'resize') => {
   .remove {
     background-color: $--color-warn;
   }
-  .resize {
+  .resize,
+  .fullResize {
     background-color: $--color-success;
   }
 }

+ 1 - 1
src/i18n/index.ts

@@ -1,7 +1,7 @@
 //语言
 import { lang } from '@/settings/designSetting'
 import { createI18n } from 'vue-i18n' //引入vue-i18n组件
-import { getLocalStorage } from '@/utils/index'
+import { getLocalStorage } from '@/utils/storage'
 import { GO_LANG_SELECT } from '@/settings/storageConst'
 import zh from './zh/index'
 import en from './en/index'

+ 6 - 3
src/plugins/icon.ts

@@ -6,10 +6,11 @@ import {
   CopyOutline as CopyIcon,
   Trash as TrashIcon,
   Pencil as PencilIcon,
-  Hammer as HammerIcon,
+  HammerOutline as HammerIcon,
   ApertureSharp as ApertureSharpIcon,
   DownloadOutline as DownloadIcon,
-  Open as OpenIcon
+  Open as OpenIcon,
+  Send as SendIcon
 } from '@vicons/ionicons5'
 
 // ionicons5 在这里
@@ -35,7 +36,9 @@ const ionicons5 = {
   // 下载
   DownloadIcon,
   // 导出
-  OpenIcon
+  OpenIcon,
+  // 导出
+  SendIcon,
 }
 
 // https://www.xicons.org/#/ 还有很多

+ 2 - 2
src/settings/designSetting.ts

@@ -41,7 +41,7 @@ export const theme = {
   // 默认是否开启深色主题
   darkTheme: true,
   //系统主题色
-  appTheme: '#63e2b7',
+  appTheme: '#51d6a9',
   //系统内置主题色列表
   appThemeList
 }
@@ -53,7 +53,7 @@ export const asideWidth = '270'
 export const asideCollapsedWidth = '60'
 
 // 修改边框圆角
-export const borderRadius = '4px'
+export const borderRadius = '6px'
 
 // 轮播间隔
 export const carouselInterval = 4000

+ 1 - 1
src/store/modules/designStore/designStore.ts

@@ -2,7 +2,7 @@ import { defineStore } from 'pinia'
 import { store } from '@/store'
 import { theme } from '@/settings/designSetting'
 import { DesignStateType } from './designStore.d'
-import { setLocalStorage, getLocalStorage } from '@/utils/index'
+import { setLocalStorage, getLocalStorage } from '@/utils/storage'
 import { GO_Theme_SELECT } from '@/settings/storageConst'
 import { ThemeEnum } from '@/enums/styleEnum'
 

+ 1 - 1
src/store/modules/langStore/langStore.ts

@@ -3,7 +3,7 @@ import { lang } from '@/settings/designSetting'
 import { LangStateType } from './langStore.d'
 import { LangEnum } from '@/enums/styleEnum'
 import i18n from '@/i18n/index'
-import { setLocalStorage } from '@/utils/index'
+import { setLocalStorage } from '@/utils/storage'
 import { GO_LANG_SELECT } from '@/settings/storageConst'
 
 export const useLangStore = defineStore({

+ 3 - 1
src/styles/common/_light.scss

@@ -3,11 +3,13 @@
 $light: (
   // 文字颜色
     color: $--color-text,
+  // aside 背景
+    aside-background_color: $--color-light-fill-1,
   //背景
     background_color: $--color-light-fill-3,
   //渐变背景
     background-image:
-    linear-gradient(120deg, $--color-text-1 0%, $--color-text-1 100%),
+    linear-gradient(120deg, $--color-light-fill 0%, $--color-light-fill 100%),
   // 斑点背景
     background-point:
     (

+ 1 - 1
src/styles/common/var.scss

@@ -12,7 +12,7 @@ $--color-text-4: #f2f3f5;
 
 // 白色
 $--color-light-fill: #fff;
-$--color-light-fill-1: #f7f8fa;
+$--color-light-fill-1: #fafafc;
 $--color-light-fill-2: #f2f3f5;
 $--color-light-fill-3: #e5e6eb;
 $--color-light-fill-4: #c9cdd4;

+ 11 - 50
src/utils/index.ts

@@ -1,6 +1,6 @@
 import { h } from 'vue'
 import { NIcon } from 'naive-ui'
-
+import screenfull from 'screenfull'
 /**
  * * 生成一个用不重复的ID
  * @param { Number } randomLength
@@ -64,56 +64,17 @@ export const requireUrl = (path: string, name: string) => {
   return new URL(`${path}/${name}`, import.meta.url).href
 }
 
-/**
- * * 存储本地会话数据
- * @param k 键名
- * @param v 键值
- * @returns RemovableRef
- */
-export const setLocalStorage = <T>(k: string, v: T) => {
-  try {
-    window.localStorage.setItem(k, JSON.stringify(v))
-  } catch (error) {
-    return false
-  }
-}
-
-/**
- * * 获取本地会话数据
- * @returns any
- */
-export const getLocalStorage: (k: string) => any = (k: string) => {
-  const item = window.localStorage.getItem(k)
-  try {
-    return item ? JSON.parse(item) : item
-  } catch (err) {
-    return item
-  }
-}
+export const screenfullFn = (isFullscreen?: boolean, isEnabled?: boolean) => {
+  // 是否是全屏
+  if (isFullscreen) return screenfull.isFullscreen
 
-/**
- * * 存储临时会话数据
- * @param k 键名
- * @param v 键值
- * @returns RemovableRef
- */
-export const setSessionStorage = <T>(k: string, v: T) => {
-  try {
-    window.sessionStorage.setItem(k, JSON.stringify(v))
-  } catch (error) {
-    return false
-  }
-}
+  // 是否支持全屏
+  if (isEnabled) return screenfull.isEnabled
 
-/**
- * * 获取临时会话数据
- * @returns any
- */
-export const getSessionStorage: (k: string) => any = (k: string) => {
-  const item = window.sessionStorage.getItem(k)
-  try {
-    return item ? JSON.parse(item) : item
-  } catch (err) {
-    return item
+  if (screenfull.isEnabled) {
+    screenfull.toggle()
+    return
   }
+  // TODO lang
+  window['$message'].warning('您的浏览器不支持全屏功能!')
 }

+ 54 - 0
src/utils/storage.ts

@@ -0,0 +1,54 @@
+
+/**
+ * * 存储本地会话数据
+ * @param k 键名
+ * @param v 键值
+ * @returns RemovableRef
+ */
+ export const setLocalStorage = <T>(k: string, v: T) => {
+  try {
+    window.localStorage.setItem(k, JSON.stringify(v))
+  } catch (error) {
+    return false
+  }
+}
+
+/**
+ * * 获取本地会话数据
+ * @returns any
+ */
+export const getLocalStorage: (k: string) => any = (k: string) => {
+  const item = window.localStorage.getItem(k)
+  try {
+    return item ? JSON.parse(item) : item
+  } catch (err) {
+    return item
+  }
+}
+
+/**
+ * * 存储临时会话数据
+ * @param k 键名
+ * @param v 键值
+ * @returns RemovableRef
+ */
+export const setSessionStorage = <T>(k: string, v: T) => {
+  try {
+    window.sessionStorage.setItem(k, JSON.stringify(v))
+  } catch (error) {
+    return false
+  }
+}
+
+/**
+ * * 获取临时会话数据
+ * @returns any
+ */
+export const getSessionStorage: (k: string) => any = (k: string) => {
+  const item = window.sessionStorage.getItem(k)
+  try {
+    return item ? JSON.parse(item) : item
+  } catch (err) {
+    return item
+  }
+}

+ 53 - 21
src/views/project/items/components/Card/index.vue

@@ -4,37 +4,41 @@
       <div class="list-content">
         <!-- 顶部按钮 -->
         <n-space class="list-content-top">
-          <AppleControlBtn @close="deleteHanlde" />
+          <AppleControlBtn @close="deleteHanlde" @resize="resizeHandle" />
         </n-space>
         <!-- 中间 -->
         <div class="list-content-img">
           <n-image
             object-fit="contain"
             height="200"
+            preview-disabled
             :src="requireUrl('.', '20211219181327.png')"
-            :alt="CardData.title"
+            :alt="cardData.title"
           />
         </div>
       </div>
       <template #action>
-        <Skeleton v-if="loading" :loading="loading" text round size="small" />
-        <n-space v-else justify="space-between">
+        <n-space class="list-footer" justify="space-between">
           <n-text>
-            {{ CardData.title || '' }}
+            {{ cardData.title || '' }}
           </n-text>
 
           <!-- 工具 -->
           <n-space>
             <n-text>
-              <n-badge class="animation-twinkle" dot :color="CardData.release ? '#34c749' : '#fcbc40'" />
-              {{ CardData.release ? '已发布' : '未发布' }}
+              <n-badge
+                class="animation-twinkle"
+                dot
+                :color="cardData.release ? '#34c749' : '#fcbc40'"
+              />
+              {{ cardData.release ? '已发布' : '未发布' }}
             </n-text>
 
             <template v-for="item in fnBtnList" :key="item.key">
               <template v-if="item.key === 'select'">
                 <n-dropdown
                   trigger="hover"
-                  placement="bottom-start"
+                  placement="bottom"
                   :options="selectOptions"
                   :show-arrow="true"
                   @select="handleSelect"
@@ -47,11 +51,16 @@
                 </n-dropdown>
               </template>
 
-              <n-button v-else size="small">
-                <template #icon>
-                  <component :is="item.icon" />
+              <n-tooltip v-else placement="bottom" trigger="hover">
+                <template #trigger>
+                  <n-button size="small">
+                    <template #icon>
+                      <component :is="item.icon" />
+                    </template>
+                  </n-button>
                 </template>
-              </n-button>
+                <span> {{ item.label }}</span>
+              </n-tooltip>
             </template>
           </n-space>
           <!-- end -->
@@ -73,17 +82,26 @@ const {
   TrashIcon,
   PencilIcon,
   ApertureSharpIcon,
-  DownloadIcon
+  DownloadIcon,
+  HammerIcon,
+  SendIcon
 } = icon.ionicons5
 
-const loading = ref<boolean>(true)
 const dialog = useDialog()
 const message = useMessage()
-defineProps({
-  CardData: Object
+
+const emit = defineEmits(['resize'])
+
+const props = defineProps({
+  cardData: Object
 })
 
 const fnBtnList = [
+  {
+    label: '编辑',
+    key: 'edit',
+    icon: renderIcon(HammerIcon)
+  },
   {
     lable: '更多',
     key: 'select',
@@ -107,6 +125,15 @@ const selectOptions = [
     key: 'rename',
     icon: renderIcon(PencilIcon)
   },
+  {
+    type: 'divider',
+    key: 'd1'
+  },
+  {
+    label: props.cardData?.release ? '取消发布' : '发布',
+    key: 'send',
+    icon: renderIcon(SendIcon)
+  },
   {
     label: '下载',
     key: 'download',
@@ -114,7 +141,7 @@ const selectOptions = [
   },
   {
     type: 'divider',
-    key: 'd1'
+    key: 'd2'
   },
   {
     label: '删除',
@@ -131,6 +158,7 @@ const requireUrl = (path: string, name: string) => {
   return new URL(`${path}/${name}`, import.meta.url).href
 }
 
+// 删除处理
 const deleteHanlde = () => {
   goDialog(dialog.warning, {
     type: 'delete',
@@ -140,9 +168,10 @@ const deleteHanlde = () => {
   })
 }
 
-setTimeout(() => {
-  loading.value = false
-}, 1500)
+// 放大处理
+const resizeHandle = () => {
+  emit('resize', props.cardData)
+}
 </script>
 
 <style lang="scss" scoped>
@@ -157,7 +186,7 @@ $contentHeight: 200px;
     @extend .go-point-bg;
     &-top {
       position: absolute;
-      top: 5px;
+      top: 10px;
       left: 10px;
       height: 22px;
     }
@@ -172,5 +201,8 @@ $contentHeight: 200px;
       }
     }
   }
+  .list-footer {
+    line-height: 30px;
+  }
 }
 </style>

+ 26 - 10
src/views/project/items/components/List/index.vue

@@ -7,24 +7,21 @@
       responsive="screen"
     >
       <n-grid-item v-for="item in list" :key="item.id">
-        <Card :CardData="item" />
+        <Card :cardData="item" @resize="resizeHandle" />
       </n-grid-item>
     </n-grid>
   </div>
+  <ModalCard :show="modalShow" :cardData="modalData" @close="closeModal" />
 </template>
 
 <script setup lang="ts">
 import { reactive, ref } from 'vue'
 import { Card } from '../Card/index'
+import { ModalCard } from '../ModalCard/index'
 import {
   EllipsisHorizontalSharp as EllipsisHorizontalCircleSharpIcon,
   CopyOutline as CopyIcon
 } from '@vicons/ionicons5'
-const loading = ref<boolean>(true)
-
-setTimeout(() => {
-  loading.value = false
-}, 500)
 
 const list = reactive([
   {
@@ -34,21 +31,40 @@ const list = reactive([
   },
   {
     id: 2,
-    title: '物料1'
+    title: '物料2',
+    release: false
   },
   {
     id: 3,
-    title: '物料1'
+    title: '物料3',
+    release: false
   },
   {
     id: 4,
-    title: '物料1'
+    title: '物料4',
+    release: false
   },
   {
     id: 5,
-    title: '物料1'
+    title: '物料5',
+    release: false
   }
 ])
+
+const modalData = ref({})
+const modalShow = ref(false)
+
+// 关闭 modal
+const closeModal = () => {
+  modalShow.value = false
+}
+
+// 打开 modal
+const resizeHandle = (cardData: object) => {
+  modalShow.value = true
+  modalData.value = cardData
+}
+
 </script>
 
 <style lang="scss" scoped>

BIN
src/views/project/items/components/ModalCard/20211219181327.png


+ 3 - 0
src/views/project/items/components/ModalCard/index.ts

@@ -0,0 +1,3 @@
+import ModalCard from './index.vue'
+
+export { ModalCard }

+ 127 - 0
src/views/project/items/components/ModalCard/index.vue

@@ -0,0 +1,127 @@
+<template>
+  <n-modal class="go-modal-card" v-model:show="showModal">
+    <slot name="default">
+      <n-card hoverable size="small">
+        <div class="list-content">
+          <!-- 顶部按钮 -->
+          <n-space class="list-content-top">
+            <AppleControlBtn
+              :narrow="true"
+              :hidden="['close']"
+              @remove="closeHandle"
+            />
+          </n-space>
+          <!-- 中间 -->
+          <div class="list-content-img">
+            <img
+              :src="requireUrl('.', '20211219181327.png')"
+              :alt="cardData?.title"
+            />
+          </div>
+        </div>
+        <template #action>
+          <n-space class="list-footer" justify="space-between">
+            <n-text>
+              {{ cardData?.title || '' }}
+            </n-text>
+
+            <!-- 工具 -->
+            <n-space>
+              <n-text>
+                <n-badge
+                  class="animation-twinkle"
+                  dot
+                  :color="cardData?.release ? '#34c749' : '#fcbc40'"
+                />
+                {{ cardData?.release ? '已发布' : '未发布' }}
+              </n-text>
+
+              <template v-for="item in fnBtnList" :key="item.key">
+                <n-tooltip placement="bottom" trigger="hover">
+                  <template #trigger>
+                    <n-button size="small">
+                      <template #icon>
+                        <component :is="item.icon" />
+                      </template>
+                    </n-button>
+                  </template>
+                  <span> {{ item.label }}</span>
+                </n-tooltip>
+              </template>
+            </n-space>
+            <!-- end -->
+          </n-space>
+        </template>
+      </n-card>
+    </slot>
+  </n-modal>
+</template>
+
+<script setup lang="ts">
+import { renderIcon } from '@/utils/index'
+import { icon } from '@/plugins'
+import { AppleControlBtn } from '@/components/AppleControlBtn'
+const { HammerIcon } = icon.ionicons5
+
+const emit = defineEmits(['close'])
+
+const props = defineProps({
+  modalShow: Boolean,
+  cardData: Object
+})
+
+const handleSelect = (key: string) => {
+  console.log(key)
+}
+
+const requireUrl = (path: string, name: string) => {
+  return new URL(`${path}/${name}`, import.meta.url).href
+}
+
+const fnBtnList = [
+  {
+    label: '编辑',
+    key: 'edit',
+    icon: renderIcon(HammerIcon)
+  }
+]
+// 放大处理
+const resizeHandle = () => {}
+
+// 关闭对话框
+const closeHandle = () => {
+  emit('close')
+}
+</script>
+
+<style lang="scss" scoped>
+$padding: 30px;
+$contentHeight: calc(80vh);
+@include go('modal-card') {
+  position: relative;
+  width: 82vw;
+  .list-content {
+    margin-top: 20px;
+    border-radius: $--border-radius-base;
+    overflow: hidden;
+    @include background-point('background-point');
+    @extend .go-point-bg;
+    &-top {
+      position: absolute;
+      top: 10px;
+      left: 10px;
+      height: 22px;
+    }
+    &-img {
+      @extend .go-flex-center;
+      img {
+        height: $contentHeight;
+        @extend .go-border-radius;
+      }
+    }
+  }
+  .list-footer {
+    line-height: 30px;
+  }
+}
+</style>

+ 2 - 1
src/views/project/layout/components/Sider/index.vue

@@ -1,6 +1,6 @@
 <template>
   <n-layout-sider
-    class="go-project-layout-sider"
+    class="go-project-sider"
     bordered
     collapse-mode="width"
     show-trigger="bar"
@@ -68,6 +68,7 @@ $siderHeight: 100vh;
 
 @include go(project) {
   &-sider {
+    @include filter-bg-color('aside-background_color');
     &-top {
       display: flex;
       align-items: center;

+ 2 - 0
types/shims-vue.d.ts

@@ -3,3 +3,5 @@ declare module '*.vue' {
   const component: DefineComponent<{}, {}, any>
   export default component
 }
+
+declare module 'lodash'