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

add:新增面板部件支持

上级 5e586c16
......@@ -14,6 +14,8 @@ import net.ibizsys.model.control.dashboard.IPSDBContainerPortletPart;
import net.ibizsys.model.control.dashboard.IPSDBPortletPart;
import net.ibizsys.model.control.grid.IPSDEGrid;
import net.ibizsys.model.control.grid.IPSDEGridColumn;
import net.ibizsys.model.control.list.IPSList;
import net.ibizsys.model.control.panel.IPSLayoutPanel;
import net.ibizsys.model.control.toolbar.IPSDETBUIActionItem;
import net.ibizsys.model.control.toolbar.IPSDEToolbar;
import net.ibizsys.model.view.IPSUIAction;
......@@ -202,6 +204,22 @@ public class CtrlModel extends BaseModel{
}
}
}
if (control instanceof IPSList) {
IPSList list = (IPSList)control;
IPSLayoutPanel layoutPanel = list.getItemPSLayoutPanel();
if (layoutPanel != null) {
CtrlModel ctrlModel = new CtrlModel(app, layoutPanel);
if (ctrlModel.getControl().getPSAppDataEntity() != null) {
AppEntityModel ctrlAppEntity = app.getAppEntity(ctrlModel.getControl().getPSAppDataEntity().getCodeName());
ctrlModel.setAppEntity(ctrlAppEntity);
ctrlAppEntity.addCtrl(ctrlModel.getId(), ctrlModel);
}
addCtrl(ctrlModel.getId(), ctrlModel);
if(!app.getCtrlsMap().containsKey(ctrlModel.getId())) {
app.getCtrlsMap().put(ctrlModel.getId(),ctrlModel);
}
}
}
}
public void handleAllPortlets(IPSControlContainer control) {
......
<AppSpan
{{#if (and (eq ctrlType 'grid') dataItemName)}}
name="{{dataItemName}}"
{{else}}
name="{{item.codeName}}"
{{/if}}
{{#eq ctrlType 'panel'}}
name="{{item.name}}"
:disabled="state.detailsModel.{{item.name}}.disabled"
{{/eq}}
{{#eq ctrlType 'form'}}
name="{{item.codeName}}"
{{/eq}}
{{#if (eq ctrlType 'form')}}
:disabled="state.detailsModel.{{item.codeName}}.disabled"
{{else if (eq ctrlType 'grid')}}
......
{{#eq type 'CONTAINER'}}{{> @macro/front-end/widgets/panel-detail/panel-container.hbs item=item}}{{/eq}}
{{#eq type 'BUTTON'}}{{> @macro/front-end/widgets/panel-detail/panel-button.hbs item=item}}{{/eq}}
{{#eq type 'FIELD'}}{{> @macro/front-end/widgets/panel-detail/panel-field.hbs item=item}}{{/eq}}
{{#eq type 'RAWITEM'}}{{> @macro/front-end/widgets/panel-detail/panel-rawitem.hbs item=item}}{{/eq}}
{{#eq type 'TABPANEL'}}{{> @macro/front-end/widgets/panel-detail/panel-tabpanel.hbs item=item}}{{/eq}}
{{#eq type 'TABPAGE'}}{{> @macro/front-end/widgets/panel-detail/panel-tabpage.hbs item=item}}{{/eq}}
{{#eq type 'CONTROL'}}{{> @macro/front-end/widgets/panel-detail/panel-control.hbs item=item}}{{/eq}}
\ No newline at end of file
<AppPanelContainer
caption="{{item.caption}}"
{{#if item.psSysCss}}
class="{{item.psSysCss.cssName}}"
{{/if}}
name="{{item.name}}"
:layoutOpts="{{> @macro/front-end/common/layoutPos.hbs layout=item.psLayout layoutPos=item.psLayoutPos}}"
:visible="state.detailsModel.{{item.name}}.visible"
{{#if (or item.width item.height)}}
style="{{#if item.width}}width: {{item.width}}px;{{/if}}{{#if item.height}}height: {{item.height}}px;{{/if}}"
{{/if}}
{{#if item.psSysImage.cssClass}}
iconClass="{{item.psSysImage.cssClass}}"
{{/if}}
{{#if item.psSysImage.imagePath}}
imgPath="{{item.psSysImage.imagePath}}"
{{/if}}
:showCaption="{{item.showCaption}}"
{{#if item.labelPSSysCss}}
labelCssName="{{item.labelPSSysCss.cssName}}"
{{/if}}
>
{{#if item.psPanelItems}}
{{#each item.psPanelItems as | childItem |}}
{{> @macro/front-end/widgets/panel-detail/include-panel.hbs item=childItem type=childItem.itemType}}
{{/each}}
{{/if}}
</AppPanelContainer>
{{item.name}}: {
{{#item}}
caption: '{{caption}}',
disabled: false,
tooltip: '{{tooltip}}',
name: '{{name}}',
itemType: '{{itemType}}',
visible: true,
{{#if (and (eq itemType 'BUTTON') psUIAction)}}
{{#psUIAction}}
uIAction: {
actionTarget: '{{actionTarget}}',
dataAccessAction: '{{dataAccessAction}}',
noPrivDisplayMode: '{{noPrivDisplayMode}}'
uIActionType: '{{uIActionType}}',
uIActionTag: '{{uIActionTag}}',
uIActionMode: '{{uIActionMode}}',
}
{{/psUIAction}}
{{/if}}
{{/item}}
},
{{#if item.psPanelItems}}
{{#each item.psPanelItems as | childItem |}}
{{> @macro/front-end/widgets/panel-detail/panel-detail-model.hbs item=childItem}}
{{/each}}
{{/if}}
{{#if item.psPanelTabPages}}
{{#each item.psPanelTabPages as | tabPage |}}
{{#if tabPage.psPanelItems}}
{{#each tabPage.psPanelItems as | tabPanel |}}
{{> @macro/front-end/widgets/panel-detail/panel-detail-model.hbs item=tabPanel}}
{{/each}}
{{/if}}
{{/each}}
{{/if}}
<AppPanelField
{{#if item.caption}}
caption="{{item.caption}}"
{{/if}}
{{#if item.psSysCss}}
class="{{item.psSysCss.cssName}}"
{{/if}}
name="{{item.name}}"
:layoutOpts="{{> @macro/front-end/common/layoutPos.hbs layout=item.psLayout layoutPos=item.psLayoutPos}}"
:visible="state.detailsModel.{{item.name}}.visible"
{{#if (or item.width item.height)}}
style="{{#if item.width}}width: {{item.width}}px;{{/if}}{{#if item.height}}height: {{item.height}}px;{{/if}}"
{{/if}}
{{#if item.psSysImage.cssClass}}
iconClass="{{item.psSysImage.cssClass}}"
{{/if}}
{{#if item.psSysImage.imagePath}}
imgPath="{{item.psSysImage.imagePath}}"
{{/if}}
:showCaption="{{item.showCaption}}"
{{#if item.labelPSSysCss}}
labelCssName="{{item.labelPSSysCss.cssName}}"
{{/if}}
{{#if item.labelPos}}
labelPos="{{item.labelPos}}"
{{/if}}
>
{{#if item.psEditor}}
<div class="panel-editor-container" style="{{#if item.psEditor.editorWidth}}width: {{item.psEditor.editorWidth}}px;{{/if}}{{#if item.psEditor.editorHeight}}height: {{item.psEditor.editorHeight}}px{{/if}}">
{{> @macro/front-end/editors/include-editor.hbs type=item.psEditor.editorType item=item ctrlType="panel"}}
</div>
{{/if}}
</AppPanelField>
<script setup lang="ts">
import { ILayoutOpts } from "@core";
// 输入参数
interface IProps {
caption?: string
name: string;
layoutOpts: ILayoutOpts;
visible: boolean;
showCaption?: boolean
}
const props = withDefaults(defineProps<IProps>(), {
showCaption: true
});
</script>
<template>
<AppCol :layoutOpts="layoutOpts">
<slot></slot>
</AppCol>
</template>
\ No newline at end of file
<script setup lang="ts">
interface IProps {
caption?: string;
name: string;
iconClass?: string;
imgPath?: string;
showCaption?: boolean;
labelCssName?: string;
labelPos?: string | 'LEFT' | 'TOP' | 'RIGHT' | 'BOTTOM' | 'NONE';
visible: boolean;
}
const props = withDefaults(defineProps<IProps>(), {
showCaption: true
});
</script>
<template>
<AppCol :layoutOpts="layoutOpts">
<div class="app-panel-field">
<slot></slot>
</div>
</AppCol>
</template>
\ No newline at end of file
......@@ -44,13 +44,19 @@ export interface ControlStateBase {
viewSubject: Subject<IActionParam>;
/**
* 父容器
*
* @description 父容器
* @type {*}
* @memberof ControlStateBase
*/
parent: any;
/**
* @description 导航数据
* @type {any[]}
* @memberof ControlStateBase
*/
navDatas?: any[];
// 声明任意属性
[propName: string]: any;
}
\ No newline at end of file
......@@ -16,3 +16,4 @@ export * from './portlet-control'
export * from './tab-exp-panel-control'
export * from './tab-view-panel-control'
export * from './list-control'
export * from './panel-control'
import { IParam } from "@core";
import { ListControlState } from "./list-control-state";
import { MDControl } from "../md-control";
/**
......@@ -9,6 +10,13 @@ import { MDControl } from "../md-control";
*/
export class ListControl extends MDControl {
/**
* @description 部件状态
* @type {ListControlState}
* @memberof ListControl
*/
public declare state: ListControlState;
/**
* @description 触发界面行为
* @protected
......
export * from './panel-control-prop'
export * from './panel-control-state'
export * from './panel-control'
\ No newline at end of file
import { MainControlProps } from "../main-control";
/**
* @description 面板部件输入参数
* @export
* @interface PanelControlProps
* @extends {MainControlProps}
*/
export interface PanelControlProps extends MainControlProps {
}
\ No newline at end of file
import { MainControlState } from "../main-control";
/**
* @description 面板部件状态
* @export
* @interface PanelControlState
* @extends {MainControlState}
*/
export interface PanelControlState extends MainControlState {
}
\ No newline at end of file
import { IActionParam, IParam } from "@core";
import { MainControl } from "../main-control";
import { PanelControlState } from "./panel-control-state";
/**
* @description 面板部件
* @export
* @class PanelControl
* @extends {MainControl}
*/
export class PanelControl extends MainControl {
/**
* @description 部件状态
* @type {FormControlState}
* @memberof PanelControl
*/
public declare state: PanelControlState;
/**
* @description 处理导航数据模块
* @protected
* @memberof PanelControl
*/
protected useNavDatas() {
const navDatas: any = toRef(this.props, 'navDatas');
if (this.props.panelType === 'LAYOUT') {
this.load();
}
watch(navDatas, (newVal: any, oldVal: any) => {
this.load();
});
this.state.navDatas = navDatas;
}
/**
* @description 数据加载
* @protected
* @param {IParam} [opts={}]
* @memberof PanelControl
*/
protected async load(opts: IParam = {}) { }
/**
* @description 使用数据加载模块
* @memberof PanelControl
*/
public useLoad() {
const { viewSubject, controlName } = this.state;
const load = async (opts: IParam = {}) => {
const { dataMode } = this.state;
const { navDatas, data } = toRefs(this.state);
if (dataMode === 0) {
// 不获取,使用传入数据
if (navDatas && navDatas.value && navDatas.value.length) {
data.value = navDatas.value[0];
console.log(data.value);
}
} else if (dataMode === 1) {
// 存在传入数据时,不获取
if (navDatas && navDatas.value && navDatas.value.length) {
data.value = navDatas.value[0];
} else {
await this.loadPanelData(opts);
}
} else if (dataMode === 2) {
// 始终获取
await this.loadPanelData(opts);
}
}
this.load = load;
// 订阅viewSubject,监听load行为
if (viewSubject) {
let subscription = viewSubject.subscribe(({ tag, action, data }: IActionParam) => {
if (Object.is(controlName, tag) && Object.is('load', action)) {
load(data);
}
});
// 部件卸载时退订viewSubject
onUnmounted(() => {
subscription.unsubscribe();
});
}
return load;
}
private loadPanelData(opts: IParam = {}) {
}
/**
* @description 安装部件所有功能模块的方法
* @return {*}
* @memberof PanelControl
*/
public moduleInstall() {
const superParams = super.moduleInstall();
this.useNavDatas();
return {
...superParams,
load: this.useLoad(),
}
}
}
\ No newline at end of file
......@@ -2,6 +2,11 @@
import { Subject } from 'rxjs';
import { ctrlState } from './{{spinalCase ctrl.codeName}}-list-state';
import { ListControl, IActionParam, IParam, IContext, ControlAction, deepCopy } from '@core';
{{#if ctrl.itemPSLayoutPanel}}
{{#ctrl.itemPSLayoutPanel}}
import { {{codeName}}Panel } from '@widgets/{{spinalCase psAppDataEntity.codeName}}/{{spinalCase codeName}}-panel';
{{/ctrl.itemPSLayoutPanel}}
{{/if}}
{{#if ctrl.batchToolBarItems}}
import AppToolbar from '@components/common/app-toolbar.vue';
{{/if}}
......@@ -51,6 +56,14 @@ defineExpose({ name, state, newRow, remove, save, load, refresh, getData, export
<a-list-item
:class="['app-list-item', isSelected(item) ? 'app-list-item__selection' : '']"
@click="(event) => onListItemSelected(item, event)">
{{#if ctrl.itemPSLayoutPanel}}
<{{ctrl.itemPSLayoutPanel.codeName}}Panel
:context="state.context"
:viewParams="state.viewParams"
:navDatas="[item]"
panelType="LAYOUT">
</{{ctrl.itemPSLayoutPanel.codeName}}Panel>
{{else}}
<a-list-item-meta
:description="item.srfdescription">
<template #title>
......@@ -77,6 +90,7 @@ defineExpose({ name, state, newRow, remove, save, load, refresh, getData, export
</template>
</div>
</template>
{{/if}}
</a-list-item>
</template>
</a-list>
......
import {{ctrl.codeName}}Panel from "./{{spinalCase ctrl.codeName}}-panel.vue";
export { {{ctrl.codeName}}Panel };
export const ctrlState = {
controlCodeName: '{{ctrl.codeName}}',
controlName: '{{ctrl.name}}',
appEntityCodeName: '{{ctrl.psAppDataEntity.codeName}}',
appDeCodeName:'{{ctrl.psAppDataEntity.codeName}}',
appDeLogicName: '{{ctrl.psAppDataEntity.logicName}}',
appDeKeyFieldName: '{{#if ctrl.psAppDataEntity.keyPSAppDEField}}{{ctrl.psAppDataEntity.keyPSAppDEField.codeName}}{{/if}}',
appDeMajorFieldName: '{{#if ctrl.psAppDataEntity.majorPSAppDEField}}{{ctrl.psAppDataEntity.majorPSAppDEField.codeName}}{{/if}}',
data: {},
dataMode: {{ctrl.dataMode}},
detailsModel: {
{{#each ctrl.rootPSPanelItems as | panelItem |}}
{{> @macro/front-end/widgets/panel-detail/panel-detail-model.hbs item=panelItem}}
{{/each}}
},
navDatas: []
}
\ No newline at end of file
<script setup lang="ts">
import { Subject } from 'rxjs';
import { ctrlState } from './{{spinalCase ctrl.codeName}}-panel-state';
import { PanelControl, IActionParam, IParam, ControlAction, IContext } from '@core';
interface Props {
name:string,
parent: IParam;
context: IContext;
navDatas?: IParam[];
viewParams?: IParam;
controlAction: ControlAction;
showBusyIndicator?: boolean;
viewSubject: Subject<IActionParam>;
panelType?: 'DEFAULT' | 'LAYOUT' | string;
}
const props = withDefaults(defineProps < Props > (), {
viewSubject: () => new Subject < IActionParam > (),
showBusyIndicator: true,
panelType: 'DEFAULT'
})
// emit声明
interface CtrlEmit {
(name: "ctrlEvent", value: IActionParam): void;
}
const emit = defineEmits <CtrlEmit> ();
// 安装功能模块,提供状态和能力方法
const { name, state, load, loadDraft, save, remove, refresh, onEditorEvent, onComponentEvent, getData, xDataCtrl } = new PanelControl(ctrlState, props, emit).moduleInstall();
// 暴露内部状态及能力
defineExpose({ name, state, load, loadDraft, save, remove, refresh, getData });
</script>
<template>
<AppRow
:class="[
'app-panel',
{{#eq ctrl.layoutMode 'FLEX'}}
'has-flex',
{{/eq}}
panelType === 'LAYOUT' ? 'app-layout-panel' : '',
{{#if ctrl.psSysCss}}
'{{ctrl.psSysCss.cssName}}'
{{/if}}
]"
:layoutOpts="{{> @macro/front-end/common/layoutPos.hbs layout=ctrl.psLayout layoutPos=ctrl.psLayoutPos}}"
>
{{#each ctrl.rootPSPanelItems as | panelItem |}}
{{> @macro/front-end/widgets/panel-detail/include-panel.hbs item=panelItem type=panelItem.itemType}}
{{/each}}
</AppRow>
</template>
<style lang="scss">
</style>
\ No newline at end of file
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册