Przeglądaj źródła

fix: layout修改+table组件修改

sunhongyao341504 2 lat temu
rodzic
commit
15dcfd6364

+ 34 - 0
mock/login/routers.ts

@@ -63,6 +63,40 @@ const list = [
       },
     ],
   },
+
+  {
+    path: '/cameras',
+    name: 'cameras',
+    component: 'LAYOUT',
+    redirect: '/cameras/overview',
+    meta: {
+      icon: 'PictureOutlined',
+      title: '相机配置',
+      noCache: false,
+      hidden: false,
+      isFrame: '1',
+      status: '0',
+      isRoot: false,
+      alwaysShow: false,
+    },
+    children: [
+      {
+        path: 'overview',
+        name: 'cameras-overview',
+        component: '/cameras/overview/CamerasOverview',
+        meta: {
+          title: '相机管理',
+          noCache: false,
+          hidden: false,
+          isFrame: '1',
+          status: '0',
+          isRoot: false,
+          alwaysShow: false,
+        },
+      },
+    ],
+  },
+
   {
     path: '/map-config',
     name: 'map_config',

BIN
src/assets/images/table/table-empty.png


+ 50 - 4
src/components/Table/src/Table.vue

@@ -82,14 +82,28 @@
       </div>
     </div>
     <div class="s-table" ref="sTableRef" v-if="isShowTable">
-      <el-table ref="tableElRef" v-bind="getBindValues" v-loading="getLoading">
+      <el-table
+        ref="tableElRef"
+        v-bind="getBindValues"
+        v-loading="getLoading"
+        @sort-change="sortChange"
+      >
         <template v-for="item in getTableColumns" :key="item.key">
           <el-table-column
-            v-if="item.type === 'index' || item.type === 'selection'"
+            v-if="item.type === 'index'"
+            label="序号"
+            :index="getIndexNum"
             :type="item.type"
-            :width="item.width"
+            :minWidth="item.minWidth"
+            :fixed="item.fixed"
           />
-          <el-table-column v-else :prop="item.prop" v-bind="item">
+          <el-table-column
+            v-else-if="item.type === 'selection'"
+            :type="item.type"
+            :minWidth="item.minWidth"
+            :fixed="item.fixed"
+          />
+          <el-table-column v-else :prop="item.prop" :sortable="item.sortable" v-bind="item">
             <template #default="scope" v-if="item.render">
               <Render :column="item" :row="scope.row" :render="item.render" :index="scope.$index" />
             </template>
@@ -146,6 +160,7 @@
   } from '@vicons/antd';
   import { useFullscreen } from '@vueuse/core';
   import { ElIcon } from 'element-plus';
+  import { PaginationProps } from './types/pagination';
 
   const props = defineProps({
     ...basicProps,
@@ -162,6 +177,9 @@
     'edit-row-end',
     'edit-change',
     'columns-change',
+    'order-change',
+    'page-num-change',
+    'page-size-change',
   ]);
 
   const striped = ref(false);
@@ -235,17 +253,36 @@
     reload(opt);
   }
 
+  //表格index计算
+  const getIndexNum = (index) => {
+    if (!isBoolean(unref(pagination))) {
+      const { currentPage = 1, pageSize = 10 } = unref(pagination) as PaginationProps;
+      return (currentPage - 1) * pageSize + (index + 1);
+    }
+    return index + 1;
+  };
+
   //页码切换
   async function updatePage(page) {
     !getProps.value.isKeepRowKeys && (await restCheckedRowKeys());
     setPagination({ currentPage: page });
     reload();
+    //自定义页码切换脚本
+    setLoading(true);
+    nextTick(() => {
+      emit('page-num-change', page);
+    });
   }
 
   //分页数量切换
   function updatePageSize(size) {
     setPagination({ currentPage: 1, pageSize: size });
     reload();
+    //自定义分页数量切换脚本
+    setLoading(true);
+    nextTick(() => {
+      emit('page-size-change', size);
+    });
   }
 
   //密度切换
