提交 b2fdcaf1 编写于 作者: ibizdev's avatar ibizdev

chitanda 发布系统代码 [TrainSys,网页端]

上级 2996e441
......@@ -13,13 +13,13 @@
"dependencies": {
"@floating-ui/dom": "^1.0.11",
"@ibiz-template/command": "^0.0.1-beta.50",
"@ibiz-template/controller": "^0.0.1-beta.51",
"@ibiz-template/controller": "^0.0.1-beta.55",
"@ibiz-template/core": "^0.0.1-beta.51",
"@ibiz-template/model": "^0.0.1-beta.50",
"@ibiz-template/runtime": "^0.0.1-beta.51",
"@ibiz-template/service": "^0.0.1-beta.51",
"@ibiz-template/theme": "^0.0.1-beta.50",
"@ibiz-template/vue-util": "^0.0.1-beta.51",
"@ibiz-template/model": "^0.0.1-beta.55",
"@ibiz-template/runtime": "^0.0.1-beta.55",
"@ibiz-template/service": "^0.0.1-beta.55",
"@ibiz-template/theme": "^0.0.1-beta.54",
"@ibiz-template/vue-util": "^0.0.1-beta.55",
"@ibiz/dynamic-model-api": "^2.1.17",
"dayjs": "^1.11.7",
"lodash-es": "^4.17.21",
......
......@@ -8,26 +8,26 @@ dependencies:
specifier: ^0.0.1-beta.50
version: 0.0.1-beta.50
'@ibiz-template/controller':
specifier: ^0.0.1-beta.51
version: 0.0.1-beta.51(@ibiz-template/core@0.0.1-beta.51)(@ibiz-template/model@0.0.1-beta.50)(@ibiz-template/runtime@0.0.1-beta.51)(@ibiz-template/service@0.0.1-beta.51)(lodash-es@4.17.21)(qs@6.11.1)(qx-util@0.4.8)
specifier: ^0.0.1-beta.55
version: 0.0.1-y.0(@ibiz-template/core@0.0.1-beta.51)(@ibiz-template/model@0.0.1-y.0)(@ibiz-template/runtime@0.0.1-y.0)(@ibiz-template/service@0.0.1-y.0)(lodash-es@4.17.21)(qs@6.11.1)(qx-util@0.4.8)
'@ibiz-template/core':
specifier: ^0.0.1-beta.51
version: 0.0.1-beta.51(lodash-es@4.17.21)(qx-util@0.4.8)
'@ibiz-template/model':
specifier: ^0.0.1-beta.50
version: 0.0.1-beta.50(@ibiz/dynamic-model-api@2.1.17)(lodash-es@4.17.21)(qx-util@0.4.8)
specifier: ^0.0.1-beta.55
version: 0.0.1-y.0(@ibiz/dynamic-model-api@2.1.17)(lodash-es@4.17.21)(qx-util@0.4.8)
'@ibiz-template/runtime':
specifier: ^0.0.1-beta.51
version: 0.0.1-beta.51(@ibiz-template/core@0.0.1-beta.51)(@ibiz-template/model@0.0.1-beta.50)(@ibiz-template/service@0.0.1-beta.51)(qx-util@0.4.8)
specifier: ^0.0.1-beta.55
version: 0.0.1-y.0(@ibiz-template/core@0.0.1-beta.51)(@ibiz-template/model@0.0.1-y.0)(@ibiz-template/service@0.0.1-y.0)(qx-util@0.4.8)
'@ibiz-template/service':
specifier: ^0.0.1-beta.51
version: 0.0.1-beta.51(@ibiz-template/core@0.0.1-beta.51)(@ibiz-template/model@0.0.1-beta.50)(qx-util@0.4.8)(ramda@0.28.0)
specifier: ^0.0.1-beta.55
version: 0.0.1-y.0(@ibiz-template/core@0.0.1-beta.51)(@ibiz-template/model@0.0.1-y.0)(qx-util@0.4.8)(ramda@0.28.0)
'@ibiz-template/theme':
specifier: ^0.0.1-beta.50
version: 0.0.1-beta.50
specifier: ^0.0.1-beta.54
version: 0.0.1-beta.54
'@ibiz-template/vue-util':
specifier: ^0.0.1-beta.51
version: 0.0.1-beta.51(@ibiz-template/controller@0.0.1-beta.51)(@ibiz-template/core@0.0.1-beta.51)(@ibiz-template/model@0.0.1-beta.50)(@ibiz-template/service@0.0.1-beta.51)(qs@6.11.1)(qx-util@0.4.8)(ramda@0.28.0)(vue-router@3.6.5)(vue@2.7.14)
specifier: ^0.0.1-beta.55
version: 0.0.1-y.0(@ibiz-template/controller@0.0.1-y.0)(@ibiz-template/core@0.0.1-beta.51)(@ibiz-template/model@0.0.1-y.0)(@ibiz-template/service@0.0.1-y.0)(qs@6.11.1)(qx-util@0.4.8)(ramda@0.28.0)(vue-router@3.6.5)(vue@2.7.14)
'@ibiz/dynamic-model-api':
specifier: ^2.1.17
version: 2.1.17(qx-util@0.4.8)
......@@ -938,8 +938,8 @@ packages:
qx-util: 0.4.8
dev: false
/@ibiz-template/controller@0.0.1-beta.51(@ibiz-template/core@0.0.1-beta.51)(@ibiz-template/model@0.0.1-beta.50)(@ibiz-template/runtime@0.0.1-beta.51)(@ibiz-template/service@0.0.1-beta.51)(lodash-es@4.17.21)(qs@6.11.1)(qx-util@0.4.8):
resolution: {integrity: sha512-kJCA2xgi3S6svxO6UWB1tm39oYG49ZUpmi6bacjLC3S2Mnzms64H04G20jA7uClgaSnOfmvuC6SZlqgTrlAErw==}
/@ibiz-template/controller@0.0.1-y.0(@ibiz-template/core@0.0.1-beta.51)(@ibiz-template/model@0.0.1-y.0)(@ibiz-template/runtime@0.0.1-y.0)(@ibiz-template/service@0.0.1-y.0)(lodash-es@4.17.21)(qs@6.11.1)(qx-util@0.4.8):
resolution: {integrity: sha512-W9fVVBTDEh6h/lCbNVZiPo6sJSkc/2Rb2DajNUamCFflwBc534umpxz6o3Mpflsmbln3ISxD7WsUfGJ8ngP9GA==}
peerDependencies:
'@ibiz-template/core': ^0.0.1-beta.30
'@ibiz-template/model': ^0.0.1-beta.30
......@@ -950,9 +950,9 @@ packages:
qx-util: ^0.4.8
dependencies:
'@ibiz-template/core': 0.0.1-beta.51(lodash-es@4.17.21)(qx-util@0.4.8)
'@ibiz-template/model': 0.0.1-beta.50(@ibiz/dynamic-model-api@2.1.17)(lodash-es@4.17.21)(qx-util@0.4.8)
'@ibiz-template/runtime': 0.0.1-beta.51(@ibiz-template/core@0.0.1-beta.51)(@ibiz-template/model@0.0.1-beta.50)(@ibiz-template/service@0.0.1-beta.51)(qx-util@0.4.8)
'@ibiz-template/service': 0.0.1-beta.51(@ibiz-template/core@0.0.1-beta.51)(@ibiz-template/model@0.0.1-beta.50)(qx-util@0.4.8)(ramda@0.28.0)
'@ibiz-template/model': 0.0.1-y.0(@ibiz/dynamic-model-api@2.1.17)(lodash-es@4.17.21)(qx-util@0.4.8)
'@ibiz-template/runtime': 0.0.1-y.0(@ibiz-template/core@0.0.1-beta.51)(@ibiz-template/model@0.0.1-y.0)(@ibiz-template/service@0.0.1-y.0)(qx-util@0.4.8)
'@ibiz-template/service': 0.0.1-y.0(@ibiz-template/core@0.0.1-beta.51)(@ibiz-template/model@0.0.1-y.0)(qx-util@0.4.8)(ramda@0.28.0)
async-validator: 4.2.5
dayjs: 1.11.7
lodash-es: 4.17.21
......@@ -976,8 +976,8 @@ packages:
- debug
dev: false
/@ibiz-template/model@0.0.1-beta.50(@ibiz/dynamic-model-api@2.1.17)(lodash-es@4.17.21)(qx-util@0.4.8):
resolution: {integrity: sha512-id83BJg56lskHAuac9Wx3QMy53A4bYe3EX0H/JJmG5XupMzsYMMB/crvEhhJU6/sM7NPfELR7dFVDstXDcC/5Q==}
/@ibiz-template/model@0.0.1-y.0(@ibiz/dynamic-model-api@2.1.17)(lodash-es@4.17.21)(qx-util@0.4.8):
resolution: {integrity: sha512-EK1MHA1jVfce2ZMIGqkeLbEv9dTFawGxMSJbgcSNJB4Ec8Gl7pMFE5ChAyCc1CKxQstJc7IsdA8n9cFKQGeQ0Q==}
peerDependencies:
'@ibiz/dynamic-model-api': ^2.1.17
lodash-es: ^4.17.21
......@@ -989,8 +989,8 @@ packages:
qx-util: 0.4.8
dev: false
/@ibiz-template/runtime@0.0.1-beta.51(@ibiz-template/core@0.0.1-beta.51)(@ibiz-template/model@0.0.1-beta.50)(@ibiz-template/service@0.0.1-beta.51)(qx-util@0.4.8):
resolution: {integrity: sha512-Zs31UILmTaP8dh1kGePp4uoXf5RiE5lPMs9cMw3cn84uOLZFc2Ftojhta3s2Xtl1tKD3E0QVAqMjr8HFvq+bng==}
/@ibiz-template/runtime@0.0.1-y.0(@ibiz-template/core@0.0.1-beta.51)(@ibiz-template/model@0.0.1-y.0)(@ibiz-template/service@0.0.1-y.0)(qx-util@0.4.8):
resolution: {integrity: sha512-mrg6pBWd7zS3skyCbpzFoRsY5s3JxN4Xpn4a1eFGEPsWkXKpbeiTvKezmeylRG/ELrlYMQPpknU6SeIFDpHvQw==}
peerDependencies:
'@ibiz-template/core': ^0.0.1-beta.30
'@ibiz-template/model': ^0.0.1-beta.30
......@@ -999,14 +999,14 @@ packages:
dependencies:
'@ibiz-template/command': 0.0.1-beta.50
'@ibiz-template/core': 0.0.1-beta.51(lodash-es@4.17.21)(qx-util@0.4.8)
'@ibiz-template/model': 0.0.1-beta.50(@ibiz/dynamic-model-api@2.1.17)(lodash-es@4.17.21)(qx-util@0.4.8)
'@ibiz-template/service': 0.0.1-beta.51(@ibiz-template/core@0.0.1-beta.51)(@ibiz-template/model@0.0.1-beta.50)(qx-util@0.4.8)(ramda@0.28.0)
'@ibiz-template/model': 0.0.1-y.0(@ibiz/dynamic-model-api@2.1.17)(lodash-es@4.17.21)(qx-util@0.4.8)
'@ibiz-template/service': 0.0.1-y.0(@ibiz-template/core@0.0.1-beta.51)(@ibiz-template/model@0.0.1-y.0)(qx-util@0.4.8)(ramda@0.28.0)
qs: 6.11.1
qx-util: 0.4.8
dev: false
/@ibiz-template/service@0.0.1-beta.51(@ibiz-template/core@0.0.1-beta.51)(@ibiz-template/model@0.0.1-beta.50)(qx-util@0.4.8)(ramda@0.28.0):
resolution: {integrity: sha512-sc4vy0zYlbcj2VjB3XShoJArXTLtaFn8NGyBweU8dCSpBw6PMV9Ltdm1SxxEyyrd7a989jCGq2aJfFvE+k8i9g==}
/@ibiz-template/service@0.0.1-y.0(@ibiz-template/core@0.0.1-beta.51)(@ibiz-template/model@0.0.1-y.0)(qx-util@0.4.8)(ramda@0.28.0):
resolution: {integrity: sha512-Re9yRSx5+tQe7HJ1u8yx9tch+IODFHtY99xYkW1pXo854aLW4hhlEzTVao9lfJJMdCfKxoT5TrsyZpbS1VpDSw==}
peerDependencies:
'@ibiz-template/core': ^0.0.1-beta.30
'@ibiz-template/model': ^0.0.1-beta.30
......@@ -1014,17 +1014,17 @@ packages:
ramda: ^0.28.0
dependencies:
'@ibiz-template/core': 0.0.1-beta.51(lodash-es@4.17.21)(qx-util@0.4.8)
'@ibiz-template/model': 0.0.1-beta.50(@ibiz/dynamic-model-api@2.1.17)(lodash-es@4.17.21)(qx-util@0.4.8)
'@ibiz-template/model': 0.0.1-y.0(@ibiz/dynamic-model-api@2.1.17)(lodash-es@4.17.21)(qx-util@0.4.8)
qx-util: 0.4.8
ramda: 0.28.0
dev: false
/@ibiz-template/theme@0.0.1-beta.50:
resolution: {integrity: sha512-ZyUvekQpuTUVh8YuF4i+ylheA5NO0zO+sEVggSvulo9xmhjbqXGP3sUOV12728M3tn5dM3E6alPtGRvlTAiTzQ==}
/@ibiz-template/theme@0.0.1-beta.54:
resolution: {integrity: sha512-xN2cqT43TbQxIPu+8rUd0MFriE9Xfjbyqe5EXWwLqtkigrZf71Ff2xKgW0ILyBSm+0KliXfgPAxFfYtXGFVw/g==}
dev: false
/@ibiz-template/vue-util@0.0.1-beta.51(@ibiz-template/controller@0.0.1-beta.51)(@ibiz-template/core@0.0.1-beta.51)(@ibiz-template/model@0.0.1-beta.50)(@ibiz-template/service@0.0.1-beta.51)(qs@6.11.1)(qx-util@0.4.8)(ramda@0.28.0)(vue-router@3.6.5)(vue@2.7.14):
resolution: {integrity: sha512-XmZ4q/hDp0X1yqOISWjFsxy182RhQ6Lg8zoDJHOXjp8HYlR1ob5nnpHNlzBDqhjhzTtknLZbLoCW85rq9T7LrQ==}
/@ibiz-template/vue-util@0.0.1-y.0(@ibiz-template/controller@0.0.1-y.0)(@ibiz-template/core@0.0.1-beta.51)(@ibiz-template/model@0.0.1-y.0)(@ibiz-template/service@0.0.1-y.0)(qs@6.11.1)(qx-util@0.4.8)(ramda@0.28.0)(vue-router@3.6.5)(vue@2.7.14):
resolution: {integrity: sha512-iTn/jNOcBY3tgGrzigPej+z0f4WgYHCplBq1RZn0Hkb3ZSgyBOzq7fO/VpPoE2XJn6YUP2lWnoqL2zQ/P15gvw==}
peerDependencies:
'@ibiz-template/controller': ^0.0.1-beta.30
'@ibiz-template/core': ^0.0.1-beta.30
......@@ -1036,10 +1036,10 @@ packages:
vue: ^2.7.14
vue-router: ^3.6.5
dependencies:
'@ibiz-template/controller': 0.0.1-beta.51(@ibiz-template/core@0.0.1-beta.51)(@ibiz-template/model@0.0.1-beta.50)(@ibiz-template/runtime@0.0.1-beta.51)(@ibiz-template/service@0.0.1-beta.51)(lodash-es@4.17.21)(qs@6.11.1)(qx-util@0.4.8)
'@ibiz-template/controller': 0.0.1-y.0(@ibiz-template/core@0.0.1-beta.51)(@ibiz-template/model@0.0.1-y.0)(@ibiz-template/runtime@0.0.1-y.0)(@ibiz-template/service@0.0.1-y.0)(lodash-es@4.17.21)(qs@6.11.1)(qx-util@0.4.8)
'@ibiz-template/core': 0.0.1-beta.51(lodash-es@4.17.21)(qx-util@0.4.8)
'@ibiz-template/model': 0.0.1-beta.50(@ibiz/dynamic-model-api@2.1.17)(lodash-es@4.17.21)(qx-util@0.4.8)
'@ibiz-template/service': 0.0.1-beta.51(@ibiz-template/core@0.0.1-beta.51)(@ibiz-template/model@0.0.1-beta.50)(qx-util@0.4.8)(ramda@0.28.0)
'@ibiz-template/model': 0.0.1-y.0(@ibiz/dynamic-model-api@2.1.17)(lodash-es@4.17.21)(qx-util@0.4.8)
'@ibiz-template/service': 0.0.1-y.0(@ibiz-template/core@0.0.1-beta.51)(@ibiz-template/model@0.0.1-y.0)(qx-util@0.4.8)(ramda@0.28.0)
qs: 6.11.1
qx-util: 0.4.8
ramda: 0.28.0
......
......@@ -8,7 +8,9 @@ import { IViewRegister } from './i-view-register';
import {
AppLayout,
ControlLayout,
ExpViewBase,
MDViewBase,
PortletLayout,
ViewBase,
ViewLayout,
} from './components/layout';
......@@ -36,6 +38,7 @@ import {
DashboardControl,
PortletContainer,
PortletPart,
ViewPortlet,
ListControl,
ListPortlet,
} from './components/widgets';
......@@ -52,6 +55,9 @@ import {
WFDynaStartView,
WFStepTraceView,
AppPortalView,
TabExpView,
ListExpView,
ListView,
} from './components/views';
import { IndexView } from './views';
import AppKeepAlive from './components/common/app-keep-alive/app-keep-alive.vue';
......@@ -136,6 +142,9 @@ export const AppRegister = {
v.component('WFDynaEditView3', WFDynaEditView3);
v.component('WFStepTraceView', WFStepTraceView);
v.component('AppPortalView', AppPortalView);
v.component('TabExpView', TabExpView);
v.component('ListExpView', ListExpView);
v.component('ListView', ListView);
// 注册部件组件
v.component('AppMenu', AppMenu);
v.component('GridControl', GridControl);
......@@ -159,6 +168,7 @@ export const AppRegister = {
v.component('PickupViewPanel', PickupViewPanel);
v.component('DashboardControl', DashboardControl);
v.component('PortletPart', PortletPart);
v.component('ViewPortlet', ViewPortlet);
v.component('ListPortlet', ListPortlet);
v.component('PortletContainer', PortletContainer);
// 注册通用组件
......@@ -182,6 +192,7 @@ export const AppRegister = {
v.component('DataExport', DataExport);
v.component('ImagePreview', ImagePreview);
v.component('CodeList', CodeList);
v.component('PortletLayout', PortletLayout);
// 注册编辑器组件
v.component('GridEditor', GridEditor);
v.component('IBizSpan', IBizSpan);
......@@ -209,5 +220,6 @@ export const AppRegister = {
v.component('IBizGridDropdown', IBizGridDropdown);
v.component('IBizGridRadio', IBizGridRadio);
v.component('IBizGridPicker', IBizGridPicker);
v.component('ExpViewBase', ExpViewBase);
},
};
@include b(exp-view) {
@include set-component-css-var('exp-view', $exp-view);
display: inline-flex;
width: 100%;
height: 100%;
}
@include b(exp-view-left) {
width: getCssVar('exp-view', 'left-width');
}
@include b(exp-view-right) {
width: calc(100% - getCssVar('exp-view', 'left-width'));
}
@include b(exp-view-exp-bar) {
height: 100%;
@include b(exp-view-exp-bar-header) {
@include flex(row, space-between, center);
padding: 16px;
border-bottom: 1px solid #dcdfe6;
@include b(exp-view-exp-bar-header-right) {
@include flex(row, flex-start, center);
}
}
@include b(exp-view-exp-bar-content) {
height: calc(100% - 65px);
}
@include when(no-header) {
@include b(exp-view-exp-bar-header) {
padding: 0;
border: none;
}
@include b(exp-view-exp-bar-content) {
height: 100%;
}
}
}
import { useNamespace } from '@ibiz-template/vue-util';
import { computed, defineComponent, PropType } from 'vue';
import './exp-view-base.scss';
import { IExpBarModel } from '@ibiz-template/model';
import { ListExpViewController } from '@ibiz-template/controller';
export const ExpViewBase = defineComponent({
name: 'ExpViewBase',
props: {
controller: {
type: Object as PropType<ListExpViewController>,
required: true,
},
expBarModel: {
type: Object as PropType<IExpBarModel>,
required: true,
},
},
setup(props) {
const ns = useNamespace('exp-view');
const cssVars = computed(() => {
if (props.controller.model.expBarWidth) {
return ns.cssVarBlock({
'left-width': `${props.controller.model.expBarWidth}px`,
});
}
return {};
});
// 是否显示头部
const isShowHeader = computed(() => {
return (
props.expBarModel.showTitleBar ||
props.expBarModel.enableSearch ||
props.controller.model.toolbar
);
});
return { ns, cssVars, isShowHeader };
},
render() {
const c = this.controller;
// 外面的插槽同样传给view-layout
const inheritSlots: IData = {};
Object.keys(this.$scopedSlots).forEach(key => {
inheritSlots[key] = (arg: IData) => this.$scopedSlots[key]!(arg);
});
return (
<div class={[this.ns.b()]} style={this.cssVars}>
<div class={[this.ns.b('left')]}>
<view-layout
class={[
c.complete && this.ns.b(this.controller.model.typeClass),
c.complete && this.ns.m(this.controller.model.modelClass),
]}
isComplete={c.complete}
modelData={c.model}
viewMode={c.modal.mode}
isLoading={c.viewLoading.isLoading}
scopedSlots={{
caption: () => {
return (
<div class={this.ns.b('caption')}>
{c.complete && c.model.source.getPSSysImage() ? (
[
<app-icon
class={this.ns.be('caption', 'icon')}
icon={c.model.source.getPSSysImage()}
></app-icon>,
<span
class={this.ns.be('caption', 'text')}
title={c.caption}
>
{c.caption}
</span>,
]
) : (
<span
class={this.ns.be('caption', 'text')}
title={c.caption}
>
{c.caption}
</span>
)}
</div>
);
},
...inheritSlots,
default: () => {
return (
<div
class={[
this.ns.b('exp-bar'),
this.ns.is('no-header', !this.isShowHeader),
]}
>
<div class={this.ns.b('exp-bar-header')}>
<div class={this.ns.b('exp-bar-header-left')}>
<div
class={this.ns.be('exp-bar-header-left', 'caption')}
>
{this.expBarModel.showTitleBar &&
(this.expBarModel.getPSSysImage ? (
[
<app-icon
class={this.ns.be('caption', 'icon')}
icon={this.expBarModel.getPSSysImage}
></app-icon>,
<span
class={this.ns.be('caption', 'text')}
title={this.expBarModel.title}
>
{this.expBarModel.title}
</span>,
]
) : (
<span
class={this.ns.be('caption', 'text')}
title={this.expBarModel.title}
>
{this.expBarModel.title}
</span>
))}
</div>
</div>
<div class={this.ns.b('exp-bar-header-right')}>
<div class={this.ns.e('quick-search')}>
{c.complete && this.expBarModel.enableSearch && (
<quick-search
value={c.query}
viewMode={c.modal.mode}
placeholder={c.model.placeholder}
onUpdate={(val: string) => {
c.query = val;
}}
onSearch={() => c.onSearch()}
></quick-search>
)}
</div>
<div class={this.ns.e('toolbar')}>
{c.complete && c.model.toolbar && (
<view-toolbar
modelData={c.model.toolbar}
on-neuronInit={c.nerve.onNeuronInit(
c.model.toolbar.source.name,
)}
toolbarState={c.toolbarState}
viewMode={c.modal.mode}
></view-toolbar>
)}
</div>
</div>
</div>
<div class={this.ns.b('exp-bar-content')}>
{inheritSlots.default && inheritSlots.default()}
</div>
</div>
);
},
}}
></view-layout>
</div>
<div class={[this.ns.b('right')]}>
{this.$scopedSlots.expView && this.$scopedSlots.expView({})}
</div>
</div>
);
},
});
......@@ -3,5 +3,15 @@ import ControlLayout from './control-layout/control-layout';
import { ViewBase } from './view-base/view-base';
import { MDViewBase } from './md-view-base/md-view-base';
import { ViewLayout } from './view-layout/view-layout';
import { PortletLayout } from './portlet-layout/portlet-layout';
import { ExpViewBase } from './exp-view-base/exp-view-base';
export { AppLayout, ControlLayout, ViewLayout, ViewBase, MDViewBase };
export {
AppLayout,
ControlLayout,
PortletLayout,
ViewLayout,
ViewBase,
MDViewBase,
ExpViewBase,
};
@include b(portlet-layout) {
@include set-component-css-var('portlet-layout', $portlet-layout);
width: 100%;
height: 100%;
background-color: getCssVar('portlet-layout','bg-color');
// 标题样式
@include e(caption){
max-width: getCssVar('portlet-layout','caption-max-width');
@include e(caption-text){
font-size: getCssVar('portlet-layout','caption-font-size');
font-weight: getCssVar('portlet-layout','caption-font-weight');
color: getCssVar('portlet-layout','caption-color');
vertical-align: middle;
}
}
// 无头部时的样式
@include when(no-header) {
>.#{bem(portlet-layout-content)}{
height: 100%;
}
}
}
// 头部样式
@include b(portlet-layout-header) {
@include flex(row, space-between, center);
height: getCssVar('portlet-layout','header-height');
padding: getCssVar('portlet-layout','header-padding');
margin: getCssVar('portlet-layout','header-margin');
background-color: getCssVar('portlet-layout','header-bg-color');
border-bottom: getCssVar('portlet-layout','header-border-bottom');
}
// 内容区样式
@include b(portlet-layout-content) {
height: calc(100% - getCssVar('portlet-layout','header-height'));
padding: getCssVar('portlet-layout','content-padding');
margin: getCssVar('portlet-layout','content-margin');
background-color: getCssVar('portlet-layout','content-bg-color');
}
\ No newline at end of file
import { PortletPartController } from '@ibiz-template/controller';
import { useNamespace } from '@ibiz-template/vue-util';
import { computed, defineComponent } from 'vue';
import './portlet-layout.scss';
/**
* 门户控件布局
*/
export const PortletLayout = defineComponent({
props: {
controller: {
type: PortletPartController,
required: true,
},
},
setup(props) {
const ns = useNamespace('portlet-layout');
const c = props.controller;
// 处理标题
const isShowHeader = computed(() => {
// return c.model.showTitleBar || c.model.actionGroup;
return c.model.showTitleBar;
});
// 点击工具栏处理
// const onActionClick = async (
// detail: IPSUIActionGroupDetail,
// event: MouseEvent,
// ) => {
// await props.controller.onActionClick(detail, event);
// };
return { ns, isShowHeader };
},
render() {
const { model } = this.$props.controller;
return (
<div class={[this.ns.b(), this.ns.is('no-header', !this.isShowHeader)]}>
{this.isShowHeader && (
<div key='header' class={this.ns.b('header')}>
<div class={this.ns.be('header', 'left')}>
{model.showTitleBar && (
<div class={this.ns.e('caption')}>
<app-icon
class={this.ns.e('caption-icon')}
icon={model.source.getPSSysImage()}
></app-icon>
<span class={this.ns.e('caption-text')} title={model.title}>
{model.title}
</span>
</div>
)}
</div>
{/* <div class={this.ns.be('header', 'right')}>
{model.actionGroup && (
<action-toolbar
class={this.ns.e('toolbar')}
action-details={this.controller.model.uiActionGroupDetails}
actions-state={state.actionGroupState}
onActionClick={this.onActionClick}
></action-toolbar>
)}
</div> */}
</div>
)}
<div key='content' class={this.ns.b('content')}>
{this.$slots.default}
</div>
</div>
);
},
});
......@@ -30,6 +30,7 @@ export const ViewBase = defineComponent({
this.ns.b(),
c.complete && this.ns.b(this.controller.model.typeClass),
c.complete && this.ns.m(this.controller.model.modelClass),
c.complete && this.controller.model.sysCssName,
]}
isComplete={c.complete}
modelData={c.model}
......
......@@ -26,7 +26,6 @@ export default defineComponent({
},
setup(props, ctx) {
const { proxy } = getCurrentInstance()!;
const route = useRoute(proxy) as Route;
const router = useRouter(proxy);
const viewData = ref<{
viewPath?: string;
......@@ -62,9 +61,8 @@ export default defineComponent({
if (appModel) {
// 获取视图
try {
const route = useRoute(proxy) as Route;
const _viewData = parseRouteViewData(appModel, route, props.level);
// 路由绘制的视图,添加一个上下文isRouter
_viewData.context!.isRouter = true;
const _context = IBizContext.create(_viewData.context);
viewData.value = {
......@@ -82,7 +80,7 @@ export default defineComponent({
calcViewData();
watch(
() => route.params.view1,
() => proxy.$route.params.view1,
() => {
if (props.level === 1) {
// 第一级路由壳监测到view1变化后,就重新计算一遍viewData
......@@ -92,7 +90,6 @@ export default defineComponent({
);
return {
route,
viewData,
isLoaded,
onNeuronInit,
......@@ -108,7 +105,11 @@ export default defineComponent({
context: this.viewData.context,
params: this.viewData.params,
modelPath: this.viewData.viewPath,
srfnav: this.viewData.srfnav,
modal: this.viewModal,
isRouter: true,
},
key: this.viewData.viewPath,
on: {
neuronInit: this.onNeuronInit,
},
......
......@@ -8,9 +8,10 @@ import { IModal } from '@ibiz-template/runtime';
export const ViewShell = defineComponent({
name: 'ViewShell',
props: {
context: Object as PropType<IContext>,
context: { type: Object as PropType<IContext>, required: true },
params: { type: Object as PropType<IParams> },
modal: { type: Object as PropType<IModal> },
isRouter: { type: Boolean },
modelPath: { type: String, required: true },
},
setup(props) {
......@@ -21,16 +22,21 @@ export const ViewShell = defineComponent({
},
);
const ns = useNamespace('view-shell');
return { ns, provider };
// 路由绘制的视图,添加一个上下文isRouter
const cloneContext = props.context.clone();
cloneContext.isRouter = props.isRouter === true;
return { ns, provider, cloneContext };
},
render(h) {
if (this.provider) {
return h('AppTransition', {}, [
h(this.provider.component, {
...this.$vnode.data,
on: this.$listeners,
}),
]);
const opts = {
...this.$vnode.data,
on: this.$listeners,
};
opts.props!.context = this.cloneContext;
return h('AppTransition', {}, [h(this.provider.component, opts)]);
}
return (
<div class={this.ns.b()}>
......
......@@ -10,3 +10,6 @@ export * from './wf-dyna-edit-view3/wf-dyna-edit-view3';
export * from './wf-dyna-start-view/wf-dyna-start-view';
export * from './wf-step-trace-view/wf-step-trace-view';
export * from './app-portal-view/app-portal-view';
export * from './tab-exp-view/tab-exp-view';
export * from './list-exp-view/list-exp-view';
export * from './list-view/list-view';
import { IModal, ViewMode } from '@ibiz-template/runtime';
import {
defineComponent,
PropType,
h,
ref,
Ref,
toRef,
getCurrentInstance,
} from 'vue';
import qs from 'qs';
import {
useListExpViewController,
useRoute,
useRouteKey,
} from '@ibiz-template/vue-util';
export const ListExpView = defineComponent({
name: 'ListExpView',
props: {
context: Object as PropType<IContext>,
params: { type: Object as PropType<IParams> },
srfnav: String,
modelPath: { type: String, required: true },
modal: { type: Object as PropType<IModal> },
},
setup(props) {
const { proxy } = getCurrentInstance()!;
const c = useListExpViewController(proxy, props.modelPath);
const routeViewKey: Ref<string> = ref('');
const defaultSelectKeys: Ref<string[]> = ref([]);
if (c.context.isRouter === true) {
const route = useRoute(proxy);
// 第一次设置key是由自身通知,后续走监听
c.nerve.self.evt.on('created', () => {
// 解析首页上下文参数里的主键
if (route.params.params1) {
const params1Str = route.params.params1 as string;
const params1Obj = qs.parse(params1Str, { delimiter: ';' });
const key = params1Obj[c.model.appEntity.deName] as string;
if (key) {
c.navItem.key = key;
defaultSelectKeys.value = [key];
}
}
// 监听并变更routeViewKey
useRouteKey(toRef(c.navItem, 'key'), proxy, routeViewKey);
});
}
return { c, defaultSelectKeys, routeViewKey };
},
render() {
if (this.c.complete) {
const isRouter = this.c.context.isRouter === true;
const { listExpBar } = this.c.model;
const { list } = listExpBar;
return (
<exp-view-base
controller={this.c}
expBarModel={this.c.model.listExpBar}
scopedSlots={{
default: () => {
if (this.c.providers[list.name]) {
const listComp = this.c.providers[list.name].component;
return h(listComp, {
props: {
modelData: list,
context: this.c.context,
params: this.c.params,
isExpView: true,
isSelectFirstDefault: true,
mdCtrlActiveMode: 1,
defaultSelectKeys: this.defaultSelectKeys,
},
on: {
neuronInit: this.c.nerve.onNeuronInit(list.name),
},
});
}
},
expView: () => {
if (!list.navView) {
return null;
}
if (isRouter) {
if (this.routeViewKey) {
return <router-view key={this.routeViewKey}></router-view>;
}
return null;
}
// 非路由模式下绘制嵌入视图
return h('ViewShell', {
props: {
context: this.c.navItem.context,
params: this.c.navItem.params,
modal: { mode: ViewMode.EMBED },
modelPath: list.navView.source.modelPath,
},
key: this.c.navItem.key,
});
},
}}
></exp-view-base>
);
}
return null;
},
});
import { IModal } from '@ibiz-template/runtime';
import { useListViewController } from '@ibiz-template/vue-util';
import { defineComponent, getCurrentInstance, PropType } from 'vue';
export const ListView = defineComponent({
props: {
context: Object as PropType<IContext>,
params: { type: Object as PropType<IParams>, default: () => ({}) },
modelPath: { type: String, required: true },
modal: { type: Object as PropType<IModal> },
},
setup(props) {
const { proxy } = getCurrentInstance()!;
const c = useListViewController(proxy, props.modelPath);
return { c };
},
render(h) {
let listComponent = null;
if (this.c.complete) {
const { list } = this.c.model;
if (this.c.providers[list.name]) {
listComponent = h(this.c.providers[list.name].component, {
props: {
modelData: list,
context: this.c.context,
params: this.c.params,
},
on: {
neuronInit: this.c.nerve.onNeuronInit(list.name),
},
});
}
}
return <md-view-base controller={this.c}>{listComponent}</md-view-base>;
},
});
@include b(view-detabexpview) {
// 分页头部样式
.ivu-tabs-nav .ivu-tabs-tab {
font-size: getCssVar('font-size', 'medium');
}
// 分页高度撑满,头部固定,内容区出滚动条
.#{bem('view-layout-content','body')} {
> .ivu-tabs {
height: 100%;
// 分页margin-bottom清除
> .ivu-tabs-bar{
margin-bottom: 0;
}
// 内容高度撑满除头部的区域
> .ivu-tabs-content {
height: calc(100% - 39px);
> .ivu-tabs-tabpane {
height: 100%;
overflow: auto;
}
}
}
}
@include e(tab){
z-index: 1;
}
@include m(route) {
// 分页高度自适应,分页内容区隐藏
.#{bem('view-layout-content','body')} {
position: relative;
> .ivu-tabs {
height: auto;
// 内容高度撑满除头部的区域
> .ivu-tabs-content {
display: none;
}
}
}
@include e(route-content) {
height: calc(100% - 39px);
> .#{bem('view-layout')} {
.#{bem('view-layout-header')} {
position: absolute;
top: -50px;
right: 0;
border: 0;
.#{bem('view-layout-header-content', 'caption')} {
display: none;
}
}
}
}
}
}
import { IModal, ViewMode } from '@ibiz-template/runtime';
import {
getViewName,
useNamespace,
useRoute,
useRouter,
useTabExpViewController,
} from '@ibiz-template/vue-util';
import {
computed,
defineComponent,
getCurrentInstance,
h,
PropType,
ref,
} from 'vue';
import './tab-exp-view.scss';
export const TabExpView = defineComponent({
props: {
context: Object as PropType<IContext>,
params: { type: Object as PropType<IParams> },
modelPath: { type: String, required: true },
modal: { type: Object as PropType<IModal> },
},
setup(props) {
const { proxy } = getCurrentInstance()!;
const ns = useNamespace('view-detabexpview');
const c = useTabExpViewController(proxy, props.modelPath);
const lazyList = ref<string[]>([]);
const activeTab = ref('');
// 使分页都不激活
const deactivateAll = ref(false);
const router = useRouter(proxy);
const tabExpPagesHistory: {
[page: string]: string;
} = {};
// 点击回调
const onTabClick = async (name: string) => {
const route = useRoute(proxy);
// 标签切换前缓存当前路径
const fullPath = route.fullPath;
tabExpPagesHistory[activeTab.value] = fullPath;
// 找到对应分页模型并初始化分页视图模型
const page = c.model.tabExpPanel.tabExpPages.find(
item => item.name === name,
);
// 分页面板视图延迟初始化
if (page?.embedView.initialized === false) {
await page.embedView.init();
}
if (c.context.isRouter) {
// 先让已有的分页变为不活跃
deactivateAll.value = true;
// 路由模式下变更路由
if (tabExpPagesHistory[name]) {
// 如果缓存过了路径直接跳路径
router.push(tabExpPagesHistory[name]);
} else {
const tempContext = Object.assign(c.context.clone(), {
toRouteLevel: c.modal.level! + 1,
});
ibiz.openView.root(page!.embedView.source, tempContext, c.params);
}
setTimeout(() => {
deactivateAll.value = false;
activeTab.value = name;
}, 0);
} else if (!lazyList.value.includes(name)) {
lazyList.value.push(name);
activeTab.value = name;
}
};
// 处理默认展示分页,预置是第一个分页
c.nerve.self.evt.on('created', () => {
const route = useRoute(proxy);
const { tabExpPages } = c.model.tabExpPanel;
// 路由呈现下,处理默认打开的标签页
if (c.context.isRouter) {
const tabLevel = props.modal!.level! + 1;
const tabViewName = route.params[`view${tabLevel}`];
if (tabViewName) {
const page = tabExpPages.find(item => {
return getViewName(item.embedView.source) === tabViewName;
});
if (page) {
activeTab.value = page.name;
}
}
}
// 路由没有打开的分页时,默认打开第一个分页
if (tabExpPages.length && !activeTab.value) {
const defaultTab = tabExpPages[0].name;
onTabClick(defaultTab);
}
});
const keyHistory = computed(() => {
return Object.values(c.tabExpPages).map(item => item.key);
});
return {
c,
ns,
onTabClick,
lazyList,
deactivateAll,
activeTab,
keyHistory,
};
},
render() {
const isRouter = this.c.context.isRouter === true;
return (
<view-base
class={[this.ns.b(), isRouter ? this.ns.m('route') : '']}
controller={this.c}
>
{this.c.complete && [
<i-tabs
class={this.ns.e('tab')}
name={this.c.model.codeName}
model-value={this.activeTab}
on-on-click={this.onTabClick}
>
{this.c.model.tabExpPanel.tabExpPages.map(page => {
const tabExpPage = this.c.tabExpPages[page.name];
if (!tabExpPage) {
return;
}
return (
<i-tab-pane
class={this.ns.e('tab-item')}
tab={this.c.model.codeName}
label={page.source.caption}
name={page.name}
>
{this.lazyList.includes(page.name) &&
h('ViewShell', {
props: {
context: this.c.context,
params: this.c.params,
modal: { mode: ViewMode.EMBED },
modelPath: page.embedView.source.modelPath,
},
on: {
neuronInit: this.c.nerve.onNeuronInit(page.name),
},
key: tabExpPage.key,
})}
</i-tab-pane>
);
})}
</i-tabs>,
isRouter && this.activeTab && (
<div class={this.ns.e('route-content')}>
<router-view
// manualKey={this.c.tabExpPages[this.activeTab].key}
key={this.c.tabExpPages[this.activeTab].key}
on-neuron-init={this.c.nerve.onNeuronInit(this.activeTab)}
>
{({ Component }: { Component: string }) => {
return (
Component && (
<appKeepAlive keyList={this.keyHistory}>
<Component />
</appKeepAlive>
)
);
}}
</router-view>
</div>
),
]}
</view-base>
);
},
});
......@@ -24,12 +24,10 @@ export const AppMenuPortlet = defineComponent({
this.ns.b(),
this.ns.m(this.modelData.modelClass),
];
const header: unknown = null;
return (
<div class={classArr}>
{header}
<div class={[this.ns.b('content')]}>{this.modelData.modelClass}</div>
</div>
<portlet-layout controller={this.controller} class={classArr}>
菜单
</portlet-layout>
);
},
});
@include b(dashboard) {
@include e(content){
width: 100%;
height: 100%;
}
}
\ No newline at end of file
......@@ -6,6 +6,7 @@ import {
} from '@ibiz-template/model';
import { useDashboardController, useNamespace } from '@ibiz-template/vue-util';
import { defineComponent, getCurrentInstance, h, PropType, VNode } from 'vue';
import './dashboard-control.scss';
/**
* 根据类型绘制数据看板成员
......@@ -77,10 +78,10 @@ export const DashboardControl = defineComponent({
render() {
return (
<control-layout modelData={this.c.model}>
<control-layout class={[this.ns.b()]} modelData={this.c.model}>
{this.c.complete && (
<app-row
class={[this.ns.b()]}
class={this.ns.e('content')}
layout={this.modelData.source.getPSLayout()}
>
{this.modelData.children.map(child => {
......
......@@ -2,4 +2,5 @@ export * from './portlet-part/portlet-part';
export * from './portlet-container/portlet-container';
export * from './app-menu-portlet/app-menu-portlet';
export * from './list-portlet/list-portlet';
export * from './view-portlet/view-portlet';
export * from './dashboard-control';
......@@ -42,12 +42,10 @@ export const ListPortlet = defineComponent({
this.ns.b(),
this.ns.m(this.modelData.modelClass),
];
const header: unknown = null;
return (
<div class={classArr}>
{header}
<div class={[this.ns.b('content')]}>{listComponent}</div>
</div>
<portlet-layout controller={this.controller} class={classArr}>
{listComponent}
</portlet-layout>
);
},
});
@include b(portlet-container) {
@include e(content){
width: 100%;
height: 100%;
}
}
\ No newline at end of file
......@@ -2,6 +2,7 @@ import { ContainerPortletController } from '@ibiz-template/controller';
import { ContainerPortletModel } from '@ibiz-template/model';
import { useNamespace } from '@ibiz-template/vue-util';
import { defineComponent, VNode } from 'vue';
import './portlet-container.scss';
export const PortletContainer = defineComponent({
name: 'PortletContainer',
......@@ -22,7 +23,10 @@ export const PortletContainer = defineComponent({
render() {
const defaultSlots: VNode[] = this.$slots.default || [];
const content = (
<app-row layout={this.modelData.source.getPSLayout()}>
<app-row
class={this.ns.e('content')}
layout={this.modelData.source.getPSLayout()}
>
{defaultSlots.map(slot => {
if (!slot.componentOptions) {
return slot;
......@@ -43,21 +47,10 @@ export const PortletContainer = defineComponent({
this.ns.b(),
this.ns.m(this.modelData.modelClass),
];
let header: unknown = null;
if (this.modelData.showTitleBar) {
header = (
<div class={[this.ns.b('header')]}>
<div class={[this.ns.e('caption')]}>
{this.modelData.source.title}
</div>
</div>
);
}
return (
<div class={classArr}>
{header}
<div class={[this.ns.b('content')]}>{content}</div>
</div>
<portlet-layout controller={this.controller} class={classArr}>
{content}
</portlet-layout>
);
},
});
......@@ -24,12 +24,10 @@ export const PortletPart = defineComponent({
this.ns.b(),
this.ns.m(this.modelData.modelClass),
];
const header: unknown = null;
return (
<div class={classArr}>
{header}
<div class={[this.ns.b('content')]}>{this.modelData.modelClass}</div>
</div>
<portlet-layout controller={this.controller} class={classArr}>
{this.modelData.source.portletType}暂未支持
</portlet-layout>
);
},
});
@include b(view-portlet) {
.#{bem('portlet-layout-content')}{
>.#{bem('view')}{
width: 100%;
height: 100%;
}
}
}
import { ViewMode } from '@ibiz-template/runtime';
import { ViewPortletModel } from '@ibiz-template/model';
import { defineComponent, h } from 'vue';
import './view-portlet.scss';
import { useNamespace } from '@ibiz-template/vue-util';
import { ViewNeuron, ViewPortletController } from '@ibiz-template/controller';
export const ViewPortlet = defineComponent({
name: 'ViewPortlet',
props: {
modelData: {
type: ViewPortletModel,
required: true,
},
controller: {
type: ViewPortletController,
required: true,
},
},
setup(props) {
const ns = useNamespace('view-portlet');
const onNeuronInit = (n: ViewNeuron) => {
props.controller.setViewNeuron(n);
};
return { ns, onNeuronInit };
},
render() {
const c = this.controller;
const classArr: string[] = [
this.ns.b(),
this.ns.m(this.modelData.modelClass),
];
return (
<portlet-layout controller={this.controller} class={classArr}>
{h('ViewShell', {
props: {
context: c.viewContext,
params: c.params,
modal: { mode: ViewMode.EMBED },
modelPath: c.model.embedView.source.modelPath,
},
on: {
neuronInit: this.onNeuronInit,
},
key: c.model.embedView.codeName,
})}
</portlet-layout>
);
},
});
......@@ -77,6 +77,9 @@ export const GridControl = defineComponent({
const columnSlots: IData = {};
// 表格列自定义
this.c.model.columns.forEach(column => {
if (column.source.columnType === 'GROUPGRIDCOLUMN') {
return;
}
const columnName = column.codeName;
columnSlots[columnName] = ({ row, index }: IData) => {
const rowController = this.c.rows[index];
......
/* eslint-disable no-param-reassign */
import { GridController } from '@ibiz-template/controller';
import { GridFieldColumnModel, GridModel } from '@ibiz-template/model';
import {
GridColumnModel,
GridFieldColumnModel,
GridGroupColumnModel,
GridModel,
} from '@ibiz-template/model';
import { ControlVO } from '@ibiz-template/service';
import { computed, ref } from 'vue';
export function generateColumnData(column: GridColumnModel, c: GridController) {
const columnChildren: IData[] = [];
if (column.source.columnType === 'GROUPGRIDCOLUMN') {
// 如果是分组列,递归生成children
(column as GridGroupColumnModel).children.forEach(child => {
columnChildren.push(generateColumnData(child, c));
});
}
const columnData = {
title: column.title,
width: column.source.widthUnit === 'STAR' ? undefined : column.width,
minWidth: column.width,
align: column.source.align?.toLowerCase() || 'center',
slot: column.codeName,
key: column.codeName,
fieldName: (column as GridFieldColumnModel).deFieldName,
ellipsis: true,
tooltip: false, // todo 表格提示用title
resizable: true,
sortable: !c.noSort && column.source.enableSort ? 'custom' : false,
};
if (columnChildren.length > 0) {
Object.assign(columnData, { children: columnChildren });
}
return columnData;
}
/**
* 生成iViewTable要用的columns
*
......@@ -15,21 +47,19 @@ import { computed, ref } from 'vue';
*/
export function generateIViewColumns(c: GridController): IData[] {
const gridModel: GridModel = c.model;
const columns: IData[] = gridModel.columns.map(column => {
const width = column.source.widthUnit === 'STAR' ? undefined : column.width;
return {
title: column.title,
width,
minWidth: column.width,
align: column.source.align?.toLowerCase() || 'center',
slot: column.codeName,
key: column.codeName,
fieldName: (column as GridFieldColumnModel).deFieldName,
ellipsis: true,
tooltip: false, // todo 表格提示用title
resizable: true,
sortable: !c.noSort && column.source.enableSort ? 'custom' : false,
};
const columns: IData[] = [];
// 生成所有表格列对应的iView表格需要的对象
const tempColumns: IData[] = gridModel.columns.map(column => {
return generateColumnData(column, c);
});
// 根据表格第一层的子去生成iView表格需要的columns
gridModel.children.forEach((childColumn: GridColumnModel) => {
const tempColumn = tempColumns.find(column => {
return column.key === childColumn.codeName;
});
if (tempColumn) {
columns.push(tempColumn);
}
});
// 多选的时候给第一列添加选择列
......
@include b(control-list-item) {
@include set-component-css-var('control-list-item', $control-list-item);
padding: getCssVar('control-list-item', 'padding');
cursor: pointer;
&:hover {
background-color: getCssVar('control-list-item', 'hover-bg-color');
}
@include when(active) {
background-color: getCssVar('control-list-item', 'active-bg-color');
}
}
@include b(control-list) {
// 加载更多样式
@include e(load-more) {
text-align: center;
cursor: pointer;
}
}
import { ListModel } from '@ibiz-template/model';
import { ControlVO } from '@ibiz-template/service';
import { useListController, useNamespace } from '@ibiz-template/vue-util';
import { defineComponent, getCurrentInstance, PropType } from 'vue';
import {
defineComponent,
h,
PropType,
onMounted,
watch,
getCurrentInstance,
} from 'vue';
import './list-control.scss';
import { useListEvent } from './list-control.util';
export const ListControl = defineComponent({
name: 'ListControl',
......@@ -11,27 +21,164 @@ export const ListControl = defineComponent({
},
context: { type: Object as PropType<IContext>, required: true },
params: { type: Object as PropType<IParams>, default: () => ({}) },
/**
* 行数据默认激活模式
* - 0 不激活
* - 1 单击激活
* - 2 双击激活(默认值)
*
* @type {(number | 0 | 1 | 2)}
*/
mdCtrlActiveMode: { type: Number, default: 2 },
/**
* 是否默认选中第一条数据
*
* @type boolean
*/
isSelectFirstDefault: { type: Boolean, required: false },
/**
* 默认选中的数据
*
* @type Array
*/
defaultSelectKeys: { type: Array<string>, required: false },
/**
* 是否包含在导航视图内
*
* @type boolean
*/
isExpView: { type: Boolean, required: false },
},
setup(props) {
const { proxy } = getCurrentInstance()!;
const ns = useNamespace('list');
const ns = useNamespace('control-list');
const c = useListController(
proxy,
props.modelData,
props.context,
props.modelData!,
props.context!,
props.params,
);
return { c, ns };
const { handleClick, handleDblClick } = useListEvent(c);
onMounted(() => {
// 外部传入默认选中数组,第一次加载数据后选中其中第一项,未传入默认数据,选中全部数据第一项
watch(
() => c,
(newVal, oldVal) => {
if (props.isExpView && newVal && newVal !== oldVal) {
let defaultSelectItem = c.items[0];
if (props.defaultSelectKeys && props.defaultSelectKeys.length > 0) {
const defaultItem = c.items.find((item: ControlVO) => {
return item.srfkey === props.defaultSelectKeys![0];
});
if (defaultItem) {
defaultSelectItem = defaultItem;
}
}
// 默认选中数据
if (defaultSelectItem) {
c.onSelectionChange([defaultSelectItem]);
}
}
},
{ immediate: true },
);
watch(
() => c.items.length,
(newVal, oldVal) => {
// 导航删除后高亮第一条
if (props.isExpView && newVal && newVal + 1 === oldVal) {
c.onSelectionChange([c.items[0]]);
}
},
{ immediate: true, deep: true },
);
});
// 绘制默认列表项
const renderDefaultItem = (item: ControlVO) => {
const findIndex = c.selectedData.findIndex(data => {
return data.srfkey === item.srfkey;
});
const itemClass = [ns.b('item'), ns.is('active', findIndex !== -1)];
return (
<div
class={itemClass}
key={item.srfkey}
onClick={() => handleClick(item)}
onDblclick={() => handleDblClick(item)}
>
{c.layoutPanelProvider
? h(c.layoutPanelProvider.component, {
props: {
modelData: c.model,
context: c.context,
params: c.params,
inputData: item,
},
})
: `${item.srfmajortext}:${item.srfkey}`}
</div>
);
};
// // 绘制分组
// const renderGroup = () => {
// return c.groupData.map((group: IData) => {
// return (
// <el-collapse-item class={ns.e('group-item')}>
// {{
// title: () => {
// return <b>{group.group}</b>;
// },
// default: () => {
// if (group.children.length > 0) {
// return (
// <div>
// {group.children.map((groupChild: ControlVO) => {
// return renderDefaultItem(groupChild);
// })}
// </div>
// );
// }
// return <div class={ns.e('group-item-empty')}>无数据</div>;
// },
// }}
// </el-collapse-item>
// );
// });
// };
// 绘制卡片内容
const renderListContent = () => {
if (!c.model.source.enableGroup) {
return c.items.map(item => {
return renderDefaultItem(item);
});
}
return <el-collapse></el-collapse>;
};
// 绘制加载更多
const renderLoadMore = () => {
return Object.is(c.total, c.items.length) ? null : (
<div
onClick={(e: MouseEvent) => c.loadMore(e)}
class={ns.e('load-more')}
>
加载更多
</div>
);
};
return { c, ns, renderListContent, renderLoadMore };
},
render() {
if (!this.c.complete) {
return;
}
return (
<control-layout modelData={this.c.model}>
{this.c.items.map(item => {
return <div>{`${item.srfmajortext}:${item.srfkey}`}</div>;
})}
{this.c.complete && [this.renderListContent(), this.renderLoadMore()]}
</control-layout>
);
},
......
import { ListController } from '@ibiz-template/controller';
import { ControlVO } from '@ibiz-template/service';
/**
* 使用列表
*
* @export
* @param {ListController} c
* @returns {*}
*/
export function useListEvent(c: ListController) {
// 处理单击
const handleClick = (data: ControlVO) => {
const selectIndex = c.selectedData.findIndex(selectData => {
return data.srfkey === selectData.srfkey;
});
if (!c.singleSelect) {
// 多选
const selections = c.selectedData;
// 没有加入,有就删除
if (selectIndex === -1) {
selections.push(data);
} else {
selections.splice(selectIndex, 1);
}
c.onSelectionChange(selections);
} else if (selectIndex === -1) {
// 单选,没有就放这一条,有就清空
c.onSelectionChange([data]);
} else {
c.onSelectionChange([]);
}
c.handleClick(data);
};
// 处理双击
const handleDblClick = (data: ControlVO) => {
c.handleDblClick(data);
};
return { handleClick, handleDblClick };
}
......@@ -37,20 +37,22 @@ export const SearchFormControl = defineComponent({
controller={this.c}
nativeOnkeyup={(e: KeyboardEvent) => this.c.onKeyUp(e)}
></form-control>
<div class={this.ns.b('buttons')}>
<i-button
class={this.ns.be('buttons', 'search')}
on-click={() => this.c.onSearchButtonClick()}
>
查询
</i-button>
<i-button
class={this.ns.be('buttons', 'reset')}
on-click={() => this.c.reset()}
>
重置
</i-button>
</div>
{this.c.model.source.searchButtonStyle === 'NONE' ? null : (
<div class={this.ns.b('buttons')}>
<i-button
class={this.ns.be('buttons', 'search')}
on-click={() => this.c.onSearchButtonClick()}
>
查询
</i-button>
<i-button
class={this.ns.be('buttons', 'reset')}
on-click={() => this.c.reset()}
>
重置
</i-button>
</div>
)}
</div>
);
},
......
......@@ -22,6 +22,7 @@ import {
Spin,
Tabs,
Button,
ButtonGroup,
Select,
Option,
RadioGroup,
......@@ -42,6 +43,7 @@ import {
LoadingBar,
Notice,
Badge,
Progress,
} from 'view-design';
const components = [
......@@ -67,6 +69,7 @@ const components = [
Spin,
Tabs,
Button,
ButtonGroup,
Select,
Option,
RadioGroup,
......@@ -84,6 +87,7 @@ const components = [
InputNumber,
Drawer,
Badge,
Progress,
];
export const IViewRegister = {
......
import { RuntimeError } from '@ibiz-template/core';
import { DefectModelError } from '@ibiz-template/model';
import {
IPluginFactory,
IPluginItem,
......@@ -155,7 +154,7 @@ export class PluginFactory implements IPluginFactory {
pluginRef.rTObjectRepo,
);
} catch (error) {
throw new DefectModelError(pluginRef, `配置加载失败`);
ibiz.log.error(error);
}
}
}
......
import {
IGridColumnProvider,
GridController,
GridGroupColumnController,
} from '@ibiz-template/controller';
import { GridGroupColumnModel } from '@ibiz-template/model';
/**
* 表格分组列适配器
*
* @export
* @class GridGroupColumnProvider
* @implements {IGridColumnProvider}
*/
export class GridGroupColumnProvider implements IGridColumnProvider {
component: string = '';
async createController(
columnModel: GridGroupColumnModel,
grid: GridController,
): Promise<GridGroupColumnController> {
const c = new GridGroupColumnController(columnModel, grid);
await c.init();
return c;
}
}
import { GridFieldColumnProvider } from './grid-field-column-provider';
import { GridFieldEditColumnProvider } from './grid-field-edit-column-provider';
import { GridUAColumnProvider } from './grid-ua-column-provider';
import { GridGroupColumnProvider } from './grid-group-column-provider';
/**
* 预置默认的表格列适配器
......@@ -20,11 +21,13 @@ export function presetGridColumnProvider(): void {
gridColumn.register('DEFGRIDCOLUMN_EDIT', new GridFieldEditColumnProvider());
// 表格操作列
gridColumn.register('UAGRIDCOLUMN', new GridUAColumnProvider());
// todo 表格分组列 GROUPGRIDCOLUMN
// 表格分组列
gridColumn.register('GROUPGRIDCOLUMN', new GridGroupColumnProvider());
}
export {
GridFieldColumnProvider,
GridUAColumnProvider,
GridFieldEditColumnProvider,
GridGroupColumnProvider,
};
......@@ -15,7 +15,7 @@ import { PortletPartModel, ViewPortletModel } from '@ibiz-template/model';
* @class ViewPortletProvider
*/
export class ViewPortletProvider implements IPortletPartProvider {
component: string = 'PortletPart';
component: string = 'ViewPortlet';
async createController(
portletModel: PortletPartModel,
......
......@@ -4,10 +4,13 @@ import { EditViewProvider } from './edit-view-provider';
import { EditView3Provider } from './edit-view3-provider';
import { GridViewProvider } from './grid-view-provider';
import { IndexViewProvider } from './index-view-provider';
import { ListExpViewProvider } from './list-exp-view-provider';
import { ListViewProvider } from './list-view-provider';
import { MPickupViewProvider } from './mpickup-view-provider';
import { OptViewProvider } from './opt-view-provider';
import { PickupGridViewProvider } from './pickup-grid-view-provider';
import { PickupViewProvider } from './pickup-view-provider';
import { TabExpViewProvider } from './tab-exp-view-provider';
import { WFDynaActionViewProvider } from './wf-dyna-action-view-provider';
import { WFDynaEditView3Provider } from './wf-dyna-edit-view3-provider';
import { WFDynaStartViewProvider } from './wf-dyna-start-view-provider';
......@@ -28,6 +31,7 @@ export function presetViewProvider(): void {
}
view.register(ViewType.APP_INDEX_VIEW, new IndexViewProvider());
view.register(ViewType.DE_EDIT_VIEW, new EditViewProvider());
view.register(ViewType.DE_EDIT_VIEW9, new EditViewProvider());
view.register(ViewType.DE_GRID_VIEW, new GridViewProvider());
view.register(ViewType.DE_GRID_VIEW9, new GridViewProvider());
view.register(ViewType.DE_EDIT_VIEW3, new EditView3Provider());
......@@ -43,6 +47,10 @@ export function presetViewProvider(): void {
);
view.register(ViewType.APP_WF_STEP_TRACE_VIEW, new WFStepTraceViewProvider());
view.register(ViewType.APP_PORTAL_VIEW, new AppPortalViewProvider());
// 导航
view.register(ViewType.DE_TAB_EXP_VIEW, new TabExpViewProvider());
view.register(ViewType.DE_LIST_EXP_VIEW, new ListExpViewProvider());
view.register(ViewType.DE_LIST_VIEW, new ListViewProvider());
}
export {
......@@ -59,4 +67,7 @@ export {
WFDynaActionViewProvider,
WFStepTraceViewProvider,
AppPortalViewProvider,
ListExpViewProvider,
ListViewProvider,
TabExpViewProvider,
};
import { IViewProvider } from '@ibiz-template/controller';
/**
* 列表导航视图适配器
*
* @export
* @class ListExpViewProvider
* @implements {IViewProvider}
*/
export class ListExpViewProvider implements IViewProvider {
component: string = 'ListExpView';
}
import { IViewProvider } from '@ibiz-template/controller';
/**
* 列表视图适配器
*
* @export
* @class ListViewProvider
* @implements {IViewProvider}
*/
export class ListViewProvider implements IViewProvider {
component: string = 'ListView';
}
import { IViewProvider } from '@ibiz-template/controller';
/**
* 分页导航视图适配器
*
* @author lxm
* @date 2022-10-25 18:10:57
* @export
* @class TabExpViewProvider
* @implements {IViewProvider}
*/
export class TabExpViewProvider implements IViewProvider {
component: string = 'TabExpView';
}
......@@ -58,11 +58,15 @@ export default defineConfig({
target: 'http://172.16.240.140:20086',
changeOrigin: true,
},
'/jskq__kqwebapp': {
target: 'http://172.16.103.134:30060',
changeOrigin: true,
},
},
cors: true,
fs: {
strict: false
}
strict: false,
},
},
css: {
preprocessorOptions: {
......
此差异已折叠。
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册