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

add:新增树导航视图、树导航栏、树部件支持

上级 1ac02701
......@@ -8,6 +8,10 @@ import lombok.experimental.Accessors;
import net.ibizsys.model.control.IPSControl;
import net.ibizsys.model.control.layout.IPSGridLayoutPos;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
@Getter
@Setter
@NoArgsConstructor
......@@ -30,12 +34,26 @@ public class CtrlModel extends BaseModel{
}
public Map<String,CtrlModel> ctrlsMap = new LinkedHashMap();
private AppModel app;
private AppEntityModel appEntity;
private LabelExt folder;
public CtrlModel addCtrl(String codeName,CtrlModel ctrlModel)
{
if(!ctrlsMap.containsKey(codeName))
ctrlsMap.put(codeName,ctrlModel);
return this;
}
public Collection<CtrlModel> getCtrls()
{
return ctrlsMap.values();
}
public IPSControl getControl()
{
return (IPSControl)opt;
......
......@@ -7,6 +7,8 @@ import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;
import net.ibizsys.model.app.view.IPSAppView;
import net.ibizsys.model.control.IPSControl;
import net.ibizsys.model.control.expbar.IPSExpBar;
import net.ibizsys.model.control.toolbar.IPSDETBUIActionItem;
import net.ibizsys.model.control.toolbar.IPSDEToolbar;
import net.ibizsys.model.view.IPSUIAction;
......@@ -44,6 +46,23 @@ public class PageModel extends BaseModel{
this.app.getCtrlsMap().put(ctrl.getId(),ctrl);
this.ctrlsMap.put(ctrl.getCodeName().toString(),ctrl);
}
if ("TREEEXPBAR".equals(ctrl.getControl().getControlType())) {
List<IPSControl> controls = ((IPSExpBar)item).getPSControls();
if (controls.size() > 0) {
for (IPSControl control : controls) {
CtrlModel ctrlModel = new CtrlModel(appModel, control);
if(ctrlModel.getControl().getPSAppDataEntity()!=null) {
AppEntityModel ctrlAppEntity = app.getAppEntity(ctrlModel.getControl().getPSAppDataEntity().getCodeName());
ctrlModel.setAppEntity(ctrlAppEntity);
ctrlAppEntity.addCtrl(ctrlModel.getCodeName().toString(), ctrlModel);
}
ctrl.addCtrl(ctrlModel.getCodeName().toString(), ctrlModel);
if(!this.app.getCtrlsMap().containsKey(ctrl.getId())) {
this.app.getCtrlsMap().put(ctrl.getId(),ctrl);
}
}
}
}
});
}
// 初始化工具栏数据
......
<script setup lang="ts">
</script>
<template>
<IbizViewBaseLayout>
<template v-slot:header-left>
<slot name="caption" />
</template>
<template v-slot:header-right>
<slot name="toolbar" />
</template>
<template v-slot:header-bottom>
<slot name="topMessage" />
<slot name="searchForm" />
</template>
<template v-slot:body-top>
<slot name="bodyMessage" />
</template>
<slot />
<template v-slot:footer-content>
<slot name="bottomMessage" />
</template>
</IbizViewBaseLayout>
</template>
<style lang="scss">
</style>
\ No newline at end of file
import { MainViewProps } from "@core";
/**
* @description 导航视图props
* @export
* @interface ExpViewProps
* @extends {MainViewProps}
*/
export interface ExpViewProps extends MainViewProps { }
\ No newline at end of file
import { MainViewState } from '@core';
/**
* @description 导航视图基类状态
* @export
* @interface ExpViewState
* @extends {MainViewState}
*/
export interface ExpViewState extends MainViewState { }
import { MainView } from "@core";
import { ExpViewProps } from "./exp-view-prop";
import { ExpViewState } from "./exp-view-state";
/**
* @description 导航视图基类
* @export
* @class ExpView
* @extends {MainView}
*/
export class ExpView extends MainView {
/**
* @description 视图状态
* @type {ExpViewState}
* @memberof ExpView
*/
public declare viewState: ExpViewState;
/**
* @description 使用加载功能模块
* @param {ExpViewProps} props 传入的props
* @memberof ExpView
*/
public useLoad(props: ExpViewProps) {
const { viewSubject } = this.viewState;
}
/**
* @description 安装视图所有功能模块的方法
* @param {ExpViewProps} props 传入的Props
* @param {Function} [emit] [emit] 事件
* @return {*}
* @memberof ExpView
*/
public moduleInstall(props: ExpViewProps, emit?: Function) {
const superParams = super.moduleInstall(props, emit);
this.useLoad(props);
return {
...superParams,
state: this.viewState
};
}
}
\ No newline at end of file
export * from './exp-view-prop';
export * from './exp-view-state';
export { ExpView } from './exp-view';
\ No newline at end of file
export * from './view-base'
export * from './main-view'
export * from './exp-view'
export * from './edit-view'
export * from './index-view'
export * from './grid-view'
export * from './pickup-view'
export * from './pickup-grid-view'
\ No newline at end of file
export * from './pickup-grid-view'
export * from './tree-exp-view'
\ No newline at end of file
export * from './tree-exp-view-prop';
export * from './tree-exp-view-state';
export { TreeExpView } from './tree-exp-view';
\ No newline at end of file
import { ExpViewProps } from "@core";
/**
* @description 树导航视图props
* @export
* @interface TreeExpViewProps
* @extends {ExpViewProps}
*/
export interface TreeExpViewProps extends ExpViewProps {}
import { ExpViewState } from "@core";
/**
* @description 树导航视图状态
* @export
* @interface TreeExpViewState
* @extends {ExpViewState}
*/
export interface TreeExpViewState extends ExpViewState {}
\ No newline at end of file
import { ExpView } from "@core";
import { TreeExpViewProps } from "./tree-exp-view-prop";
import { TreeExpViewState } from "./tree-exp-view-state";
/**
* @description 树导航视图
* @export
* @class TreeExpView
* @extends {ExpView}
*/
export class TreeExpView extends ExpView {
/**
* @description 视图状态
* @type {TreeExpViewState}
* @memberof TreeExpView
*/
public declare viewState: TreeExpViewState;
/**
* @description 使用加载功能模块
* @param {TreeExpViewProps} props 传入的props
* @memberof TreeExpView
*/
public useLoad(props: TreeExpViewProps) {
const { viewSubject } = this.viewState;
onMounted(() => {
viewSubject.next({ tag: 'grid', action: "load", data: {} })
})
}
/**
* @description 安装视图所有功能模块的方法
* @param {TreeExpViewProps} props 传入的Props
* @param {Function} [emit] [emit] 事件
* @return {*}
* @memberof TreeExpView
*/
public moduleInstall(props: TreeExpViewProps, emit?: Function) {
this.emit = emit;
const superParams = super.moduleInstall(props, emit);
this.useLoad(props);
return {
...superParams,
handleCtrlEvent: this.handleCtrlEvent.bind(this),
state: this.viewState,
};
}
}
\ No newline at end of file
import { MainControlProps } from "@core";
/**
* @description 导航部件props
* @export
* @interface ExpBarControlProps
* @extends {MainControlProps}
*/
export interface ExpBarControlProps extends MainControlProps { }
\ No newline at end of file
import { MainControlState } from "@core";
/**
* @description 导航栏部件通讯对象
* @export
* @interface ExpBarControlState
* @extends {MainControlState}
*/
export interface ExpBarControlState extends MainControlState { }
\ No newline at end of file
import { MainControl } from "@core";
import { ExpBarControlProps } from "./exp-bar-control-prop";
import { ExpBarControlState } from "./exp-bar-control-state";
/**
* @description 导航栏部件
* @export
* @class ExpBarControl
* @extends {MainControl}
*/
export class ExpBarControl extends MainControl {
/**
* @description 部件状态
* @type {ExpBarControlState}
* @memberof ExpBarControl
*/
public declare controlState: ExpBarControlState;
/**
* @description 使用加载功能模块
* @param {ExpBarControlProps} props 传入的props
* @memberof ExpBarControl
*/
public useLoad(props: ExpBarControlProps) {
}
/**
* @description 安装部件所有功能模块的方法
* @param {ExpBarControlProps} props 传入的Props
* @param {Function} [emit]
* @return {*}
* @memberof ExpBarControl [emit] 事件
*/
public moduleInstall(props: ExpBarControlProps, emit?: Function) {
const superParams = super.moduleInstall(props, emit);
return {
...superParams,
state: this.controlState,
};
}
}
\ No newline at end of file
export * from './exp-bar-control-prop';
export * from './exp-bar-control-state';
export { ExpBarControl } from './exp-bar-control';
\ No newline at end of file
export * from './control-base'
export * from './main-control'
export * from './exp-bar-control'
export * from './form-control'
export * from './menu-control'
export * from './grid-control'
export * from './pickupviewpanel-control'
\ No newline at end of file
export * from './pickupviewpanel-control'
export * from './tree-exp-bar-control'
export * from './tree-control'
\ No newline at end of file
export * from './tree-control-prop';
export * from './tree-control-state';
export { TreeControl } from './tree-control';
\ No newline at end of file
import { MainControlProps } from "@core";
/**
* @description 树部件props
* @export
* @interface TreeControlProps
* @extends {MainControlProps}
*/
export interface TreeControlProps extends MainControlProps {}
\ No newline at end of file
import { MainControlState } from "@core";
/**
* @description 树部件通讯对象
* @export
* @interface TreeControlState
* @extends {MainControlState}
*/
export interface TreeControlState extends MainControlState {
}
\ No newline at end of file
import { MainControl } from "@core";
import { TreeControlProps } from "./tree-control-prop";
import { TreeControlState } from "./tree-control-state";
/**
* @description 树部件
* @export
* @class TreeControl
* @extends {MainControl}
*/
export class TreeControl extends MainControl {
/**
* @description 部件状态
* @type {TreeControlState}
* @memberof TreeControl
*/
public declare controlState: TreeControlState;
/**
* @description 使用加载功能模块
* @param {TreeControlProps} props 传入的props
* @return {*}
* @memberof TreeControl
*/
public useLoad(props: TreeControlProps) {
const { viewSubject, controlName } = this.controlState;
const load = async (opt: any = {}) => {
}
return {
load
};
}
/**
* @description 安装部件所有功能模块的方法
* @param {TreeControlProps} props 传入的Props
* @param {Function} [emit]
* @return {*}
* @memberof TreeControl [emit] 事件
*/
public moduleInstall(props: TreeControlProps, emit?: Function) {
const superParams = super.moduleInstall(props, emit);
const { load } = this.useLoad(props);
return {
...superParams,
state: this.controlState,
load
};
}
}
\ No newline at end of file
export * from './tree-exp-bar-control-prop';
export * from './tree-exp-bar-control-state';
export { TreeExpBarControl } from './tree-exp-bar-control';
\ No newline at end of file
import { ExpBarControlProps } from "@core";
/**
* @description 树导航栏部件props
* @export
* @interface TreeExpBarControlProps
* @extends {ExpBarControlProps}
*/
export interface TreeExpBarControlProps extends ExpBarControlProps { }
\ No newline at end of file
import { ExpBarControlState } from "@core";
/**
* @description 树导航栏部件通讯对象
* @export
* @interface TreeExpBarControlState
* @extends {ExpBarControlState}
*/
export interface TreeExpBarControlState extends ExpBarControlState {
/**
* @description 过滤属性
* @type {string}
* @memberof TreeExpBarControlState
*/
srfnodefilter: string;
}
\ No newline at end of file
import { deepCopy, deepObjectMerge, ExpBarControl, IParam } from "@core";
import { TreeExpBarControlProps } from "./tree-exp-bar-control-prop";
import { TreeExpBarControlState } from "./tree-exp-bar-control-state";
/**
* @description 导航栏部件
* @export
* @class TreeExpBarControl
* @extends {ExpBarControl}
*/
export class TreeExpBarControl extends ExpBarControl {
/**
* @description 部件状态
* @type {ExpBarControlState}
* @memberof TreeExpBarControl
*/
public declare controlState: TreeExpBarControlState;
/**
* @description 选中数据
* @private
* @type {IParam}
* @memberof TreeExpBarControl
*/
private selection: IParam = {};
private computecurNodeContext(curNode: any) {
const { context } = this.controlState;
let tempContext: any = {};
if (curNode && curNode.data && curNode.data.srfappctx) {
tempContext = deepCopy(curNode.data.srfappctx);
} else {
tempContext = deepCopy(context);
}
return tempContext;
}
/**
* @description 使用加载功能模块
* @param {TreeExpBarControlProps} props 传入的props
* @memberof TreeExpBarControl
*/
public useLoad(props: TreeExpBarControlProps) {
const load = async (node: IParam) => {
console.log(1111, node);
if (node.dataRef.children) {
return null;
}
const {
controlService, context, viewParams, srfnodefilter
} = this.controlState;
let tempViewParams: any = deepCopy(viewParams);
let curNode: any = {};
curNode = deepObjectMerge(curNode, node);
const params: any = {
srfnodeid: node.data && node.data.id ? node.data.id : '#',
srfnodefilter: srfnodefilter,
parentData: curNode.data?.curData
}
let tempContext: any = this.computecurNodeContext(curNode);
}
return {
load
}
}
/**
* @description 安装部件所有功能模块的方法
* @param {TreeExpBarControlProps} props 传入的Props
* @param {Function} [emit]
* @return {*}
* @memberof TreeExpBarControl [emit] 事件
*/
public moduleInstall(props: TreeExpBarControlProps, emit?: Function) {
const superParams = super.moduleInstall(props, emit);
const { load } = this.useLoad(props);
return {
...superParams,
selection: this.selection,
load
};
}
}
\ No newline at end of file
......@@ -10,6 +10,23 @@ export function deepCopy(data: Record<any, any>): Record<any, any>{
return clone(data)
}
/**
* @description 深度合并对象
* @export
* @param {*} FirstOBJ 目标对象
* @param {*} SecondOBJ 源对象
* @return {*}
*/
export function deepObjectMerge(FirstOBJ: any, SecondOBJ: any) {
for (var key in SecondOBJ) {
FirstOBJ[key] =
FirstOBJ[key] && FirstOBJ[key].toString() === '[object Object]'
? deepObjectMerge(FirstOBJ[key], SecondOBJ[key])
: (FirstOBJ[key] = SecondOBJ[key]);
}
return FirstOBJ;
}
/**
* @description 日期格式化
* @export
......
import {{page.codeName}} from "./{{spinalCase page.codeName}}.vue";
export default {{page.codeName}};
export const ViewConfig = {
{{> @macro/front-end/view/common/viewBaseConfig.hbs}}
};
\ No newline at end of file
<script setup lang="ts">
import { Subject } from 'rxjs';
import { TreeExpView, IActionParam, IParam, IContext } from '@core';
import { ViewConfig } from './{{spinalCase page.codeName}}-config';
{{#page.ctrls}}
{{#eq controlType "TREEEXPBAR"}}
import { {{codeName}}TreeExpBar } from '@widgets/{{spinalCase appEntity.codeName}}/{{spinalCase codeName}}-tree-exp-bar';
{{/eq}}
{{/page.ctrls}}
interface Props {
context: IContext;
viewParams?: IParam;
openType?: "ROUTE" | "MODAL" | "EMBED";
viewSubject?: Subject<IActionParam>;
}
const props = withDefaults(defineProps<Props>(), {
openType:'ROUTE',
viewSubject: () => new Subject<IActionParam>()
})
interface ViewEmit {
(name: "viewEvent", value: IActionParam): void;
}
const emit = defineEmits<ViewEmit>();
// 安装功能模块
const { state } = new TreeExpView(ViewConfig).moduleInstall(props, emit);
</script>
<template>
<IbizTreeExpViewLayout class="ibiz-tree-exp-view">
<template v-slot:caption>
<IbizIconText class="ibiz-view__caption" size="large" :text="state.viewCaption" />
</template>
{{#page.ctrls}}
{{#eq controlType "TOOLBAR"}}
<template v-slot:toolbar>
<IbizToolbar
mode="button"
name="{{lowerCase codeName}}"
:actionModel="state.toolbar"
@toolbarEvent="handleToolbarEvent"/>
</template>
{{/eq}}
{{#eq controlType "TREEEXPBAR"}}
<{{codeName}}TreeExpBar
:context="state.context"
:showBusyIndicator="true"
:viewParams="state.viewParams"
:controlAction="state.controlsAction.{{name}}"
:viewSubject="state.viewSubject"
@ctrlEvent="handleCtrlEvent"
></{{codeName}}TreeExpBar>
{{/eq}}
{{/page.ctrls}}
</IbizTreeExpViewLayout>
</template>
\ No newline at end of file
......@@ -17,7 +17,7 @@ const routes = [
{{#each app.appEntityResources as |appEntityResource|}}
{{#if appEntityResource.appDataEntity.allPSAppViews}}
{{#each appEntityResource.appDataEntity.allPSAppViews as |appView|}}
{{#if (or (eq appView.viewType 'DEEDITVIEW') (eq appView.viewType 'DEGRIDVIEW'))}}
{{#if (or (eq appView.viewType 'DEEDITVIEW') (eq appView.viewType 'DEGRIDVIEW') (eq appView.viewType 'DETREEEXPVIEW'))}}
{
path: "{{appEntityResource.path}}/views/{{lowerCase appView.codeName}}",
meta: {
......
import {{ctrl.codeName}}TreeExpBar from "./{{spinalCase ctrl.codeName}}-tree-exp-bar.vue";
export { {{ctrl.codeName}}TreeExpBar };
<script setup lang="ts">
import { Subject } from 'rxjs';
import { IActionParam, IParam, ControlAction, TreeExpBarControl, IContext } from '@core';
import { CtrlConfig } from './{{spinalCase ctrl.codeName}}-tree-exp-bar-config';
{{#ctrl.ctrls}}
{{#eq controlType "TREEVIEW"}}
import { {{codeName}}Tree} from '@widgets/{{spinalCase appEntity.codeName}}/{{spinalCase codeName}}-tree';
{{/eq}}
{{/ctrl.ctrls}}
interface Props {
context: IContext;
viewParams?: IParam;
controlAction: ControlAction;
showBusyIndicator?: boolean;
viewMode?: number;
viewSubject: Subject<IActionParam>;
}
const props = withDefaults(defineProps < Props > (), {
viewSubject: () => new Subject < IActionParam > (),
viewMode: 0,
showBusyIndicator: true,
});
interface CtrlEmit {
(name: "ctrlEvent", value: IActionParam): void;
}
const emit = defineEmits < CtrlEmit > ();
// 安装功能模块,提供状态和能力方法
const { state, selection } = new TreeExpBarControl(CtrlConfig).moduleInstall(props, emit);
</script>
<template>
<a-layout
class="ibiz-tree-exp-bar{{#if ctrl.psSysCss}} {{ctrl.psSysCss.cssName}}{{/if}}"
>
<a-layout-sider>
{{#ctrl.ctrls}}
{{#eq controlType "TREEVIEW"}}
<{{codeName}}Tree>
</{{codeName}}Tree>
{{/eq}}
{{/ctrl.ctrls}}
</a-layout-sider>
<a-layout>
<component
v-if="selection.view && !Object.is(this.selection.view.viewname, '')"
:is="selection.view.viewname"
:viewDefaultUsage="false"
:viewdata="JSON.stringify(selection.context)"
:viewParam="JSON.stringify(selection.viewParam)">
</component>
</a-layout>
</a-layout>
</template>
\ No newline at end of file
import {{ctrl.codeName}}Tree from "./{{spinalCase ctrl.codeName}}-tree.vue";
export { {{ctrl.codeName}}Tree };
export const CtrlConfig = {
controlCodeName: '{{ctrl.codeName}}',
controlName: '{{ctrl.name}}',
};
\ No newline at end of file
<script setup lang="ts">
import { Subject } from 'rxjs';
import { IActionParam, IParam, ControlAction, TreeControl, IContext } from '@core';
import { CtrlConfig } from './{{spinalCase ctrl.codeName}}-tree-config';
interface Props {
context: IContext;
multiple: boolean;
selectedData: IParam[];
selectFirstDefault: boolean;
viewParams?: IParam;
controlAction: ControlAction;
showBusyIndicator?: boolean;
viewSubject: Subject<IActionParam>;
}
const props = withDefaults(defineProps<Props>(), {
viewSubject: () => new Subject<IActionParam>(),
showBusyIndicator: true,
selectFirstDefault: false,
})
// emit声明
interface CtrlEmit {
(name: "ctrlEvent", value: IActionParam): void;
}
const emit = defineEmits<CtrlEmit>();
// 安装功能模块,提供状态和能力方法
const { state, load } = new TreeControl(CtrlConfig).moduleInstall(props, emit);
</script>
<template>
<a-tree
class="ibiz-tree{{#if ctrl.psSysCss}} {{ctrl.psSysCss.cssName}}{{/if}}"
:tree-data="state.data">
</a-tree>
</template>
\ No newline at end of file
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册