diff --git a/CHANGELOG.md b/CHANGELOG.md index 3263a3e37b9fe6388628b2f6c1915ca7380dce5d..0ca81fdfa29f63e6c11f30c4604597b48d1dab70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ ### Change - 卡片视图绘制为卡片样式 +- 卡片视图部件支持分页模式 ### Fixed diff --git a/src/control/data-view/data-view.scss b/src/control/data-view/data-view.scss index 4d3db9db70a4ea321a9b2ae396884a346953567f..204d4fed3eaa531f3e1cbb5d1da86176fa551607 100644 --- a/src/control/data-view/data-view.scss +++ b/src/control/data-view/data-view.scss @@ -3,6 +3,7 @@ $control-dataview: (text-color: getCssVar(color, text, 0), padding: getCssVar(spacing, base-tight) getCssVar(spacing, base), card-margin:getCssVar(spacing, base-tight), item-margin: calc( getCssVar(spacing, base, tight) / 2 ), + pagination-height: var(--van-pagination-height), ); @include b(control-dataview-item) { @@ -42,4 +43,17 @@ $control-dataview: (text-color: getCssVar(color, text, 0), @include e(item-col) { margin: getCssVar(control-dataview, item-margin) 0; } + + @include when(enable-page) { + .#{bem(control-dataview, content)} { + height: calc(100% - getCssVar(control-dataview, pagination-height)); + } + } + + @include e(load-more) { + @include flex(row, center, center); + height: getCssVar(control-dataview, pagination-height); + cursor: pointer; + color: getCssVar(color, link); + } } \ No newline at end of file diff --git a/src/control/data-view/data-view.tsx b/src/control/data-view/data-view.tsx index d66fe9d914104b0a016abc30164dc31a01a3ef57..e1156b1ef6c43386fab3b581325e40c1296218c2 100644 --- a/src/control/data-view/data-view.tsx +++ b/src/control/data-view/data-view.tsx @@ -1,12 +1,13 @@ import { useControlController, useNamespace } from '@ibiz-template/vue3-util'; -import { defineComponent, PropType, ref, VNode } from 'vue'; +import { computed, defineComponent, PropType, ref, VNode } from 'vue'; import { IDEDataView, ILayoutPanel, IUIActionGroupDetail, } from '@ibiz/model-core'; -import './data-view.scss'; import { DataViewControlController } from '@ibiz-template/runtime'; +import { usePagination } from '../../util'; +import './data-view.scss'; export const DataViewControl = defineComponent({ name: 'IBizDataViewControl', @@ -24,6 +25,29 @@ export const DataViewControl = defineComponent({ const ns = useNamespace(`control-${c.model.controlType!.toLowerCase()}`); const active = ref([]); + // 是否可以加载更多 + const isLodeMoreDisabled = computed(() => { + if (c.model.enablePagingBar === true) { + return true; + } + if (c.model.pagingMode !== 2) { + return true; + } + return ( + c.state.items.length >= c.state.total || + c.state.isLoading || + c.state.total <= c.state.size + ); + }); + + const { onPageChange } = usePagination(c); + + // 是否显示数据伸缩图标 + // 如果未开启分组,并且加载模式为【加载更多】,并且已经加载过一次更多,则为 true + const showCollapseOrExpandIcon = computed(() => { + return !c.model.enableGroup && c.model.pagingMode === 3; + }); + // 绘制项布局面板 const renderPanelItem = (item: IData, modelData: ILayoutPanel): VNode => { const { context, params } = c; @@ -166,26 +190,76 @@ export const DataViewControl = defineComponent({ const renderMDContent = () => { const model: IDEDataView = c.model; return ( -
+ c.loadMore()} + > {model.groupMode !== 'NONE' ? renderGroup() : renderDefault()} + + ); + }; + + // 加载更多 + const loadMoreIcon = () => { + return ( +
c.loadMore()}> + {ibiz.i18n.t('control.common.loadMore')}
); }; + // 分页模式为点击加载时并且当前数量小于总数 + const renderLoadMore = () => { + let icon = null; + const loadMore = + c.state.items.length < c.state.total && c.state.total > c.state.size; + if (showCollapseOrExpandIcon.value && loadMore) { + icon = loadMoreIcon(); + } + return icon; + }; + return { c, ns, + showCollapseOrExpandIcon, + onPageChange, renderNoData, renderMDContent, + renderLoadMore, }; }, render() { + const enablePagingBar = + this.c.state.enablePagingBar && this.c.model.pagingMode === 1; return ( - + {this.c.state.isCreated && (this.c.state.items.length > 0 ? this.renderMDContent() : this.renderNoData())} + {enablePagingBar ? ( + + ) : null} + {this.renderLoadMore()} ); }, diff --git a/src/util/index.ts b/src/util/index.ts index 6acfe1e93a7eef7d7f27d2f488d53951cf66ea65..c813241e40d432996f775bd7d2b7320b6ce2a163 100644 --- a/src/util/index.ts +++ b/src/util/index.ts @@ -7,4 +7,5 @@ export { OverlayController } from './overlay-controller/overlay-controller'; export { loadingDirective } from './directive/loading'; export { ConfirmUtil } from './confirm-util/confirm-util'; export { AppUtil } from './app-util/app-util'; +export { usePagination } from './pagination/use-pagination'; export * from './store'; diff --git a/src/util/pagination/use-pagination.ts b/src/util/pagination/use-pagination.ts new file mode 100644 index 0000000000000000000000000000000000000000..2b575d8db21f0559a41199d55a8adc47a1d1caae --- /dev/null +++ b/src/util/pagination/use-pagination.ts @@ -0,0 +1,69 @@ +import { + ControlVO, + GridController, + GridRowState, + IMDControlController, +} from '@ibiz-template/runtime'; +import { chunk } from 'lodash-es'; + +/** + * 使用分页组件 + * + * @author lxm + * @date 2022-09-06 17:09:09 + * @export + * @param {GridController} c + * @returns {*} + */ +export function usePagination(c: IMDControlController): { + onPageChange: (page: number) => void; + onPageSizeChange: (size: number) => void; + onPageRefresh: () => void; +} { + // 初始化表格项 + const initGridItems = () => { + const controller = c as GridController; + if (Array.isArray(controller.state.simpleData)) { + controller.state.items = + chunk(controller.state.simpleData, controller.state.size)[ + controller.state.curPage - 1 + ] || []; + controller.state.rows = controller.state.items.map(item => { + const row = new GridRowState(new ControlVO(item), controller); + return row; + }); + } + }; + + function onPageChange(page: number): void { + if (!page || page === c.state.curPage) { + return; + } + c.state.curPage = page; + if (c.context && c.context.srfrunmode === 'DESIGN') { + initGridItems(); + return; + } + c.load(); + } + + function onPageSizeChange(size: number): void { + if (!size || size === c.state.size) { + return; + } + c.state.size = size; + if (c.context && c.context.srfrunmode === 'DESIGN') { + initGridItems(); + return; + } + // 当page为第一页的时候切换size不会触发pageChange,需要自己触发加载 + if (c.state.curPage === 1) { + c.load(); + } + } + + function onPageRefresh(): void { + c.load(); + } + return { onPageChange, onPageSizeChange, onPageRefresh }; +}