Procházet zdrojové kódy

完成vxe-table的升级,以及优化代码

xiaochan před 1 rokem
rodič
revize
575d0c72a3

+ 38 - 9
package-lock.json

@@ -13,6 +13,7 @@
         "@kjgl77/datav-vue3": "1.7.2",
         "@vitejs/plugin-legacy": "5.4.0",
         "@vueuse/core": "10.9.0",
+        "@vxe-ui/plugin-render-chart": "^4.0.1",
         "axios": "1.6.0",
         "clipboard": "2.0.11",
         "crypto-js": "4.2.0",
@@ -40,7 +41,7 @@
         "vue-router": "4.0.16",
         "vue3-json-viewer": "2.2.2",
         "vue3-print-nb": "0.1.4",
-        "vxe-table": "4.6.12",
+        "vxe-table": "^4.7.50",
         "vxe-table-plugin-export-xlsx": "4.0.1",
         "xe-utils": "3.5.26",
         "xlsx": "0.17.0"
@@ -3724,6 +3725,30 @@
         }
       }
     },
+    "node_modules/@vxe-ui/core": {
+      "version": "1.0.12",
+      "resolved": "https://registry.npmmirror.com/@vxe-ui/core/-/core-1.0.12.tgz",
+      "integrity": "sha512-s79mQw6uYSbTVGBWbxrisHwJV1b770vZMT9XpY3khcFQhXNo25+PS3FLrNCSsBBJR0ZkBLOXDER/ft9DIqgFTw==",
+      "dependencies": {
+        "dom-zindex": "^1.0.4",
+        "xe-utils": "^3.5.28"
+      }
+    },
+    "node_modules/@vxe-ui/core/node_modules/dom-zindex": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmmirror.com/dom-zindex/-/dom-zindex-1.0.4.tgz",
+      "integrity": "sha512-PNk7u71TJ1C9Lwjjp5nNuQcVWuECFMmr9kZAwi2UbgWUM7jXdTCe4O4x5bhLUa07jpcZUVA5Du3ho7/FXzS9Ng=="
+    },
+    "node_modules/@vxe-ui/core/node_modules/xe-utils": {
+      "version": "3.5.28",
+      "resolved": "https://registry.npmmirror.com/xe-utils/-/xe-utils-3.5.28.tgz",
+      "integrity": "sha512-oeLLJ0b54QdOSSgYQ9TiKW/xAGrc9r0weCA/5UfyGdm3n3js4cNOuuf9Tml7UwgBQpl4uWMbMwUZKLh2yqPF3A=="
+    },
+    "node_modules/@vxe-ui/plugin-render-chart": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmmirror.com/@vxe-ui/plugin-render-chart/-/plugin-render-chart-4.0.1.tgz",
+      "integrity": "sha512-xr1w99Ap1NnxTjdBR3osSU8E8gIkpPpwOxfyOddA48z5sJZCt91iUDtJKeibolPjpBVpfMKHgaFgfyjz4ICMTg=="
+    },
     "node_modules/@webassemblyjs/ast": {
       "version": "1.11.6",
       "resolved": "https://registry.npmmirror.com/@webassemblyjs/ast/-/ast-1.11.6.tgz",
@@ -12177,16 +12202,20 @@
         "vue": "^3.0.5"
       }
     },
