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

update:更新

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