Commit b1fcdaebabecd8a0623b3be0a3c5424fa745a9f6
1 parent
441f73b9
Exists in
master
and in
3 other branches
feat: 优化Scheme自定义渲染及详情和删除接口
Showing
7 changed files
with
255 additions
and
48 deletions
Show diff stats
examples/styles/index.scss
| ... | ... | @@ -53,6 +53,21 @@ body { |
| 53 | 53 | } |
| 54 | 54 | } |
| 55 | 55 | |
| 56 | +.zee-scheme__view { | |
| 57 | + .el-form-item { | |
| 58 | + font-weight: normal !important; | |
| 59 | + margin-bottom: 0 !important; | |
| 60 | + &__label { | |
| 61 | + line-height: 1.5 !important; | |
| 62 | + color: #595959 !important; | |
| 63 | + } | |
| 64 | + &__content { | |
| 65 | + line-height: 1.5 !important; | |
| 66 | + color: #000 !important; | |
| 67 | + } | |
| 68 | + } | |
| 69 | +} | |
| 70 | + | |
| 56 | 71 | @media only screen and (min-width: 1400px) { |
| 57 | 72 | .code-snippet-box { |
| 58 | 73 | .code-snippet { | ... | ... |
examples/views/docs/component/scheme.md
| ... | ... | @@ -111,6 +111,18 @@ export default { |
| 111 | 111 | <template> |
| 112 | 112 | <z-scheme ref="scheme" :list="list" url="/customer" :http="$http" :alias="{ getUrl: '/getCustomerByCode', getKey: 'code' }" auto real-selection> |
| 113 | 113 | <el-table-column type="selection" align="center" width="40"></el-table-column> |
| 114 | + <template #render-code="{ value, row, openView }"> | |
| 115 | + <el-link type="primary" @click="openView(row)">{{ value }}</el-link> | |
| 116 | + </template> | |
| 117 | + <template #view-name="{ value }"> | |
| 118 | + <el-tag size="mini">{{ value }}</el-tag> | |
| 119 | + </template> | |
| 120 | + <template #cell-name="{ value }"> | |
| 121 | + <el-tag size="mini" type="danger">{{ value }}</el-tag> | |
| 122 | + </template> | |
| 123 | + <template #form-id="{ value }"> | |
| 124 | + <el-tag size="mini">{{ value }}</el-tag> | |
| 125 | + </template> | |
| 114 | 126 | </z-scheme> |
| 115 | 127 | </template> |
| 116 | 128 | ... | ... |
packages/filter/index.vue
| 1 | 1 | <template> |
| 2 | - <z-form v-model="model" class="zee-filter" :list="formattedList" :span="span" :labelWidth="labelWidth" :colClass="colVisibleRender" :size="size"> | |
| 2 | + <z-form v-model="model" class="zee-filter" :list="formattedList" :span="span" :labelWidth="labelWidth" :colClass="colVisibleRender" :size="size" :formProps="formProps"> | |
| 3 | 3 | <div slot="$operation" class="zee-filter__button-group"> |
| 4 | 4 | <el-button-group :size="size"> |
| 5 | - <el-button type="primary" @click="handleSearch" :loading="loading"><span>查询</span></el-button> | |
| 5 | + <el-button type="primary" @click="handleSearch" :loading="loading" icon="el-icon-search"><span>查询</span></el-button> | |
| 6 | 6 | <el-button @click="handleReset"><span>重置</span></el-button> |
| 7 | 7 | <el-button v-if="showCollapsed" @click="collapsed = !collapsed"> |
| 8 | 8 | <span>{{ collapsed ? '展开' : '收起' }}</span> |
| 9 | - <!-- <i :class="`el-icon-arrow-${collapsed ? 'down' : 'up'}`" class="el-icon--right"></i> --> | |
| 10 | 9 | </el-button> |
| 11 | 10 | </el-button-group> |
| 12 | 11 | </div> |
| ... | ... | @@ -36,6 +35,10 @@ export default { |
| 36 | 35 | default: 3, |
| 37 | 36 | }, |
| 38 | 37 | loading: Boolean, |
| 38 | + formProps: { | |
| 39 | + type: Object, | |
| 40 | + default: () => ({}), | |
| 41 | + }, | |
| 39 | 42 | }, |
| 40 | 43 | data() { |
| 41 | 44 | return { | ... | ... |
packages/form/form-render.vue
| ... | ... | @@ -47,7 +47,7 @@ |
| 47 | 47 | :class="colClassRender(item, index, colClass)" |
| 48 | 48 | > |
| 49 | 49 | <el-form-item :label="item.label" :label-width="item.labelWidth" :prop="item.fullKey" :rules="item.rules" :class="itemClass || 'zee-form__item'"> |
| 50 | - <slot v-if="$slots[item.fullKey]" :name="item.fullKey" :value="itemValue(item)" :model="value"></slot> | |
| 50 | + <slot v-if="$scopedSlots[item.fullKey]" :name="item.fullKey" :value="itemValue(item)" :model1="value"></slot> | |
| 51 | 51 | <template v-else> |
| 52 | 52 | <!-- 自定义组件 --> |
| 53 | 53 | <dynamic-render | ... | ... |
packages/form/index.vue
| ... | ... | @@ -16,7 +16,7 @@ |
| 16 | 16 | </style> |
| 17 | 17 | |
| 18 | 18 | <template> |
| 19 | - <el-form ref="form" :size="size" :class="formClass" :model="formModel" :label-width="labelWidth" :label-position="labelPosition || labelWidth ? 'right' : 'top'"> | |
| 19 | + <el-form ref="form" :size="size" :class="formClass" :model="formModel" :label-width="labelWidth" :label-position="labelPosition || labelWidth ? 'right' : 'top'" v-bind="formProps"> | |
| 20 | 20 | <form-render |
| 21 | 21 | :title-class="titleClass" |
| 22 | 22 | :content-class="contentClass" |
| ... | ... | @@ -64,15 +64,23 @@ export default { |
| 64 | 64 | type: Number, |
| 65 | 65 | default: 24, |
| 66 | 66 | }, |
| 67 | + formProps: { | |
| 68 | + type: Object, | |
| 69 | + default: () => ({}), | |
| 70 | + }, | |
| 67 | 71 | }, |
| 68 | 72 | data() { |
| 69 | 73 | return { |
| 70 | - slotKeys: Object.keys(this.$slots), | |
| 71 | 74 | model: {}, |
| 72 | 75 | formModel: {}, |
| 73 | 76 | formList: [], |
| 74 | 77 | }; |
| 75 | 78 | }, |
| 79 | + computed: { | |
| 80 | + slotKeys() { | |
| 81 | + return Object.keys(this.$scopedSlots); | |
| 82 | + }, | |
| 83 | + }, | |
| 76 | 84 | watch: { |
| 77 | 85 | value: { |
| 78 | 86 | handler(val = {}) { | ... | ... |
packages/scheme/index.vue
| ... | ... | @@ -4,44 +4,80 @@ |
| 4 | 4 | |
| 5 | 5 | <template> |
| 6 | 6 | <div class="zee-scheme"> |
| 7 | + <!-- 头部内容 --> | |
| 7 | 8 | <div v-if="$scopedSlots.header || $slots.header" class="zee-scheme__header"> |
| 8 | 9 | <slot name="header" :filterModel="filterModel" v-bind="_slotScope"></slot> |
| 9 | 10 | </div> |
| 11 | + <!-- 筛选组件 --> | |
| 10 | 12 | <div class="zee-scheme__filter"> |
| 11 | - <z-filter v-if="filter" :value="_filterModel" :list="listMap.filter | noRulesFilter" :size="size" @input="onFilterInput" @search="search" :loading="loading"></z-filter> | |
| 13 | + <z-filter | |
| 14 | + v-if="filter" | |
| 15 | + :value="_filterModel" | |
| 16 | + :list="filterList || listMap.filter | noRulesFilter" | |
| 17 | + :size="size" | |
| 18 | + @input="onFilterInput" | |
| 19 | + @search="search" | |
| 20 | + :loading="loading" | |
| 21 | + v-bind="filterProps" | |
| 22 | + ></z-filter> | |
| 12 | 23 | </div> |
| 24 | + <!-- 按钮区 --> | |
| 13 | 25 | <div v-if="action" class="zee-scheme__action"> |
| 14 | 26 | <slot v-if="hadSlot('action')" name="action" v-bind="_slotScope"></slot> |
| 15 | 27 | <template v-else> |
| 16 | 28 | <el-button :size="size" type="primary" @click="openNew">新增</el-button> |
| 17 | - <slot name="button" :size="size" v-bind="_slotScope"></slot> | |
| 29 | + <el-button :size="size" plain :disabled="selection.length === 0" @click="handleDeleteMul(selection)">删除</el-button> | |
| 30 | + <slot name="button" v-bind="_slotScope"></slot> | |
| 18 | 31 | </template> |
| 19 | 32 | </div> |
| 33 | + <!-- 表格内容 --> | |
| 20 | 34 | <div class="zee-scheme__table"> |
| 21 | 35 | <z-table |
| 22 | 36 | ref="table" |
| 23 | 37 | v-model="tableData" |
| 24 | 38 | v-loading="loading" |
| 25 | - :list="listMap.table" | |
| 39 | + :list="tableList || listMap.table" | |
| 26 | 40 | :tableProps="{ border: true, 'row-key': 'id', ...tableProps }" |
| 27 | 41 | :size="size" |
| 28 | 42 | @selection-change="onTableSelectionChange" |
| 29 | 43 | @selection="onTableSelection" |
| 30 | 44 | > |
| 31 | 45 | <slot></slot> |
| 46 | + <!-- 表格列内容渲染 --> | |
| 47 | + <template v-for="(item, index) in renderList"> | |
| 48 | + <template v-if="$scopedSlots[`cell-${item.fullKey}`]"> | |
| 49 | + <el-table-column :slot="item.fullKey" v-bind="item" :prop="item.agentKey || item.key" :key="`table-cell-${index}`"> | |
| 50 | + <template slot-scope="{ row, column, $index }"> | |
| 51 | + <slot :name="`cell-${item.fullKey}`" v-bind="{ ...item, ..._slotScope }" :row="row" :value="row[item.key]" :column="column" :index="$index"></slot> | |
| 52 | + </template> | |
| 53 | + </el-table-column> | |
| 54 | + </template> | |
| 55 | + <template v-else-if="$scopedSlots[`render-${item.fullKey}`]"> | |
| 56 | + <el-table-column :slot="item.fullKey" v-bind="item" :prop="item.agentKey || item.key" :key="`table-render-${index}`"> | |
| 57 | + <template slot-scope="{ row, column, $index }"> | |
| 58 | + <slot :name="`render-${item.fullKey}`" v-bind="{ ...item, ..._slotScope }" :row="row" :value="row[item.key]" :column="column" :index="$index"></slot> | |
| 59 | + </template> | |
| 60 | + </el-table-column> | |
| 61 | + </template> | |
| 62 | + </template> | |
| 63 | + <slot slot="column-append" name="column-append" v-bind="_slotScope"></slot> | |
| 64 | + <!-- 表格尾追加操作列 --> | |
| 32 | 65 | <template #column-end> |
| 33 | - <el-table-column prop="$operation" label="操作" :width="140" fixed="right"> | |
| 66 | + <slot slot="column-end" name="column-end" v-bind="_slotScope"></slot> | |
| 67 | + <el-table-column v-if="operation" prop="$operation" label="操作" v-bind="{ width: 100, fixed: 'right', ...operationProps }"> | |
| 34 | 68 | <div class="zee-scheme__table-operation" slot-scope="slotScope"> |
| 35 | - <el-button type="text" icon="el-icon-edit" title="编辑" @click="openEdit(slotScope)"></el-button> | |
| 36 | - <el-popconfirm confirmButtonText="确定" cancelButtonText="取消" title="确定删除吗?" placement="top" @onConfirm="handleDelete(slotScope)"> | |
| 69 | + <el-button type="text" icon="el-icon-edit" title="编辑" @click="openEdit(slotScope.row)"></el-button> | |
| 70 | + <el-popconfirm confirmButtonText="确定" cancelButtonText="取消" title="确定删除吗?" placement="top" @onConfirm="handleDelete([slotScope.row])"> | |
| 37 | 71 | <el-button slot="reference" type="text" icon="el-icon-delete" title="删除"></el-button> |
| 38 | 72 | </el-popconfirm> |
| 73 | + <slot name="operation-button" v-bind="_slotScope"></slot> | |
| 39 | 74 | </div> |
| 40 | 75 | </el-table-column> |
| 41 | 76 | </template> |
| 42 | 77 | </z-table> |
| 43 | 78 | </div> |
| 44 | - <div v-if="pagination" class="zee-scheme__footer"> | |
| 79 | + <!-- 底部区域 --> | |
| 80 | + <div class="zee-scheme__footer"> | |
| 45 | 81 | <div v-if="selection.length > 0" class="selection-info"> |
| 46 | 82 | <span>已选中</span> |
| 47 | 83 | <span class="num">{{ selection.length }}</span> |
| ... | ... | @@ -50,7 +86,9 @@ |
| 50 | 86 | <el-button slot="reference" :size="size" type="text">清除</el-button> |
| 51 | 87 | </el-popconfirm> |
| 52 | 88 | </div> |
| 89 | + <!-- 分页器 --> | |
| 53 | 90 | <el-pagination |
| 91 | + v-if="pagination" | |
| 54 | 92 | @size-change="handleSizeChange" |
| 55 | 93 | @current-change="handleCurrentChange" |
| 56 | 94 | :current-page="currentPage" |
| ... | ... | @@ -61,12 +99,62 @@ |
| 61 | 99 | > |
| 62 | 100 | </el-pagination> |
| 63 | 101 | </div> |
| 64 | - <el-dialog :visible.sync="dialogVisible" :title="dialogTitle" destroy-on-close append-to-body :lock-scroll="false" :close-on-click-modal="false" @closed="onDialogClosed"> | |
| 102 | + <!-- 弹出框 --> | |
| 103 | + <el-dialog | |
| 104 | + :visible.sync="dialogVisible" | |
| 105 | + :title="dialogTitle" | |
| 106 | + destroy-on-close | |
| 107 | + append-to-body | |
| 108 | + :lock-scroll="false" | |
| 109 | + :close-on-click-modal="false" | |
| 110 | + @closed="onDialogClosed" | |
| 111 | + v-bind="dialogProps" | |
| 112 | + > | |
| 65 | 113 | <div v-loading="dialogLoading"> |
| 114 | + <!-- 自定义弹出框标题 --> | |
| 66 | 115 | <slot v-if="hadSlot('dialog-title')" slot="title" name="dialog-title" :dialogType="dialogType" v-bind="_slotScope"></slot> |
| 67 | 116 | <template v-if="dialogRender"> |
| 117 | + <!-- 自定义弹出框内容 --> | |
| 68 | 118 | <slot v-if="hadSlot(`dialog-${dialogType}`)" :name="`dialog-${dialogType}`" :model="_formModel" v-bind="_slotScope"></slot> |
| 69 | - <z-form v-else ref="form" :value="_formModel" :list="listMap.form" label-width="80px" :span="12" @input="onFormInput" @validate="onFormValidate"></z-form> | |
| 119 | + <!-- 内置弹出框新增修改表单 --> | |
| 120 | + <template v-if="['new', 'edit'].includes(dialogType)"> | |
| 121 | + <z-form | |
| 122 | + ref="form" | |
| 123 | + :value="_formModel" | |
| 124 | + :list="formList || listMap.form" | |
| 125 | + @input="onFormInput" | |
| 126 | + @validate="onFormValidate" | |
| 127 | + v-bind="{ span: 12, 'label-width': '80px', ...formProps }" | |
| 128 | + > | |
| 129 | + <!-- 表单自定义插槽 --> | |
| 130 | + <template v-for="item in renderList"> | |
| 131 | + <template v-if="$scopedSlots[`form-${item.fullKey}`]"> | |
| 132 | + <slot :slot="item.fullKey" :name="`form-${item.fullKey}`" :value="get(_formModel, item.fullKey)" :row="_formModel" :model="_formModel" v-bind="_slotScope"></slot> | |
| 133 | + </template> | |
| 134 | + </template> | |
| 135 | + </z-form> | |
| 136 | + </template> | |
| 137 | + <!-- 内置弹出框详情表单 --> | |
| 138 | + <template v-else> | |
| 139 | + <z-form | |
| 140 | + ref="form" | |
| 141 | + class="zee-scheme__view" | |
| 142 | + :value="_formModel" | |
| 143 | + :list="viewList || listMap.form | viewTypeFilter | noRulesFilter" | |
| 144 | + v-bind="{ span: 12, 'label-width': '80px', ...viewProps }" | |
| 145 | + > | |
| 146 | + <!-- 详情自定义插槽渲染 --> | |
| 147 | + <template v-for="item in renderList"> | |
| 148 | + <template v-if="$scopedSlots[`view-${item.fullKey}`]"> | |
| 149 | + <slot :slot="item.fullKey" :name="`view-${item.fullKey}`" :value="get(_formModel, item.fullKey)" :row="_formModel" :model="_formModel" v-bind="_slotScope"></slot> | |
| 150 | + </template> | |
| 151 | + <template v-else-if="$scopedSlots[`render-${item.fullKey}`]"> | |
| 152 | + <slot :slot="item.fullKey" :name="`render-${item.fullKey}`" :value="get(_formModel, item.fullKey)" :row="_formModel" :model="_formModel" v-bind="_slotScope"></slot> | |
| 153 | + </template> | |
| 154 | + </template> | |
| 155 | + </z-form> | |
| 156 | + </template> | |
| 157 | + <!-- 内置弹出框新增修改按钮 --> | |
| 70 | 158 | <div class="zee-scheme__dialog-button" v-if="['new', 'edit'].includes(dialogType)"> |
| 71 | 159 | <el-button :size="size" type="primary" @click="handleConfirm" :loading="submitting">确定</el-button> |
| 72 | 160 | <el-button :size="size" plain @click="closeDialog">取消</el-button> |
| ... | ... | @@ -78,47 +166,52 @@ |
| 78 | 166 | </template> |
| 79 | 167 | |
| 80 | 168 | <script> |
| 81 | -import { cloneDeep } from '../_utils'; | |
| 169 | +import { cloneDeep, get } from '../_utils'; | |
| 82 | 170 | import { clear } from '../_utils/param'; |
| 83 | 171 | |
| 172 | +let propsMap = {}; | |
| 173 | +const propsKeys = ['tableProps', 'filterProps', 'formProps', 'viewProps', 'dialogProps', 'operationProps']; | |
| 174 | +propsKeys.forEach(key => { | |
| 175 | + propsMap[key] = { | |
| 176 | + type: Object, | |
| 177 | + default: function() { | |
| 178 | + return {}; | |
| 179 | + }, | |
| 180 | + }; | |
| 181 | +}); | |
| 182 | +const apiKeys = ['searchApi', 'submitApi', 'addApi', 'modifyApi', 'getApi', 'viewApi', 'deleteApi']; | |
| 183 | +apiKeys.forEach(key => { | |
| 184 | + propsMap[key] = { | |
| 185 | + type: Function, | |
| 186 | + }; | |
| 187 | +}); | |
| 188 | +const blockKeys = ['filter', 'action', 'pagination', 'operation']; | |
| 189 | +blockKeys.forEach(key => { | |
| 190 | + propsMap[key] = { | |
| 191 | + type: Boolean, | |
| 192 | + default: true, | |
| 193 | + }; | |
| 194 | +}); | |
| 195 | + | |
| 84 | 196 | export default { |
| 85 | 197 | name: 'Scheme', |
| 86 | 198 | props: { |
| 199 | + ...propsMap, | |
| 87 | 200 | list: Array, |
| 88 | - filter: { | |
| 89 | - type: Boolean, | |
| 90 | - default: true, | |
| 91 | - }, | |
| 92 | - action: { | |
| 93 | - type: Boolean, | |
| 94 | - default: true, | |
| 95 | - }, | |
| 96 | - pagination: { | |
| 97 | - type: Boolean, | |
| 98 | - default: true, | |
| 99 | - }, | |
| 201 | + filterList: Array, | |
| 202 | + tableList: Array, | |
| 203 | + formList: Array, | |
| 204 | + viewList: Array, | |
| 100 | 205 | size: { |
| 101 | 206 | type: String, |
| 102 | 207 | default: 'mini', |
| 103 | 208 | }, |
| 104 | - tableProps: { | |
| 105 | - type: Object, | |
| 106 | - default: () => ({}), | |
| 107 | - }, | |
| 108 | 209 | formModel: Object, |
| 109 | 210 | filterModel: Object, |
| 110 | 211 | auto: Boolean, |
| 111 | 212 | realSelection: Boolean, |
| 112 | - /* 模板API */ | |
| 113 | 213 | url: String, // 请求地址 |
| 114 | 214 | http: [Function, Promise], // http库 |
| 115 | - /* 自定义API */ | |
| 116 | - searchApi: Function, // 搜索 | |
| 117 | - submitApi: Function, // 提交 | |
| 118 | - addApi: Function, // 新增 | |
| 119 | - modifyApi: Function, // 修改 | |
| 120 | - getApi: Function, // 查询详情 | |
| 121 | - deleteApi: Function, // 删除 | |
| 122 | 215 | alias: Object, // 别名配置 |
| 123 | 216 | }, |
| 124 | 217 | data() { |
| ... | ... | @@ -161,6 +254,17 @@ export default { |
| 161 | 254 | clearRules(list); |
| 162 | 255 | return list; |
| 163 | 256 | }, |
| 257 | + // 详情类型过滤器 | |
| 258 | + viewTypeFilter(val = []) { | |
| 259 | + let list = cloneDeep(val); | |
| 260 | + const clearRules = list => { | |
| 261 | + list.forEach(item => { | |
| 262 | + item.type = (h, { model, config }) => h('span', config, model[item.key]); | |
| 263 | + }); | |
| 264 | + }; | |
| 265 | + clearRules(list); | |
| 266 | + return list; | |
| 267 | + }, | |
| 164 | 268 | }, |
| 165 | 269 | computed: { |
| 166 | 270 | listMap() { |
| ... | ... | @@ -199,6 +303,28 @@ export default { |
| 199 | 303 | }); |
| 200 | 304 | return array; |
| 201 | 305 | }, |
| 306 | + renderList() { | |
| 307 | + // 深度克隆传入的列表,避免原始值被修改 | |
| 308 | + const newList = cloneDeep(this.list); | |
| 309 | + // 生成列表值的全路径key,即列表项为对象时,对象内的key与上一级的key合并作为全路径key | |
| 310 | + const generateFullKey = (list, parentKey) => { | |
| 311 | + list.forEach(item => { | |
| 312 | + if (item.group && item.list) { | |
| 313 | + if (item.group.key) { | |
| 314 | + item.fullKey = `${parentKey ? `${parentKey}-${item.group.key}` : item.group.key}`; | |
| 315 | + } else { | |
| 316 | + item.fullKey = parentKey || item.key; | |
| 317 | + } | |
| 318 | + generateFullKey(item.list, item.fullKey); | |
| 319 | + } else { | |
| 320 | + item.fullKey = `${parentKey ? `${parentKey}-${item.key}` : item.key}`; | |
| 321 | + } | |
| 322 | + }); | |
| 323 | + }; | |
| 324 | + // 生成fullKey | |
| 325 | + generateFullKey(newList); | |
| 326 | + return newList; | |
| 327 | + }, | |
| 202 | 328 | _filterModel() { |
| 203 | 329 | return this.filterModel || this.filterForm || {}; |
| 204 | 330 | }, |
| ... | ... | @@ -209,6 +335,9 @@ export default { |
| 209 | 335 | return { |
| 210 | 336 | openDialog: this.openDialog, |
| 211 | 337 | closeDialog: this.closeDialog, |
| 338 | + openView: this.openView, | |
| 339 | + handleDelete: this.handleDelete, | |
| 340 | + size: this.size, | |
| 212 | 341 | }; |
| 213 | 342 | }, |
| 214 | 343 | _alias() { |
| ... | ... | @@ -221,6 +350,7 @@ export default { |
| 221 | 350 | }, |
| 222 | 351 | }, |
| 223 | 352 | methods: { |
| 353 | + get, | |
| 224 | 354 | // 空Promise |
| 225 | 355 | emptyPromise() { |
| 226 | 356 | return new Promise(resolve => resolve()); |
| ... | ... | @@ -367,17 +497,44 @@ export default { |
| 367 | 497 | return undefined; |
| 368 | 498 | }, |
| 369 | 499 | // 打开编辑弹出框 |
| 370 | - openEdit({ row }) { | |
| 500 | + openEdit(row) { | |
| 371 | 501 | this.dialogLoading = true; |
| 372 | 502 | this.openDialog('edit', '编辑'); |
| 373 | 503 | const getRow = () => |
| 374 | 504 | new Promise(resolve => { |
| 375 | - resolve({ ...row }); | |
| 505 | + resolve(row); | |
| 376 | 506 | }); |
| 377 | 507 | const getAPI = this.getApi || this._getAPI || getRow; |
| 378 | 508 | getAPI(row) |
| 379 | 509 | .then(result => { |
| 380 | - this.editForm = { ...result }; | |
| 510 | + this.editForm = result; | |
| 511 | + }) | |
| 512 | + .finally(() => { | |
| 513 | + this.dialogLoading = false; | |
| 514 | + }); | |
| 515 | + }, | |
| 516 | + // 内置查询详情接口 | |
| 517 | + _viewAPI(row) { | |
| 518 | + if (this.url && (this.http || this.zHttp)) { | |
| 519 | + const _http = this.http || this.zHttp; | |
| 520 | + const _viewKey = this._alias.viewKey || this._alias.getKey || this._alias.primaryKey || 'id'; | |
| 521 | + const _resultKey = this._alias.result || 'result'; | |
| 522 | + return _http({ url: `${clear(this.url)}/${this._alias.getUrl || 'queryById'}`, params: { [_viewKey]: row[_viewKey] } }).then(response => response[_resultKey] || {}); | |
| 523 | + } | |
| 524 | + return undefined; | |
| 525 | + }, | |
| 526 | + // 打开详情弹出框 | |
| 527 | + openView(row) { | |
| 528 | + this.dialogLoading = true; | |
| 529 | + this.openDialog('view', '详情'); | |
| 530 | + const getRow = () => | |
| 531 | + new Promise(resolve => { | |
| 532 | + resolve(row); | |
| 533 | + }); | |
| 534 | + const viewAPI = this.viewApi || this.getApi || this._viewAPI || this._getAPI || getRow; | |
| 535 | + viewAPI(row) | |
| 536 | + .then(result => { | |
| 537 | + this.editForm = result; | |
| 381 | 538 | }) |
| 382 | 539 | .finally(() => { |
| 383 | 540 | this.dialogLoading = false; |
| ... | ... | @@ -392,7 +549,7 @@ export default { |
| 392 | 549 | return undefined; |
| 393 | 550 | }, |
| 394 | 551 | // 删除 |
| 395 | - handleDelete({ row, $index }) { | |
| 552 | + handleDelete(selection) { | |
| 396 | 553 | const loading = this.$loading({ |
| 397 | 554 | text: '处理中', |
| 398 | 555 | spinner: 'el-icon-loading', |
| ... | ... | @@ -400,7 +557,7 @@ export default { |
| 400 | 557 | }); |
| 401 | 558 | const deleteAPI = this.deleteApi || this._deleteAPI || this.emptyPromise; |
| 402 | 559 | const _deleteKey = this._alias.deleteKey || this._alias.primaryKey || 'id'; |
| 403 | - const keys = [row[_deleteKey]]; | |
| 560 | + const keys = selection.map(i => i[_deleteKey]); | |
| 404 | 561 | deleteAPI(keys) |
| 405 | 562 | .then(() => { |
| 406 | 563 | this.search(); |
| ... | ... | @@ -410,16 +567,30 @@ export default { |
| 410 | 567 | loading.close(); |
| 411 | 568 | }); |
| 412 | 569 | }, |
| 570 | + // 批量删除 | |
| 571 | + handleDeleteMul(selection) { | |
| 572 | + this.$confirm(`是否删除这 [${selection.length}] 项?`, '提示', { | |
| 573 | + confirmButtonText: '确定', | |
| 574 | + cancelButtonText: '取消', | |
| 575 | + type: 'warning', | |
| 576 | + }) | |
| 577 | + .then(() => { | |
| 578 | + this.handleDelete(selection); | |
| 579 | + }) | |
| 580 | + .catch(() => {}); | |
| 581 | + }, | |
| 413 | 582 | // 打开弹出框 |
| 414 | 583 | openDialog(type, title) { |
| 415 | 584 | this.dialogVisible = true; |
| 416 | 585 | this.dialogRender = true; |
| 417 | 586 | this.dialogType = type; |
| 418 | 587 | this.dialogTitle = title; |
| 588 | + this.$emit('dialog-change', type); | |
| 419 | 589 | }, |
| 420 | 590 | // 关闭弹出框 |
| 421 | 591 | closeDialog() { |
| 422 | 592 | this.dialogVisible = false; |
| 593 | + this.$emit('dialog-change', 'none'); | |
| 423 | 594 | }, |
| 424 | 595 | // 清空表单 |
| 425 | 596 | clearEditForm() { | ... | ... |