Parcourir la source

[update] 子表性能问题优化,bug448、bug516修复

cfort il y a 2 ans
Parent
commit
a892283ae4

+ 1 - 1
src/business/platform/form/constants/fieldOptions.js

@@ -376,7 +376,7 @@ export const intervalTypes = [{
 /**
  * 子表分页大小选项
  */
-export const defaultPageSize = 20
+export const defaultPageSize = 10
 /**
  * 子表分页大小选项
  */

+ 5 - 3
src/business/platform/form/formrender/dynamic-form/dynamic-form-field.vue

@@ -36,7 +36,9 @@
                     :readonly="readonly"
                     unselectable="on"
                     :style="{ width: width }"
-                    clearable
+                    :clearable="clearable && hasFocus"
+                    @focus="() => hasFocus = true"
+                    @blur="() => hasFocus = false"
                     v-on="$listeners"
                 />
 
@@ -664,7 +666,8 @@ export default {
             watchKey: false,
             inputKey: '',
             dict_add: false,
-            selectDataResult: []
+            selectDataResult: [],
+            hasFocus: false
         }
     },
     computed: {
@@ -963,7 +966,6 @@ export default {
         },
         dataModel: {
             handler (val) {
-                this.$emit('change-data', this.field.name,val)
                 this.$emit('update:value', val)
             },
             deep: true

+ 100 - 119
src/business/platform/form/formrender/dynamic-form/dynamic-form-table.vue

@@ -23,7 +23,7 @@
                 <div class="panel-body">
                     <el-table
                         ref="elTable"
-                        :data.sync="copDataModel"
+                        :data="copDataModel"
                         :header-cell-style="{ color: '#000', 'font-size': '14px', padding: '4px 0' }"
                         :row-class-name="tableRowClassName"
                         :show-summary="showSummary"
@@ -57,7 +57,7 @@
                                         <ibps-dynamic-form-table-item
                                             :ref="'formItem' + column.name"
                                             :key="scope.$index + j"
-                                            :models.sync="copDataModelCont[scope.$index + (currentPage * 10 - 10)]"
+                                            :models.sync="copDataModelCont[scope.$index + (currentPage - 1) * pageSize]"
                                             :rights.sync="columnsRights"
                                             :form-data="models"
                                             :field="column"
@@ -116,7 +116,16 @@
                         </el-table-column>
                     </el-table>
                     <!-- 分页 -->
-                    <el-pagination v-if="mode === 'dialog' || mode === 'inner'" :current-page="currentPage" :page-size="10" layout="total, prev, pager, next" :total="pageSize" @current-change="handleCurrentChange" />
+                    <el-pagination
+                        v-if="needPage !== 'N' && (mode === 'dialog' || mode === 'inner')"
+                        :current-page="currentPage"
+                        :page-size="pageSize"
+                        :page-sizes="pageSizeOptions"
+                        layout="total, sizes, prev, pager, next, jumper"
+                        :total="totalCount"
+                        @current-change="handleCurrentChange"
+                        @size-change="handleSizeChange"
+                    />
                 </div>
             </div>
             <!--================表内和弹窗模式end=================================-->
@@ -222,7 +231,7 @@ import IbpsImport from '@/plugins/import'
 const JForm = window.JForm
 // 获取子表展示数据
 const getShowData = (data, current = 1, size = defaultPageSize) => {
-    return data ? JSON.parse(JSON.stringify(data)).slice((current - 1) * size, current * size) : []
+    return data && data.length ? JSON.parse(JSON.stringify(data)).slice((current - 1) * size, current * size) : []
 }
 
 export default {
@@ -259,24 +268,23 @@ export default {
         }
     },
     data () {
-        let val = []
-        let tableType = ''
-        let copVal = []
-        if (this.$utils.isNotEmpty(this.value)) {
-            val = this.value || []
-            copVal = tableType === 'dialog' || 'inner' ? JSON.parse(JSON.stringify(val)).slice(0, 10) : val
+        const { page, pageSize = defaultPageSize, mode = 'inner' } = this.field.field_options || {}
+        let initData = []
+        if (page === 'N' || mode === 'block' || !this.value) {
+            initData = this.value || []
+        } else {
+            initData = getShowData(this.value, 1, pageSize)
         }
-        tableType = this.field.field_options.mode || 'inner'
-        /* 由于内容遍历卡顿问题,需再建个中间对象进行渲染.*/
         return {
-            editFromType: 'add', // 列表编辑弹出框类型
+            pageSize,
+            pageSizeOptions,
+            editFromType: '', // 列表编辑弹出框类型
             npmDialogFormVisible: false, // 弹窗
             defId: '', // 编辑dialog需要使用
             currentPage: 1,
-            dataPage: 0, // 当前条数
-            pageSize: val.length,
-            dataModel: val,
-            copDataModel: copVal,
+            totalCount: 0,
+            dataModel: [],
+            copDataModel: initData,
             multipleSelection: '',
             countNumber: 0,
             fieldRights: {}, // 子表配置权限
@@ -305,7 +313,7 @@ export default {
 
             oldList: [], // 子表旧数据
             importList: [],
-            importVlaue: null
+            importValue: null
         }
     },
     computed: {
@@ -354,12 +362,11 @@ export default {
         //     return this.field.field_options.pageSize || 10
         // },
         // copDataModel () {
+        //     // 自动计算显示数据,缺陷:子表数据任何变化都将触发
         //     // 非块模式且数据不为空
         //     if (this.$utils.isNotEmpty(this.dataModel) && ['dialog', 'inner'].includes(this.mode)) {
-        //         console.log(this.currentPage, (this.currentPage - 1) * this.pageSize, this.pageSize)
         //         return this.$utils.newData(this.dataModel).slice((this.currentPage - 1) * this.pageSize, this.currentPage * this.pageSize)
         //     } else {
-        //         console.log(2, this.dataModel)
         //         return this.dataModel
         //     }
         // },
@@ -445,15 +452,13 @@ export default {
                 // if (!valueEquals(val, oldVal)) {
                 //     this.dispatch('ElFormItem', 'el.form.change', val)
                 // }
-            },
-            immediate: true
+            }
         },
         dataModel: {
             handler (val, oldVal) {
                 // 进行分页操作
-                this.pageOperation(val, oldVal)
-            },
-            deep: true
+                this.handlePagination(val)
+            }
         },
         rights: {
             handler (val, oldVal) {
@@ -496,62 +501,44 @@ export default {
     methods: {
         getShowData,
         indexMethod (index) {
-            return (this.currentPage - 1) * 10 + index + 1
+            return (this.currentPage - 1) * this.pageSize + index + 1
         },
-        /* 更新后的参数*/ // 定义删除、增加 不做操作。修改时才做更新 ,分页修改时,根据页表修改。
+        /**
+         * 定义删除、增加 不做操作。修改时才做更新 ,分页修改时,根据页表修改。
+         */
         updateModel (key, val, index, page) {
-            this.dataModel[page * 10 - 10 + index][key] = val
+            this.dataModel[(page - 1) * this.pageSize + index][key] = val
             this.$emit('change-data', key, val)
         },
-        /* 分页操作及数据操作内容*/
-        pageOperation (val, oldVal) {
-            let page = this.currentPage * 10 - 10
-            const size = val.length
-            if (val.length > this.oldList.length && this.oldList.length >= 0) {
-                const valBai = size % 10
-                const valChu = parseInt(size / 10)
-                if (valBai === 0) {
-                    this.currentPage = valChu
-                } else {
-                    this.currentPage = valChu + 1
-                }
-                page = this.currentPage * 10 - 10
-            }
-            if (this.dataModel.length < this.oldList.length) {
-                const valBai = size % 10
-                const valChu = parseInt(size / 10)
-                if (this.editFromType == 'remove' && this.multipleSelection.length !== 0) {
-                    // 指定页删除数满10条:
-                    // 删完之后,如果下一页还有数据,则页码继续不变,如果下一页没有数据那么页码减1,直至页码=0
-                    // 除去本页剩余个数
-                    const yuShu = this.oldList.length - this.currentPage * 10
-                    if (yuShu < this.multipleSelection.length && yuShu < 0) {
-                        this.currentPage = this.currentPage - 1
-                    }
-                } else {
-                    if (valBai === 0) {
-                        this.currentPage = valChu
-                    } else {
-                        this.currentPage = valChu + 1
-                    }
-                }
-                page = this.currentPage * 10 - 10
-            }
-            this.pageSize = size
-            this.oldList = JSON.parse(JSON.stringify(this.dataModel))
-            // 具体操作
-            if (this.mode === 'dialog' || this.mode === 'inner') {
-                this.copDataModel = JSON.parse(JSON.stringify(val)).slice(page, page + 10)
+        handlePagination (val) {
+            this.totalCount = val.length
+            // 限制最小页数为1
+            const pageCount = Math.ceil(this.totalCount / this.pageSize) || 1
+            // 逻辑:删除后当前页大于总页数,替换为总页数,否则留在当前页
+            if (this.editFromType === 'add') {
+                // 新增按钮逻辑:前往最后一页
+                this.currentPage = pageCount
+            } else if (this.editFromType === 'import') {
+                // 导入定位到第一页
+                this.currentPage = 1
+            } else {
+                // 其余逻辑(编辑、删除、整表赋值):操作后当前页大于总页数,替换为总页数,否则留在当前页
+                this.currentPage = this.currentPage > pageCount ? pageCount : this.currentPage
             }
+            this.copDataModel = this.getShowData(val, this.currentPage, this.pageSize)
+            this.editFromType = ''
             this.$emit('update:value', val)
         },
-
-        // 简单的分页 usnin
+        // 处理切换分页
         handleCurrentChange (val) {
-            this.dataPage = val * 10 - 10
-            // 深度克隆主要数据
-            this.copDataModel = JSON.parse(JSON.stringify(this.dataModel)).slice(this.dataPage, this.dataPage + 10)
             this.currentPage = val
+            this.copDataModel = this.getShowData(this.dataModel, this.currentPage, this.pageSize)
+        },
+        // 处理切换分页大小
+        handleSizeChange (val) {
+            this.pageSize = val
+            this.currentPage = 1
+            this.copDataModel = this.getShowData(this.dataModel, this.currentPage, this.pageSize)
         },
         columnHidden (column) {
             // 是否隐藏
@@ -639,7 +626,7 @@ export default {
         },
         handleActionEvent (button, buttonIndex) {
             // 起始下标
-            const index = this.currentPage * 10 - 10 + buttonIndex
+            const index = (this.currentPage - 1) * this.pageSize + buttonIndex
             this.actionCode = button.key === 'custom' ? button.code || button.key + index : button.key
             this.actionPosition = button.position || 'toolbar'
             // 前置事件
@@ -722,7 +709,7 @@ export default {
             const selection = []
             if (position === 'toolbar' && this.mode !== 'block') {
                 if (this.multipleSelection && this.multipleSelection.length > 0) {
-                    const startIndex = this.currentPage * 10 - 10
+                    const startIndex = (this.currentPage - 1) * this.pageSize
                     this.multipleSelection.forEach((row) => {
                         selection.push(row.$index + startIndex)
                     })
@@ -735,21 +722,19 @@ export default {
         handleRemove (button, index) {
             const position = button.position
             const selection = this.getSelection(position, index)
-            ActionUtils.removeRecord(selection, '确定删除当前数据?', true)
-                .then((ids) => {
-                    for (let i = this.dataModel.length - 1; i >= 0; i--) {
-                        if (ids.indexOf(i) > -1) {
-                            this.dataModel.splice(i, 1)
-                        }
+            ActionUtils.removeRecord(selection, '确定删除当前数据?', true).then((ids) => {
+                for (let i = this.dataModel.length - 1; i >= 0; i--) {
+                    if (ids.indexOf(i) > -1) {
+                        this.dataModel.splice(i, 1)
                     }
-                    this.pageSize = this.dataModel.length
-                    // 后置事件
-                    this.afterScript(this.actionCode, position, {
-                        selection: selection,
-                        index: index
-                    })
+                }
+                this.totalCount = this.dataModel.length
+                // 后置事件
+                this.afterScript(this.actionCode, position, {
+                    selection: selection,
+                    index: index
                 })
-                .catch(() => {})
+            }).catch(() => {})
         },
         // 初始化运行公式计算
         initRunCalFormula (row) {
@@ -762,24 +747,24 @@ export default {
         importTableAction (val) {
             this.importTableDialogVisible = false
             this.importList = []
-            this.importVlaue = null
+            this.importValue = null
         },
         handleImportTableActionEvent (file, options) {
             if (this.importList.length > 0) {
                 this.loading = false
-                const formData = this.setValue(this.importVlaue)
+                const formData = this.setValue(this.importValue)
                 IbpsImport.xlsx(file, options).then(({ header, results }) => {
                     results.forEach((item) => {
                         const data = JSON.parse(JSON.stringify(formData))
                         for (const key in item) {
-                            if (this.importVlaue[key]) {
-                                data[this.importVlaue[key]] = item[key]
+                            if (this.importValue[key]) {
+                                data[this.importValue[key]] = item[key]
                             }
                         }
                         this.dataModel.push(data)
                     })
                     this.importTableDialogVisible = false
-                    this.importVlaue = null
+                    this.importValue = null
                     this.importList = []
                     ActionUtils.success('导入成功')
                 })
@@ -809,11 +794,10 @@ export default {
                 })
             }
         },
-
         // 自定义导入
         customHandleImport (data = []) {
             this.importList = data
-            this.importVlaue = this.getKeys(this.importList)
+            this.importValue = this.getKeys(this.importList)
             this.importTableDialogVisible = true
         },
         setValue (data) {
@@ -834,7 +818,6 @@ export default {
                 return obj
             }
         },
-
         // 数据导出
         getIbpsExport (columns, data, title, message, nameKey = 'name') {
             IbpsExport.excel({
@@ -1200,7 +1183,7 @@ export default {
     }
 }
 </script>
-<style lang="scss">
+<style lang="scss" scoped>
 .dynamic-form-table {
     .panel-heading {
         color: #000;
@@ -1227,6 +1210,27 @@ export default {
         position: relative;
         display: inline-block;
     }
+
+    ::v-deep .el-table {
+        th {
+            background-color: #84d5cf !important;
+            font-size: 12px;
+            font-weight: bold;
+            border: 0px;
+        }
+        td {
+            font-size: 12px;
+            padding: 0px 0 !important;
+        }
+        .warning-row {
+            background: #e0f0ee;
+            color: #000000;
+        }
+        .success-row {
+            background: #f9ffff;
+            color: #000000;
+        }
+    }
 }
 
 .is-error {
@@ -1248,27 +1252,4 @@ export default {
     font-size: 12px;
     color: #999999;
 }
-
-.dynamic-form-table .el-table th {
-    background-color: #84d5cf !important;
-    font-size: 12px;
-    font-weight: bold;
-    border: 0px;
-}
-
-.dynamic-form-table .el-table td {
-    font-size: 12px;
-    padding: 0px 0 !important;
-}
-
-.dynamic-form-table .el-table .warning-row {
-    background: #e0f0ee;
-    color: #000000;
-}
-
-.dynamic-form-table .el-table .success-row {
-    background: #f9ffff;
-    color: #000000;
-}
 </style>
-