提交 5d89de7e 编写于 作者: WodahsOrez's avatar WodahsOrez

update: 门户

上级 3cb85367
......@@ -9,6 +9,7 @@ import net.ibizsys.model.app.view.IPSAppViewRef;
import net.ibizsys.model.control.IPSControl;
import net.ibizsys.model.control.IPSControlContainer;
import net.ibizsys.model.control.dashboard.IPSDBContainerPortletPart;
import net.ibizsys.model.control.dashboard.IPSDBPortletPart;
import java.util.Collection;
import java.util.LinkedHashMap;
......@@ -46,10 +47,15 @@ public class CtrlModel extends BaseModel{
}
}
handleChildControls();
if("DASHBOARD".equals( getControl().getControlType())){
handleAllPortlets((IPSControlContainer)getControl());
}
}
public Map<String,CtrlModel> ctrlsMap = new LinkedHashMap();
public Map<String,IPSControl> portletsMap = new LinkedHashMap();
private AppModel app;
private AppEntityModel appEntity;
......@@ -70,6 +76,11 @@ public class CtrlModel extends BaseModel{
return ctrlsMap.values();
}
public Collection<IPSControl> getAllPortlets()
{
return portletsMap.values();
}
public IPSControl getControl()
{
return (IPSControl)opt;
......@@ -110,6 +121,21 @@ public class CtrlModel extends BaseModel{
}
}
public void handleAllPortlets(IPSControlContainer control) {
List<IPSControl> controls = control.getPSControls();
if (controls != null && controls.size() > 0) {
for (IPSControl _control : controls) {
if("CONTAINER".equals( ((IPSDBPortletPart)_control).getPortletType() )){
this.handleAllPortlets((IPSControlContainer)_control);
}else{
if(!this.portletsMap.containsKey(_control.getCodeName())) {
this.portletsMap.put(_control.getCodeName(),_control);
}
}
}
}
}
// 忽略发布
public Boolean ignore() {
IPSControl control = getControl();
......
<AppPortletCard
name={{portlet.name}}
:isContainer="true"
{{#if portlet.caption}}
title="{{portlet.caption}}"
{{/if}}
:showCaption="{{portlet.isShowTitleBar}}"
{{#if portlet.psSysImage}}
{{#if portlet.psSysImage.imagePath}}imgPath="{{portlet.psSysImage.imagePath}}"{{else if portlet.psSysImage.cssClass}}iconClass="{{portlet.psSysImage.cssClass}}"{{/if}}
{{/if}}
:layoutOpts="{{> @macro/front-end/common/layoutPos.hbs layout=portlet.psLayout layoutPos=portlet.psLayoutPos}}"
class="app-portletContainer {{portlet.psSysCss.cssName}}"
{{#if (or portlet.width portlet.height)}}
style="{{#if portlet.width}}width: {{portlet.width}}px;{{/if}}{{#if portlet.height}}height: {{portlet.height}}px;{{/if}}"
{{/if}}
>
{{#each portlet.psControls as | subPortlet | }}
{{#eq subPortlet.portletType 'CONTAINER'}}
{{>(lookup 'PORTLET_CONTAINER') portlet=subPortlet}}
{{else}}
{{>(lookup 'PORTLET') portlet=subPortlet}}
{{/eq}}
{{/each}}
</AppPortletCard>
{{#*inline "DASHBOARD"}}{{>@macro/front-end/widgets/dashboard-detail/dashboard.hbs}}{{/inline}}
{{#*inline "CONTAINER"}}{{>@macro/front-end/widgets/dashboard-detail/portlet-container.hbs}}{{/inline}}
\ No newline at end of file
{{#*inline "PORTLET_CONTAINER"}}{{>@macro/front-end/widgets/dashboard-detail/container.hbs}}{{/inline}}
{{#*inline "PORTLET"}}{{>@macro/front-end/widgets/dashboard-detail/portlet.hbs}}{{/inline}}
\ No newline at end of file
<{{codeName}}Portlet
ref="portlet"
name="{{portlet.name}}"
{{#if portlet.caption}}
title="{{portlet.caption}}"
{{/if}}
:showCaption="{{portlet.isShowTitleBar}}"
:layoutOpts="{{> @macro/front-end/common/layoutPos.hbs layout=portlet.psLayout layoutPos=portlet.psLayoutPos}}"
{{#if portlet.psSysImage}}
{{#if portlet.psSysImage.imagePath}}imgPath="{{portlet.psSysImage.imagePath}}"{{else if portlet.psSysImage.cssClass}}iconClass="{{portlet.psSysImage.cssClass}}"{{/if}}
{{/if}}
{{#if portlet.psSysCss}}
class="{{portlet.psSysCss.cssName}}"
{{/if}}
{{#if (or portlet.width portlet.height)}}
style="{{#if portlet.width}}width: {{portlet.width}}px;{{/if}}{{#if portlet.height}}height: {{portlet.height}}px;{{/if}}"
{{/if}}
:context="state.context"
:viewParams="state.viewParams"
:viewSubject="state.viewSubject"
@ctrlEvent="onCtrlEvent"
/>
<AppFormTabpanel
name="{{item.codeName}}"
:visible="state.detailsModel.{{item.codeName}}.visible"
:layoutOpts="{{> @macro/front-end/common/layoutPos.hbs layout=formDetail.psLayout layoutPos=formDetail.psLayoutPos}}"
name={{item.name}}>
......
......@@ -20,51 +20,52 @@ if (props.layoutOpts) {
}
// 插槽类名和插槽样式,只有不绘制根元素的时候需要传递给插槽
const attrs = useAttrs()
// 在template里写会丢失响应性,故封一个计算属性。
const attrs = useAttrs()
let slotStyle = computed(() => {
// 有根元素无需传样式给插槽
if(!props.noRoot){
return ''
}
let result = '';
result += isObject(attrs.style ) ? styleObj2Str(attrs.style) : attrs.style;
result += isObject(attrs.style) ? styleObj2Str(attrs.style) : attrs.style;
console.log(attrs.style)
console.log(result)
if(layout?.value?.colStyle){
if (layout?.value?.colStyle) {
result += layout.value.colStyle;
}
result += props.visible == true ? "" : "display: none;";
return result;
});
let slotClass = computed(()=>{
let result = '';
// 插槽类名
let slotClass = computed(() => {
// 有根元素无需传类名给插槽
if(!props.noRoot){
return ''
}
let result = 'app-col ';
result += attrs.class;
if(props.layoutOpts?.parentLayout == 'FLEX' && props.noRoot){
result += " app-col app-col--flex";
if (props.layoutOpts?.parentLayout == 'FLEX') {
result += " app-col--flex";
}
return result;
})
// 计算是否需要绘制根元素(layoutOpts不存在或者flex模式下noRoot为true时不绘制根元素)
let hasRoot = computed(()=>{
return props.layoutOpts !== undefined &&
( props.layoutOpts.parentLayout !== 'FLEX' || !props.noRoot );
})
</script>
<template>
<template v-if="!hasRoot">
<!-- 没有根元素的直接输出插槽 -->
<template v-if="layoutOpts">
<!-- 有布局模式配置的 -->
<template v-if="layoutOpts.parentLayout == 'FLEX'">
<template v-if="noRoot">
<!-- Flex布局,没根元素时,需要把相关样式和类型传给插槽 -->
<slot :slotStyle="slotStyle" :slotClass="slotClass"></slot>
</template>
<div
v-else-if="layoutOpts?.parentLayout == 'FLEX'"
v-show="visible"
:style="layout.colStyle"
class="app-col app-col--flex"
>
<slot slotStyle="" slotClass="" ></slot>
<div v-else v-show="visible" :style="layout.colStyle" class="app-col app-col--flex">
<slot :slotStyle="slotStyle" :slotClass="slotClass"></slot>
</div>
</template>
<a-col
v-else
v-show="visible"
......@@ -74,8 +75,18 @@ let hasRoot = computed(()=>{
:sm="layout.colGridOpts.sm"
class="app-col app-col--grid"
>
<slot slotStyle="" slotClass=""></slot>
<slot :slotStyle="slotStyle" :slotClass="slotClass"></slot>
</a-col>
</template>
<template v-else>
<!-- 无布局模式配置,根据noRoot输出根元素 -->
<template v-if="noRoot">
<slot :slotStyle="slotStyle" :slotClass="slotClass"></slot>
</template>
<div v-else class="app-col">
<slot :slotStyle="slotStyle" :slotClass="slotClass"></slot>
</div>
</template>
</template>
<style lang="scss">
......
......@@ -19,7 +19,7 @@ const props = withDefaults(defineProps<FormButtonProps>(), {
</script>
<template>
<app-col :visible="visible" noRoot :layoutOpts="layoutOpts" class="app-formButton">
<AppCol :visible="visible" noRoot :layoutOpts="layoutOpts" class="app-formButton">
<template #default="{slotStyle, slotClass}">
<a-button
:class="slotClass"
......@@ -28,7 +28,7 @@ const props = withDefaults(defineProps<FormButtonProps>(), {
<AppIconText :class="labelCssName" :iconClass="iconClass" :imgPath="imagePath" :text="showCaption ? caption : '' "/>
</a-button>
</template>
</app-col>
</AppCol>
</template>
<style lang="scss">
......
......@@ -121,7 +121,7 @@ const viewEvent = (action:any) => {
</script>
<template>
<app-col noRoot :visible="visible" :layoutOpts="layoutOpts" :class="['app-form-druipart', `app-form-druipart-${name}`]">
<AppCol noRoot :visible="visible" :layoutOpts="layoutOpts" :class="['app-form-druipart', `app-form-druipart-${name}`]">
<template #default="{slotStyle, slotClass}">
<a-card :class="slotClass" :style="slotStyle" :bordered="false">
<template #title>
......@@ -132,7 +132,7 @@ const viewEvent = (action:any) => {
<slot :context="druipartContext" :viewParams="druipartViewParams" :viewEvent="viewEvent" ></slot>
</a-card>
</template>
</app-col>
</AppCol>
</template>
<style lang="scss">
......
......@@ -37,7 +37,7 @@ const handleMenuGroupAction = ($event: IParam) => {
</script>
<template>
<app-col
<AppCol
noRoot
:visible="visible"
:layoutOpts="layoutOpts"
......@@ -93,12 +93,12 @@ const handleMenuGroupAction = ($event: IParam) => {
</template>
</template>
</template>
<app-row :layoutOpts="layoutOpts">
<AppRow :layoutOpts="layoutOpts">
<slot></slot>
</app-row>
</AppRow>
</a-card>
</template>
</app-col>
</AppCol>
</template>
<style lang="scss">
......
......@@ -14,9 +14,9 @@ const props = withDefaults(defineProps<FormIframeProps>(), {
</script>
<template>
<app-col class="app-formDruipart" :visible="visible" :layoutOpts="layoutOpts" v-show="visible">
<AppCol class="app-formDruipart" :visible="visible" :layoutOpts="layoutOpts" v-show="visible">
<iframe class="app-formDruipart__iframe" :src="iFrameUrl" style="height: 100%;width: 100%;border: 0"></iframe>
</app-col>
</AppCol>
</template>
<style lang="scss">
......
......@@ -42,7 +42,7 @@ const initRules = () => {
</script>
<template>
<app-col :visible="visible" noRoot :layoutOpts="layoutOpts" class="app-form-item">
<AppCol :visible="visible" noRoot :layoutOpts="layoutOpts" class="app-form-item">
<template v-slot:default="{slotStyle, slotClass}">
<a-form-item
:class="slotClass"
......@@ -62,7 +62,7 @@ const initRules = () => {
<slot></slot>
</a-form-item>
</template>
</app-col>
</AppCol>
</template>
<style lang="scss">
......
......@@ -13,9 +13,9 @@ const props = withDefaults(defineProps<FormPageProps>(), {
<template>
<a-tab-pane class="app-formPage" :key="$attrs.key" :tab="tab">
<app-row :layoutOpts="layoutOpts">
<AppRow :layoutOpts="layoutOpts">
<slot></slot>
</app-row>
</AppRow>
</a-tab-pane>
</template>
......
......@@ -17,7 +17,7 @@ const props = withDefaults(defineProps<FormRawProps>(), {
</script>
<template>
<app-col :visible="visible" noRoot :layoutOpts="layoutOpts" class="app-formRaw">
<AppCol :visible="visible" noRoot :layoutOpts="layoutOpts" class="app-formRaw">
<template #default="{slotStyle, slotClass}">
<AppRaw
:class="slotClass"
......@@ -27,7 +27,7 @@ const props = withDefaults(defineProps<FormRawProps>(), {
:contentType="contentType">
</AppRaw>
</template>
</app-col>
</AppCol>
</template>
<style lang="scss">
......
......@@ -16,9 +16,9 @@ const props = withDefaults(defineProps<FormTabPageProps>(), {
<template>
<a-tab-pane class="app-formTabPage" v-show="visible" :tab="caption">
<app-row :layoutOpts="layoutOpts">
<AppRow :layoutOpts="layoutOpts">
<slot></slot>
</app-row>
</AppRow>
</a-tab-pane>
</template>
......
......@@ -14,13 +14,13 @@ const props = withDefaults(defineProps<FormTabPanelProps>(), {
</script>
<template>
<app-col :visible="visible" noRoot :layoutOpts="layoutOpts" class="app-formTabPanel">
<AppCol :visible="visible" noRoot :layoutOpts="layoutOpts" class="app-formTabPanel">
<template v-slot:default="{ slotStyle, slotClass }">
<a-tabs :class="slotClass" :style="slotStyle">
<slot></slot>
</a-tabs>
</template>
</app-col>
</AppCol>
</template>
<style lang="scss">
......
<script setup lang="ts">
import { ILayoutOpts } from "@core";
import { LayoutTool } from "@core/modules/common/layout-tool";
interface AppPortletCardProps {
layoutOpts: ILayoutOpts;
// 是否是容器,是容器的话需要在默认插槽外层适配布局
isContainer?: boolean;
showCaption?: boolean;
title?: string;
imgPath?: string;
iconClass?: string;
}
const props = withDefaults(defineProps<AppPortletCardProps>(), {
isContainer: false,
});
// 使用布局逻辑获得响应式的layout对象
const layout = LayoutTool.useLayout(toRef(props, "layoutOpts"));
</script>
<template>
<AppCol class="app-portletCard" :layoutOpts="layoutOpts">
<div class="app-portletCard__head">
<div class="app-portletCard__headLeft">
<slot name="header-left">
<AppIconText v-if="showCaption" :text="title" :imgPath="imgPath" :iconClass="iconClass"/>
</slot>
</div>
<div class="app-portletCard__headerRight">
<slot name="header-right"></slot>
</div>
</div>
<div class="app-portletCard__body">
<AppRow v-if="isContainer" :layoutOpts="layoutOpts">
<slot></slot>
</AppRow>
<template v-else >
<slot></slot>
</template>
</div>
</AppCol>
</template>
<style lang="scss">
</style>
\ No newline at end of file
......@@ -39,8 +39,6 @@ const { state, dashboard, onCtrlEvent } = new PortalView(viewState, props, emit)
<AppIconText
class="app-view__caption"
size="large"
:subCaption="state.subCaption"
:showCaptionBar="state.showCaptionBar"
:text="state.viewCaption"
/>
</template>
......
......@@ -4,23 +4,12 @@ import { Subject } from 'rxjs';
import { ctrlState } from './{{spinalCase ctrl.codeName}}-dashboard-state';
import { DashboardControl, IActionParam, IParam, IContext } from '@core';
{{#each ctrl.psControls as | control |}}
{{#eq control.portletType "CONTAINER"}}
{{#each control.psControls as | control2 |}}
{{#if control2.psAppDataEntity}}
import { {{codeName}}Portlet } from '@widgets/{{spinalCase control2.psAppDataEntity.codeName}}/{{spinalCase codeName}}-portlet';
{{#each ctrl.allPortlets as | control |}}
{{#if control.psAppDataEntity}}
import { {{codeName}}Portlet } from '@widgets/{{spinalCase control.psAppDataEntity.codeName}}/{{spinalCase codeName}}-portlet';
{{else}}
import { {{codeName}}Portlet } from '@widgets/app/{{spinalCase codeName}}-portlet';
{{/if}}
{{/each}}
{{/eq}}
{{#neq control.portletType "CONTAINER"}}
{{#if control.psAppDataEntity}}
import { {{codeName}}Portlet } from '@widgets/{{spinalCase control.psAppDataEntity.codeName}}/{{spinalCase codeName}}-portlet';
{{else}}
import { {{codeName}}Portlet } from '@widgets/app/{{spinalCase codeName}}-portlet';
{{/if}}
{{/neq}}
{{/each}}
interface Props {
......@@ -50,7 +39,13 @@ defineExpose({ name, state });
<template>
<div class="app-dashboard{{#if ctrl.psSysCss}} {{ctrl.psSysCss.cssName}}{{/if}}">
<template v-if="!state.isEnableCustomized">
{{>(lookup 'DASHBOARD') ctrl=ctrl}}
{{#each ctrl.psControls as |portlet|}}
{{#eq portlet.portletType 'CONTAINER'}}
{{>(lookup 'PORTLET_CONTAINER') portlet=portlet}}
{{else}}
{{>(lookup 'PORTLET') portlet=portlet}}
{{/eq}}
{{/each}}
</template>
</div>
</template>
......
......@@ -2,16 +2,7 @@
export const ctrlState = {
controlCodeName: '{{ctrl.codeName}}',
controlName: '{{ctrl.name}}',
showTitleBar: {{#if ctrl.showTitleBar}}true{{else}}false{{/if}},
title: '{{ctrl.title}}',
portletType: '{{ctrl.portletType}}',
{{#if ctrl.psSysImage}}
{{#if ctrl.psSysImage.cssClass}}
iconcls: '{{ctrl.psSysImage.cssClass}}',
{{else if (ctrl.psSysImage.imagePath)}}
imgPath: '{{ctrl.psSysImage.imagePath}}',
{{/if}}
{{/if}}
{{#if ctrl.psLayoutPos.height}}
// 部件高度
height: {{ctrl.psLayoutPos.height}},
......
......@@ -2,14 +2,14 @@
import { Subject } from 'rxjs';
import { ctrlState } from './{{spinalCase ctrl.codeName}}-portlet-state';
import { PortletControl, IActionParam, IParam, IContext } from '@core';
// 引入视图start
{{!-- 引入视图start --}}
{{#if (eq ctrl.portletType "VIEW")}}
{{#if ctrl.portletPSAppView}}
import {{ctrl.portletPSAppView.codeName}} from '@views/{{spinalCase ctrl.portletPSAppView.psAppModule.codeName}}/{{spinalCase ctrl.portletPSAppView.codeName}}';
{{/if}}
{{/if}}
// 引入视图end
// 引入菜单start
{{!-- 引入视图end --}}
{{!-- 引入菜单start --}}
{{#if (eq ctrl.portletType "APPMENU")}}
{{#each ctrl.psControls as | control |}}
{{#eq control.controlType "APPMENU"}}
......@@ -17,7 +17,7 @@ import { {{control.codeName}}Menu } from '@widgets/app/{{spinalCase control.code
{{/eq}}
{{/each}}
{{/if}}
// 引入菜单end
{{!-- 引入菜单end --}}
interface Props {
......@@ -25,10 +25,27 @@ interface Props {
context: IContext;
viewParams?: IParam;
viewSubject: Subject<IActionParam>;
showCaption?: boolean;
title?: string;
imgPath?: string;
iconClass?: string;
}
const props = withDefaults(defineProps < Props > (), {
viewSubject: () => new Subject < IActionParam > (),
{{#if ctrl.title}}
title: '{{ctrl.title}}',
{{/if}}
{{#if ctrl.showTitleBar}}
showCaption: '{{ctrl.showTitleBar}}',
{{/if}}
{{#if ctrl.psSysImage}}
{{#if ctrl.psSysImage.cssClass}}
iconcls: '{{ctrl.psSysImage.cssClass}}',
{{else if (ctrl.psSysImage.imagePath)}}
imgPath: '{{ctrl.psSysImage.imagePath}}',
{{/if}}
{{/if}}
})
// emit声明
......@@ -45,14 +62,17 @@ const { name, state, onViewEvent, onCtrlEvent, handleItemClick, handleActionClic
defineExpose({ name, state });
</script>
<template>
<div class="app-portlet{{#if ctrl.psSysCss}} {{ctrl.psSysCss.cssName}}{{/if}}" >
<template v-if="state.showTitleBar && state.title">
<div class='portlet-title'>
<span>
<i v-if="state.iconcls" :class="state.iconcls" />
<img v-if="state.imagePath" :src="state.imagePath" />
\{{state.title}}
</span>
<AppPortletCard
class="app-portlet{{#if ctrl.psSysCss}} {{ctrl.psSysCss.cssName}}{{/if}}"
:title="title"
:iconClass="iconClass"
:imgPath="imgPath"
:showCaption="showCaption"
{{#if (or ctrl.width ctrl.height)}}
style="{{#if ctrl.width}}width: {{ctrl.width}}px;{{/if}}{{#if ctrl.height}}height: {{ctrl.height}}px;{{/if}}"
{{/if}}
>
<template #header-right>
<span class="portlet-action" v-if="state.actionBarModelData && state.portletType !== 'ACTIONBAR'">
<template v-for="(item,index) in Object.values(state.actionBarModelData)" :key="index">
<a-tooltip>
......@@ -67,9 +87,7 @@ defineExpose({ name, state });
</a-tooltip>
</template>
</span>
</div>
</template>
<div :class="{'portlet-with-title': state.showTitleBar, 'portlet-without-title': !state.showTitleBar}">
{{#if (eq ctrl.portletType 'VIEW') }}
<{{ctrl.portletPSAppView.codeName}}
:context="state.context"
......@@ -102,7 +120,7 @@ defineExpose({ name, state });
{{else if (eq ctrl.portletType 'TOOLBAR')}}
<div>暂未支持工具栏绘制</div>
{{else if (eq ctrl.portletType 'HTML')}}
<iframe :src="state.pageUrl" :style="{height: state.height && state.height > 0 ? state.height + 'px' : '400px', width: '100%', borderWidth: '0px'}"></iframe>
<iframe :src="state.pageUrl" :style="{height: state.height && state.height > 0 ? '100%' : '400px', width: '100%', borderWidth: '0px'}"></iframe>
{{else if (eq ctrl.portletType 'RAWITEM')}}
<app-raw
:name="state.controlName"
......@@ -111,11 +129,10 @@ defineExpose({ name, state });
:imgPath="state.imagePath"
style="{{#if ctrl.rawItemHeight}}height: {{ctrl.rawItemHeight}}px;{{/if}}{{#if ctrl.rawItemWidth}}width: {{ctrl.rawItemWidth}}px{{/if}}"
{{#if (eq ctrl.contentType 'RAW')}}value="{{ctrl.rawContent}}"{{else if (eq ctrl.contentType 'HTML')}}:value="`{{ctrl.htmlContent}}`"{{/if}}
></app-raw>>
></app-raw>
{{else}}
{{/if}}
</div>
</div>
</AppPortletCard>
</template>
<style lang="scss">
</style>
\ No newline at end of file
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册