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

update:更新

上级 1cb59d67
import { SyncSeriesHook } from "qx-util"; import { SyncSeriesHook } from "qx-util";
import { Environment } from "@/environments/environment"; import { Environment } from "@/environments/environment";
import router from "@/router"; import router from "@/router";
import { AppBase, IParam, ViewDetail, IApp, IOpenViewService, deepCopy, Http, IAppAuthService, IAppNotificationService, IAppFuncService, IAppActionService } from "@core"; import { AppBase, IParam, ViewDetail, IApp, IOpenViewService, deepCopy, Http, IAppAuthService, IAppNotificationService, IAppFuncService, IAppActionService, IAppCodeListService } from "@core";
import { AppFuncConfig, AppViewConfig, AppEntityConfig } from './config'; import { AppFuncConfig, AppViewConfig, AppEntityConfig } from './config';
import { DataServiceRegister, UIServiceRegister } from "./register"; import { DataServiceRegister, UIServiceRegister } from "./register";
import { AppActionService, AppAuthService, AppFuncService, AppNotificationService, OpenViewService } from "@/service"; import { AppActionService, AppAuthService, AppCodeListService, AppFuncService, AppNotificationService, OpenViewService } from "@/service";
export class App extends AppBase implements IApp { export class App extends AppBase implements IApp {
...@@ -120,6 +120,16 @@ export class App extends AppBase implements IApp { ...@@ -120,6 +120,16 @@ export class App extends AppBase implements IApp {
return AppActionService.getInstance(); return AppActionService.getInstance();
} }
/**
* 获取代码表服务
*
* @return {*} {IAppCodeListService}
* @memberof App
*/
public getCodeListService(): IAppCodeListService {
return AppCodeListService.getInstance();
}
/** /**
* 获取UI服务 * 获取UI服务
* *
......
...@@ -126,7 +126,7 @@ const props = withDefaults(defineProps<CheckboxListProps>(), { ...@@ -126,7 +126,7 @@ const props = withDefaults(defineProps<CheckboxListProps>(), {
mode: 'string', mode: 'string',
}); });
const emit = defineEmits<EditorEmit>(); const emit = defineEmits<EditorEmit>();
const { handleEditorNavParams, handleLevelCodeList, loadCodeListData } = new EditorBase(); const { handleEditorNavParams, loadCodeListData } = new EditorBase();
const { navContext, navViewParam } = handleEditorNavParams(props); const { navContext, navViewParam } = handleEditorNavParams(props);
let items: Ref<IParam[]> = ref([]); let items: Ref<IParam[]> = ref([]);
const selectArray: Ref<boolean> = computed(() => { const selectArray: Ref<boolean> = computed(() => {
...@@ -205,8 +205,8 @@ const formatCodeList = (items: Array<any>) => { ...@@ -205,8 +205,8 @@ const formatCodeList = (items: Array<any>) => {
} }
}; };
onBeforeMount(() => { onBeforeMount(() => {
loadCodeListData(props.codeListTag, props.codeListType, navContext, navViewParam).then((codeListData: IParam[]) => { loadCodeListData(props.codeListTag, navContext, navViewParam).then((codeListData: IParam[]) => {
items.value = formatCodeList(handleLevelCodeList(codeListData)); items.value = formatCodeList(codeListData);
}); });
}); });
</script> </script>
......
...@@ -56,7 +56,7 @@ interface DropdownListProps { ...@@ -56,7 +56,7 @@ interface DropdownListProps {
/** /**
* @description 代码表标识 * @description 代码表标识
*/ */
codeListTag?: string; codeListTag: string;
/** /**
* @description 代码表类型 * @description 代码表类型
...@@ -79,7 +79,7 @@ const props = withDefaults(defineProps<DropdownListProps>(), { ...@@ -79,7 +79,7 @@ const props = withDefaults(defineProps<DropdownListProps>(), {
}) })
const emit = defineEmits<EditorEmit>() const emit = defineEmits<EditorEmit>()
const { handleEditorNavParams, loadCodeListData, handleLevelCodeList } = new EditorBase(); const { handleEditorNavParams, loadCodeListData } = new EditorBase();
const { navContext, navViewParam } = handleEditorNavParams(props); const { navContext, navViewParam } = handleEditorNavParams(props);
let curValue: Ref<any> = ref( let curValue: Ref<any> = ref(
props.multiple ? props.multiple ?
...@@ -93,12 +93,11 @@ const onChange = (select: any, option: any) => { ...@@ -93,12 +93,11 @@ const onChange = (select: any, option: any) => {
onBeforeMount(() => { onBeforeMount(() => {
loadCodeListData( loadCodeListData(
props.codeListTag, props.codeListTag,
props.codeListType,
navContext, navContext,
navViewParam, navViewParam,
).then((codeListData: IParam[]) => { ).then((codeListData: IParam[]) => {
items.value = handleLevelCodeList(codeListData); items.value = codeListData;
}) })
}) })
......
...@@ -56,7 +56,7 @@ interface ListBoxProps { ...@@ -56,7 +56,7 @@ interface ListBoxProps {
* @type {string} * @type {string}
* @memberof ListBoxProps * @memberof ListBoxProps
*/ */
codeListTag?: string; codeListTag: string;
/** /**
* 代码表类型 * 代码表类型
...@@ -128,7 +128,7 @@ interface ListBoxProps { ...@@ -128,7 +128,7 @@ interface ListBoxProps {
* @type {any} * @type {any}
* @memberof ListBoxProps * @memberof ListBoxProps
*/ */
multiple?: Boolean; multiple?: boolean;
/** /**
* 应用实体主信息属性名称 * 应用实体主信息属性名称
...@@ -179,7 +179,7 @@ const props = withDefaults(defineProps<ListBoxProps>(), { ...@@ -179,7 +179,7 @@ const props = withDefaults(defineProps<ListBoxProps>(), {
deKeyField: 'srfkey', deKeyField: 'srfkey',
}); });
const emit = defineEmits<EditorEmit>(); const emit = defineEmits<EditorEmit>();
const { handleEditorNavParams, handleLevelCodeList, loadCodeListData } = new EditorBase(); const { handleEditorNavParams, loadCodeListData } = new EditorBase();
const { navContext, navViewParam } = handleEditorNavParams(props); const { navContext, navViewParam } = handleEditorNavParams(props);
let items: Ref<IParam[]> = ref([]); let items: Ref<IParam[]> = ref([]);
const selectArray: Ref<boolean> = computed(() => { const selectArray: Ref<boolean> = computed(() => {
...@@ -205,13 +205,13 @@ const selectArray: Ref<boolean> = computed(() => { ...@@ -205,13 +205,13 @@ const selectArray: Ref<boolean> = computed(() => {
} }
}); });
const curMajorField: Ref<string> = computed(() => { // const curMajorField: Ref<string> = computed(() => {
return Object.is(props.editorType, 'LISTBOX') ? 'text' : props.deMajorField; // return Object.is(props.editorType, 'LISTBOX') ? 'text' : props.deMajorField;
}); // });
const curKeyField: Ref<string> = computed(() => { // const curKeyField: Ref<string> = computed(() => {
return Object.is(props.editorType, 'LISTBOX') ? 'value' : props.deKeyField; // return Object.is(props.editorType, 'LISTBOX') ? 'value' : props.deKeyField;
}); // });
const onChange = ($event: any[]) => { const onChange = ($event: any[]) => {
let value: null | string | number = null; let value: null | string | number = null;
...@@ -291,8 +291,8 @@ const loadData = () => { ...@@ -291,8 +291,8 @@ const loadData = () => {
}; };
onBeforeMount(() => { onBeforeMount(() => {
if (Object.is('LISTBOX', props.editorType)) { if (Object.is('LISTBOX', props.editorType)) {
loadCodeListData(props.codeListTag, props.codeListType, navContext, navViewParam).then((codeListData: IParam[]) => { loadCodeListData(props.codeListTag, navContext, navViewParam).then((codeListData: IParam[]) => {
items.value = formatCodeList(handleLevelCodeList(codeListData)); items.value = formatCodeList(codeListData);
}); });
} else if (Object.is('LISTBOXPICKUP', props.editorType)) { } else if (Object.is('LISTBOXPICKUP', props.editorType)) {
loadData(); loadData();
......
<script setup lang="ts"> <script setup lang="ts">
import { import { IActionParam, IParam, EditorBase, IContext } from '@core';
IActionParam, import { onBeforeMount, ref, Ref } from 'vue';
IParam,
EditorBase,
IContext
} from "@core";
import { onBeforeMount, ref, Ref } from "vue";
interface RadioGroupProps { interface RadioGroupProps {
/** /**
* 值 * 值
...@@ -96,7 +91,7 @@ interface RadioGroupProps { ...@@ -96,7 +91,7 @@ interface RadioGroupProps {
} }
interface EditorEmit { interface EditorEmit {
(name: "editorEvent", value: IActionParam): void; (name: 'editorEvent', value: IActionParam): void;
} }
const props = withDefaults(defineProps<RadioGroupProps>(), { const props = withDefaults(defineProps<RadioGroupProps>(), {
...@@ -104,39 +99,28 @@ const props = withDefaults(defineProps<RadioGroupProps>(), { ...@@ -104,39 +99,28 @@ const props = withDefaults(defineProps<RadioGroupProps>(), {
readonly: false, readonly: false,
}); });
const emit = defineEmits<EditorEmit>(); const emit = defineEmits<EditorEmit>();
const { handleEditorNavParams, loadCodeListData, handleLevelCodeList } = new EditorBase(); const { handleEditorNavParams, loadCodeListData } = new EditorBase();
const { navContext, navViewParam } = handleEditorNavParams(props); const { navContext, navViewParam } = handleEditorNavParams(props);
let items: Ref<IParam[]> = ref([]); let items: Ref<IParam[]> = ref([]);
const onChange = ($event: any) => { const onChange = ($event: any) => {
const value = $event.target.value const value = $event.target.value;
emit("editorEvent", { emit('editorEvent', {
tag: props.name, tag: props.name,
action: "valueChange", action: 'valueChange',
data: value, data: value,
}); });
}; };
onBeforeMount(() => { onBeforeMount(() => {
loadCodeListData( loadCodeListData(props.codeListTag, navContext, navViewParam).then((codeListData: IParam[]) => {
props.codeListTag, items.value = codeListData;
props.codeListType,
navContext,
navViewParam
).then((codeListData: IParam[]) => {
items.value = handleLevelCodeList(codeListData);
}); });
}); });
</script> </script>
<template> <template>
<div :class="['app-editor-container', 'app-radio-group', `app-radio-group-${name}`]"> <div :class="['app-editor-container', 'app-radio-group', `app-radio-group-${name}`]">
<a-radio-group <a-radio-group @change="onChange" :value="value" :options="items" :disabled="disabled || readonly"></a-radio-group>
@change="onChange"
:value="value"
:options="items"
:disabled="disabled || readonly"
>
</a-radio-group>
</div> </div>
</template> </template>
......
...@@ -100,8 +100,7 @@ let textFormat: Ref<string> = ref(""); ...@@ -100,8 +100,7 @@ let textFormat: Ref<string> = ref("");
onBeforeMount(() => { onBeforeMount(() => {
if (props.codeListTag) { if (props.codeListTag) {
loadCodeListData( loadCodeListData(
props.codeListTag, props.codeListTag as string,
props.codeListType,
navContext, navContext,
navViewParam navViewParam
).then((codeListData: IParam[]) => { ).then((codeListData: IParam[]) => {
......
import { IParam, ViewDetail } from "../common"; import { IParam, ViewDetail } from "../common";
import { IAppActionService, IAppAuthService, IAppFuncService, IAppNotificationService, IOpenViewService } from "../service"; import { IAppActionService, IAppAuthService, IAppCodeListService, IAppFuncService, IAppNotificationService, IOpenViewService } from "../service";
/** /**
...@@ -59,6 +59,14 @@ export interface IApp { ...@@ -59,6 +59,14 @@ export interface IApp {
*/ */
getAppActionService(): IAppActionService; getAppActionService(): IAppActionService;
/**
* 获取代码表服务
*
* @return {*} {IAppCodeListService}
* @memberof IApp
*/
getCodeListService(): IAppCodeListService;
/** /**
* 获取UI服务 * 获取UI服务
* *
......
import { IContext, IParam } from "../common";
/**
* @description 应用代码表服务
* @export
* @interface IAppCodeListService
*/
export interface IAppCodeListService {
/**
* 获取代码项
*
* @param { tag, context, viewParams }: { tag: string, context: IContext | undefined, viewParams: IParam | undefined }
* @return {*} {Promise<any>}
* @memberof IAppCodeListService
*/
getCodeListItems({ tag, context, viewParams }: { tag: string, context: IContext | undefined, viewParams: IParam | undefined }): Promise<any>;
}
\ No newline at end of file
...@@ -4,4 +4,5 @@ export * from './i-app-action-service'; ...@@ -4,4 +4,5 @@ export * from './i-app-action-service';
export * from './i-open-view-service'; export * from './i-open-view-service';
export * from './i-data-service-register'; export * from './i-data-service-register';
export * from './i-ui-service-register'; export * from './i-ui-service-register';
export * from './i-app-auth-service'; export * from './i-app-auth-service';
\ No newline at end of file export * from './i-app-code-list-service';
\ No newline at end of file
import { IApp, IAppFuncService, IOpenViewService, ViewDetail } from "@core"; import { IApp, IAppFuncService, IOpenViewService, ViewDetail } from "@core";
import { IAppActionService, IAppAuthService, IAppNotificationService, IParam } from "@core/interface"; import { IAppActionService, IAppAuthService, IAppCodeListService, IAppNotificationService, IParam } from "@core/interface";
/** /**
* 应用基类 * 应用基类
...@@ -89,6 +89,16 @@ export abstract class AppBase implements IApp { ...@@ -89,6 +89,16 @@ export abstract class AppBase implements IApp {
throw new Error("Method not implemented."); throw new Error("Method not implemented.");
} }
/**
* 获取代码表服务
*
* @return {*} {IAppCodeListService}
* @memberof AppBase
*/
public getCodeListService(): IAppCodeListService {
throw new Error("Method not implemented.");
}
/** /**
* 获取UI服务 * 获取UI服务
* *
......
import { toRefs } from 'vue'; import { toRefs } from 'vue';
import { UIUtil, IParam, UIBase } from '@core'; import { UIUtil, IParam, UIBase, IContext } from '@core';
import axios from 'axios'; import axios from 'axios';
/** /**
* @description 部件基类 * @description 部件基类
...@@ -35,83 +35,20 @@ export class EditorBase { ...@@ -35,83 +35,20 @@ export class EditorBase {
/** /**
* @description 加载代码表数据 * @description 加载代码表数据
* @export * @export
* @param {string} codeListTag 代码表标识 * @param {string} tag 代码表标识
* @param {string} codeListType 代码表类型 * @param {IContext} context 导航上下文
* @param {IParam} navContext 导航上下文 * @param {IParam} viewParams 导航视图参数
* @param {IParam} navViewParam 导航视图参数
* @param {boolean} isNumber 是否为数值类型
* @return {Promise<any[]>} {any[]} * @return {Promise<any[]>} {any[]}
*/ */
public async loadCodeListData(codeListTag?: string, codeListType?: string, navContext?: IParam, navViewParam?: IParam): Promise<IParam[]> { public async loadCodeListData(tag: string, context?: IContext, viewParams?: IParam) {
const data: IParam[] = [ if (!tag) {
{ console.log("无代码表标识,无法加载数据");
value: '243144', return;
label: 'Jack',
},
{
value: '7dawda',
label: 'Lucy',
},
{
value: 'disaweqeqeqbled',
label: 'Disabled',
disabled: true,
},
{
value: 'yimirwqrqwenghe',
label: 'Yiminghe',
}
];
if (codeListTag) {
// todo 调用代码表服务获取数据
}
return data;
}
/**
* @description 处理层级代码表
* @export
* @param {IParam[]} codeListData 代码表数据
*/
public handleLevelCodeList(codeListData: IParam[]): IParam[] {
let items: IParam[] = [...codeListData]
const hasChildren: boolean = codeListData.some((item:any) =>{
return item.pvalue;
})
if(hasChildren){
let list: IParam[] = [];
items.forEach((codeItem: IParam) =>{
if(!codeItem.pvalue){
let valueField: string = codeItem.value;
this.setChildCodeItems(valueField, items, codeItem);
list.push(codeItem);
}
})
items = list;
} }
const items = await App.getCodeListService().getCodeListItems({ tag, context, viewParams });
return items; return items;
} }
/**
* @description 设置子代码表
* @param {string} pValue 父代码项值
* @param {IParam[]} result 代码表
* @param {IParam} codeItem 代码项
*/
public setChildCodeItems(pValue: string, result: IParam[], codeItem: IParam) {
result.forEach((item: IParam) =>{
if(item.pvalue == pValue){
let valueField:string = item.value;
this.setChildCodeItems(valueField, result, item);
if(!codeItem.options){
codeItem.children = [];
}
codeItem.children.push(item);
}
})
}
/** /**
* @description 打开选择视图 * @description 打开选择视图
* @export * @export
...@@ -208,63 +145,63 @@ export class EditorBase { ...@@ -208,63 +145,63 @@ export class EditorBase {
* @return {*} * @return {*}
* @memberof EditorBase * @memberof EditorBase
*/ */
public getImgURLOfBase64(url: string, loadingImgMap: Map<string, any>, successImgMap: Map<string, any>): Promise<string> { public getImgURLOfBase64(url: string, loadingImgMap: Map<string, any>, successImgMap: Map<string, any>): Promise<string> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let img = '/'; let img = '/';
// 富文本CV上传图片与鼠标移出抛值冲突问题,上传成功回调还没执行时就抛值 // 富文本CV上传图片与鼠标移出抛值冲突问题,上传成功回调还没执行时就抛值
var reg = /^\s*data:([a-z]+\/[a-z0-9-+.]+(;[a-z-]+=[a-z0-9-]+)?)?(;base64)?,([a-z0-9!$&',()*+;=\-._~:@\/?%\s]*?)\s*$/i; var reg = /^\s*data:([a-z]+\/[a-z0-9-+.]+(;[a-z-]+=[a-z0-9-]+)?)?(;base64)?,([a-z0-9!$&',()*+;=\-._~:@\/?%\s]*?)\s*$/i;
if (reg.test(url)) { if (reg.test(url)) {
return resolve(url); return resolve(url);
} }
// 缓存中有从缓存中拿 // 缓存中有从缓存中拿
if (successImgMap.get(url)) { if (successImgMap.get(url)) {
let img = successImgMap.get(url); let img = successImgMap.get(url);
resolve(img); resolve(img);
} }
const callback: Function = (url: string, promise: Promise<any>) => { const callback: Function = (url: string, promise: Promise<any>) => {
promise.then((response: any) => { promise.then((response: any) => {
if (response && response.status === 200 && response.data) { if (response && response.status === 200 && response.data) {
// 获取文件名 // 获取文件名
const disposition = response.headers['content-disposition']; const disposition = response.headers['content-disposition'];
const filename = disposition.split('filename=')[1]; const filename = disposition.split('filename=')[1];
let type = 'image/png'; let type = 'image/png';
if (filename && filename.indexOf('.') > 0) { if (filename && filename.indexOf('.') > 0) {
const start = filename.lastIndexOf('.'); const start = filename.lastIndexOf('.');
const expandedName = filename.substring(start + 1); const expandedName = filename.substring(start + 1);
if (expandedName.match(/(bmp|jpg|jpeg|png|tif|gif|pcx|tga|exif|fpx|svg|psd|cdr|pcd|dxf|ufo|eps|ai|raw|WMF|webp)/gi) != null) { if (expandedName.match(/(bmp|jpg|jpeg|png|tif|gif|pcx|tga|exif|fpx|svg|psd|cdr|pcd|dxf|ufo|eps|ai|raw|WMF|webp)/gi) != null) {
type = 'image/' + expandedName; type = 'image/' + expandedName;
} else {
resolve(img);
}
}
let blob = new Blob([response.data],{type: type});
this.blobToBase64(blob).then((res: any) => {
// 转化后的base64
img = `${res}`;
// 缓存图片
successImgMap.set(url, img);
resolve(img);
})
} else { } else {
resolve(img); resolve(img);
} }
}).catch((result: any) => { }
return resolve(img); let blob = new Blob([response.data], { type: type });
}) this.blobToBase64(blob).then((res: any) => {
// 转化后的base64
img = `${res}`;
// 缓存图片
successImgMap.set(url, img);
resolve(img);
})
} else {
resolve(img);
}
}).catch((result: any) => {
return resolve(img);
})
} }
// 加载中 // 加载中
if (loadingImgMap.get(url)) { if (loadingImgMap.get(url)) {
callback(url, loadingImgMap.get(url)); callback(url, loadingImgMap.get(url));
} else { } else {
let _url = url; let _url = url;
if (!Object.is('/', _url.substring(0,1))) { if (!Object.is('/', _url.substring(0, 1))) {
_url = '/'+_url; _url = '/' + _url;
} }
let result:Promise<any> = axios({method: 'get', url: _url, responseType: 'blob'}); let result: Promise<any> = axios({ method: 'get', url: _url, responseType: 'blob' });
loadingImgMap.set(url, result); loadingImgMap.set(url, result);
callback(url, result); callback(url, result);
} }
}); });
} }
/** /**
...@@ -277,13 +214,13 @@ export class EditorBase { ...@@ -277,13 +214,13 @@ export class EditorBase {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const fileReader = new FileReader(); const fileReader = new FileReader();
fileReader.onload = (e: any) => { fileReader.onload = (e: any) => {
resolve(e.target.result); resolve(e.target.result);
}; };
fileReader.readAsDataURL(blob); fileReader.readAsDataURL(blob);
fileReader.onerror = () => { fileReader.onerror = () => {
reject(new Error('blobToBase64 error')); reject(new Error('blobToBase64 error'));
}; };
}); });
} }
/** /**
......
import { IAppCodeListService, IContext, IParam } from "@core";
/**
* 应用代码表服务基类
*
* @export
* @abstract
* @class AppCodeListServiceBase
* @implements {IAppCodeListService}
*/
export abstract class AppCodeListServiceBase implements IAppCodeListService {
/**
* 获取代码表项
*
* @param { tag, context, viewParams }: { tag: string, context: IContext | undefined, viewParams: IParam | undefined }
* @return {*} {Promise<any>}
* @memberof AppCodeListServiceBase
*/
public async getCodeListItems({ tag, context, viewParams }: { tag: string, context: IContext | undefined, viewParams: IParam | undefined }): Promise<any> {
throw new Error("Method not implemented.");
}
}
\ No newline at end of file
export { AppActionServiceBase } from './app-action-service-base'; export { AppActionServiceBase } from './app-action-service-base';
export { AppCodeListServiceBase } from './app-code-list-service-base';
export { AppAuthServiceBase } from './app-auth-service-base'; export { AppAuthServiceBase } from './app-auth-service-base';
export { AppFuncServiceBase } from './app-func-service-base'; export { AppFuncServiceBase } from './app-func-service-base';
export { AppNotificationServiceBase } from './app-notification-service-base'; export { AppNotificationServiceBase } from './app-notification-service-base';
......
import { AppCodeListConfig } from "@/app/config";
import { AppCodeListServiceBase, IAppCodeListService, IContext, IParam } from "@core";
/**
* 应用代码表服务基类
*
* @export
* @abstract
* @class AppCodeListService
* @extends AppCodeListServiceBase
* @implements {IAppCodeListService}
*/
export class AppCodeListService extends AppCodeListServiceBase implements IAppCodeListService {
/**
* 唯一实例
*
* @private
* @static
* @memberof AppCodeListService
*/
private static readonly instance = new AppCodeListService();
/**
* 获取唯一实例
*
* @static
* @return {*} {AppCodeListService}
* @memberof AppCodeListService
*/
public static getInstance(): AppCodeListService {
return AppCodeListService.instance;
}
/**
* 获取代码表项
*
* @param { tag, context, viewParams }: { tag: string, context: IContext | undefined, viewParams: IParam | undefined }
* @return {*} {Promise<any>}
* @memberof AppCodeListService
*/
public async getCodeListItems({ tag, context, viewParams }: { tag: string, context: IContext | undefined, viewParams: IParam | undefined }): Promise<any> {
const codeList = AppCodeListConfig[tag];
if (!codeList) return;
let items: any;
if (Object.is(codeList.codeListType, 'STATIC')) {
items = await this.getItemsWithStatic(codeList);
} else {
if (codeList.predefinedType) {
items = await this.getItemsWithPredefined(codeList);
} else {
items = await this.getItemsWithDynamic(codeList);
}
}
// 处理成UI相关结构
this.handleItemData(items);
return items;
}
/**
* 获取静态代码表
*
* @param {IParam} codeList
* @return {*}
* @memberof AppCodeListService
*/
public async getItemsWithStatic(codeList: IParam): Promise<IParam[]> {
const { items } = codeList;
if (items && items.length > 0) {
return items;
} else {
return [];
}
}
/**
* 获取动态代码表(非预置)
*
* @param {IParam} codeList
* @return {*}
* @memberof AppCodeListService
*/
public async getItemsWithDynamic(codeList: IParam): Promise<IParam[]> {
return [];
}
/**
* 获取预定义代码表
*
* @param {IParam} codeList
* @return {*}
* @memberof AppCodeListService
*/
public async getItemsWithPredefined(codeList: IParam): Promise<IParam[]> {
return [];
}
/**
* 处理成UI相关结构
* 1.将{value: 'val',text: 'label'}处理成{value: 'val',label: 'label'}
* 2.处理代码表层级问题
*
* @param {IParam[]} items
* @memberof AppCodeListService
*/
public handleItemData(items: IParam[]) {
// 将{value: 'val',text: 'label'}处理成{value: 'val',label: 'label'}
if (items && (items.length > 0)) {
items.forEach((element: IParam) => {
Object.assign(element, { label: element.text });
});
}
// 处理代码表层级问题
const hasChildren: boolean = items.some((item: any) => {
return item.pvalue;
})
if (hasChildren) {
let list: IParam[] = [];
items.forEach((codeItem: IParam) => {
if (!codeItem.pvalue) {
this.setChildCodeItems(codeItem.value, items, codeItem);
list.push(codeItem);
}
})
items = list;
}
}
/**
* 设置子项数据
*
* @param {string} pValue 父代码项值
* @param {IParam[]} items 代码表集合
* @param {IParam} codeItem 代码项
* @memberof AppCodeListService
*/
public setChildCodeItems(pValue: string, items: IParam[], codeItem: IParam) {
items.forEach((item: IParam) => {
if (item.pvalue == pValue) {
this.setChildCodeItems(item.value, items, item);
if (!codeItem.children) {
codeItem.children = [];
}
codeItem.children.push(item);
}
})
}
}
\ No newline at end of file
export { AppCodeListService } from './app-code-list-service';
\ No newline at end of file
export * from './app-open-view-service'; export * from './app-open-view-service';
export * from './app-code-list-service';
export { AppActionService } from './app-action-service'; export { AppActionService } from './app-action-service';
export { AppAuthService } from './app-auth-service'; export { AppAuthService } from './app-auth-service';
export { AppFuncService } from './app-func-service'; export { AppFuncService } from './app-func-service';
......
import { Subject } from 'rxjs';
import Router from '@/router';
import Antd from 'ant-design-vue';
import AppDrawerComponent from "./app-drawer.vue";
import AppLoading from '@components/common/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
<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
import { Subject } from 'rxjs';
import Router from '@/router';
import Antd from 'ant-design-vue';
import AppModalComponent from "./app-modal.vue";
import AppLoading from '@components/common/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
<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
.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
import { Subject } from 'rxjs';
import Router from '@/router';
import Antd from 'ant-design-vue';
import AppPopoverComponent from "./app-popover.vue";
import AppLoading from '@components/common/app-loading.vue';
import { IParam, ViewDetail } from '@core';
import './app-popover.scss';
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
<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
export { AppModal } from './app-modal/app-modal';
export { AppDrawer } from './app-drawer/app-drawer';
export { AppPopover } from './app-popover/app-popover';
export { OpenViewService } from './open-view/open-view-service';
import { IContext, IOpenViewService, IParam, RouteUtil, ViewDetail } from '@core';
import router from '@/router';
import { AppModal } from '@/utils';
import { Subject } from 'rxjs';
interface Params extends IParam {
context: IContext;
viewParams: IParam;
}
/**
* 视图打开服务
* @export
* @class OpenViewService
*/
export class OpenViewService 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 openView(view: ViewDetail, params: Params): 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 相关参数
*/
public openByOpenMode(view: ViewDetail, params: Params): 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: Params) {
// TODO 重定向视图处理
}
}
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册