提交 ec958233 编写于 作者: tony001's avatar tony001

update:更新

上级 1165434b
......@@ -13,6 +13,7 @@ declare module 'vue' {
AppDataPickerView: typeof import('./src/components/editors/app-data-picker-view.vue')['default']
AppDatePicker: typeof import('./src/components/editors/app-date-picker.vue')['default']
AppDefaultIndexViewLayout: typeof import('./src/components/layout/app-default-index-view-layout.vue')['default']
AppDrawer: typeof import('./src/components/render/app-drawer.vue')['default']
AppDropdownList: typeof import('./src/components/editors/app-dropdown-list.vue')['default']
AppEditViewLayout: typeof import('./src/components/layout/app-edit-view-layout.vue')['default']
AppFilterTree: typeof import('./src/components/render/app-filter-tree.vue')['default']
......@@ -28,9 +29,11 @@ declare module 'vue' {
AppLoading: typeof import('./src/components/render/app-loading.vue')['default']
AppMenuCenter: typeof import('./src/components/render/app-menu-center.vue')['default']
AppMenuItem: typeof import('./src/components/render/app-menu-item.vue')['default']
AppModal: typeof import('./src/components/render/app-modal.vue')['default']
AppMpickupViewLayout: typeof import('./src/components/layout/app-mpickup-view-layout.vue')['default']
AppPickupGridViewLayout: typeof import('./src/components/layout/app-pickup-grid-view-layout.vue')['default']
AppPickupViewLayout: typeof import('./src/components/layout/app-pickup-view-layout.vue')['default']
AppPopover: typeof import('./src/components/render/app-popover.vue')['default']
AppPortalViewLayout: typeof import('./src/components/layout/app-portal-view-layout.vue')['default']
AppQuickGroup: typeof import('./src/components/render/app-quick-group.vue')['default']
AppRadioGroup: typeof import('./src/components/editors/app-radio-group.vue')['default']
......
import { SyncSeriesHook } from "qx-util";
import { Environment } from "@/environments/environment";
import router from "@/router";
import { OpenViewService } from "@/utils";
import { AppBase, IParam, ViewDetail, IApp, IOpenViewService, deepCopy, Http, IAppAuthService } from "@core";
import { AppBase, IParam, ViewDetail, IApp, IOpenViewService, deepCopy, Http, IAppAuthService, IAppNotificationService, IAppFuncService, IAppActionService } from "@core";
import { AppFuncConfig, AppViewConfig, AppEntityConfig } from './config';
import { DataServiceRegister, UIServiceRegister } from "./register";
import { AppAuthService } from "./service/app-auth-service";
import { AppActionService, AppAuthService, AppFuncService, AppNotificationService, OpenViewService } from "@/service";
export class App extends AppBase implements IApp {
......@@ -91,6 +90,36 @@ export class App extends AppBase implements IApp {
return OpenViewService.getInstance();
}
/**
* 获取通知服务
*
* @return {*} {IAppNotificationService}
* @memberof App
*/
public getNotificationService(): IAppNotificationService {
return AppNotificationService.getInstance();
}
/**
* 获取应用功能服务
*
* @return {IAppFuncService}
* @memberof App
*/
public getAppFuncService(): IAppFuncService {
return AppFuncService.getInstance();
}
/**
* 获取界面行为服务
*
* @return {*} {IAppActionService}
* @memberof App
*/
public getAppActionService(): IAppActionService {
return AppActionService.getInstance();
}
/**
* 获取UI服务
*
......
<script setup lang="ts">
import { IParam, ViewDetail } from '@core';
import { Subject } from 'rxjs';
import { Ref, ref } from 'vue';
interface AppDrawerProps {
/**
* @description 视图
*/
view: ViewDetail;
/**
* @description 视图上下文参数
*/
context?: any;
/**
* @description 视图参数
*/
viewParams?: any;
/**
* @description 数据传递对象
*/
subject?: Subject<any>;
/**
* @description 关闭回调
*/
close: Function;
/**
* @description 是否全屏
*/
isFullscreen:boolean;
/**
* @description 模态参数
*/
option?: IParam;
}
const props = withDefaults(defineProps<AppDrawerProps>(), {
context: {},
viewParams: {},
});
/**
* 是否显示
*/
let isVisible: Ref<boolean> = ref(false);
/**
* 临时结果
*/
let tempResult = { ret: '' };
/**
* 视图名称
*/
let viewName: Ref<string> = ref('');
/**
* 抽屉的方向
*/
let placement: Ref<string> = ref('right');
/**
* 视图标题
*/
let title: string = '';
/**
* 视图宽度
*/
let width: Ref<number> = ref(0);
/**
* 视图高度
*/
let height: Ref<number> = ref(0);
/**
* 视图样式
*/
let style: any = {};
/**
* 暴露subject
*/
const getSubject = () => {
return props.subject;
};
/**
* Vue生命周期beforeMount
*/
onBeforeMount(() => {
if (props.view) {
viewName.value = props.view.name as string;
title = props.view.title || '';
placement.value = props.view.placement || 'right';
if (props.isFullscreen) {
Object.assign(style, { height: 'auto' });
} else {
if (!props.view.width || props.view.width === 0 || Object.is(props.view.width, '0px')) {
let viewWidth = 600;
if (window && window.innerWidth > 100) {
if (window.innerWidth > 100) {
viewWidth = window.innerWidth - 100;
} else {
viewWidth = window.innerWidth;
}
}
width.value = viewWidth;
} else {
width.value = props.view.width;
}
if (props.view.height && !Object.is(props.view.height, '0px')) {
Object.assign(style, { height: props.view.height + 'px' });
height.value = props.view.height;
} else {
height.value = 800;
}
}
}
});
/**
* Vue生命周期mounted
*/
onMounted(() => {
isVisible.value = true;
});
/**
* 视图关闭
*/
const close = (result: any) => {
if (result && Array.isArray(result) && result.length > 0) {
Object.assign(tempResult, { ret: 'OK' }, { datas: JSON.parse(JSON.stringify(result)) });
}
isVisible.value = false;
};
/**
* 视图数据变化
*/
const viewDataChange = (result: any) => {
tempResult = { ret: '' };
if (result && Array.isArray(result) && result.length > 0) {
Object.assign(tempResult, { ret: 'OK' }, { datas: JSON.parse(JSON.stringify(result)) });
}
};
/**
* 视图数据激活
*/
const viewDataActivated = (result: any) => {
if (result && Array.isArray(result) && result.length > 0) {
close(result);
}
};
/**
* 模态显示隐藏切换回调
*/
const onVisibleChange = ($event: any) => {
handleShowState($event);
props.close(tempResult);
};
/**
* 处理数据,向外抛值
*/
const handleShowState = ($event: any) => {
if (props.subject && tempResult) {
props.subject.next(tempResult);
}
};
</script>
<template>
<a-drawer
ref="curDrawer"
class="app-drawer"
v-model:visible="isVisible"
:placement="placement"
:title="title"
:footer="null"
:maskClosable="true"
:destroyOnClose="true"
:width="width"
:height="height"
:bodyStyle="style"
@close="onVisibleChange($event)"
>
<component
:is="viewName"
class="app-drawer-view-component"
:width="width"
:height="height"
:context="context"
:viewParams="viewParams"
:viewDefaultUsage="false"
:noViewCaption="true"
@viewDataChange="viewDataChange($event)"
@viewDataActivated="viewDataActivated($event)"
@close="close($event)"
:ref="viewName"
></component>
</a-drawer>
</template>
\ No newline at end of file
<script setup lang="ts">
import { IActionParam, IParam, ViewDetail } from '@core';
import { Subject } from 'rxjs';
import { Ref, ref } from 'vue';
interface AppModalProps {
/**
* @description 视图
*/
view: ViewDetail;
/**
* @description 视图上下文参数
*/
context?: any;
/**
* @description 视图参数
*/
viewParams?: any;
/**
* @description 数据传递对象
*/
subject?: Subject<any>;
/**
* @description 关闭回调
*/
close: Function;
/**
* @description 是否全屏
*/
isFullscreen: boolean;
/**
* @description 模态参数
*/
option?: IParam;
}
const props = withDefaults(defineProps<AppModalProps>(), {
context: {},
viewParams: {},
});
/**
* 是否显示
*/
let isVisible: Ref<boolean> = ref(false);
/**
* 临时结果
*/
let tempResult = { ret: '' };
/**
* 视图名称
*/
let viewName: Ref<string> = ref('');
/**
* 视图标题
*/
let title: string = '';
/**
* 视图宽度
*/
let width: Ref<number> = ref(0);
/**
* 视图高度
*/
let height: Ref<number> = ref(0);
/**
* 视图样式
*/
let style: any = {};
/**
* 暴露subject
*/
const getSubject = () => {
return props.subject;
};
/**
* Vue生命周期beforeMount
*/
onBeforeMount(() => {
if (props.view) {
viewName.value = props.view.name as string;
title = props.view.title || '';
if (props.isFullscreen) {
Object.assign(style, { height: 'auto' });
} else {
if (!props.view.width || props.view.width === 0 || Object.is(props.view.width, '0px')) {
let viewWidth = 600;
if (window && window.innerWidth > 100) {
if (window.innerWidth > 100) {
viewWidth = window.innerWidth - 100;
} else {
viewWidth = window.innerWidth;
}
}
width.value = viewWidth;
} else {
width.value = props.view.width;
}
if (props.view.height && !Object.is(props.view.height, '0px')) {
Object.assign(style, { height: props.view.height + 'px' });
height.value = props.view.height;
} else {
height.value = 800;
}
}
}
});
/**
* Vue生命周期mounted
*/
onMounted(() => {
isVisible.value = true;
});
/**
* 视图关闭
*/
const close = (result: any) => {
if (result && Array.isArray(result) && result.length > 0) {
Object.assign(tempResult, { ret: 'OK' }, { resultData: JSON.parse(JSON.stringify(result)) });
}
props.subject?.next(tempResult);
isVisible.value = false;
};
/**
* 视图数据变化
*/
const viewDataChange = (result: any) => {
tempResult = { ret: '' };
if (result && Array.isArray(result) && result.length > 0) {
Object.assign(tempResult, { ret: 'OK' }, { resultData: JSON.parse(JSON.stringify(result)) });
}
};
/**
* 视图数据激活
*/
const viewDataActivated = (result: any) => {
if (result && Array.isArray(result) && result.length > 0) {
close(result);
}
};
const handelViewEvent = (actionParam: IActionParam) => {
const { tag, action, data } = actionParam;
switch (action) {
case 'viewDataChange':
viewDataChange(data);
break;
case 'close':
close(data);
break;
}
};
/**
* 模态显示隐藏切换回调
*/
const onVisibleChange = ($event: any) => {
handleShowState($event);
props.close(tempResult);
};
/**
* 处理数据,向外抛值
*/
const handleShowState = ($event: any) => {
if (props.subject && tempResult) {
props.subject.next(tempResult);
}
};
</script>
<template>
<a-modal
ref="curModal"
class="app-modal"
v-model:visible="isVisible"
:title="title"
:footer="null"
:maskClosable="true"
:destroyOnClose="true"
:width="width"
:height="height"
:bodyStyle="style"
@cancel="onVisibleChange($event)"
>
<component
:is="viewName"
class="app-modal-view-component"
:context="context"
:viewParams="viewParams"
:viewDefaultUsage="false"
:noViewCaption="true"
@viewEvent="handelViewEvent($event)"
@viewDataActivated="viewDataActivated($event)"
@close="close($event)"
:ref="viewName"
></component>
</a-modal>
</template>
\ No newline at end of file
<script setup lang="ts">
import { IActionParam, IParam, ViewDetail } from '@core';
import { Subject } from 'rxjs';
import { Ref, ref, h } from 'vue';
interface AppPopoverProps {
/**
* @description 视图
*/
view: ViewDetail;
/**
* @description 视图上下文参数
*/
context?: any;
/**
* @description 视图参数
*/
viewParams?: any;
/**
* @description 数据传递对象
*/
subject?: Subject<any>;
/**
* @description 是否全屏
*/
isFullscreen:boolean;
/**
* @description 模态参数
*/
option?: IParam;
/**
* @description 鼠标移出回调
*/
mouseout: Function;
}
const props = withDefaults(defineProps<AppPopoverProps>(), {
context: {},
viewParams: {},
});
/**
* 临时结果
*/
let tempResult = { ret: '' };
/**
* 视图名称
*/
let viewName: Ref<string> = ref('');
/**
* 抽屉的方向
*/
let placement: Ref<string> = ref('bottom');
/**
* 视图标题
*/
let title: string = '';
/**
* 视图宽度
*/
let width: Ref<number> = ref(0);
/**
* 视图高度
*/
let height: Ref<number> = ref(0);
/**
* 视图样式
*/
let style: any = {};
/**
* 暴露subject
*/
const getSubject = () => {
return props.subject;
};
/**
* Vue生命周期beforeMount
*/
onBeforeMount(() => {
if (props.view) {
viewName.value = props.view.name as string;
title = props.view.title || '';
placement.value = props.view.placement || 'bottom';
if (props.isFullscreen) {
Object.assign(style, { height: 'auto' });
} else {
if (!props.view.width || props.view.width === 0 || Object.is(props.view.width, '0px')) {
width.value = 300;
Object.assign(style, { width: width.value + 'px' });
} else {
width.value = props.view.width;
Object.assign(style, { width: width.value + 'px' });
}
if (props.view.height && !Object.is(props.view.height, '0px')) {
height.value = props.view.height;
Object.assign(style, { height: height.value + 'px' });
} else {
height.value = 300;
Object.assign(style, { height: height.value + 'px' });
}
}
}
});
/**
* 视图关闭
*/
const close = (result: any) => {
if (result && Array.isArray(result) && result.length > 0) {
Object.assign(tempResult, { ret: 'OK' }, { datas: JSON.parse(JSON.stringify(result)) });
}
props.subject?.next(tempResult);
};
/**
* 视图数据变化
*/
const viewDataChange = (result: any) => {
tempResult = { ret: '' };
if (result && Array.isArray(result) && result.length > 0) {
Object.assign(tempResult, { ret: 'OK' }, { datas: JSON.parse(JSON.stringify(result)) });
}
};
/**
* 视图数据激活
*/
const viewDataActivated = (result: any) => {
if (result && Array.isArray(result) && result.length > 0) {
close(result);
}
};
/**
* 显示隐藏切换回调
*/
const onVisibleChange = ($event: any) => {
handleShowState($event);
};
/**
* 处理数据,向外抛值
*/
const handleShowState = ($event: any) => {
if (props.subject && tempResult) {
props.subject.next(tempResult);
}
};
/**
* 处理视图事件
*/
const handelViewEvent = (actionParam: IActionParam) => {
const { tag, action, data } = actionParam;
switch (action) {
case 'viewDataChange':
viewDataChange(data);
break;
case 'close':
close(data);
break;
}
};
/**
* 点击事件
*/
const click = (e:any) => {
e.stopPropagation()
}
/**
* 鼠标移出事件
*/
const mouseout = (e:any) => {
props.mouseout();
}
</script>
<template>
<div :style="style" class="app-popover" @click="click" @mouseleave="mouseout">
<component
:is="viewName"
class="app-popover-component"
:width="width"
:height="height"
:context="context"
:viewParams="viewParams"
:viewDefaultUsage="false"
:noViewCaption="true"
@viewEvent="handelViewEvent($event)"
@viewDataActivated="viewDataActivated($event)"
@close="close($event)"
></component>
</div>
</template>
\ No newline at end of file
import { IParam, ViewDetail } from "../common";
import { IAppAuthService, IAppFuncService, IOpenViewService } from "../service";
import { IAppActionService, IAppAuthService, IAppFuncService, IAppNotificationService, IOpenViewService } from "../service";
/**
......@@ -43,6 +43,22 @@ export interface IApp {
*/
getAppAuthService(): IAppAuthService;
/**
* 获取通知服务
*
* @return {*} {IAppNotificationService}
* @memberof IApp
*/
getNotificationService(): IAppNotificationService;
/**
* 获取界面行为服务
*
* @return {*} {IAppActionService}
* @memberof IApp
*/
getAppActionService(): IAppActionService;
/**
* 获取UI服务
*
......
/**
* @description 应用权限服务
* @export
* @interface IAppNotificationService
*/
export interface IAppNotificationService {
/**
* 成功提示
*
* @param {*} opts 参数
* @memberof IAppNotificationService
*/
success(opts: any): void;
/**
* 信息提示
*
* @param {*} opts 参数
* @memberof IAppNotificationService
*/
info(opts: any): void;
/**
* 警告提示
*
* @param {*} opts 参数
* @memberof IAppNotificationService
*/
warning(opts: any): void;
/**
* 错误提示
*
* @param {*} opts 参数
* @memberof IAppNotificationService
*/
error(opts: any): void;
}
\ No newline at end of file
export * from './i-app-func-service';
export * from './i-app-notification-service';
export * from './i-app-action-service';
export * from './i-open-view-service';
export * from './i-data-service-register';
......
import { AppActionService, IContext, IParam, UIActionUtil } from "@core";
import { IContext, IParam, UIActionUtil } from "@core";
export interface ActionParams {
/**
......@@ -211,7 +211,7 @@ export class AppActionBase {
return;
}
// 参数合并 todo
AppActionService.getInstance().execute(actionModel, params);
App.getAppActionService().execute(actionModel, params);
}
/**
......
import { AppFuncService, IApp, IAppFuncService, IOpenViewService, ViewDetail } from "@core";
import { IAppAuthService, IParam } from "@core/interface";
import { IApp, IAppFuncService, IOpenViewService, ViewDetail } from "@core";
import { IAppActionService, IAppAuthService, IAppNotificationService, IParam } from "@core/interface";
/**
* 应用基类
......@@ -9,15 +9,6 @@ import { IAppAuthService, IParam } from "@core/interface";
*/
export abstract class AppBase implements IApp {
/**
* 应用功能服务
*
* @private
* @type {AppFuncService}
* @memberof AppBase
*/
private appFuncService: AppFuncService = AppFuncService.getInstance();
/**
* 初始化应用
*
......@@ -58,6 +49,16 @@ export abstract class AppBase implements IApp {
throw new Error("Method not implemented.");
}
/**
* 获取通知服务
*
* @return {*} {IAppNotificationService}
* @memberof AppBase
*/
public getNotificationService(): IAppNotificationService {
throw new Error("Method not implemented.");
}
/**
* 获取应用功能服务
*
......@@ -65,7 +66,7 @@ export abstract class AppBase implements IApp {
* @memberof AppBase
*/
public getAppFuncService(): IAppFuncService {
return this.appFuncService;
throw new Error("Method not implemented.");
}
/**
......@@ -78,6 +79,16 @@ export abstract class AppBase implements IApp {
throw new Error("Method not implemented.");
}
/**
* 获取界面行为服务
*
* @return {*} {IAppActionService}
* @memberof AppBase
*/
public getAppActionService(): IAppActionService {
throw new Error("Method not implemented.");
}
/**
* 获取UI服务
*
......@@ -139,5 +150,5 @@ export abstract class AppBase implements IApp {
public gotoLoginPage(): void {
throw new Error("Method not implemented.");
}
}
\ No newline at end of file
import { ViewBase, MainViewState, IActionParam, IParam, AppActionService } from '@core';
import { ViewBase, MainViewState, IActionParam, IParam } from '@core';
/**
* 实体视图
......@@ -49,7 +49,7 @@ export class MainView extends ViewBase {
actionEnvironment: this
};
// 执行行为
AppActionService.getInstance().execute(uIAction, inputParam);
App.getAppActionService().execute(uIAction, inputParam);
}
/**
......
......@@ -34,7 +34,7 @@ export class MDControl extends MainControl {
* @protected
* @param [opt={}]
*/
protected async load(opt: any = {}) {}
protected async load(opt: any = {}) { }
/**
* @description 使用加载功能模块
......@@ -80,9 +80,11 @@ export class MDControl extends MainControl {
}
this.handleStateChange();
}
} catch (error) {
// todo 错误异常处理
console.log(error);
} catch (error: any) {
App.getNotificationService().error({
message: '加载数据失败',
description: error?.data
})
}
};
......@@ -111,7 +113,7 @@ export class MDControl extends MainControl {
* @protected
* @param [opt={}]
*/
protected async save(opt: any = {}) {}
protected async save(opt: any = {}) { }
/**
* @description 使用保存功能模块
......@@ -128,7 +130,7 @@ export class MDControl extends MainControl {
const { updateAction, createAction } = controlAction;
const saveAction: any =
item.rowDataState == 'update' ? updateAction : item.rowDataState == 'create' ? createAction : '';
const saveFunName = item.rowDataState == 'update' ? 'update' : 'create';
const saveFunName = item.rowDataState == 'update' ? 'update' : 'create';
if (!saveAction) {
return;
}
......@@ -175,7 +177,7 @@ export class MDControl extends MainControl {
* @protected
* @param [opt={}]
*/
protected async remove(opt: any = {}) {}
protected async remove(opt: any = {}) { }
/**
* @description 使用删除功能模块
......@@ -255,7 +257,7 @@ export class MDControl extends MainControl {
* @protected
* @param [opt={}]
*/
protected async newRow(opt: any = {}) {}
protected async newRow(opt: any = {}) { }
/**
* @description 使用新建功能模块
......@@ -313,7 +315,7 @@ export class MDControl extends MainControl {
* @protected
* @param [opt={}]
*/
protected async refresh(opt: any = {}) {}
protected async refresh(opt: any = {}) { }
/**
* @description 使用刷新功能模块
......@@ -358,7 +360,7 @@ export class MDControl extends MainControl {
*
* @memberof MDControl
*/
public handleStateChange() {}
public handleStateChange() { }
/**
* 处理数据分组
......@@ -382,7 +384,7 @@ export class MDControl extends MainControl {
* @protected
* @memberof MDControl
*/
protected autoGroupData() {}
protected autoGroupData() { }
/**
* 代码表分组
......@@ -390,7 +392,7 @@ export class MDControl extends MainControl {
* @protected
* @memberof MDControl
*/
protected codeListGroupData() {}
protected codeListGroupData() { }
/**
* 获取当前激活数据
......
import { hasFunction } from "@core";
import { IParam, IContext, IAppActionService } from "@core/interface";
import { AppSysAction } from "../../logic/app-ui-action/app-sys-action";
import { AppSysAction, hasFunction, IAppActionService, IContext, IParam } from "@core";
export class AppActionService implements IAppActionService {
/**
* @description 唯一实例
* @private
* @static
* @memberof AppActionService
*/
private static readonly instance = new AppActionService();
/**
* @description 获取唯一实例
* @static
* @return {*} {AppActionService}
* @memberof AppActionService
*/
public static getInstance(): AppActionService {
return AppActionService.instance;
}
/**
* 界面行为服务基类
*
* @export
* @class AppActionServiceBase
* @implements {IAppActionService}
*/
export abstract class AppActionServiceBase implements IAppActionService {
/**
* 执行界面行为
......
import qs from "qs";
import { clearCookie, getCookie, setCookie } from "qx-util";
import { deepCopy, getSessionStorage, Http, removeSessionStorage, setSessionStorage } from "@core";
import { IParam, IAppAuthService } from "@core/interface";
import { deepCopy, getSessionStorage, Http, IAppAuthService, IParam, removeSessionStorage, setSessionStorage } from "@core";
import { Environment } from "@/environments/environment";
/**
* 应用权限服务基类
*
* @export
* @abstract
* @class AppAuthServiceBase
* @implements {IAppAuthService}
*/
export abstract class AppAuthServiceBase implements IAppAuthService {
/**
......
import { IAppFuncService, IParam } from "@core";
export class AppFuncService implements IAppFuncService{
/**
* @description 唯一实例
* @private
* @static
* @memberof AppFuncService
*/
private static readonly instance = new AppFuncService();
/**
* @description 获取唯一实例
* @static
* @return {*} {AppFuncService}
* @memberof AppFuncService
*/
public static getInstance(): AppFuncService {
return AppFuncService.instance;
}
/**
* 应用功能服务基类
*
* @export
* @class AppFuncServiceBase
* @implements {IAppFuncService}
*/
export abstract class AppFuncServiceBase implements IAppFuncService{
/**
* @description 执行应用功能
* @param {string} menu 菜单项
* @param {IParam} context 上下文
* @param {IParam} viewParams 视图参数
* @memberof AppFuncService
* @memberof AppFuncServiceBase
*/
executeAppFunc(menu: IParam, context: IParam, viewParams: IParam) {
const appFunc = App.getAllFuncs().find((func: IParam)=> Object.is(func.funcTag, menu.funcTag));
......@@ -54,7 +43,7 @@ export class AppFuncService implements IAppFuncService{
* @param {IParam} appFunc 应用功能
* @param {IParam} context 上下文
* @param {IParam} viewParams 视图参数
* @memberof AppFuncService
* @memberof AppFuncServiceBase
*/
executeCustomFunc(appFunc: IParam, context: IParam, viewParams: IParam) {
console.warn(`${appFunc.appFuncType} 类型应用功能暂未支持`);
......@@ -65,7 +54,7 @@ export class AppFuncService implements IAppFuncService{
* @param {IParam} appFunc 应用功能
* @param {IParam} context 上下文
* @param {IParam} viewParams 视图参数
* @memberof AppFuncService
* @memberof AppFuncServiceBase
*/
executeJavaScript(appFunc: IParam, context: IParam, viewParams: IParam) {
console.warn(`${appFunc.appFuncType} 类型应用功能暂未支持`);
......@@ -77,7 +66,7 @@ export class AppFuncService implements IAppFuncService{
* @param {IParam} appFunc 应用功能
* @param {IParam} context 上下文
* @param {IParam} viewParams 视图参数
* @memberof AppFuncService
* @memberof AppFuncServiceBase
*/
executePresetFunc(appFunc: IParam, context: IParam, viewParams: IParam) {
console.warn(`${appFunc.appFuncType} 类型应用功能暂未支持`);
......@@ -88,7 +77,7 @@ export class AppFuncService implements IAppFuncService{
* @param {IParam} appFunc 应用功能
* @param {IParam} context 上下文
* @param {IParam} viewParams 视图参数
* @memberof AppFuncService
* @memberof AppFuncServiceBase
*/
openHtmlPage(appFunc: IParam, context: IParam, viewParams: IParam) {
window.open(appFunc.htmlPageUrl, '_blank');
......@@ -99,7 +88,7 @@ export class AppFuncService implements IAppFuncService{
* @param {IParam} appFunc 应用功能
* @param {IParam} context 上下文
* @param {IParam} viewParams 视图参数
* @memberof AppFuncService
* @memberof AppFuncServiceBase
*/
openAppView(appFunc: IParam, context: IParam, viewParams: IParam) {
const view = {
......
import { IAppNotificationService } from "@core/interface";
import { notification } from 'ant-design-vue';
/**
* 应用通知服务基类
*
* @export
* @abstract
* @class AppNotificationServiceBase
* @implements {IAppNotificationService}
*/
export abstract class AppNotificationServiceBase implements IAppNotificationService {
/**
* 成功提示
*
* @param {*} opts
* @memberof AppNotificationServiceBase
*/
public success(opts: any): void {
notification.success(opts);
}
/**
* 信息提示
*
* @param {*} opts
* @memberof AppNotificationServiceBase
*/
public info(opts: any): void {
notification.info(opts);
}
/**
* 警告提示
*
* @param {*} opts
* @memberof AppNotificationServiceBase
*/
public warning(opts: any): void {
notification.warning(opts);
}
/**
* 错误提示
*
* @param {*} opts
* @memberof AppNotificationServiceBase
*/
public error(opts: any): void {
notification.error(opts);
}
}
\ No newline at end of file
export { AppActionServiceBase } from './app-action-service-base';
export { AppAuthServiceBase } from './app-auth-service-base';
export { AppFuncServiceBase } from './app-func-service-base';
export { AppNotificationServiceBase } from './app-notification-service-base';
export { OpenViewServiceBase } from './open-view-service-base';
\ No newline at end of file
import { IOpenViewService, IParam, ViewDetail } from "@core";
import { Subject } from "rxjs";
/**
* 打开视图服务
*
* @export
* @class OpenViewService
*/
export abstract class OpenViewServiceBase implements IOpenViewService {
/**
* @description 打开视图
* @param {ViewDetail} view 视图对象参数
* @param {IParam} params 打开视图参数
* @return {*} {*}
* @memberof OpenViewServiceBase
*/
public openView(view: ViewDetail, params: IParam): Subject<any> | undefined {
// 获取详细视图信息
let _view: ViewDetail | undefined = App.getViewInfo(view.codeName);
if (!_view) {
console.error(`应用中不存在${view.codeName}视图`);
return;
}
// view的openMode覆盖配置的
if (view.openMode) {
_view.openMode = view.openMode;
}
// 重定向视图走重定向逻辑,其他根据openMode打开
if (_view.redirectView) {
this.openRedirectView(_view, params);
} else {
return this.openByOpenMode(_view, params);
}
}
/**
* 根据打开方式打开视图
*
* @param view 视图信息
* @param params 相关参数
* @memberof OpenViewServiceBase
*/
public openByOpenMode(_view: ViewDetail, params: IParam): Subject<any> | undefined {
throw new Error("Method not implemented.");
}
/**
* 打开重定向视图
*
* @param {ViewDetail} _view
* @param {IParam} params
* @memberof OpenViewServiceBase
*/
public openRedirectView(_view: ViewDetail, params: IParam) {
throw new Error("Method not implemented.");
}
}
\ No newline at end of file
export * from './app-action-service';
export * from './app-auth-service';
export * from './app-func-service';
export * from './app-service';
export * from './control-service';
export * from './entity-service';
export * from './entity-ui-service';
\ No newline at end of file
import { IParam } from "@core";
/**
* 界面服务基类
*
* @export
* @class UIServiceBase
*/
export class UIServiceBase {
/**
* 应用上下文
*
* @protected
* @type {IParam}
* @memberof UIServiceBase
*/
protected context: IParam;
/**
*
* @param {*} [opts={}]
* @memberof UIServiceBase
*/
constructor(context: IParam = {}) {
this.context = context;
}
/**
* 界面行为模型对象
*
* @type {*}
* @memberof UIServiceBase
*/
public uiActionModes: any = {};
/**
*
* 获取界面行为模型对象
*
* @param {string} actionName
* @memberof UIServiceBase
*/
public getUIActionModel(actionName: string) {
if (!actionName) {
return;
}
return this.uiActionModes[actionName] ? this.uiActionModes[actionName] : null;
}
}
import { AppActionServiceBase } from "@core";
import { IAppActionService } from "@core/interface";
/**
* 界面行为服务
*
* @export
* @class AppActionService
* @extends {AppActionServiceBase}
* @implements {IAppActionService}
*/
export class AppActionService extends AppActionServiceBase implements IAppActionService {
/**
* @description 唯一实例
* @private
* @static
* @memberof AppActionService
*/
private static readonly instance = new AppActionService();
/**
* @description 获取唯一实例
* @static
* @return {*} {AppActionService}
* @memberof AppActionService
*/
public static getInstance(): AppActionService {
return AppActionService.instance;
}
}
\ No newline at end of file
import { AppFuncServiceBase, IAppFuncService } from "@core";
/**
* 应用功能服务
*
* @export
* @class AppFuncService
* @extends {AppFuncServiceBase}
* @implements {IAppFuncService}
*/
export class AppFuncService extends AppFuncServiceBase implements IAppFuncService {
/**
* @description 唯一实例
* @private
* @static
* @memberof AppFuncService
*/
private static readonly instance = new AppFuncService();
/**
* @description 获取唯一实例
* @static
* @return {*} {AppFuncService}
* @memberof AppFuncService
*/
public static getInstance(): AppFuncService {
return AppFuncService.instance;
}
}
\ No newline at end of file
import { IAppNotificationService, AppNotificationServiceBase } from "@core";
/**
* 通知提示服务
*
* @export
* @class AppNotificationService
* @extends {AppNotificationServiceBase}
* @implements {IAppNotificationService}
*/
export class AppNotificationService extends AppNotificationServiceBase implements IAppNotificationService {
/**
* 唯一实例
*
* @private
* @static
* @memberof AppNotificationService
*/
private static readonly instance = new AppNotificationService();
/**
* 获取唯一实例
*
* @static
* @return {*} {AppNotificationService}
* @memberof AppNotificationService
*/
public static getInstance(): AppNotificationService {
return AppNotificationService.instance;
}
}
\ No newline at end of file
import { Subject } from 'rxjs';
import Router from '@/router';
import Antd from 'ant-design-vue';
import AppDrawerComponent from "@components/render/app-drawer.vue";
import AppLoading from '@components/render/app-loading.vue';
import { IParam, ViewDetail } from '@core';
export class AppDrawer {
/**
* 实例对象
*
* @private
* @static
* @memberof AppDrawer
*/
private static drawer = new AppDrawer();
/**
* 构造方法
*
* @memberof AppDrawer
*/
constructor() {
if (AppDrawer.drawer) {
return AppDrawer.drawer;
}
}
/**
* 获取实例对象
*
* @static
* @returns
* @memberof AppDrawer
*/
public static getInstance() {
if (!AppDrawer.drawer) {
AppDrawer.drawer = new AppDrawer();
}
return AppDrawer.drawer;
}
/**
* 创建 Vue 实例对象
*
* @private
* @param {view} ViewDetail 视图对象
* @param {IParam} params 视图参数
* @param {IParam} [options] 模态配置项
* @return {*} {Subject<any>}
* @memberof AppDrawer
*/
private createVueExample(view: ViewDetail, params: IParam, options?: IParam): Subject<any> {
try {
let subject: null | Subject<any> = new Subject<any>();
let props = { view: view, context: params.context, viewParams: params.viewParams, isFullscreen: params.isFullscreen, subject: subject, options: options };
let dir = view.fileDir?.replace(/@views/, '');
//Vite 支持使用特殊的 import.meta.glob 函数从文件系统导入多个模块
const modules = import.meta.glob('../../page/*/*/index.ts');
const AsyncComp = defineAsyncComponent({
// 工厂函数
loader: modules['../../page' + dir + '/index.ts'],
// 加载异步组件时要使用的组件
loadingComponent: AppLoading,
// 在显示 loadingComponent 之前的延迟 | 默认值:200(单位 ms)
delay: 0,
});
if (AsyncComp) {
const component = AppDrawerComponent;
const div = document.createElement('div');
document.body.appendChild(div);
const app = createApp(component,
{
close: () => { document.body.removeChild(div); app.unmount(); },
...props
}
);
app.component(view.name as string, AsyncComp);
app.use(Router).use(Antd).mount(div);
}
return subject;
} catch (error) {
console.error(error);
return new Subject<any>();
}
}
/**
* 打开抽屉
*
* @param {View} view 视图对象
* @param {IParam} params 视图参数
* @param {IParam} [options] 模态配置项
* @returns {Subject<any>}
* @memberof AppDrawer
*/
public openDrawer(view: ViewDetail, params: IParam, options?: IParam): Subject<any> {
try {
const subject = this.createVueExample(view, params, options);
return subject;
} catch (error) {
console.log(error);
return new Subject<any>();
}
}
/**
* 生成uuid
*
* @private
* @returns {string}
* @memberof AppDrawer
*/
private getUUID(): string {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
}
}
\ No newline at end of file
import { Subject } from 'rxjs';
import Router from '@/router';
import Antd from 'ant-design-vue';
import AppModalComponent from "@components/render/app-modal.vue";
import AppLoading from '@components/render/app-loading.vue';
import { IParam, ViewDetail } from '@core';
export class AppModal {
/**
* 实例对象
*
* @private
* @static
* @memberof AppModal
*/
private static modal = new AppModal();
/**
*
*
* @type {*}
* @memberof AppModal
*/
public asyncComp: any;
/**
* Creates an instance of AppModal.
*
* @memberof AppModal
*/
private constructor() {
if (AppModal.modal) {
return AppModal.modal;
}
}
/**
* 获取单例对象
*
* @static
* @returns {AppModal}
* @memberof AppModal
*/
public static getInstance(): AppModal {
if (!AppModal.modal) {
AppModal.modal = new AppModal();
}
return AppModal.modal;
}
/**
* 创建vue对象
*
* @private
* @param {view} ViewDetail 视图对象
* @param {IParam} params 视图参数
* @param {IParam} [options] 模态配置项
* @return {*} {Subject<any>}
* @memberof AppModal
*/
private createVueExample(view: ViewDetail, params: IParam, options?: IParam): Subject<any> {
try {
let subject: null | Subject<any> = new Subject<any>();
let props = { view: view, context: params.context, viewParams: params.viewParams, isFullscreen: params.isFullscreen, subject: subject, options: options };
let dir = view.fileDir?.replace(/@views/, '');
//Vite 支持使用特殊的 import.meta.glob 函数从文件系统导入多个模块
const modules = import.meta.glob('../../views/*/*/index.ts');
const AsyncComp = defineAsyncComponent({
// 工厂函数
loader: modules['../../views' + dir + '/index.ts'],
// 加载异步组件时要使用的组件
loadingComponent: AppLoading,
// 在显示 loadingComponent 之前的延迟 | 默认值:200(单位 ms)
delay: 0,
});
if (AsyncComp) {
const component = AppModalComponent;
const div = document.createElement('div');
document.body.appendChild(div);
const app = createApp(component,
{
close: () => { document.body.removeChild(div); app.unmount(); },
...props
}
);
app.component(view.name as string, AsyncComp);
app.use(Router).use(Antd).mount(div);
}
return subject;
} catch (error) {
console.error(error);
return new Subject<any>();
}
}
/**
* 打开模态视图
*
* @param {View} view 视图对象
* @param {IParam} params 视图参数
* @param {IParam} [options] 模态配置项
* @return {*} {Subject<any>}
* @memberof AppModal
*/
public openModal(view: ViewDetail, params: IParam, options?: IParam): Subject<any> {
try {
const subject = this.createVueExample(view, params, options);
return subject;
} catch (error) {
console.log(error);
return new Subject<any>();
}
}
/**
* 获取节点标识
*
* @private
* @returns {string}
* @memberof AppModal
*/
private getUUID(): string {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
}
}
\ No newline at end of file
import { Subject } from 'rxjs';
import Router from '@/router';
import Antd from 'ant-design-vue';
import AppPopoverComponent from "@components/render/app-popover.vue";
import AppLoading from '@components/render/app-loading.vue';
import { IParam, ViewDetail } from '@core';
import { createPopper, Instance } from '@popperjs/core/lib/popper-lite.js';
import preventOverflow from '@popperjs/core/lib/modifiers/preventOverflow.js';
import flip from '@popperjs/core/lib/modifiers/flip.js';
import { Placement } from '@popperjs/core/lib/enums';
export class AppPopover {
/**
* 实例对象
*
* @private
* @static
* @memberof AppPopover
*/
private static popover = new AppPopover();
/**
* PopperJs实例
*
* @private
* @type {Instance}
* @memberof AppPopover
*/
private popperExample?: Instance;
/**
* 是否显示悬浮窗
*
* @private
* @type {boolean}
* @memberof AppPopover
*/
private showPopper: boolean = false;
/**
* 是否在点击空白区域时自动关闭
*
* @private
* @type {boolean}
* @memberof AppPopover
*/
private isAutoClose: boolean = true;
/**
* 是否在离开该飘窗区域时自动关闭
*
* @private
* @type {boolean}
* @memberof AppPopover
*/
private isMoveOutClose: boolean = false;
/**
* 构造方法
*
* @memberof AppPopover
*/
constructor() {
if (AppPopover.popover) {
return AppPopover.popover;
}
}
/**
* 获取实例对象
*
* @static
* @returns
* @memberof AppPopover
*/
public static getInstance() {
if (!AppPopover.popover) {
AppPopover.popover = new AppPopover();
}
return AppPopover.popover;
}
/**
* 创建 Vue 实例对象
*
* @private
* @param event
* @param {view} ViewDetail 视图对象
* @param {IParam} params 视图参数
* @param {IParam} [options] 模态配置项
* @return {*} {Subject<any>}
* @memberof AppPopover
*/
private createVueExample(event:any, view: ViewDetail, params: IParam, options?: IParam): Subject<any> {
try {
// 阻止事件冒泡
event.stopPropagation();
// 处理关闭模式(点击空白区域关闭、鼠标离开飘窗区域)
if (params.isAutoClose) {
this.isAutoClose = params.isAutoClose;
}
if (params.isMoveOutClose) {
this.isMoveOutClose = params.isMoveOutClose;
}
// 获取悬浮窗相对位置的元素
const element: Element = event.toElement || event.srcElement;
let subject: null | Subject<any> = new Subject<any>();
let props = { element: element, view: view, context: params.context, viewParams: params.viewParams, isFullscreen: params.isFullscreen, subject: subject, options: options };
// 解析文件路径
let dir = view.fileDir?.replace(/@views/, '');
// Vite 支持使用特殊的 import.meta.glob 函数从文件系统导入多个模块
const modules = import.meta.glob('../../page/*/*/index.ts');
// 创建一个只有在需要时才会加载的异步组件
const AsyncComp = defineAsyncComponent({
// 工厂函数
loader: modules['../../page' + dir + '/index.ts'],
// 加载异步组件时要使用的组件
loadingComponent: AppLoading,
// 在显示 loadingComponent 之前的延迟 | 默认值:200(单位 ms)
delay: 0,
});
if (AsyncComp) {
const component = AppPopoverComponent;
// 创建dom
const container = document.createElement('div');
container.className = 'app-popover-wrapper';
const div = document.createElement('div');
container.appendChild(div);
document.body.appendChild(container);
this.showPopper = true;
const app = createApp(component,
{
mouseout: () => {
if (!this.showPopper || !this.isMoveOutClose) {
return;
}
this.popperDestroy();
document.body.removeChild(container);
app.unmount();
},
...props
}
);
app.component(view.name as string, AsyncComp);
app.use(Router).use(Antd).mount(div);
// 创建Popover实例
this.popperExample = createPopper(element, div, {
placement: view.placement as Placement,
strategy: 'absolute',
modifiers: [preventOverflow, flip]
});
// 点击空白区域时事件处理
container.addEventListener('click', () => {
if (!this.showPopper || !this.isAutoClose) {
return;
}
this.popperDestroy();
document.body.removeChild(container);
app.unmount();
})
}
return subject;
} catch (error) {
console.error(error);
return new Subject<any>();
}
}
/**
* 打开飘窗
*
* @param {*} event
* @param {View} view 视图对象
* @param {IParam} params 视图参数
* @param {IParam} [options] 模态配置项
* @returns {Subject<any>}
* @memberof AppPopover
*/
public openPopover(event:any, view: ViewDetail, params: IParam, options?: IParam): Subject<any> {
try {
const subject = this.createVueExample(event, view, params, options);
return subject;
} catch (error) {
console.log(error);
return new Subject<any>();
}
}
/**
* 销毁popper(带回填数据)
*
* @memberof AppPopover
*/
public popperDestroy(): void {
if (this.popperExample) {
this.popperExample.destroy();
this.showPopper = false;
}
}
}
\ No newline at end of file
export { AppDrawer } from './app-drawer';
export { AppModal } from './app-modal';
export { AppPopover } from './app-popover';
export { OpenViewService } from './open-view-service';
\ No newline at end of file
import { IOpenViewService, IParam, OpenViewServiceBase, RouteUtil, ViewDetail } from '@core';
import router from '@/router';
import { Subject } from 'rxjs';
import { AppModal } from './app-modal';
/**
* 打开视图服务
* @export
* @class OpenViewService
*/
export class OpenViewService extends OpenViewServiceBase implements IOpenViewService {
/**
* 唯一实例
*
* @private
* @static
* @memberof OpenViewService
*/
private static readonly instance = new OpenViewService();
/**
* 获取唯一实例
*
* @static
* @return {*} {OpenViewService}
* @memberof OpenViewService
*/
public static getInstance(): OpenViewService {
return OpenViewService.instance;
}
/**
* 根据打开方式打开视图
*
* @param view 视图信息
* @param params 相关参数
*/
public openByOpenMode(view: ViewDetail, params: IParam): Subject<any> | undefined {
const openMode = params.openMode || view.openMode;
const { viewParams, context } = params;
// 路由打开视图
if (openMode == 'INDEXVIEWTAB' || openMode == 'POPUPAPP') {
// TODO 视图关系参数处理
const routePath = RouteUtil.buildUpRoutePath(view, context, viewParams, router.currentRoute.value);
if (openMode == 'INDEXVIEWTAB') {
router.push(routePath);
} else {
window.open('./#' + routePath, '_blank');
}
return;
} else if (openMode == 'POPUPMODAL') {
return AppModal.getInstance().openModal(view, params);
} else if (openMode?.indexOf('DRAWER') !== -1) {
// TODO PMS上面抽屉DRAWER_TOP
} else if (openMode == 'POPOVER') {
// TODO 打开气泡卡片
} else {
console.error(`未支持${openMode}打开方式`);
}
}
/**
* 打开重定向视图
*
* @param view 视图信息
* @param params 相关参数
*/
public openRedirectView(view: any, params: IParam) {
// TODO 重定向视图处理
}
}
export * from './app-open-view-service';
export { AppActionService } from './app-action-service';
export { AppAuthService } from './app-auth-service';
export { AppFuncService } from './app-func-service';
export { AppNotificationService } from './app-notification-service';
\ No newline at end of file
......@@ -25,4 +25,18 @@ body{
border-radius: 0;
box-shadow: none;
border: 0;
}
// 飘窗样式
.app-popover-wrapper {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
.app-popover {
border-radius: 5px;
overflow: auto;
background: #e8e8e8;
}
}
\ No newline at end of file
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册