浏览代码

feat: 拖拽布局迁移 & 数据库页面

qinlaiqiao 3 年之前
父节点
当前提交
4008c53f7a

+ 0 - 1
src/components/index.ts

@@ -13,7 +13,6 @@ export default function (app: App<Element>) {
     app.component(Iconfont.name, Iconfont);
     app.component(Iconfont.name, Iconfont);
     app.component(ResizableLayout.name, ResizableLayout);
     app.component(ResizableLayout.name, ResizableLayout);
     app.component(ResizableLayoutItem.name, ResizableLayoutItem);
     app.component(ResizableLayoutItem.name, ResizableLayoutItem);
-    app.component(ResizableLayoutItem.name, ResizableLayoutItem);
     app.component(ContextMenu.name, ContextMenu);
     app.component(ContextMenu.name, ContextMenu);
     app.component(ContextSubMenu.name, ContextSubMenu);
     app.component(ContextSubMenu.name, ContextSubMenu);
     // app.component(Handsontable.name, Handsontable);
     // app.component(Handsontable.name, Handsontable);

+ 4 - 4
src/components/resizable-layout/ResizableLayout.vue

@@ -148,7 +148,7 @@ export default defineComponent({
 
 
     // 约定大写字母开头表示为供外界调用的方法
     // 约定大写字母开头表示为供外界调用的方法
     // 供子组件调用,给子组件返回 emitter
     // 供子组件调用,给子组件返回 emitter
-    GiveEmitter({ instance, index, minSize }: Comp.ResizableLayout.IDataParam) {
+    GiveEmitter({ instance, index, minSize }: ResizableLayout.IDataParam) {
       instance.RegisterEmitter((this as any).emitter);
       instance.RegisterEmitter((this as any).emitter);
       this.layoutItemInstances[index] = instance;
       this.layoutItemInstances[index] = instance;
       this.layoutItemsMinSize[index] = minSize;
       this.layoutItemsMinSize[index] = minSize;
@@ -201,7 +201,7 @@ export default defineComponent({
     },
     },
 
 
     // 拖拽事件监听处理器
     // 拖拽事件监听处理器
-    moveHandler(sizeProperty: string, moveParam: Comp.ResizableLayout.IMoveParam) {
+    moveHandler(sizeProperty: string, moveParam: ResizableLayout.IMoveParam) {
       const { distance, index, moveId } = moveParam;
       const { distance, index, moveId } = moveParam;
       if ((this as any).currentMoveId !== moveId) {
       if ((this as any).currentMoveId !== moveId) {
         // 一个新的move事件,即鼠标松开了之后重新按下之后的move事件
         // 一个新的move事件,即鼠标松开了之后重新按下之后的move事件
@@ -216,12 +216,12 @@ export default defineComponent({
     },
     },
 
 
     // 水平布局拖拽监听
     // 水平布局拖拽监听
-    horizontalHandler(moveParam: Comp.ResizableLayout.IMoveParam) {
+    horizontalHandler(moveParam: ResizableLayout.IMoveParam) {
       this.moveHandler('offsetWidth', moveParam);
       this.moveHandler('offsetWidth', moveParam);
     },
     },
 
 
     // 垂直布局拖拽监听
     // 垂直布局拖拽监听
-    verticalHandler(moveParam: Comp.ResizableLayout.IMoveParam) {
+    verticalHandler(moveParam: ResizableLayout.IMoveParam) {
       this.moveHandler('offsetHeight', moveParam);
       this.moveHandler('offsetHeight', moveParam);
     },
     },
   },
   },

+ 28 - 28
src/components/resizable-layout/ResizableLayoutItem.vue

@@ -4,27 +4,27 @@
       <slot></slot>
       <slot></slot>
     </div>
     </div>
     <div
     <div
-        class="drag-bar"
-        :class="[isColumn ? 'column' : 'horizontal', dragBarActive ? 'active' : '']"
-        :style="dragBarStyleObj"
-        @mousedown.prevent="handleDragBarMouseDown"
-        ref="dragBarRef"
+      class="drag-bar"
+      :class="[isColumn ? 'column' : 'horizontal', dragBarActive ? 'active' : '']"
+      :style="dragBarStyleObj"
+      @mousedown.prevent="handleDragBarMouseDown"
+      ref="dragBarRef"
     >
     >
       <div class="drag-bar-inner"></div>
       <div class="drag-bar-inner"></div>
       <div class="drag-handle" :style="dragHandleStyleObj">
       <div class="drag-handle" :style="dragHandleStyleObj">
-        <i class="dot"/>
-        <i class="dot"/>
-        <i class="dot"/>
+        <i class="dot" />
+        <i class="dot" />
+        <i class="dot" />
       </div>
       </div>
     </div>
     </div>
   </section>
   </section>
 </template>
 </template>
 
 
 <script lang="ts">
 <script lang="ts">
-import {defineComponent} from 'vue';
-import {Emitter} from 'mitt';
-import {debounce} from 'lodash';
-import {EmitterType} from '@/constants/emitter';
+import { defineComponent } from 'vue';
+import { Emitter } from 'mitt';
+import { debounce } from 'lodash';
+import { EmitterType } from '@/constants/emitter';
 import ProvideInject from '@/constants/provideInject';
 import ProvideInject from '@/constants/provideInject';
 
 
 export default defineComponent({
 export default defineComponent({
@@ -80,7 +80,7 @@ export default defineComponent({
       const height = self.isColumn ? '5px' : '100%';
       const height = self.isColumn ? '5px' : '100%';
       const cursor = self.isColumn ? 'ns-resize' : 'ew-resize';
       const cursor = self.isColumn ? 'ns-resize' : 'ew-resize';
       const flexDirection = self.isColumn ? 'row' : 'column';
       const flexDirection = self.isColumn ? 'row' : 'column';
-      return {width, height, cursor, flexDirection};
+      return { width, height, cursor, flexDirection };
     },
     },
 
 
     // 拖拽手柄的样式
     // 拖拽手柄的样式
@@ -89,21 +89,21 @@ export default defineComponent({
       const width = self.isColumn ? '36px' : '9px';
       const width = self.isColumn ? '36px' : '9px';
       const height = self.isColumn ? '9px' : '36px';
       const height = self.isColumn ? '9px' : '36px';
       const cursor = self.isColumn ? 'ns-resize' : 'ew-resize';
       const cursor = self.isColumn ? 'ns-resize' : 'ew-resize';
-      return {width, height, cursor};
+      return { width, height, cursor };
     },
     },
   },
   },
   created() {
   created() {
     const self = this as any;
     const self = this as any;
     self.emitter = null;
     self.emitter = null;
     self.debouncedEmit = debounce(
     self.debouncedEmit = debounce(
-        () => {
-          const size = this.isColumn
-              ? (this.$refs.layoutItemRef as HTMLElement).offsetHeight
-              : (this.$refs.layoutItemRef as HTMLElement).offsetWidth;
-          this.$emit('resize', size);
-        },
-        self.debounce,
-        {maxWait: self.maxWait}
+      () => {
+        const size = this.isColumn
+          ? (this.$refs.layoutItemRef as HTMLElement).offsetHeight
+          : (this.$refs.layoutItemRef as HTMLElement).offsetWidth;
+        this.$emit('resize', size);
+      },
+      self.debounce,
+      { maxWait: self.maxWait }
     );
     );
   },
   },
   mounted() {
   mounted() {
@@ -147,7 +147,7 @@ export default defineComponent({
             instance: this,
             instance: this,
             index: this.getLayoutItemIndex(),
             index: this.getLayoutItemIndex(),
             minSize: (this as any)[this.minSize],
             minSize: (this as any)[this.minSize],
-          } as Comp.ResizableLayout.IDataParam);
+          } as ResizableLayout.IDataParam);
         }
         }
       }, 500);
       }, 500);
     },
     },
@@ -168,11 +168,11 @@ export default defineComponent({
     // 向外触发 drag-bar-move
     // 向外触发 drag-bar-move
     emitMoveEvent(distance: number, moveId: symbol) {
     emitMoveEvent(distance: number, moveId: symbol) {
       (this as any).emitter &&
       (this as any).emitter &&
-      (this as any).emitter.emit(EmitterType.DRAG_BAR_MOVE, {
-        index: this.getLayoutItemIndex(),
-        distance,
-        moveId,
-      } as Comp.ResizableLayout.IMoveParam);
+        (this as any).emitter.emit(EmitterType.DRAG_BAR_MOVE, {
+          index: this.getLayoutItemIndex(),
+          distance,
+          moveId,
+        } as ResizableLayout.IMoveParam);
     },
     },
     // 拖拽条移动
     // 拖拽条移动
     handleDragBarMouseDown(downEvent: MouseEvent) {
     handleDragBarMouseDown(downEvent: MouseEvent) {

+ 3 - 3
src/router/index.ts

@@ -17,9 +17,9 @@ const routes: Array<RouteRecordRaw> = [
                 component: () => import('@/views/project-list/ProjectList.vue'),
                 component: () => import('@/views/project-list/ProjectList.vue'),
             },
             },
             {
             {
-                path: 'ration',
-                name: 'Ration',
-                component: () => import('@/views/ration/Ration.vue'),
+                path: 'data-library',
+                name: 'DataLibrary',
+                component: () => import('@/views/data-library/DataLibrary.vue'),
             },
             },
             {
             {
                 path: 'project',
                 path: 'project',

+ 1 - 1
src/styles/_variables.scss

@@ -22,7 +22,7 @@ $danger-deep: #d51d1d;
 $info: #232a2d;
 $info: #232a2d;
 $backdrop: #fbfaf9;
 $backdrop: #fbfaf9;
 $text-primary: #535a5d;
 $text-primary: #535a5d;
-$border-gray: #ddd;
+$border-grey: #ddd;
 
 
 /* 导出变量(css in js) 变量名为cssVars */
 /* 导出变量(css in js) 变量名为cssVars */
 :export {
 :export {

+ 18 - 0
src/types/components.d.ts

@@ -16,4 +16,22 @@ declare namespace ContextMenu {
 
 
     // 菜单项分组
     // 菜单项分组
     type MenuGroup = IMenuItem[];
     type MenuGroup = IMenuItem[];
+}
+
+declare namespace ResizableLayout {
+    interface IDataParam {
+        index: number;
+        instance: any;
+        minSize: number;
+    }
+
+    interface IMoveParam {
+        index: number; // 当前layoutItem是父组件的第几个子组件
+        distance: number; // 鼠标移动的距离,负数代表左移,正数代表右移
+        moveId: symbol; // move事件的唯一标志
+    }
+
+    interface IResizableLayoutComponent {
+        Refresh: () => void;
+    }
 }
 }

+ 43 - 0
src/views/data-library/DataLibrary.vue

@@ -0,0 +1,43 @@
+<script setup lang="ts">
+import { onMounted, reactive, ref } from "vue";
+</script>
+
+<template>
+  <article class="data-library">
+    <header class="header">
+      <h1 class="title">系统数据库</h1>
+      <p class="desc">包括系统所有的清单、定额、人材机等。</p>
+    </header>
+
+    <main class="main-wrap">
+      <el-row :gutter="20">
+        <el-col :span="8" :md="6" :lg="4">
+          <el-card shadow="never">Never</el-card>
+        </el-col>
+        <el-col :span="8" :md="6" :lg="4">
+          <el-card shadow="never">Never</el-card>
+        </el-col>
+        <el-col :span="8" :md="6" :lg="4">
+          <el-card shadow="never">Never</el-card>
+        </el-col>
+        <el-col :span="8" :md="6" :lg="4">
+          <el-card shadow="never">Never</el-card>
+        </el-col>
+        <el-col :span="8" :md="6" :lg="4">
+          <el-card shadow="never">Never</el-card>
+        </el-col>
+        <el-col :span="8" :md="6" :lg="4">
+          <el-card shadow="never">Never</el-card>
+        </el-col>
+        <el-col :span="8" :md="6" :lg="4">
+          <el-card shadow="never">Never</el-card>
+        </el-col>
+        <el-col :span="8" :md="6" :lg="4">
+          <el-card shadow="never">Never</el-card>
+        </el-col>
+      </el-row>
+    </main>
+  </article>
+</template>
+
+<style lang="scss" src="./style.scss" scoped></style>

+ 38 - 0
src/views/data-library/style.scss

@@ -0,0 +1,38 @@
+.data-library {
+    .header {
+        padding: 16px 32px;
+        border-bottom: 1px solid #e8eaec;
+        background: #fff;
+
+        .title {
+            font-size: 20px;
+            font-weight: 500;
+            color: #17233d;
+            margin-bottom: 16px;
+        }
+    }
+    .main-wrap {
+        padding: 16px 24px 60px;
+
+        .el-row {
+            margin-bottom: 20px;
+            &:last-child {
+                margin-bottom: 0;
+            }
+        }
+
+        .el-col {
+            border-radius: 4px;
+            margin-bottom: 16px;
+
+            .el-card {
+                border: none;
+                transition: all 0.2s ease-in-out;
+                &:hover {
+                    box-shadow: 0 1px 6px rgb(0 0 0 / 20%);
+                    border-color: #eee;
+                }
+            }
+        }
+    }
+}

+ 1 - 1
src/views/main-frame/MainFrame.vue

@@ -49,7 +49,7 @@ const route = useRoute()
             <iconfont class="icon dsk-city-one" />
             <iconfont class="icon dsk-city-one" />
           </li>
           </li>
         </router-link>
         </router-link>
-        <router-link custom to="/ration" v-slot="{ navigate, isExactActive }">
+        <router-link custom to="/data-library" v-slot="{ navigate, isExactActive }">
           <li class="item" @click="navigate" :class="{ 'active': isExactActive }">
           <li class="item" @click="navigate" :class="{ 'active': isExactActive }">
             <iconfont class="icon dsk-data" />
             <iconfont class="icon dsk-data" />
           </li>
           </li>

+ 1 - 1
src/views/project-list/style.scss

@@ -43,7 +43,7 @@
     ::v-deep .el-table {
     ::v-deep .el-table {
       width: 100%;
       width: 100%;
       background-color: #fff;
       background-color: #fff;
-      border: 1px solid $border-gray;
+      border: 1px solid $border-grey;
       border-left: none;
       border-left: none;
       border-right: none;
       border-right: none;
 
 

+ 2 - 1
src/views/project/summary/Summary.vue

@@ -17,6 +17,7 @@ const {
   mainRightSize,
   mainRightSize,
   mainLeftTopSize,
   mainLeftTopSize,
   mainLeftBottomSize,
   mainLeftBottomSize,
+
   handleProjectExplorerSize,
   handleProjectExplorerSize,
   handleMainContentSize,
   handleMainContentSize,
   handleMainLeftSize,
   handleMainLeftSize,
@@ -95,7 +96,7 @@ onMounted(async () => {
       </resizable-layout-item>
       </resizable-layout-item>
       <resizable-layout-item
       <resizable-layout-item
         :weight="mainContentSize"
         :weight="mainContentSize"
-        :min-width="400"
+        :min-width="800"
         @resize="handleMainContentSize"
         @resize="handleMainContentSize"
       >
       >
         <!-- 工具栏 -->
         <!-- 工具栏 -->

+ 0 - 1
src/views/project/summary/components/subject-tree/style.scss

@@ -20,7 +20,6 @@
 
 
       &.active {
       &.active {
         color: #1e93ff;
         color: #1e93ff;
-        font-weight: 600;
       }
       }
 
 
       &:first-child {
       &:first-child {

+ 13 - 11
src/views/project/summary/components/tool-bar/ToolBar.vue

@@ -1,5 +1,5 @@
 <script setup lang="ts">
 <script setup lang="ts">
-import {onMounted, reactive, ref} from "vue";
+import { onMounted, reactive, ref } from "vue";
 </script>
 </script>
 
 
 <template>
 <template>
@@ -8,47 +8,49 @@ import {onMounted, reactive, ref} from "vue";
       <el-dropdown trigger="click">
       <el-dropdown trigger="click">
         <el-tooltip content="导入" placement="top" :offset="10">
         <el-tooltip content="导入" placement="top" :offset="10">
           <el-button size="small" class="submenu">
           <el-button size="small" class="submenu">
-            <iconfont class="dsk-upload"/>
+            <iconfont class="dsk-upload" />
           </el-button>
           </el-button>
         </el-tooltip>
         </el-tooltip>
         <template #dropdown>
         <template #dropdown>
           <el-dropdown-menu>
           <el-dropdown-menu>
-            <el-dropdown-item command="item1">这是菜单1</el-dropdown-item>
+            <el-dropdown-item command="item1">这是一个非常非常非常长的菜单1</el-dropdown-item>
             <el-dropdown-item command="item2">这是菜单2</el-dropdown-item>
             <el-dropdown-item command="item2">这是菜单2</el-dropdown-item>
           </el-dropdown-menu>
           </el-dropdown-menu>
         </template>
         </template>
       </el-dropdown>
       </el-dropdown>
       <el-tooltip content="删除" placement="bottom">
       <el-tooltip content="删除" placement="bottom">
         <el-button size="small">
         <el-button size="small">
-          <iconfont class="dsk-close"/>
+          <iconfont class="dsk-close" />
         </el-button>
         </el-button>
       </el-tooltip>
       </el-tooltip>
       <el-tooltip content="升级" placement="bottom">
       <el-tooltip content="升级" placement="bottom">
         <el-button size="small">
         <el-button size="small">
-          <iconfont class="dsk-arrow-left"/>
+          <iconfont class="dsk-arrow-left" />
         </el-button>
         </el-button>
       </el-tooltip>
       </el-tooltip>
       <el-tooltip content="降级" placement="bottom">
       <el-tooltip content="降级" placement="bottom">
         <el-button size="small">
         <el-button size="small">
-          <iconfont class="dsk-arrow-right"/>
+          <iconfont class="dsk-arrow-right" />
         </el-button>
         </el-button>
       </el-tooltip>
       </el-tooltip>
       <el-tooltip content="上移" placement="bottom">
       <el-tooltip content="上移" placement="bottom">
         <el-button size="small">
         <el-button size="small">
-          <iconfont class="dsk-arrow-up"/>
+          <iconfont class="dsk-arrow-up" />
         </el-button>
         </el-button>
       </el-tooltip>
       </el-tooltip>
       <el-tooltip content="下移" placement="bottom">
       <el-tooltip content="下移" placement="bottom">
         <el-button size="small">
         <el-button size="small">
-          <iconfont class="dsk-arrow-down"/>
+          <iconfont class="dsk-arrow-down" />
         </el-button>
         </el-button>
       </el-tooltip>
       </el-tooltip>
     </div>
     </div>
     <div class="menus">
     <div class="menus">
-      <span class="menu-item">标准清单</span>
-      <span class="menu-item">定额库</span>
+      <span class="menu-item active">
+        <i class="text">标准清单</i>
+      </span>
+      <span class="menu-item"><i class="text">定额库</i></span>
       <span class="menu-item toggle-icon">
       <span class="menu-item toggle-icon">
-        <iconfont class="icon dsk-menu-unfold"/>
+        <iconfont class="icon dsk-menu-unfold" />
       </span>
       </span>
     </div>
     </div>
   </section>
   </section>

+ 26 - 4
src/views/project/summary/components/tool-bar/style.scss

@@ -8,11 +8,11 @@
 
 
   .tools {
   .tools {
     .el-button {
     .el-button {
-      height: 34px;
+      height: 24px;
       line-height: 16px;
       line-height: 16px;
       min-height: auto;
       min-height: auto;
       border: none;
       border: none;
-      padding: 4px 10px;
+      padding: 4px;
       border-radius: 0;
       border-radius: 0;
       margin-right: 6px;
       margin-right: 6px;
 
 
@@ -39,11 +39,33 @@
     line-height: 34px;
     line-height: 34px;
 
 
     .menu-item {
     .menu-item {
-      @apply inline-block align-top cursor-pointer;
+      @apply relative inline-block align-bottom cursor-pointer;
       margin-left: 10px;
       margin-left: 10px;
       padding: 0 8px;
       padding: 0 8px;
+
+      &.active {
+        &::before {
+          display: block;
+          content: " ";
+          position: absolute;
+          left: 0;
+          top: -1px;
+          width: 100%;
+          height: 35px;
+          border: 1px solid #ddd;
+          border-top-color: #409eff;
+          border-bottom: none;
+          background-color: #f5f7f9;
+        }
+        color: #409eff;
+      }
+      .text {
+        @apply relative;
+        z-index: 1;
+      }
+
       .icon {
       .icon {
-        font-size: 18px;
+        font-size: 17px;
       }
       }
     }
     }
   }
   }

+ 1 - 0
src/views/project/summary/scripts/useSummaryLayout.ts

@@ -1,5 +1,6 @@
 import { ref } from "vue";
 import { ref } from "vue";
 
 
+// 布局相关代码
 export default function useSummaryLayout() {
 export default function useSummaryLayout() {
     const projectExplorerSize = ref(60)
     const projectExplorerSize = ref(60)
     const mainContentSize = ref(300)
     const mainContentSize = ref(300)

+ 0 - 11
src/views/ration/Ration.vue

@@ -1,11 +0,0 @@
-<script setup lang="ts">
-import { onMounted, reactive, ref } from "vue";
-</script>
-
-<template>
-  <article class="ration">
-    <h1 class="title">数据库,暂未实现。</h1>
-  </article>
-</template>
-
-<style lang="scss" src="./style.scss" scoped></style>

+ 0 - 6
src/views/ration/style.scss

@@ -1,6 +0,0 @@
-.ration {
-    .title {
-        font-size: 20px;
-        margin: 50px;
-    }
-}