提交 eea3989e 编写于 作者: Mosher's avatar Mosher

update:列表分组支持

上级 a6ffb0d3
...@@ -10,8 +10,8 @@ import { MDControlState } from "../md-control"; ...@@ -10,8 +10,8 @@ import { MDControlState } from "../md-control";
export interface ListControlState extends MDControlState { export interface ListControlState extends MDControlState {
/** /**
* @description 界面行为集合 * @description 界面行为集合
* @type {IParam[]} * @type {IParam}
* @memberof ListControlState * @memberof ListControlState
*/ */
uIActions: IParam[]; uIActions: IParam;
} }
\ No newline at end of file
import { IParam } from "@core"; import { deepCopy, IParam, isExistAndNotEmpty } from "@core";
import { ListControlState } from "./list-control-state"; import { ListControlState } from "./list-control-state";
import { MDControl } from "../md-control"; import { MDControl } from "../md-control";
...@@ -17,6 +17,146 @@ export class ListControl extends MDControl { ...@@ -17,6 +17,146 @@ export class ListControl extends MDControl {
*/ */
public declare state: ListControlState; public declare state: ListControlState;
/**
* @description 处理状态变化
* @memberof ListControl
*/
public handleStateChange() {
// 计算列表数据界面行为权限
const { items, uIActions } = toRefs(this.state);
if (items.value.length > 0 && uIActions.value && Object.keys(uIActions.value).length > 0) {
Object.keys(uIActions.value).forEach((key: string) => {
const tempActionModel = uIActions.value[key];
items.value.forEach((item: any) => {
Object.assign(item, { [key]: this.getActionAuthState(item, [tempActionModel]) });
});
})
}
// 处理分组
this.handleDataGroup();
// 处理默认选中
this.handleDefaultSelect();
}
/**
* @description 自动分组
* @protected
* @memberof ListControl
*/
protected autoGroupData() {
const { groupField } = this.state.mdCtrlGroup;
const { items } = toRefs(this.state);
if (!items.value || items.value.length === 0) {
return;
}
// 所有的分组值
const groupValueMap: string[] = [];
items.value.forEach((item: IParam) => {
if (isExistAndNotEmpty(item[groupField]) && !groupValueMap.includes(item[groupField])) {
groupValueMap.push(item[groupField]);
}
});
if (groupValueMap.length) {
const listData: IParam[] = [];
groupValueMap.forEach((value: string, index: number) => {
const children: IParam[] = [];
items.value.forEach((item: IParam) => {
if (item[groupField] === value) {
children.push(item);
}
});
listData.push({
srfmajortext: value,
type: 'GROUP',
expanded: false,
children: children
});
})
items.value = listData;
}
}
/**
* @description 代码表分组
* @protected
* @memberof ListControl
*/
protected async codeListGroupData() {
const { groupCodeList, groupField } = this.state.mdCtrlGroup;
if (!groupCodeList) {
App.getNotificationService().warning({
message: '警告',
description: '未配置分组代码表'
});
return;
}
const { context, viewParams } = this.state;
const { items } = toRefs(this.state);
const codeListService = App.getCodeListService();
let codeListItems: IParam[] = [];
try {
codeListItems = await codeListService.getCodeListItems({
tag: groupCodeList.codeListTag,
context,
viewParams
});
} catch(error) {
console.warn(`分组代码表 ${groupCodeList.codeListTag} 获取数据项异常`);
}
if (codeListItems.length) {
const listData: IParam[] = [];
codeListItems.forEach((codeListItem: IParam, index: number) => {
const children: IParam[] = [];
items.value.forEach((item: IParam) => {
if (item[groupField] === codeListItem.value) {
children.push(item);
}
});
listData.push({
srfmajortext: codeListItem.text,
type: 'GROUP',
expanded: false,
children: children
});
});
const otherGroupItems: IParam[] = [];
items.value.forEach((item: IParam) => {
if (codeListItems.findIndex((codeListItem: IParam) => codeListItem.value === item[groupField]) === -1) {
otherGroupItems.push(item);
}
});
if (otherGroupItems.length) {
listData.push({
srfmajortext: '其他',
type: 'GROUP',
expanded: false,
children: otherGroupItems
});
}
items.value = listData;
}
}
/**
* @description 默认选中
* @private
* @memberof ListControl
*/
private handleDefaultSelect() {
const { selectFirstDefault } = this.state;
const { selectedData, items } = toRefs(this.state);
if (selectFirstDefault) {
if (items.value && items.value.length > 0) {
selectedData.value.push(items.value[0]);
this.emit("ctrlEvent", {
tag: this.props.name,
action: "selectionChange",
data: [deepCopy(items.value[0])],
});
}
}
}
/** /**
* @description 触发界面行为 * @description 触发界面行为
* @protected * @protected
......
...@@ -36,6 +36,27 @@ export interface MDControlState extends MainControlState { ...@@ -36,6 +36,27 @@ export interface MDControlState extends MainControlState {
*/ */
isMultiple: boolean; isMultiple: boolean;
/**
* @description 多数据部件分组
* @type {IParam}
* @memberof MDControlState
*/
mdCtrlGroup: IParam;
/**
* @description 多数据部件排序
* @type {IParam}
* @memberof MDControlState
*/
mdCtrlSort: IParam;
/**
* @description 多数据部件分页
* @type {IParam}
* @memberof MDControlState
*/
mdCtrlPaging: IParam;
/** /**
* @description 行编辑状态 * @description 行编辑状态
* @type {boolean} * @type {boolean}
......
...@@ -31,6 +31,11 @@ body{ ...@@ -31,6 +31,11 @@ body{
display: flex; display: flex;
} }
.full-container {
width: 100%;
height: 100%;
}
// 去除antd 卡片自带样式 // 去除antd 卡片自带样式
.ant-card-body { .ant-card-body {
padding: 0; padding: 0;
......
...@@ -17,4 +17,20 @@ ...@@ -17,4 +17,20 @@
.app-list-item__selection { .app-list-item__selection {
background-color: #dcf4ff; background-color: #dcf4ff;
} }
.app-list-group-item .app-list-item {
padding-left: 12px;
}
.load-more {
text-align: center;
margin-top: 12px;
height: 32px;
line-height: 32px;
span {
text-decoration: underline;
color: #2d8cf0;
}
& button:hover {
background-color: transparent;
}
}
} }
\ No newline at end of file
...@@ -54,11 +54,59 @@ defineExpose({ name, state, newRow, remove, save, load, refresh, getData, export ...@@ -54,11 +54,59 @@ defineExpose({ name, state, newRow, remove, save, load, refresh, getData, export
item-layout="horizontal" item-layout="horizontal"
:data-source="state.items"> :data-source="state.items">
<template #loadMore> <template #loadMore>
<div :style="{ textAlign: 'center', marginTop: '12px', height: '32px', lineHeight: '32px' }"> <div class="load-more">
<a-button v-else @click="loadMore">加载更多</a-button> <a-button @click="loadMore" type="text">加载更多</a-button>
</div> </div>
</template> </template>
<template #renderItem="{ item }"> <template #renderItem="{ item }">
{{#if (and ctrl.enableGroup ctrl.groupPSAppDEField)}}
<a-list-item class="app-list-group-item">
<a-collapse :bordered="false" ghost class="full-container">
<a-collapse-panel :key="item.srfmajortext" :header="item.srfmajortext">
<a-list-item
v-for="child of item.children" :key="child.srfkey"
:class="['app-list-item', isSelected(child) ? 'app-list-item__selection' : '']"
@click="(event) => onListItemSelected(child, event)">
{{#if ctrl.itemPSLayoutPanel}}
<{{ctrl.itemPSLayoutPanel.codeName}}Panel
:context="state.context"
:viewParams="state.viewParams"
:navDatas="[child]"
panelType="LAYOUT">
</{{ctrl.itemPSLayoutPanel.codeName}}Panel>
{{else}}
<a-list-item-meta
:description="child.srfdescription">
<template #title>
<span class="text">\{{child.srfmajortext}}</span>
</template>
<template #avatar v-if="child.srficon">
<img :src="child.srficon" />
</template>
</a-list-item-meta>
<template #actions v-if="state.uIActions">
<div class="list-item__actions">
<template v-for="(action, index) of state.uIActions" :key="index">
<span
v-if="child[action.uIActionTag][0].visible"
:class="['list-item__action', child[action.uIActionTag][0].disabled ? 'disabled' : '']"
:title="action.tooltip ? action.tooltip : action.caption"
@click.stop="(event) => onUIAction(item, child[action.uIActionTag][0], event)">
<template v-if="action.showIcon">
<i v-if="action.cssClass" :class="action.cssClass" />
<img v-if="action.imagePath" :src="action.imagePath" />
</template>
<span v-if="action.showCaption" class="text">\{{action.caption}}</span>
</span>
</template>
</div>
</template>
{{/if}}
</a-list-item>
</a-collapse-panel>
</a-collapse>
</a-list-item>
{{else}}
<a-list-item <a-list-item
:class="['app-list-item', isSelected(item) ? 'app-list-item__selection' : '']" :class="['app-list-item', isSelected(item) ? 'app-list-item__selection' : '']"
@click="(event) => onListItemSelected(item, event)"> @click="(event) => onListItemSelected(item, event)">
...@@ -83,10 +131,10 @@ defineExpose({ name, state, newRow, remove, save, load, refresh, getData, export ...@@ -83,10 +131,10 @@ defineExpose({ name, state, newRow, remove, save, load, refresh, getData, export
<div class="list-item__actions"> <div class="list-item__actions">
<template v-for="(action, index) of state.uIActions" :key="index"> <template v-for="(action, index) of state.uIActions" :key="index">
<span <span
v-if="action.visible" v-if="item[action.uIActionTag][0].visible"
:class="['list-item__action', action.disabled ? 'disabled' : '']" :class="['list-item__action', item[action.uIActionTag][0].disabled ? 'disabled' : '']"
:title="action.tooltip ? action.tooltip : action.caption" :title="action.tooltip ? action.tooltip : action.caption"
@click.stop="(event) => onUIAction(item, action, event)"> @click.stop="(event) => onUIAction(item, item[action.uIActionTag][0], event)">
<template v-if="action.showIcon"> <template v-if="action.showIcon">
<i v-if="action.cssClass" :class="action.cssClass" /> <i v-if="action.cssClass" :class="action.cssClass" />
<img v-if="action.imagePath" :src="action.imagePath" /> <img v-if="action.imagePath" :src="action.imagePath" />
...@@ -98,6 +146,7 @@ defineExpose({ name, state, newRow, remove, save, load, refresh, getData, export ...@@ -98,6 +146,7 @@ defineExpose({ name, state, newRow, remove, save, load, refresh, getData, export
</template> </template>
{{/if}} {{/if}}
</a-list-item> </a-list-item>
{{/if}}
</template> </template>
</a-list> </a-list>
</template> </template>
......
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册