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

update:更新

1、补充表单关系界面导航参数处理逻辑
2、增加主数据视图刷新逻辑
3、调整主数据视图通知部件加载逻辑
上级 601a40e8
<AppFormDruipart <AppFormDruipart
name="{{item.codeName}}" name="{{item.codeName}}"
title="{{item.caption}}" title="{{item.caption}}"
:formSubject="state.formSubject"
:visible="state.detailsModel.{{item.codeName}}.visible" :visible="state.detailsModel.{{item.codeName}}.visible"
viewCodeName="{{item.psAppView.codeName}}"
:layoutOpts="{{> @macro/front-end/common/layoutPos.hbs layout=item.psLayout layoutPos=item.psLayoutPos}}" :layoutOpts="{{> @macro/front-end/common/layoutPos.hbs layout=item.psLayout layoutPos=item.psLayoutPos}}"
{{#if item.psSysCss}} {{#if item.psSysCss}}
class="{{item.psSysCss.cssName}}" class="{{item.psSysCss.cssName}}"
...@@ -9,19 +11,29 @@ ...@@ -9,19 +11,29 @@
{{#if (or item.width item.height)}} {{#if (or item.width item.height)}}
style="{{#if item.width}}width: {{item.width}}px;{{/if}}{{#if item.height}}height: {{item.height}}px;{{/if}}" style="{{#if item.width}}width: {{item.width}}px;{{/if}}{{#if item.height}}height: {{item.height}}px;{{/if}}"
{{/if}} {{/if}}
paramItem="{{#if item.paramItem}}{{item.paramItem}}{{else}}srfkey{{/if}}"
deCodeName="{{lowerCase ctrl.appEntity.codeName}}"
:context="context" :context="context"
:viewParams="viewParams" :viewParams="viewParams"
{{#if item.psNavigateContexts}}
:localContext="{{> @macro/front-end/common/navparam.hbs appNavParams=item.psNavigateContexts}}"
{{/if}}
{{#if item.psNavigateParams}}
:localViewParams="{{> @macro/front-end/common/navparam.hbs appNavParams=item.psNavigateParams}}"
{{/if}}
:data="state.data" :data="state.data"
:viewSubject="state.viewSubject"> :viewSubject="state.viewSubject">
<template #default="druipartParams"> <template #default="druipartParams">
<{{item.psAppView.codeName}} <{{item.psAppView.codeName}}
:class="['app-view-layout--from-druipart']" :class="['app-view-layout--from-druipart']"
:context="druipartParams.context" :context="druipartParams.context"
:viewParams="druipartParams.viewParams" :viewParams="druipartParams.viewParams"
:viewDefaultUsage="false" :viewDefaultUsage="false"
:noViewCaption="true" :showCaptionBar="false"
@viewEvent="druipartParams.viewEvent" openType="EMBED"
> :viewSubject="state.viewSubject"
</{{item.psAppView.codeName}}> @viewEvent="druipartParams.viewEvent"
>
</{{item.psAppView.codeName}}>
</template> </template>
</AppFormDruipart> </AppFormDruipart>
<script setup lang="ts"> <script setup lang="ts">
import { IActionParam, ILayoutOpts, IParam, RouteUtil } from '@core'; import { deepCopy, IActionParam, ILayoutOpts, IParam, RouteUtil, UIUtil } from '@core';
import { context } from 'ant-design-vue/lib/vc-image/src/PreviewGroup';
import { Subject, Subscription } from 'rxjs'; import { Subject, Subscription } from 'rxjs';
import { Ref } from 'vue';
interface FormDruipartProps { interface FormDruipartProps {
// 名称 // 名称
name: string; name: string;
...@@ -11,7 +13,9 @@ interface FormDruipartProps { ...@@ -11,7 +13,9 @@ interface FormDruipartProps {
// 禁止加载 // 禁止加载
isForbidLoad?: boolean; isForbidLoad?: boolean;
// 传入参数项名称 // 传入参数项名称
paramItem?: string; paramItem: string;
// 表单实体代码标识
deCodeName: string;
// 视图上下文 // 视图上下文
context: any; context: any;
// 视图参数 // 视图参数
...@@ -27,13 +31,21 @@ interface FormDruipartProps { ...@@ -27,13 +31,21 @@ interface FormDruipartProps {
// 表单数据 // 表单数据
data: any; data: any;
// 视图订阅对象 // 视图订阅对象
viewSubject: Subject<any>; viewSubject: Subject<IActionParam>;
// 表单订阅对象
formSubject: Subject<any>;
// 视图路由参数 // 视图路由参数
parameters?: any[]; parameters: any[];
// 是否忽略表单项值变化 // 是否忽略表单项值变化
ignoreFieldValueChange?: boolean; ignoreFieldValueChange?: boolean;
// 是否显示 // 是否显示
visible?: boolean; visible?: boolean;
// 关系视图标识
viewCodeName: string;
// 导航上下文
localContext?: IParam;
// 导航视图参数
localViewParams?: IParam;
} }
interface FormDruipartEmit { interface FormDruipartEmit {
(name: 'componentEvent', value: IActionParam): void; (name: 'componentEvent', value: IActionParam): void;
...@@ -44,15 +56,17 @@ const props = withDefaults(defineProps<FormDruipartProps>(), { ...@@ -44,15 +56,17 @@ const props = withDefaults(defineProps<FormDruipartProps>(), {
const emit = defineEmits<FormDruipartEmit>(); const emit = defineEmits<FormDruipartEmit>();
// 视图通讯事件
let viewSubjectEvent: undefined | Subscription = undefined; let viewSubjectEvent: undefined | Subscription = undefined;
const formDruipart: Subject<any> = new Subject<any>(); // 表单通讯事件
let formSubjectEvent: undefined | Subscription = undefined;
// 关秀界面上下文 // 关秀界面上下文
let druipartContext:any = undefined; let druipartContext: Ref<any> = ref({});
// 关秀界面视图参数 // 关秀界面视图参数
let druipartViewParams:any = undefined; let druipartViewParams: Ref<any> = ref({});
onBeforeMount(() => { onBeforeMount(() => {
watch( watch(
...@@ -75,44 +89,69 @@ const druipartInit = () => { ...@@ -75,44 +89,69 @@ const druipartInit = () => {
return; return;
} }
viewSubjectEvent = props.viewSubject.subscribe(($event: any) => { viewSubjectEvent = props.viewSubject.subscribe(($event: any) => {
// 表单加载完成 // 视图事件
if (Object.is($event.type, 'load')) {
refreshDRUIPart($event.data);
}
}); });
// formSubjectEvent = props.formSubject.subscribe(({ type, data }) => {
// // 表单加载完成
// if (type && Object.is(type, 'load')) {
// refreshDRUIPart(data);
// }
// })
}; };
// 刷新关系界面 // 刷新关系界面
const refreshDRUIPart = (data?: any) => { const refreshDRUIPart = (data?: any) => {
// const formData: any = data ? data : JSON.parse(props.data); const formData: any = data ? data : props.data;
// const _paramItem = formData[props.paramItem]; const paramItem = formData[props.paramItem];
// let tempContext: any = {}; // 应用上下文
// let tempParam: any = {}; const tempContext = deepCopy(props.context);
// 视图参数
// const _parameters: any[] = [RouteUtil.getIndexViewParam(), ...props.parameters]; const tempParams: any = deepCopy(props.viewParams);
// _parameters.forEach((parameter: any) => { // 路由参数
// const { pathName, parameterName }: { pathName: string; parameterName: string } = parameter; const _parameters: any[] = [RouteUtil.getIndexViewParam()];
// if (formData[parameterName] && !Object.is(formData[parameterName], '')) { if (props.parameters && props.parameters.length) {
// Object.assign(tempContext, { _parameters.push(...props.parameters);
// [parameterName]: formData[parameterName], }
// }); _parameters.forEach((parameter: any) => {
// } const { pathName, parameterName }: { pathName: string; parameterName: string } = parameter;
// }); if (formData[parameterName] && !Object.is(formData[parameterName], '')) {
// Object.assign(tempContext, { [props.paramItem]: _paramItem }); Object.assign(tempContext, {
// //设置顶层视图唯一标识 [parameterName]: formData[parameterName],
// Object.assign(tempContext, props.context); });
// Object.assign(tempContext, { }
// srfParentDeName: props.parentName, });
// srfParentDeMapName: props.parentDeName, Object.assign(tempContext, { [props.paramItem]: paramItem });
// srfParentKey: _paramItem, if (formData && (formData[props.deCodeName] || formData.srfkey)) {
// }); Object.assign(tempContext, { [props.deCodeName]: formData[props.deCodeName] || formData.srfkey });
// Object.assign(tempParam, { }
// srfParentDeName: props.parentName, //设置顶层视图唯一标识
// srfParentDeMapName: props.parentDeName, Object.assign(tempContext, {
// srfParentKey: _paramItem, srfParentDeName: props.parentName,
// }); srfParentDeMapName: props.parentDeName,
// 设置局部上下文 srfParentKey: paramItem,
formDruipart.next({ action: 'load' }); });
Object.assign(tempParams, {
srfParentDeName: props.parentName,
srfParentDeMapName: props.parentDeName,
srfParentKey: paramItem,
});
// 导航上下文
if (props.localContext) {
Object.assign(tempContext, UIUtil.computedNavData(formData, tempContext, tempParams, props.localContext))
}
// 导航视图参数
if (props.localViewParams) {
Object.assign(tempParams, UIUtil.computedNavData(formData, tempContext, tempParams, props.localViewParams))
}
Object.assign(druipartContext.value, tempContext);
Object.assign(druipartViewParams.value, tempParams);
nextTick(() => {
// 设置局部上下文
if (props.viewSubject) {
props.viewSubject.next({ tag: props.viewCodeName, action: 'viewRefresh', data: [] });
}
})
}; };
const viewEvent = (action:any) => { const viewEvent = (action:any) => {
......
...@@ -23,6 +23,33 @@ export class EditView extends MainView { ...@@ -23,6 +23,33 @@ export class EditView extends MainView {
*/ */
public declare form: IParam; public declare form: IParam;
/**
* @description 数据部件加载
* @protected
* @param {IParam} [data]
* @memberof EditView
*/
protected xDataControlLoad(data?: IParam) {
// 初始化数据能力部件
this.xDataControl = this.getForm();
const { isLoadDefault, context, viewParams, appEntityCodeName } = this.state;
if (this.getForm() && isLoadDefault) {
const tag = this.getForm().name;
let action: string = '';
if (
appEntityCodeName &&
context[appEntityCodeName.toLowerCase()] &&
!Object.is(context[appEntityCodeName.toLowerCase()], '')
) {
action = 'load';
} else {
action = 'loadDraft';
}
this.next({ tag: tag, action: action, data: viewParams });
}
this.state.isLoadDefault = true;
}
/** /**
* @description 处理视图初始化 * @description 处理视图初始化
* *
...@@ -33,24 +60,7 @@ export class EditView extends MainView { ...@@ -33,24 +60,7 @@ export class EditView extends MainView {
// 初始化表单引用 // 初始化表单引用
this.form = ref(null); this.form = ref(null);
onMounted(() => { onMounted(() => {
// 初始化数据能力部件 this.xDataControlLoad();
this.xDataControl = this.getForm();
const { isLoadDefault, context, viewparams, appDeKeyFieldName } = this.state;
if (this.getForm() && isLoadDefault) {
const tag = this.getForm().name;
let action: string = '';
if (
appDeKeyFieldName &&
context[appDeKeyFieldName] &&
!Object.is(context[appDeKeyFieldName], '')
) {
action = 'load';
} else {
action = 'loadDraft';
}
this.next({ tag: tag, action: action, data: viewparams });
}
this.state.isLoadDefault = true;
}) })
} }
......
import { ViewBase, MainViewState, IActionParam, IParam } from '@core'; import { ViewBase, MainViewState, IActionParam, IParam, isExistAndNotEmpty } from '@core';
/** /**
* 实体视图 * 实体视图
...@@ -23,6 +23,57 @@ export class MainView extends ViewBase { ...@@ -23,6 +23,57 @@ export class MainView extends ViewBase {
*/ */
public appUIService: any; public appUIService: any;
/**
* @description 使用视图初始化模块
* @memberof MainView
*/
public useViewInit(): void {
super.useViewInit();
const { viewSubject, viewCodeName } = this.state;
if (viewSubject) {
viewSubject.subscribe(({ tag, action, data }) => {
if (!tag || tag !== viewCodeName) {
return;
}
if (action === 'viewRefresh') {
this.refresh(data);
}
})
}
}
/**
* @description 数据部件加载
* @protected
* @param {IParam} [data]
* @memberof MainView
*/
protected xDataControlLoad(data?: IParam): void { }
/**
* @description 视图刷新
* @protected
* @param {IParam} [data]
* @memberof MainView
*/
protected refresh(data?: IParam): void { }
/**
* @description 使用视图刷新模块
* @return {*}
* @memberof MainView
*/
public useRefresh() {
const refresh = (data?: IParam) => {
const { xDataControlName } = this.state;
if (isExistAndNotEmpty(xDataControlName)) {
this.xDataControlLoad();
}
}
this.refresh = refresh;
return refresh;
}
/** /**
* 设置工具栏项状态 * 设置工具栏项状态
* *
...@@ -144,6 +195,7 @@ export class MainView extends ViewBase { ...@@ -144,6 +195,7 @@ export class MainView extends ViewBase {
return { return {
...superParams, ...superParams,
xDataControl: this.xDataControl, xDataControl: this.xDataControl,
refresh: this.useRefresh(),
onToolbarEvent: this.onToolbarEvent.bind(this), onToolbarEvent: this.onToolbarEvent.bind(this),
}; };
} }
......
...@@ -40,6 +40,28 @@ export class MDView extends MainView { ...@@ -40,6 +40,28 @@ export class MDView extends MainView {
*/ */
public declare searchBar: IParam; public declare searchBar: IParam;
/**
* @description 数据部件加载
* @protected
* @param {IParam} [data]
* @memberof MDView
*/
protected xDataControlLoad(data?: IParam): void {
// 初始化数据能力部件
this.xDataControl = this.getMDCtrl();
const { isLoadDefault } = this.state;
const searchForm = this.getSearchForm();
if (searchForm && isLoadDefault) {
const tag = searchForm.name;
this.next({ tag: tag, action: 'loaddraft', data: null });
} else if (this.xDataControl && isLoadDefault) {
const tag = this.xDataControl.name;
this.next({ tag: tag, action: 'load', data: null });
} else {
this.state.isLoadDefault = true;
}
}
/** /**
* @description 处理视图初始化 * @description 处理视图初始化
* *
...@@ -54,18 +76,7 @@ export class MDView extends MainView { ...@@ -54,18 +76,7 @@ export class MDView extends MainView {
// 初始化搜索栏引用 // 初始化搜索栏引用
this.searchBar = ref(null); this.searchBar = ref(null);
onMounted(() => { onMounted(() => {
// 初始化数据能力部件 this.xDataControlLoad();
this.xDataControl = this.getMDCtrl();
const { isLoadDefault } = this.state;
if (this.getSearchForm() && isLoadDefault) {
const tag = this.getSearchForm().name;
this.next({ tag: tag, action: 'loaddraft', data: null });
} else if (this.getMDCtrl() && isLoadDefault) {
const tag = this.getMDCtrl().name;
this.next({ tag: tag, action: 'load', data: null });
} else {
this.state.isLoadDefault = true;
}
}); });
} }
......
...@@ -67,6 +67,9 @@ export class ViewBase { ...@@ -67,6 +67,9 @@ export class ViewBase {
*/ */
protected handleReactiveState() { protected handleReactiveState() {
this.state.viewSubject = toRef(this.props, 'viewSubject') as any; this.state.viewSubject = toRef(this.props, 'viewSubject') as any;
if (this.props.showCaptionBar === false) {
this.state.showCaptionBar = false;
}
} }
/** /**
...@@ -111,7 +114,7 @@ export class ViewBase { ...@@ -111,7 +114,7 @@ export class ViewBase {
Object.assign(context.value, appData.context ? appData.context : {}); Object.assign(context.value, appData.context ? appData.context : {});
// 视图应用上下文 // 视图应用上下文
const pageContext = {}; const pageContext = {};
const routeParams = useRoute().params; const routeParams = useRoute()?.params;
if (routeParams && (Object.keys(routeParams).length > 0)) { if (routeParams && (Object.keys(routeParams).length > 0)) {
Object.keys(routeParams).forEach((key: string) => { Object.keys(routeParams).forEach((key: string) => {
if (routeParams[key]) { if (routeParams[key]) {
...@@ -122,7 +125,7 @@ export class ViewBase { ...@@ -122,7 +125,7 @@ export class ViewBase {
Object.assign(context.value, pageContext); Object.assign(context.value, pageContext);
// 视图参数 // 视图参数
const pageViewParams = {}; const pageViewParams = {};
const routeQuerys = useRoute().query; const routeQuerys = useRoute()?.query;
if (routeQuerys && (Object.keys(routeQuerys).length > 0)) { if (routeQuerys && (Object.keys(routeQuerys).length > 0)) {
Object.keys(routeQuerys).forEach((key: string) => { Object.keys(routeQuerys).forEach((key: string) => {
if (routeQuerys[key]) { if (routeQuerys[key]) {
...@@ -160,7 +163,8 @@ export class ViewBase { ...@@ -160,7 +163,8 @@ export class ViewBase {
// 导航视图参数处理 // 导航视图参数处理
this.handleViewContextParams(this.props, context, viewParams); this.handleViewContextParams(this.props, context, viewParams);
watch(context, (newVal: any, oldVal: any) => { watch(context, (newVal: any, oldVal: any) => {
this.handleViewContextParams(this.props, newVal, viewParams); // context转响应式对象
this.handleViewContextParams(this.props, isRef(newVal) ? newVal : ref(newVal), viewParams);
}); });
// 把Ref赋值到State上进行解包 // 把Ref赋值到State上进行解包
this.state.context = context; this.state.context = context;
......
...@@ -35,4 +35,11 @@ export interface ViewPropsBase { ...@@ -35,4 +35,11 @@ export interface ViewPropsBase {
* @memberof ViewPropsBase * @memberof ViewPropsBase
*/ */
openType?: "ROUTE" | "MODAL" | "EMBED"; openType?: "ROUTE" | "MODAL" | "EMBED";
/**
* @description 是否显示标题栏
* @type {boolean}
* @memberof ViewPropsBase
*/
showCaptionBar?: boolean;
} }
\ No newline at end of file
...@@ -15,6 +15,13 @@ export interface ViewStateBase { ...@@ -15,6 +15,13 @@ export interface ViewStateBase {
*/ */
context: IParam; context: IParam;
/**
* @description 视图标识
* @type {string}
* @memberof ViewStateBase
*/
viewCodeName: string;
/** /**
* @description 视图参数 * @description 视图参数
* @type {IParam} * @type {IParam}
...@@ -29,6 +36,13 @@ export interface ViewStateBase { ...@@ -29,6 +36,13 @@ export interface ViewStateBase {
*/ */
viewSubject: Subject<IActionParam>; viewSubject: Subject<IActionParam>;
/**
* @description 是否显示标题栏
* @type {boolean}
* @memberof ViewStateBase
*/
showCaptionBar: boolean;
// 声明任意属性 // 声明任意属性
[propName: string]: any; [propName: string]: any;
} }
import { Subject } from 'rxjs';
import { ControlVOBase, IParam, MainControlState } from '@core'; import { ControlVOBase, IParam, MainControlState } from '@core';
/** /**
...@@ -8,6 +9,13 @@ import { ControlVOBase, IParam, MainControlState } from '@core'; ...@@ -8,6 +9,13 @@ import { ControlVOBase, IParam, MainControlState } from '@core';
*/ */
export interface FormControlState extends MainControlState { export interface FormControlState extends MainControlState {
/**
* @description 行为模型
* @type {IParam}
* @memberof FormControlState
*/
actionModel: IParam;
/** /**
* @description 新建默认值集合 * @description 新建默认值集合
* @type {IParam[]} * @type {IParam[]}
...@@ -29,6 +37,13 @@ export interface FormControlState extends MainControlState { ...@@ -29,6 +37,13 @@ export interface FormControlState extends MainControlState {
*/ */
detailsModel: IParam; detailsModel: IParam;
/**
* @description 表单通讯对象
* @type {Subject<any>}
* @memberof FormControlState
*/
formSubject: Subject<any>;
/** /**
* @description 值规则 * @description 值规则
* @type {IParam} * @type {IParam}
......
import { Subject } from 'rxjs';
import { import {
DataTypes, DataTypes,
dateFormat, dateFormat,
...@@ -31,10 +32,20 @@ export class FormControl extends MainControl { ...@@ -31,10 +32,20 @@ export class FormControl extends MainControl {
* *
* @memberof FormControl * @memberof FormControl
*/ */
public getData(): IParam[] { public getData(): IParam[] {
return [this.state.data]; return [this.state.data];
} }
/**
* 设置表单状态
*
* @memberof FormControl
*/
public setState() {
super.setState();
this.state.formSubject = new Subject();
}
/** /**
* @description 检验表单动态逻辑 * @description 检验表单动态逻辑
* @param {IParam} data 表单数据 * @param {IParam} data 表单数据
...@@ -454,7 +465,7 @@ export class FormControl extends MainControl { ...@@ -454,7 +465,7 @@ export class FormControl extends MainControl {
*/ */
const load = async (opt: any = {}) => { const load = async (opt: any = {}) => {
try { try {
const { controlService, context, viewParams, showBusyIndicator, controlAction } = this.state; const { controlService, context, viewParams, showBusyIndicator, controlAction, formSubject } = this.state;
if (!controlAction.loadAction) { if (!controlAction.loadAction) {
return; return;
} }
...@@ -472,6 +483,7 @@ export class FormControl extends MainControl { ...@@ -472,6 +483,7 @@ export class FormControl extends MainControl {
this.state.data = response.data; this.state.data = response.data;
this.emit('ctrlEvent', { tag: this.props.name, action: 'load', data: [response.data] }); this.emit('ctrlEvent', { tag: this.props.name, action: 'load', data: [response.data] });
this.afterFormAction('load'); this.afterFormAction('load');
formSubject.next({ type: 'load', data: this.state.data });
} }
} catch (error) { } catch (error) {
// TODO 错误异常处理 // TODO 错误异常处理
......
...@@ -78,7 +78,7 @@ export class UIUtil { ...@@ -78,7 +78,7 @@ export class UIUtil {
let value: string | null = params[name]; let value: string | null = params[name];
if (value && value.toString().startsWith('%') && value.toString().endsWith('%')) { if (value && value.toString().startsWith('%') && value.toString().endsWith('%')) {
const key = value.substring(1, value.length - 1).toLowerCase(); const key = value.substring(1, value.length - 1).toLowerCase();
if (activedata && activedata.hasOwnProperty(key)) { if (activedata && (activedata.hasOwnProperty(key) || key in activedata)) {
value = activedata[key]; value = activedata[key];
} else if (context && context[key]) { } else if (context && context[key]) {
value = context[key]; value = context[key];
......
...@@ -35,13 +35,12 @@ const { state, form, onToolbarEvent, onCtrlEvent } = editView; ...@@ -35,13 +35,12 @@ const { state, form, onToolbarEvent, onCtrlEvent } = editView;
</script> </script>
<template> <template>
<AppEditViewLayout :class="['app-edit-view', state.viewSysCss]"> <AppEditViewLayout :class="['app-edit-view', state.viewSysCss]" :showCaptionBar="state.showCaptionBar">
<template v-slot:caption> <template v-slot:caption>
<AppIconText <AppIconText
class="app-view__caption" class="app-view__caption"
size="large" size="large"
:subCaption="state.subCaption" :subCaption="state.subCaption"
:showCaptionBar="state.showCaptionBar"
:text="state.viewCaption" :text="state.viewCaption"
/> />
</template> </template>
......
...@@ -45,7 +45,7 @@ const { state, grid, searchForm, quickSearchForm, onCtrlEvent, onToolbarEvent, o ...@@ -45,7 +45,7 @@ const { state, grid, searchForm, quickSearchForm, onCtrlEvent, onToolbarEvent, o
</script> </script>
<template> <template>
<AppGridViewLayout :class="['app-grid-view', state.viewSysCss]"> <AppGridViewLayout :class="['app-grid-view', state.viewSysCss]" :showCaptionBar="state.showCaptionBar">
<template v-slot:caption> <template v-slot:caption>
<AppIconText class="app-view__caption" size="large" :text="state.viewCaption" /> <AppIconText class="app-view__caption" size="large" :text="state.viewCaption" />
</template> </template>
......
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册