+    "node_modules/vxe-pc-ui": {
+      "version": "4.0.67",
+      "resolved": "https://registry.npmmirror.com/vxe-pc-ui/-/vxe-pc-ui-4.0.67.tgz",
+      "integrity": "sha512-GAOE7xdvbIKO3eEHEIUhheF2Kkv7atuJfvlSy5jOgbD9jd1wloudfUxERY/gR1owv0n9P0wYXo1j0NLqqTAatA==",
+      "dependencies": {
+        "@vxe-ui/core": "^1.0.12"
+      }
+    },
     "node_modules/vxe-table": {
-      "version": "4.6.12",
-      "resolved": "https://registry.npmmirror.com/vxe-table/-/vxe-table-4.6.12.tgz",
-      "integrity": "sha512-CJr+LHY5La00ur3bV4i+pUBvfqVlo2WdE9ELnEpf7/8wBdOrwe1niPoGovsAagfCdfA0Esw7F5pCN+1RjV40Ww==",
+      "version": "4.7.50",
+      "resolved": "https://registry.npmmirror.com/vxe-table/-/vxe-table-4.7.50.tgz",
+      "integrity": "sha512-7JUF3yLrHidBasl1ckX2g5GB55GQF+2CoXvUAunWHQ/abmEbruDZbfmUk/jn+enPYfdhh41zrpLEurOv4MFWKQ==",
       "dependencies": {
-        "dom-zindex": "^1.0.2",
-        "xe-utils": "^3.5.26"
-      },
-      "peerDependencies": {
-        "vue": "^3.2.28"
+        "vxe-pc-ui": "^4.0.67"
       }
     },
     "node_modules/vxe-table-plugin-export-xlsx": {

+ 2 - 1
package.json

@@ -13,6 +13,7 @@
     "@kjgl77/datav-vue3": "1.7.2",
     "@vitejs/plugin-legacy": "5.4.0",
     "@vueuse/core": "10.9.0",
+    "@vxe-ui/plugin-render-chart": "^4.0.1",
     "axios": "1.6.0",
     "clipboard": "2.0.11",
     "crypto-js": "4.2.0",
@@ -40,7 +41,7 @@
     "vue-router": "4.0.16",
     "vue3-json-viewer": "2.2.2",
     "vue3-print-nb": "0.1.4",
-    "vxe-table": "4.6.12",
+    "vxe-table": "^4.7.50",
     "vxe-table-plugin-export-xlsx": "4.0.1",
     "xe-utils": "3.5.26",
     "xlsx": "0.17.0"

+ 13 - 8
src/main.js

@@ -23,7 +23,10 @@ import VXETablePluginExportXLSX from 'vxe-table-plugin-export-xlsx'
 import ExcelJS from 'exceljs'
 import VWaves from "@/directives/v-waves";
 import piniaInstall from "@/pinia/pinia-install";
-
+import VxeUIPluginRenderChart from '@vxe-ui/plugin-render-chart'
+import '@vxe-ui/plugin-render-chart/dist/style.css'
+import VxeUI from 'vxe-pc-ui'
+import 'vxe-pc-ui/lib/style.css'
 
 DomZIndex.getNext = () => {
     return useZIndex().nextZIndex()
@@ -40,13 +43,13 @@ for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
     app.component(key, component)
 }
 
-VXETable.config({
-    version: 0,
-    table: {
-        autoResize: true,
-        height: 700
-    },
-})
+// VXETable.config({
+//     version: 0,
+//     table: {
+//         autoResize: true,
+//         height: 700
+//     },
+// })
 
 VXETable.use(VXETablePluginExportXLSX, {
     ExcelJS
@@ -61,7 +64,9 @@ app.directive('ClickOutside', ClickOutside)
 app.directive('Waves', VWaves)
 app.directive('TrapFocus', TrapFocus)
 app.use(print)
+app.use(VxeUI)
 app.use(VXETable)
+VxeUI.use(VxeUIPluginRenderChart)
 app.use(JsonViewer);
 app.use(router)
 app.mount('#app')

+ 9 - 2
src/utils/xe-utils-enhance/vxe-formatter.ts

@@ -42,15 +42,22 @@ const mixin = {
     },
     treeSearch,
     eachAndReturnList<T = any>(list: T[] | Ref<T[]> | number, iteration: (item: T, index: number) => any) {
-        const temp: any[] = []
+        const temp: any[] = [];
+
+        if (!XEUtils.isArray(list)) {
+            return temp
+        }
         if (XEUtils.isNumber(list)) {
             for (let i = 0; i < list; i++) {
                 temp.push(iteration(i as T, i))
             }
         } else {
+            if (list.length === 0) {
+                return temp;
+            }
             XEUtils.arrayEach(unref(list), (item, index) => {
                 temp.push(iteration(item, index))
-            })
+            });
         }
         return temp;
     },

+ 109 - 57
src/views/data-base/page-editor-help-v2/components/PageHelpTable.vue

@@ -1,74 +1,126 @@
 <template>
-  <vxe-table
-      :data="data"
-      :ref="setMainTableRef"
-      border
-      :export-config="{}"
-      height="auto"
-      auto-resize
-      sync-resize
-      :column-config="{resizable: true}"
-      style="{width: 100%}"
-      :row-config="{height: 48 , isCurrent: true,isHover:true, useKey: true} "
-      :scroll-x="{enabled: false}"
-      :scroll-y="{gt: 0 ,enabled: true}"
-      show-overflow
-  >
-    <VxeColumn
-        v-for="(item,index) in columns"
-        v-bind="columnBind(item)"
-    >
-      <template
-          #header
-          v-if="props.store.props.isEditor">
-        <el-input
-            v-model="columns[index].title"
-            @focus="handleFocus(columns?.[index].field)"
-        />
-      </template>
-      <template
-          #default="{row , $rowIndex}"
-          v-if="item.func && item.func.default"
-      >
-        <Component
-            :is="handleTableColumnDefault(row, $rowIndex, item)"
-        />
-      </template>
-    </VxeColumn>
-  </vxe-table>
+  <vxe-grid v-bind="tableGridComputed" :ref="setMainTableRef">
+
+  </vxe-grid>
+  <!--  <vxe-table-->
+  <!--      :data="data"-->
+  <!--      :ref="setMainTableRef"-->
+  <!--      border-->
+  <!--      :export-config="{}"-->
+  <!--      height="auto"-->
+  <!--      auto-resize-->
+  <!--      sync-resize-->
+  <!--      :column-config="{resizable: true}"-->
+  <!--      style="{width: 100%}"-->
+  <!--      :row-config="{height: 48 , isCurrent: true,isHover:true, useKey: true} "-->
+  <!--      :scroll-x="{enabled: false}"-->
+  <!--      :scroll-y="{gt: 0 ,enabled: true}"-->
+  <!--      show-overflow-->
+  <!--      v-bind="tableBind"-->
+  <!--  >-->
+  <!--    <VxeColumn-->
+  <!--        v-for="(item,index) in props.columns"-->
+  <!--        v-bind="columnBind(item)"-->
+  <!--    >-->
+  <!--      <template-->
+  <!--          #header-->
+  <!--          v-if="props.store.props.isEditor">-->
+  <!--        <el-input-->
+  <!--            v-model="columns[index].title"-->
+  <!--            @focus="handleFocus(columns?.[index].field)"-->
+  <!--        />-->
+  <!--      </template>-->
+  <!--      <template-->
+  <!--          #default="{row , $rowIndex}"-->
+  <!--          v-if="item!.func && item!.func.default"-->
+  <!--      >-->
+  <!--        <Component-->
+  <!--            :is="handleTableColumnDefault?.(row, $rowIndex, item)"-->
+  <!--        />-->
+  <!--      </template>-->
+  <!--    </VxeColumn>-->
+  <!--  </vxe-table>-->
 </template>
 
-<script setup lang="ts">
-import {PropType} from "vue";
-import {PageStore} from "@/views/data-base/page-editor-help-v2/page-help-v2";
+<script setup lang="tsx">
+import {ComputedRef} from "vue";
+import {PageHelpTableName, PageStore} from "@/views/data-base/page-editor-help-v2/page-help-v2";
 import XEUtils from "xe-utils";
+import {VxeGridProps} from 'vxe-table'
+import {VxeGridPropTypes,} from "vxe-pc-ui/types/components/grid";
+import {ElInput} from 'element-plus'
 
-const props = defineProps({
-  data: Array,
-  columns: Array,
-  handleTableColumnDefault: {
-    type: Function as PropType<(...val: any[]) => void>
-  },
-  store: {
-    type: Object as PropType<PageStore>,
-  },
-  tableRefName: {
-    type: String
+const props = defineProps<{
+  data: any[];
+  columns: any[];
+  store: PageStore,
+  tableRefName: PageHelpTableName,
+  tableBind: any,
+  getSlotsData: (code: string) => any
+}>()
+
+function handleSlots(slots, tmp) {
+  for (let key in slots) {
+    tmp.slots[key] = ({row, rowIndex}) => {
+      const code = slots[key]
+      return props.getSlotsData(row, rowIndex, code)
+    }
   }
+}
+
+// @ts-ignore
+const columnBindComputed: ComputedRef<VxeGridPropTypes.Columns> = computed(() => {
+  // @ts-ignore
+  return XEUtils.eachAndReturnList(props!.columns, (item, index) => {
+    const {func, slots, ...temp} = item
+
+    let tmp: any = {...temp, slots: {}}
+    if (props.store?.props.isEditor) {
+      tmp.slots.header = () => {
+        return <ElInput
+            modelValue={props?.columns[index]?.title}
+            onUpdate:modelValue={(value) => {
+              props.columns[index].title = value
+            }}
+            onFocus={() => handleFocus(props.columns?.[index].field)}
+        />
+      }
+    }
+    handleSlots(slots, tmp)
+    return tmp
+  });
+
 })
 
-const columnBind = (item) => {
-  const {func, ...temp} = item
-  return XEUtils.clone(temp, true)
-}
+// @ts-ignore
+const tableGridComputed: ComputedRef<VxeGridProps> = computed(() => {
+  console.log(columnBindComputed.value)
+  return {
+    data: props.data,
+    columns: columnBindComputed.value,
+    expandConfig: {},
+    height: 'auto',
+    autoResize: true,
+    syncResize: false,
+    columnConfig: {resizable: true},
+    style: {
+      width: '100%',
+    },
+    rowConfig: {height: 48, isCurrent: true, isHover: true, useKey: true},
+    scrollX: {enabled: false},
+    scrollY: {gt: 0, enabled: true},
+    showOverflow: true,
+    ...props.tableBind
+  }
+})
 
-function setMainTableRef(el) {
+function setMainTableRef(el: any) {
   if (typeof props.store !== 'undefined') {
     props.store[props.tableRefName].value = el
   }
 }
 
-function handleFocus(field) {
+function handleFocus(field: string) {
   if (typeof props.store !== 'undefined') {
     props.store!.mainTableRef.value.scrollToColumn(field)
   }

+ 24 - 20
src/views/data-base/page-editor-help-v2/components/page-editor-v2/PageHelpV2.vue

@@ -160,22 +160,25 @@ async function queryClick() {
 
 const rules = ref({})
 
-function initTable() {
-  tableBind.value = {
-    data: [],
-    columns: []
-  }
-}
-
 const dialogTableData = ref({
   data: [],
-  columns: []
+  columns: [],
+  tableBind: {}
 })
 
+function initTable() {
+  tableBind.value.data = []
+  tableBind.value.columns = [];
+  tableBind.value.tableBind = {}
+
+  dialogTableData.value.data = []
+  dialogTableData.value.columns = [];
+  dialogTableData.value.tableBind = {}
+}
+
+
 const showDialog = ref(false)
 const dialogTitle = ref('详情')
-const tableData = ref([])
-const columns = ref([])
 const loading = ref(false)
 
 function requiredInit() {
@@ -291,16 +294,18 @@ function dialogTableColumns() {
   store.getColumns(dialogTableData, 'dialogTableRef')
 }
 
-function setTableData(res) {
+function setTableData(res: any) {
   if (res === null) {
     res = {
       columns: [],
-      data: []
+      data: [],
+      tableBind: {}
     }
   }
   tableBind.value = res;
   store.getColumns(tableBind, 'mainTableRef', false)
   if (res.details) {
+    //@ts-ignore
     tableBind.value.columns.push({
       field: 'operations',
       title: '详情',
@@ -332,12 +337,9 @@ function setTableData(res) {
 }
 
 
-const handleTableColumnDefault = (row, index, item) => {
-  if (!XEUtils.has(item, 'func.defaultFunc')) {
-    item.func.defaultFunc = new Function("row", 'rowIndex', "pageData", "apiFunc", "el", "vue", "openDialogAndSetData",
-        item.func.default)
-  }
-  return item.func.defaultFunc(row, index, pageData.value, reportQueryCenterApi, ElAndXc, vue, openDialogAndSetData)
+function getSlotsData(row: any, index: number, code: string) {
+  const newFunction = new Function("row", 'rowIndex', "pageData", "apiFunc", "el", "vue", "openDialogAndSetData", code)
+  return newFunction(row, index, pageData.value, reportQueryCenterApi, ElAndXc, vue, openDialogAndSetData)
 }
 
 function exportExcel(data: { data: any[], columns: Columns[], fileName?: string }, tableRef) {
@@ -438,10 +440,11 @@ defineExpose({
            style="width: 100%; height: 100%"
            v-loading="loading">
         <PageHelpTable :data="tableBind.data"
+                       :table-bind="tableBind.tableBind"
                        :store="store"
+                       :getSlotsData="getSlotsData"
                        tableRefName="mainTableRef"
                        :columns="tableBind.columns"
-                       :handle-table-column-default="handleTableColumnDefault"
         />
       </div>
     </template>
@@ -453,10 +456,11 @@ defineExpose({
              class="page_help-dialog">
     <PageHelpTable
         :store="store"
+        :getSlotsData="getSlotsData"
+        :table-bind="dialogTableData.tableBind"
         table-ref-name="dialogTableRef"
         :data="dialogTableData.data"
         :columns="dialogTableData.columns"
-        :handle-table-column-default="handleTableColumnDefault"
     />
     <template #footer>
       <el-button v-if="props.isEditor" @click="dialogTableColumns">生成表格列</el-button>

+ 4 - 2
src/views/data-base/page-editor-help-v2/page-help-v2.ts

@@ -50,6 +50,7 @@ export interface PageHelpV2Mitt {
     [key: string]: (...args: any[]) => any;
 }
 
+export type PageHelpTableName = 'mainTableRef' | 'dialogTableRef'
 
 export interface ComponentBind {
     renderName: 'select' | 'boolean' | 'input' | 'number' | 'json',
@@ -85,7 +86,8 @@ export function usePageStore(props: any) {
 
     const tableBind = ref({
         data: [],
-        columns: []
+        columns: [],
+        tableBind: {}
     })
 
     function clearOnAndFunc() {
@@ -135,7 +137,7 @@ export function usePageStore(props: any) {
     const bindData = ref()
     let changeCurrentBind: (item: any) => Promise<any> | null = () => null
 
-    function getColumns(data: Ref<TableData>, tableName: 'dialogTableRef' | 'mainTableRef' = 'mainTableRef', copy = true) {
+    function getColumns(data: Ref<TableData>, tableName: PageHelpTableName = 'mainTableRef', copy = true) {
         if (data.value.columns.length === 0 && data.value.data.length > 0) {
             for (let key in data.value.data[0]) {
                 if (key === '_X_ROW_KEY') {