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

update:更新

上级 c243392a
......@@ -9,5 +9,6 @@
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
<script src="./environments/environment.js"></script>
</body>
</html>
import { Environment } from "@/environments/environment";
import { OpenViewService } from "@/utils";
import { AppBase, IParam, ViewDetail, IApp, IOpenViewService, deepCopy, IUIServiceRegister, IDataServiceRegister } from "@core";
import { AppBase, IParam, ViewDetail, IApp, IOpenViewService, deepCopy, getSessionStorage, Http, AppUtil } from "@core";
import { SyncSeriesHook } from "qx-util";
import { AppFuncConfig, AppViewConfig } from './config';
import { DataServiceRegister, UIServiceRegister } from "./register";
......@@ -14,6 +16,27 @@ export class App extends AppBase implements IApp {
*/
private static readonly instance = new App();
/**
* HTTP服务类
*
* @protected
* @memberof App
*/
protected http = Http.getInstance();
/**
* 执行钩子(包含获取租户前、获取租户后、获取应用数据前、获取应用数据后)
*
* @static
* @memberof App
*/
public static hooks = {
dcSystemBefore: new SyncSeriesHook<[], { dcsystem: string }>(),
dcSystemAfter: new SyncSeriesHook<[], { dcsystem: string, data: any }>(),
appBefore: new SyncSeriesHook<[], { url: string, param: any }>(),
appAfter: new SyncSeriesHook<[], { data: any }>()
};
/**
* 获取唯一实例
*
......@@ -25,6 +48,34 @@ export class App extends AppBase implements IApp {
return App.instance;
}
/**
* 初始化应用权限
*
* @param {IParam} params 应用预置参数
* @return {*} {Promise<any>}
* @memberof App
*/
public async initAppAuth(params: IParam): Promise<any> {
let result = true;
if (Environment && Environment.SaaSMode) {
if (getSessionStorage('activeOrgData')) {
result = await AppUtil.getAppData(App.hooks, params);
} else {
result = await AppUtil.getOrgsByDcsystem(App.hooks);
if (result) {
result = await AppUtil.getAppData(App.hooks, params);
}
}
} else {
result = await AppUtil.getAppData(App.hooks, params);
}
if (!result) {
// 登录
}
// TODO
return true;
}
/**
* 获取所有应用功能
*
......
......@@ -10,6 +10,15 @@ import { IAppFuncService, IDataServiceRegister, IOpenViewService, IUIServiceRegi
*/
export interface IApp {
/**
* 初始化应用权限
*
* @param {IParam} params 应用预置参数
* @return {*} {Promise<any>}
* @memberof IApp
*/
initAppAuth(params: IParam): Promise<any>;
/**
* 获取应用所有功能
*
......@@ -63,4 +72,20 @@ export interface IApp {
*/
getViewInfo(codeName: string): ViewDetail | undefined;
/**
* 获取应用数据
*
* @return {*} {IParam}
* @memberof IApp
*/
getAppData(): IParam;
/**
* 设置应用数据
*
* @param {IParam} opt
* @memberof IApp
*/
setAppData(opt:IParam): void;
}
\ No newline at end of file
import { IContext, IParam, UIActionTool } from "@core";
import { IContext, IParam } from "@core";
import { ActionParams, AppActionBase, UIActionResult } from "./app-action-base";
/**
......
......@@ -18,6 +18,46 @@ export abstract class AppBase implements IApp {
*/
private appFuncService: AppFuncService = AppFuncService.getInstance();
/**
* 应用数据
*
* @private
* @type {IParam}
* @memberof AppBase
*/
private appData: IParam = {};
/**
* 初始化应用权限
*
* @param {IParam} params 应用预置参数
* @return {*} {Promise<any>}
* @memberof AppBase
*/
public async initAppAuth(params: IParam): Promise<any> {
throw new Error("Method not implemented.");
}
/**
* 设置应用数据
*
* @param {IParam} opt
* @memberof AppBase
*/
public setAppData(opt: IParam): void {
this.appData = opt;
}
/**
* 获取应用数据
*
* @return {*} {IParam}
* @memberof AppBase
*/
public getAppData(): IParam {
return this.appData;
}
/**
* 获取应用功能服务
*
......
......@@ -2,6 +2,7 @@ import { isExist } from '@core';
import axios from 'axios';
import qs from 'qs';
import { Subject } from 'rxjs';
import { Interceptors } from './interceptor';
/**
* Http net 对象
......@@ -40,7 +41,7 @@ export class Http {
*
* @memberof Http
*/
private constructor() { }
private constructor() {}
/**
* 网络请求对象
......
export { Http } from './http';
\ No newline at end of file
export { Http } from './http';
export { Interceptors } from './interceptor';
\ No newline at end of file
import { Environment } from '@/environments/environment';
import { IParam } from '@core';
import { clearCookie, getCookie, SyncSeriesHook } from 'qx-util';
import { getSessionStorage } from '../util';
import { Http } from './http';
/**
* 拦截器
*
* @export
* @class Interceptors
*/
export class Interceptors {
/**
* 单列对象
*
* @private
* @static
* @type { Interceptors }
* @memberof Interceptors
*/
private static readonly instance: Interceptors = new Interceptors();
/**
* Creates an instance of Interceptors.
* 私有构造,拒绝通过 new 创建对象
*
* @memberof Interceptors
*/
private constructor() {
if (Interceptors.instance) {
return Interceptors.instance;
} else {
this.intercept();
}
}
/**
* 获取 Interceptors 单例对象
*
* @static
* @returns {Interceptors}
* @memberof Interceptors
*/
public static getInstance(): Interceptors {
return this.instance;
}
/**
* 执行钩子(请求、响应)
*
* @memberof Interceptors
*/
public static hooks = {
request: new SyncSeriesHook<[], { config: any }>(),
response: new SyncSeriesHook<[], { response: any }>()
};
/**
* 拦截器实现接口
*
* @private
* @memberof Interceptors
*/
private intercept(): void {
Http.getHttp().interceptors.request.use((config: any) => {
Interceptors.hooks.request.callSync({ config: config });
if (Environment.SaaSMode && (!config.url.startsWith("/uaa/getbydcsystem/"))) {
let activeOrgData = getSessionStorage('activeOrgData');
config.headers['srforgid'] = activeOrgData?.orgid;
config.headers['srfsystemid'] = activeOrgData?.systemid;
}
if (getCookie('ibzuaa-token')) {
config.headers['Authorization'] = `Bearer ${getCookie('ibzuaa-token')}`;
}
if (!Object.is(Environment.BaseUrl, "") && !config.url.startsWith('https://') && !config.url.startsWith('http://') && !config.url.startsWith('./assets')) {
config.url = Environment.BaseUrl + config.url;
}
console.log(config);
return config;
}, (error: any) => {
return Promise.reject(error);
});
Http.getHttp().interceptors.response.use((response: any) => {
Interceptors.hooks.response.callSync({ response: response });
return response;
}, (error: any) => {
error = error ? error : { response: {} };
let { response: res } = error;
let { data: _data } = res;
// 处理异常
if (res.headers && res.headers['x-ibz-error']) {
res.data.errorKey = res.headers['x-ibz-error'];
}
if (res.headers && res.headers['x-ibz-params']) {
res.data.entityName = res.headers['x-ibz-params'];
}
if (res.status === 401) {
this.doNoLogin(res, _data.data);
}
if (res.status === 403) {
if (res.data && res.data.status && Object.is(res.data.status, "FORBIDDEN")) {
let alertMessage: string = "非常抱歉,您无权操作此数据,如需操作请联系管理员!";
Object.assign(res.data, { localizedMessage: alertMessage, message: alertMessage });
}
}
// if (res.status === 404) {
// this.router.push({ path: '/404' });
// } else if (res.status === 500) {
// this.router.push({ path: '/500' });
// }
return Promise.reject(res);
});
}
/**
* 处理未登录异常情况
*
* @private
* @param {*} [data={}]
* @memberof Interceptors
*/
private doNoLogin(response: any, data: any = {}): void {
// todo
}
}
\ No newline at end of file
import { Environment } from "@/environments/environment";
import { getSessionStorage, Http, IParam, setSessionStorage } from "@core";
import qs from "qs";
import { getCookie } from "qx-util";
/**
* 应用相关处理逻辑工具类
*
* @export
* @class AppUtil
*/
export class AppUtil {
/**
* 获取应用数据
*
* @static
* @param {IParam} hooks 应用钩子
* @param {IParam} [params={}] 应用参数
* @return {*} {Promise<boolean>}
* @memberof AppUtil
*/
public static async getAppData(hooks: IParam, params: IParam = {}): Promise<boolean> {
try {
const url = '/appdata';
hooks.appBefore.callSync({ url: url, param: params });
const response: any = await Http.getInstance().get(url);
if (response && response.status === 200) {
let { data }: { data: any } = response;
hooks.appAfter.callSync({ data: data });
if (!data) {
return false;
}
// token认证把用户信息放入应用级数据
if (getCookie('ibzuaa-user')) {
let user: any = JSON.parse(getCookie('ibzuaa-user') as string);
let localAppData: any = {};
if (user.sessionParams) {
localAppData = { context: user.sessionParams };
Object.assign(localAppData, data);
}
data = JSON.parse(JSON.stringify(localAppData));
}
App.setAppData(data);
return true;
} else {
return false;
}
} catch (error) {
console.warn(error);
return false;
}
}
/**
* 通过租户获取组织数据
*
* @static
* @param {IParam} hooks 应用钩子
* @return {*} {Promise<boolean>}
* @memberof AppUtil
*/
public static async getOrgsByDcsystem(hooks: IParam): Promise<boolean> {
try {
let tempViewParam = this.hanldeViewParam(window.location.href);
if (!tempViewParam.srfdcsystem) {
if (!tempViewParam.redirect) {
if (getSessionStorage('dcsystem')) {
tempViewParam = getSessionStorage('dcsystem');
}
} else {
tempViewParam = this.hanldeViewParam(tempViewParam.redirect);
}
}
if (!tempViewParam.srfdcsystem && Environment.mockDcSystemId) {
Object.assign(tempViewParam, { srfdcsystem: Environment.mockDcSystemId });
}
if (tempViewParam.srfdcsystem) {
hooks.dcSystemBefore.callSync({ dcsystem: tempViewParam.srfdcsystem });
setSessionStorage('dcsystem', tempViewParam);
let requestUrl: string = `/uaa/getbydcsystem/${tempViewParam.srfdcsystem}`;
const response: any = await Http.getInstance().get(requestUrl);
if (response && response.status === 200) {
let { data }: { data: any } = response;
hooks.dcSystemAfter.callSync({ dcsystem: tempViewParam.srfdcsystem, data: data });
if (data && data.length > 0) {
setSessionStorage('orgsData', data);
setSessionStorage('activeOrgData', data[0]);
}
return true;
} else {
return false;
}
} else {
return false;
}
} catch (error) {
console.warn(error);
return false;
}
}
/**
* 处理路径数据
*
* @static
* @param {string} urlStr 路径
* @return {*} {*}
* @memberof AppUtil
*/
public static hanldeViewParam(urlStr: string): any {
let tempViewParam: any = {};
const tempViewparam: any = urlStr.slice(urlStr.indexOf('?') + 1);
const viewparamArray: Array<string> = decodeURIComponent(tempViewparam).split(';');
if (viewparamArray.length > 0) {
viewparamArray.forEach((item: any) => {
Object.assign(tempViewParam, qs.parse(item));
});
}
return tempViewParam;
}
}
\ No newline at end of file
export { RouteUtil } from './route-util';
export { UIUtil } from './ui-util';
export { UIActionTool } from './uiaction-tool';
export { ViewUtil } from './view-util';
\ No newline at end of file
export { UIActionUtil } from './uiaction-util';
export { ViewUtil } from './view-util';
export { AppUtil } from './app-util';
\ No newline at end of file
export class UIActionTool {
export class UIActionUtil {
/**
* 格式化数据
......@@ -12,7 +12,7 @@ export class UIActionTool {
* @param parentParams
* @param {*} _params
* @returns {*}
* @memberof UIActionTool
* @memberof UIActionUtil
*/
public static formatDataActionData(actionTarget: any, args: any, parentContext: any, parentParams: any, _params: any): any {
const _data: any = {};
......
......@@ -266,3 +266,43 @@ function contains(value: any, value2: any): boolean {
}
return false;
}
/**
* 设置sessionStorage数据
*
*/
export const setSessionStorage: Function = (key: string, value: any) => {
if (!value) {
return;
}
sessionStorage.setItem(key, JSON.stringify(value));
}
/**
* 获取sessionStorage数据
*
*/
export const getSessionStorage: Function = (key: string) => {
if (!key) {
return null;
}
let value = sessionStorage.getItem(key);
if (value) {
return JSON.parse(value);
} else {
return value;
}
}
/**
* 删除sessionStorage数据
*
*/
export const removeSessionStorage: Function = (key: string) => {
if (!key) {
return;
}
if (sessionStorage.getItem(key)) {
sessionStorage.removeItem(key);
}
}
\ No newline at end of file
export const Environment = {
// 系统名称
SysName: '{{app.psSystem.codeName}}',
// 应用名称
AppName: '{{app.codeName}}',
// 应用 title
AppTitle: '{{app.name}}',
// 应用基础路径
BaseUrl: '/api',
// 文件导出
ExportFile: '/ibizutil/download',
// 文件上传
UploadFile: '/ibizutil/upload',
// 是否为pc端应用
isAppMode: true,
// 是否为开发模式
devMode: true,
// 是否启用AppData
enableAppData: true,
// 是否开启权限认证
enablePermissionValid: false,
// 菜单权限模式,可选值:RT(RT模式),RESOURCE(资源模式),MINIX(混合模式),RESOURCE
menuPermissionMode: 'RESOURCE',
// 是否开启工作流
workflow: false,
// 是否预览模式
isPreviewMode: false,
// SaaS模式
SaaSMode: false,
// 仿真mockDcSystemId
mockDcSystemId: '',
// 登录地址
loginUrl: ''
};
// 挂载外部配置文件
if ((window as any).Environment) {
Object.assign(Environment, (window as any).Environment);
}
\ No newline at end of file
import 'font-awesome/css/font-awesome.min.css'
import Router from '@/router';
import Antd from 'ant-design-vue';
import { Interceptors } from '@core';
import 'font-awesome/css/font-awesome.min.css';
import 'ant-design-vue/dist/antd.css';
import '@/style/index.scss'
import App from './App.vue'
// 挂载拦截器
Interceptors.getInstance();
createApp(App).use(Router).use(Antd).mount('#app')
import { createRouter, createWebHashHistory } from 'vue-router';
import { IParam } from '@core';
const routes = [
{
path: "/apps/:app?",
{{!-- beforeEnter: (to: any, from: any, next: any) => {
next();
}, --}}
beforeEnter: async (to: any, from: any) => {
const appParams:IParam = {};
const auth: Promise<any> = await App.initAppAuth(appParams);
return auth;
},
meta: {
captionTag: "{{#if app.defaultPSAppIndexView.capPSLanguageRes}}{{app.defaultPSAppIndexView.capPSLanguageRes.lanResTag}}{{/if}}",
caption: "{{app.defaultPSAppIndexView.caption}}",
viewType: "{{app.defaultPSAppIndexView.viewType}}",
{{#if app.defaultPSAppIndexView.psSysImage}}
imgPath: "{{app.defaultPSAppIndexView.psSysImage.imagePath}}",
iconCls: "{{app.defaultPSAppIndexView.psSysImage.cssClass}}",
{{/if}}
requireAuth: {{#eq app.defaultPSAppIndexView.accUserMode 0}}false{{else}}{{#eq app.defaultPSAppIndexView.accUserMode 3}}false{{else}}true{{/eq}}{{/eq}},
tag: '{{app.defaultPSAppIndexView.codeName}}'
},
component: () => import("@page/{{spinalCase app.defaultPSAppIndexView.psAppModule.codeName}}/{{spinalCase app.defaultPSAppIndexView.codeName}}"),
children: [
......@@ -25,23 +21,7 @@ const routes = [
{
path: "{{appEntityResource.path}}/views/{{lowerCase appView.codeName}}",
meta: {
{{#if appView.capPSLanguageRes}}
captionTag: "{{appView.capPSLanguageRes.lanResTag}}",
{{/if}}
caption: "{{appView.caption}}",
viewType: "{{appView.viewType}}",
{{#if appView.psSysImage}}
imgPath: "{{appView.psSysImage.imagePath}}",
iconClass: "{{appView.psSysImage.cssClass}}",
{{/if}}
parameters: [
{ pathName: "apps", parameterName: "app" },
{{#if appEntityResource.majorCodeName}}
{ pathName: "{{pluralize appEntityResource.majorCodeName}}", parameterName: "{{appEntityResource.majorCodeName}}" },
{{/if}}
{ pathName: "{{pluralize appEntityResource.curCodeName}}", parameterName: "{{appEntityResource.curCodeName}}" }
],
requireAuth: false,
tag:'{{appView.codeName}}'
},
component: () => import("@page/{{spinalCase appView.psAppModule.codeName}}/{{spinalCase appView.codeName}}"),
},
......
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册