@@ -383,6 +420,15 @@
 
   useWindowSizeFn(computeTableHeight, 280);
 
+  function sortChange(e) {
+    const { prop, order } = e;
+    const sortInfo = {
+      prop,
+      order: order === 'ascending' ? 'asc' : 'desc',
+    };
+    emit('order-change', sortInfo);
+  }
+
   onMounted(() => {
     nextTick(() => {
       computeTableHeight();

+ 6 - 1
src/components/Table/src/components/TableAction.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="tableAction">
     <div class="flex items-center justify-center">
-      <el-space>
+      <el-space :size="space">
         <template v-for="action in getActions" :key="action.label">
           <template v-if="!action.isConfirm">
             <el-button v-bind="action">
@@ -63,6 +63,11 @@
     name: 'TableAction',
     components: { DownOutlined, Render },
     props: {
+      space: {
+        type: Number,
+        default: 0,
+        required: false,
+      },
       actions: {
         type: Array as PropType<ActionItem[]>,
         default: null,

+ 6 - 1
src/components/Table/src/components/settings/ColumnSetting.vue

@@ -262,6 +262,7 @@
 
   //固定
   function fixedColumn(item, fixed) {
+    if (item.type === 'index') return;
     if (!unref(checkList).includes(item.prop as never)) return;
     let columns = getColumns();
     const isFixed = item.fixed === fixed ? undefined : fixed;
@@ -270,7 +271,11 @@
       columns[index].fixed = isFixed;
     }
     table.setCacheColumnsField(item.prop, { fixed: isFixed });
-    basicColumns.value[index].fixed = isFixed;
+
+    // basicColumns.value[index].fixed = isFixed;
+    const basicIndex = basicColumns.value.findIndex((res) => res.prop === item.prop);
+    basicColumns.value[basicIndex].fixed = isFixed;
+
     setColumns(columns);
     emit('columnsChange', table.getColumns());
   }

+ 16 - 1
src/components/Table/src/hooks/useColumns.ts

@@ -16,6 +16,7 @@ export function useColumns(propsRef: ComputedRef<BasicTableProps>) {
     const columns = cloneDeep(unref(columnsRef));
 
     handleActionColumn(propsRef, columns);
+    handleExpandColumn(propsRef, columns);
     if (!columns) return [];
     return columns;
   });
@@ -92,14 +93,28 @@ export function useColumns(propsRef: ComputedRef<BasicTableProps>) {
   function handleActionColumn(propsRef: ComputedRef<BasicTableProps>, columns: BasicColumn[]) {
     const { actionColumn } = unref(propsRef);
     if (!actionColumn) return;
-    const hasIndex = columns.findIndex((item) => item.prop === 'action');
+    const hasIndex = columns.findIndex((item) => item.prop === 'action' || item.key === 'action');
     if (hasIndex === -1) {
       columns.push({
+        label: '操作',
+        align: 'center',
         ...(actionColumn as any),
       });
     }
   }
 
+  function handleExpandColumn(propsRef: ComputedRef<BasicTableProps>, columns: BasicColumn[]) {
+    const { expandColumn } = unref(propsRef);
+    if (!expandColumn) return;
+    const hasIndex = columns.findIndex((item) => item.prop === 'expand' || item.key === 'expand');
+    if (hasIndex === -1) {
+      columns.unshift({
+        width: 50,
+        ...(expandColumn as any),
+      });
+    }
+  }
+
   //设置
   function setColumns(columnList: string[]) {
     const columns: any[] = cloneDeep(columnList);

+ 5 - 0
src/components/Table/src/types/table.ts

@@ -3,8 +3,11 @@ import { ComponentType } from './componentType';
 export interface BasicColumn {
   label?: string;
   prop?: string;
+  key?: string;
   width?: number;
+  minWidth?: number;
   align?: string;
+  sortable?: string | boolean;
   //编辑表格
   edit?: boolean;
   editRow?: boolean;
@@ -21,6 +24,7 @@ export interface BasicColumn {
   editCellRender?: Recordable;
   render?: Function;
   type?: string;
+  fixed?: string | boolean;
 }
 
 export interface TableActionType {
@@ -48,6 +52,7 @@ export interface BasicTableProps {
   pagination?: object;
   showPagination?: boolean;
   actionColumn?: object;
+  expandColumn?: object;
   canResize?: boolean;
   resizeHeightOffset?: number;
   loading?: boolean;

+ 1 - 1
src/layout/index.vue

@@ -316,7 +316,7 @@
         }
 
         &-main {
-          padding: 10px 0 0 10px;
+          padding: 12px 12px 0 12px;
           height: calc(100vh - 64px);
           position: relative;
           overflow-y: auto;

+ 121 - 0
src/views/cameras/overview/CamerasOverview.vue

@@ -0,0 +1,121 @@
+<template>
+  <div>
+    <el-card :bordered="false" class="mb-3 proCard">
+      <ConditionQuery />
+    </el-card>
+    <el-card :bordered="false" class="proCard">
+      <BasicTable
+        :columns="columns"
+        :data-source="cameraItems"
+        :row-key="(row) => row.id"
+        :action-column="actionColumn"
+        :pagination="false"
+        :tableSetting="{
+          size: false,
+          redo: false,
+          fullscreen: false,
+          striped: false,
+          setting: false,
+        }"
+        ref="tableRef"
+        @order-change="orderByItem"
+      >
+        <template #empty>
+          <div class="empty-content flex flex-col items-center">
+            <img :src="emptyImg" class="empty-img" />
+            <span class="empty-text">目前无内容,请先添加相机</span>
+          </div>
+        </template>
+      </BasicTable>
+    </el-card>
+  </div>
+</template>
+
+<script setup lang="ts">
+  import { h, reactive } from 'vue';
+  import { BasicTable, TableAction } from '@/components/Table';
+  import { BasicColumn } from '@/components/Table';
+  import { getColumns } from './overviewColumns';
+  import ConditionQuery from './components/ConditionQuery.vue';
+  import emptyImg from '@/assets/images/table/table-empty.png';
+
+  const cameraItems = [
+    {
+      cameraIp: '10.10.10.10',
+      brand: '海康威视',
+      cameraPort: '8080',
+      mac: '255.255.255.255',
+      name: 'SHGD-XDJS-0001',
+      workshopId: 'ARJ21部装车间',
+      workspaceId: '200工位',
+      networkState: 1,
+      status: 1,
+    },
+  ];
+
+  //操作列
+  const actionColumn: BasicColumn = reactive({
+    width: 150,
+    title: '操作',
+    prop: 'action',
+    key: 'action',
+    fixed: 'right',
+    render(record) {
+      return h(TableAction as any, {
+        style: 'button',
+        space: -10,
+        actions: [
+          {
+            label: '预览',
+            isConfirm: false,
+            text: true,
+            onClick: handlePreview.bind(null, record.row),
+          },
+          {
+            label: '删除',
+            isConfirm: false,
+            text: true,
+            onClick: handleDelete.bind(null, record.row),
+          },
+          {
+            label: '编辑',
+            isConfirm: false,
+            text: true,
+            onClick: handleEdit.bind(null, record.row),
+          },
+        ],
+      });
+    },
+  });
+
+  // el-switch的change事件
+  const switchChange = () => {};
+  const columns = getColumns(switchChange);
+
+  // 列排序操作
+  const orderByItem = () => {};
+
+  const handlePreview = () => {};
+
+  const handleDelete = () => {};
+
+  const handleEdit = () => {};
+</script>
+
+<style scoped>
+  .empty-content {
+    margin: auto;
+    padding: 125px 0;
+  }
+
+  .empty-img {
+    width: 396px;
+  }
+
+  .empty-text {
+    font-size: 22px;
+    color: #8e8e8e;
+    line-height: 30px;
+    text-align: center;
+  }
+</style>

+ 37 - 0
src/views/cameras/overview/components/ConditionQuery.vue

@@ -0,0 +1,37 @@
+<template>
+  <div class="flex">
+    <el-space alignment="center" :size="20">
+      <span style="font-size: 16px">牌号</span>
+      <el-input
+        :style="{ width: '150px' }"
+        v-model="queryInteriorNs"
+        clearable
+        placeholder="请输入查询牌号"
+      />
+    </el-space>
+    <div class="flex-1 flex justify-end">
+      <el-button type="primary" @click="conditionSearch">
+        <template #icon>
+          <el-icon>
+            <SearchOutlined />
+          </el-icon>
+        </template>
+        查询
+      </el-button>
+      <el-button class="mr-20" @click="resetSearch"> 重置 </el-button>
+      <el-button class="mr-5" type="primary">添加</el-button>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+  import { SearchOutlined } from '@vicons/antd';
+
+  // 条件查询事件
+  const conditionSearch = () => {};
+
+  // 重置查询条件
+  const resetSearch = () => {};
+</script>
+
+<style scoped></style>

+ 87 - 0
src/views/cameras/overview/overviewColumns.ts

@@ -0,0 +1,87 @@
+import { h } from 'vue';
+import { ElSwitch } from 'element-plus';
+import type { BasicColumn } from '@/components/Table';
+import connectedIcon from '@/assets/images/logo.png';
+import unConnectedIcon from '@/assets/images/login-pic.png';
+
+export const getColumns = (switchChange: () => unknown): BasicColumn[] => {
+  return [
+    {
+      label: '序号',
+      minWidth: 40,
+      type: 'index',
+      fixed: 'left',
+    },
+    {
+      label: 'IP地址',
+      prop: 'cameraIp',
+      minWidth: 80,
+    },
+    {
+      label: '品牌',
+      prop: 'brand',
+      minWidth: 60,
+    },
+    {
+      label: '端口地址',
+      prop: 'cameraPort',
+      minWidth: 60,
+    },
+    {
+      label: 'MAC地址',
+      prop: 'mac',
+      minWidth: 100,
+    },
+    {
+      label: '设备ID',
+      prop: 'name',
+      minWidth: 110,
+    },
+    {
+      label: '车间场景',
+      prop: 'workshopId',
+      minWidth: 100,
+    },
+    {
+      label: '工位场景',
+      prop: 'workspaceId',
+      minWidth: 60,
+    },
+    {
+      label: '联网状态',
+      prop: 'networkState',
+      render(record) {
+        return h(
+          'img',
+          {
+            src: record.row.networkState === 0 ? unConnectedIcon : connectedIcon,
+            style: 'width: 20px; height: 20px; object-fit: fill;',
+          },
+          {},
+        );
+      },
+      minWidth: 80,
+      sortable: 'custom',
+    },
+    {
+      label: '是否进入平台',
+      prop: 'status',
+      render(record) {
+        return h(
+          ElSwitch,
+          {
+            modelValue: record.row.status,
+            onChange: () => {
+              switchChange();
+            },
+            activeValue: 1,
+            inactiveValue: 0,
+          },
+          {},
+        );
+      },
+      minWidth: 100,
+      sortable: 'custom',
+    },
+  ];
+};

+ 1 - 3
src/views/map-config/mini-map/MiniMapConfig.vue

@@ -302,8 +302,6 @@
 
 <style scoped>
   .page {
-    /* margin: 10px 0; */
-    padding: 10px 0 0 10px;
   }
   .page-head {
     height: 54px;
@@ -335,7 +333,7 @@
 
   .paint-tool {
     position: relative;
-    height: calc(100vh - 140px);
+    height: calc(100vh - 138px);
     margin-top: 2px;
   }