diff --git a/src/modules/components/test_status/test_status.ts b/src/modules/components/test_status/test_status.ts index 8929f7d..a055e6e 100644 --- a/src/modules/components/test_status/test_status.ts +++ b/src/modules/components/test_status/test_status.ts @@ -29,7 +29,9 @@ export class TestStatus extends BI.Widget { failDriverMessage: Label; driverLink: FloatLeftLayout; detail: VerticalLayout; - failMaskers:any; + failMaskers: any; + + extraContainer: VerticalLayout; watch = { status: (status: string) => { @@ -38,8 +40,9 @@ export class TestStatus extends BI.Widget { } render() { + const LAYOUT_WIDTH = 400; const { loadingCls, loadingText, successCls, successText, failCls, failText, retryText } = this.options; - var self=this; + return { type: BI.CenterAdaptLayout.xtype, cls: 'bi-z-index-mask', @@ -71,10 +74,10 @@ export class TestStatus extends BI.Widget { tipCls: failCls, tipText: failText, retryText, - ref:(_ref:any)=>{ - self.failMaskers=_ref; - if(this.failMessage.getText()===''){ - this.failMaskers.populateFail(BI.i18nText("Dec-Conn-ect-Failed"),false); + ref: (_ref: TipFail) => { + this.failMaskers = _ref; + if (BI.isEmptyString(this.failMessage.getText())) { + this.failMaskers.populateFail(BI.i18nText('Dec-Conn-ect-Failed'), false); } }, listeners: [ @@ -123,10 +126,17 @@ export class TestStatus extends BI.Widget { scrolly: true, height: 75, items: [ + { + type: BI.VerticalLayout.xtype, + width: LAYOUT_WIDTH, + ref: (_ref: VerticalLayout) => { + this.extraContainer = _ref; + } + }, { type: BI.Label.xtype, whiteSpace: 'normal', - width: 400, + width: LAYOUT_WIDTH, textAlign: 'left', text: '', ref: (_ref: Label) => { @@ -175,7 +185,7 @@ export class TestStatus extends BI.Widget { this.store.setStatus(TEST_STATUS.SUCCESS); } - setFail(message: string='', driver = '', link = '') { + setFail(message: string = '', driver = '', link = '') { this.store.setStatus(TEST_STATUS.FAIL); this.failMessage.setText(message); this.failDriverMessage.setVisible(!!driver); @@ -189,4 +199,14 @@ export class TestStatus extends BI.Widget { setLoading() { this.store.setStatus(TEST_STATUS.LOADING); } + + /** + * 设置报错弹窗自定义展示内容 + */ + setExtraContainer(container: Obj) { + BI.createWidget({ + ...container, + element: this.extraContainer, + }); + } } diff --git a/src/modules/crud/api.ts b/src/modules/crud/api.ts index daa9e4d..01ed8dd 100644 --- a/src/modules/crud/api.ts +++ b/src/modules/crud/api.ts @@ -5,6 +5,7 @@ import { ConnectionPoolType, SocketResult, ResultType, + checkDriverStatusParams, } from './crud.typings'; export interface Api { @@ -46,6 +47,17 @@ export interface Api { */ testConnection(data: Connection): Promise; + /** + * 获取驱动加载路径 + */ + getDriverLoadPath(data: Connection): Promise>; + + /** + * 检测驱动冲突状态 + * @param data 驱动路径 + */ + checkDriverStatus(data: checkDriverStatusParams): Promise>; + /** * 获取连接池数据 * @param name diff --git a/src/modules/crud/crud.typings.d.ts b/src/modules/crud/crud.typings.d.ts index 0193583..8a5c8b9 100644 --- a/src/modules/crud/crud.typings.d.ts +++ b/src/modules/crud/crud.typings.d.ts @@ -306,8 +306,13 @@ export interface SocketResult { errorMsg?: string; } -export interface ResultType { - data?: any; +export interface ResultType { + data?: T; errorCode?: string; errorMsg?: string; } + +export type checkDriverStatusParams = { + path: string; + driver: ConnectionJDBC['driver']; +} \ No newline at end of file diff --git a/src/modules/crud/decision.api.ts b/src/modules/crud/decision.api.ts index a77f406..dbcf141 100644 --- a/src/modules/crud/decision.api.ts +++ b/src/modules/crud/decision.api.ts @@ -1,5 +1,5 @@ import { Api } from './api'; -import { Connection, TestRequest, ConnectionPoolType, SocketResult, ConnectionLicInfo } from './crud.typings'; +import { Connection, TestRequest, ConnectionPoolType, SocketResult, ConnectionLicInfo, ResultType, checkDriverStatusParams } from './crud.typings'; import { requestGet, requestDelete, requestPost, requestPut } from './crud.service'; import { editStatusEvent, errorCode } from '@constants/env'; @@ -48,6 +48,27 @@ export class DecisionApi implements Api { return requestPost('test', form); } + /** + * 获取驱动加载路径 + * @returns + */ + getDriverLoadPath(data: Connection): Promise> { + const form = { + ...data, + connectionData: JSON.stringify(data.connectionData), + }; + + return requestPost('driver/path', form); + } + + /** + * 检测驱动冲突状态 + * @param data 驱动路径 + */ + checkDriverStatus(data: checkDriverStatusParams): Promise> { + return requestGet(Dec.Utils.getEncodeURL('test/driver/conflict', '', data)); + } + getConnectionPool(name: string): Promise<{ data?: ConnectionPoolType }> { return requestGet(`pool/info?connectionName=${encodeURIComponent(name)}`, {}); } diff --git a/src/modules/crud/design.api.ts b/src/modules/crud/design.api.ts index 643ad8e..d629b16 100644 --- a/src/modules/crud/design.api.ts +++ b/src/modules/crud/design.api.ts @@ -1,5 +1,5 @@ import { Api } from './api'; -import { Connection, TestRequest, ConnectionPoolType, SocketResult, ConnectionLicInfo } from './crud.typings'; +import { Connection, TestRequest, ConnectionPoolType, SocketResult, ConnectionLicInfo, ResultType, ConnectionJDBC, checkDriverStatusParams } from './crud.typings'; import { requestGet } from './crud.service'; // TODO: 此页面的接口等待设计器提供相应的方法 @@ -39,6 +39,27 @@ export class DesignApi implements Api { }); } + /** + * 获取驱动加载路径 + * @param name + * @returns + */ + getDriverLoadPath(data: Connection): Promise> { + return new Promise(resolve => { + resolve({ data: '' }); + }); + } + + /** + * 检测驱动冲突状态 + * @param data 驱动路径 + */ + checkDriverStatus(data: checkDriverStatusParams): Promise> { + return new Promise(resolve => { + resolve({ data: false }); + }); + } + getConnectionPool(name: string): Promise<{ data: ConnectionPoolType }> { return new Promise(resolve => { resolve({ diff --git a/src/modules/pages/maintain/forms/form.server.ts b/src/modules/pages/maintain/forms/form.server.ts index 67647fc..2098ac1 100644 --- a/src/modules/pages/maintain/forms/form.server.ts +++ b/src/modules/pages/maintain/forms/form.server.ts @@ -5,6 +5,7 @@ import { TestStatus } from '../../../components/test_status/test_status'; import { getJdbcDatabaseType } from '../../../app.service'; import { ApiFactory } from '../../../crud/apiFactory'; const api = new ApiFactory().create(); + export function testConnection(value: Connection): Promise { return new Promise(resolve => { let testStatus = null; @@ -15,16 +16,18 @@ export function testConnection(value: Connection): Promise { return false; } + const id = BI.UUID(); const testConnection = () => { const formValue = value; + api.testConnection(formValue).then(re => { if (re && re.errorCode) { - if(re.errorCode === DecCst.ErrorCode.NO_IP_AUTHORIZED){ + if (re.errorCode === DecCst.ErrorCode.NO_IP_AUTHORIZED) { testStatus.setFail(); return; } - // 判断是否是缺少驱动,如果缺少驱动则显示下载驱动的连接 + // 判断是否是缺少驱动,如果缺少驱动则显示下载驱动的连接 if (api.isDriverError(re.errorCode)) { if (formValue.connectionType === connectionType.JDBC) { const driver = (formValue.connectionData as ConnectionJDBC).driver; @@ -44,7 +47,11 @@ export function testConnection(value: Connection): Promise { } else if (re.errorCode === errorCode.DUPLICATE_NAMES) { testStatus.setFail(BI.i18nText(re.errorMsg)); } else { + // 不缺少驱动,但连接失败,打印出当前驱动加载路径,并显示检测驱动按钮 testStatus.setFail(re.errorMsg); + api.getDriverLoadPath(formValue).then(res => { + testStatus.setExtraContainer(createDriverTestContainer(res.data)); + }) } } else if (re.data) { testStatus.setSuccess(); @@ -59,7 +66,54 @@ export function testConnection(value: Connection): Promise { BI.Maskers.remove(id); } }); + + /** + * 驱动及冲突检测内容,补充到报错弹窗里 + */ + function createDriverTestContainer(path: string) { + return { + type: BI.VerticalLayout.xtype, + vgap: 5, + items: [ + { + type: BI.Label.xtype, + text: BI.i18nText('Dec-Connection_Driver_Current_Load_Path', path), + textAlign: 'left', + whiteSpace: 'normal', + }, + { + type: BI.TextButton.xtype, + cls: 'bi-high-light', + text: BI.i18nText('Dec-Connection_Driver_Check'), + textAlign: 'left', + handler: () => { + api.checkDriverStatus({ + driver: (formValue.connectionData as ConnectionJDBC).driver, + path, + }).then(res => { + const isDriverConflict = res.data; + + testStatus.setExtraContainer({ + type: BI.VerticalLayout.xtype, + items: [ + { + type: BI.Label.xtype, + textAlign: 'left', + text: isDriverConflict + ? BI.i18nText('Dec-Connection_Driver_Has_Confilt_Tip') + : BI.i18nText('Dec-Connection_Driver_No_Confilt_Tip'), + cls: isDriverConflict ? 'bi-error' : '', + } + ] + }) + }); + } + } + ] + } + } }; + BI.Maskers.create(id, null, { render: { type: TestStatus.xtype, diff --git a/types/globals.d.ts b/types/globals.d.ts index f868d4b..0eb147e 100644 --- a/types/globals.d.ts +++ b/types/globals.d.ts @@ -16,6 +16,7 @@ declare const Dec: { personal: { username: string; }; + Utils: Obj; reqByEncrypt: (method: AxiosType.X_Method, url: string, data?: any, config?: AxiosType.X_AxiosRequestConfig) => {}, socketEmit: (type: string, name: string, callback: (re: any) => void) => void; // req