Browse Source

Merge pull request #160 in DEC/decision-webui-dcm from release/10.0 to feature/10.0

* commit 'e4cfc10910c30826de66ab138482827a732e48e3': (25 commits)
  DEC-12158 fix: 国际化测试,遇到的一些界面问题
  fix: 由于容错率的关系,Number方法改成parseInt
  fix: DEC-11221 加入对可输入数值的区间验证
  DEC-11995 feat:密码传输自定义接口
  fix: 修改eslint
  fix: 修改eslint
  fix: DEC-12046 修复本地运行时报错的问题
  DEC-11996 feat: 【华为安全】内存等敏感信息需要鉴权才能获得,前台websocket事件携带token参数
  fix: 修改i18n的写法
  fix: DEC-11815 修改数据连接名称的长度限制
  fix: 修改写法
  fix: 修复url为空时地址以/结尾的bug
  fix: DEC-11797 改用dec中自带的http请求方法
  fix: DEC-11782 oracle数据连接url端口号和数据库之间可能是/或:
  fix: 更新数据连接解析
  fix: 加一下国际化
  DEC-11528 feat: ADS数据库改为阿里云AnalyticDB
  fix: 更新注释
  fix: 移除不必要的修改
  fix: BI-56355 如果数据库类型和驱动都为空,则认为是其他jdbc
  ...
research/11.0
parent
commit
175d896fea
  1. 6
      i18n/zh_cn.properties
  2. 5
      package.json
  3. 4
      private/i18n.ts
  4. 80
      src/modules/__test__/app.test.ts
  5. 4
      src/modules/app.constant.ts
  6. 30
      src/modules/app.service.ts
  7. 11
      src/modules/constants/constant.ts
  8. 5
      src/modules/constants/env.ts
  9. 127
      src/modules/crud/crud.service.ts
  10. 2
      src/modules/crud/decision.api.ts
  11. 7
      src/modules/pages/connection/list/list_item/list_item.model.ts
  12. 11
      src/modules/pages/database/database.ts
  13. 53
      src/modules/pages/maintain/forms/components/form.jdbc.ts
  14. 9
      src/modules/pages/maintain/forms/form.ts
  15. 118
      src/request.ts
  16. 14
      types/globals.d.ts
  17. 2
      webpack/webpack.dev.js
  18. 15
      yarn.lock

6
i18n/zh_cn.properties

@ -110,7 +110,7 @@ Dec-Dcm_Connection_Deleted=该数据连接已被删除,无法进行操作
Dec-Dcm_Connection_Click_Connect_Database=点击连接数据库 Dec-Dcm_Connection_Click_Connect_Database=点击连接数据库
Dec-Dcm_Connection_Read_Mode_List=以读取模式列表 Dec-Dcm_Connection_Read_Mode_List=以读取模式列表
Dec-Dcm_Connection_NO_Connection_Pool=无数据连接,可在数据连接管理页面添加 Dec-Dcm_Connection_NO_Connection_Pool=无数据连接,可在数据连接管理页面添加
Dec-Dcm_Connection_Cannot_Too_Lang=文本长度不能大于200个字符 Dec-Dcm_Connection_Cannot_Too_Lang=文本长度不能大于{R1}个字符
Dec-Dcm_Login_Error=登录信息已失效,请重新登录 Dec-Dcm_Login_Error=登录信息已失效,请重新登录
BI-Multi_Date_Quarter_End= 季度末 BI-Multi_Date_Quarter_End= 季度末
BI-Multi_Date_Month_Begin= 月初 BI-Multi_Date_Month_Begin= 月初
@ -300,4 +300,6 @@ BI-Basic_Million= 百万
BI-Basic_Billion= 亿 BI-Basic_Billion= 亿
BI-Basic_Quarter= 季度 BI-Basic_Quarter= 季度
BI-Basic_No_Select= 不选 BI-Basic_No_Select= 不选
BI-Basic_Now= 此刻 BI-Basic_Now= 此刻
Dec-Dcm_Connection_Analytic_DB=阿里云AnalyticDB
Dec-Dcm_Connection_Value_Out_Range=数值超出范围

5
package.json

@ -19,6 +19,7 @@
"@babel/core": "7.4.5", "@babel/core": "7.4.5",
"@babel/plugin-proposal-class-properties": "^7.5.0", "@babel/plugin-proposal-class-properties": "^7.5.0",
"@babel/plugin-proposal-decorators": "7.4.4", "@babel/plugin-proposal-decorators": "7.4.4",
"@babel/polyfill": "^7.8.3",
"@babel/preset-env": "7.4.5", "@babel/preset-env": "7.4.5",
"@babel/preset-typescript": "7.3.3", "@babel/preset-typescript": "7.3.3",
"@types/jest": "24.0.11", "@types/jest": "24.0.11",
@ -66,8 +67,8 @@
"scripts": { "scripts": {
"dev": "cross-env NODE_ENV=mock webpack-dev-server -p --progress --config=webpack/webpack.dev.js --mode development --open", "dev": "cross-env NODE_ENV=mock webpack-dev-server -p --progress --config=webpack/webpack.dev.js --mode development --open",
"build": "webpack -p --progress --config=webpack/webpack.prod.js --mode production", "build": "webpack -p --progress --config=webpack/webpack.prod.js --mode production",
"eslint": "eslint './*.js' './**/*.js' './**/*.ts'", "eslint": "eslint . --ext .ts",
"eslint-fix": "eslint './*.js' './**/*.js' './**/*.ts' --fix", "eslint-fix": "eslint . --ext .ts --fix",
"const": "javac -encoding UTF-8 -d constants/classes constants/*.java && java -cp constants/classes FRConstantsWriter", "const": "javac -encoding UTF-8 -d constants/classes constants/*.java && java -cp constants/classes FRConstantsWriter",
"i18n": "node ./lib/transform-i18n/transform-i18n.js", "i18n": "node ./lib/transform-i18n/transform-i18n.js",
"test": "jest --passWithNoTests", "test": "jest --passWithNoTests",

4
private/i18n.ts

@ -109,7 +109,7 @@ export default {
'Dec-Dcm_Connection_Click_Connect_Database': '点击连接数据库', 'Dec-Dcm_Connection_Click_Connect_Database': '点击连接数据库',
'Dec-Dcm_Connection_Read_Mode_List': '以读取模式列表', 'Dec-Dcm_Connection_Read_Mode_List': '以读取模式列表',
'Dec-Dcm_Connection_NO_Connection_Pool': '无数据连接,可在数据连接管理页面添加', 'Dec-Dcm_Connection_NO_Connection_Pool': '无数据连接,可在数据连接管理页面添加',
'Dec-Dcm_Connection_Cannot_Too_Lang': '文本长度不能大于200个字符', 'Dec-Dcm_Connection_Cannot_Too_Lang': '文本长度不能大于{R1}个字符',
'Dec-Dcm_Login_Error': '登录信息已失效,请重新登录', 'Dec-Dcm_Login_Error': '登录信息已失效,请重新登录',
'BI-Multi_Date_Quarter_End': '季度末', 'BI-Multi_Date_Quarter_End': '季度末',
'BI-Multi_Date_Month_Begin': '月初', 'BI-Multi_Date_Month_Begin': '月初',
@ -300,4 +300,6 @@ export default {
'BI-Basic_Quarter': '季度', 'BI-Basic_Quarter': '季度',
'BI-Basic_No_Select': '不选', 'BI-Basic_No_Select': '不选',
'BI-Basic_Now': '此刻', 'BI-Basic_Now': '此刻',
'Dec-Dcm_Connection_Analytic_DB': '阿里云AnalyticDB',
'Dec-Dcm_Connection_Value_Out_Range': '数值超出范围',
}; };

80
src/modules/__test__/app.test.ts

@ -1,4 +1,4 @@
import { connectionCanEdit } from '../app.service'; import { connectionCanEdit, resolveUrlInfo, splitUrl, getJdbcDatabaseType } from '../app.service';
const connection = { const connection = {
connectionId: '', connectionId: '',
connectionType: '', connectionType: '',
@ -6,6 +6,84 @@ const connection = {
connectionData: '', connectionData: '',
}; };
/**
* test_author_alan
*/
test('DEC-11030 拼接url', () => {
expect(splitUrl('localhost', '22', 'dbname', 'jdbc:pivotal:greenplum://hostname:port;dbname')).toEqual('jdbc:pivotal:greenplum://localhost:22;dbname');
});
/**
* test_author_alan
*/
test('BI-56355 如果数据库类型和驱动都为空,则为其他jdbc', () => {
expect(getJdbcDatabaseType('', '').databaseType).toEqual('otherJDBC');
expect(getJdbcDatabaseType('mysql', '').databaseType).toEqual('mysql');
expect(getJdbcDatabaseType('', 'com.mysql.jdbc.Driver').databaseType).toEqual('mysql');
});
/**
* test_author_alan
*/
test('DEC-10992 数据连接名称带-', () => {
expect(resolveUrlInfo('jdbc:sqlserver://192.168.17.111:1433;databaseName=L-Pick-DAS-MengYan')).toEqual({
host: '192.168.17.111',
port: '1433',
databaseName: 'L-Pick-DAS-MengYan',
urlInfo: '',
});
});
test('解析url', () => {
expect(resolveUrlInfo('jdbc:postgresql://endpoint:port/database')).toEqual({
host: 'endpoint',
port: '',
databaseName: 'database',
urlInfo: '',
});
expect(resolveUrlInfo('jdbc:pivotal:greenplum://hostname:port;dbname')).toEqual({
host: 'hostname',
port: '',
databaseName: 'dbname',
urlInfo: '',
});
expect(resolveUrlInfo('jdbc:mysql://hostname:22/database')).toEqual({
host: 'hostname',
port: '22',
databaseName: 'database',
urlInfo: '',
});
expect(resolveUrlInfo('jdbc:sqlserver://hostname:port;databaseName=database')).toEqual({
host: 'hostname',
port: '',
databaseName: 'database',
urlInfo: '',
});
expect(resolveUrlInfo('jdbc:oracle:thin:@192.168.5.143:1521/orcl')).toEqual({
host: '192.168.5.143',
port: '1521',
databaseName: 'orcl',
urlInfo: '',
});
expect(resolveUrlInfo('jdbc:oracle:thin:@192.168.5.143:1521:orcl')).toEqual({
host: '192.168.5.143',
port: '1521',
databaseName: 'orcl',
urlInfo: '',
});
});
test('数据库可能为空', () => {
expect(resolveUrlInfo('jdbc:mysql://secure.finedevelop.com:62306/')).toEqual({
host: 'secure.finedevelop.com',
port: '62306',
databaseName: '',
urlInfo: '',
});
});
/**
* test_author_alan
*/
test('BI-51537 判断数据连接是否有权限', () => { test('BI-51537 判断数据连接是否有权限', () => {
expect(connectionCanEdit({ expect(connectionCanEdit({
...connection, ...connection,

4
src/modules/app.constant.ts

@ -1,2 +1,6 @@
export const CONSTANT_PLUGIN_TYPES = 'dec.constant.database.conf.connect.types'; export const CONSTANT_PLUGIN_TYPES = 'dec.constant.database.conf.connect.types';
BI.constant(CONSTANT_PLUGIN_TYPES, []); BI.constant(CONSTANT_PLUGIN_TYPES, []);
/**
*
*/
export const NAME_MAX_LENGTH = 150;

30
src/modules/app.service.ts

@ -27,9 +27,11 @@ export function getPluginWidgetEdit(plugin: string) {
// 由于database可能为空,所以为了兼容平台和设计器,需要根据driver来判断数据库类型 // 由于database可能为空,所以为了兼容平台和设计器,需要根据driver来判断数据库类型
export function getJdbcDatabaseType(database: string, driver: string): DatabaseType { export function getJdbcDatabaseType(database: string, driver: string): DatabaseType {
if (!database && !driver) {
return DATA_BASE_TYPES_OTHER;
}
let databaseType = null; let databaseType = null;
// KERNEL-1655 兼容旧版 由于旧版设计器创建的数据连接database都为other,所以要根据driber来判断数据类型 // KERNEL-1655 兼容旧版 由于旧版设计器创建的数据连接database都为other,所以要根据driber来判断数据类型
// DEC-10872 不能过滤other,因为新版数据连接创建的其他jdbc也是other类型,会混淆,需要和后端讨论一个最佳的解决方案。
if (database && database !== 'other' && DATA_BASE_TYPES.some(item => item.databaseType === database)) { if (database && database !== 'other' && DATA_BASE_TYPES.some(item => item.databaseType === database)) {
databaseType = DATA_BASE_TYPES.find(item => item.databaseType === database); databaseType = DATA_BASE_TYPES.find(item => item.databaseType === database);
} else { } else {
@ -47,12 +49,31 @@ export function getJdbcDatabaseType(database: string, driver: string): DatabaseT
export function resolveUrlInfo (url: string) { export function resolveUrlInfo (url: string) {
if (BI.isNull(url)) return {}; if (BI.isNull(url)) return {};
const result = url.match(/^jdbc:(oracle|mysql|sqlserver|db2|impala|kylin|phoenix|derby|gbase|gbasedbt-sqli|informix-sqli|h2|postgresql|hive2|vertica|kingbase|presto):(thin:([0-9a-zA-Z/]*)?@|thin:([0-9a-zA-Z/]*)?@\/\/|\/\/|)([0-9a-zA-Z_\\.-]+)(:([0-9|port]+))?(:|\/|;DatabaseName=)([0-9a-zA-Z_\\.]+)(.*)/i); const oracleUlr = url.match(/^jdbc:(oracle):(thin:([0-9a-zA-Z/]*)?@|thin:([0-9a-zA-Z/]*)?@\/\/|\/\/|)([0-9a-zA-Z_\\.-]+)(:([0-9|port]+))?(:|\/)([^]+)(.*)/i);
if (oracleUlr) {
return {
host: oracleUlr[5],
port: oracleUlr[7] === 'port' ? '' : oracleUlr[7],
databaseName: oracleUlr[9],
urlInfo: oracleUlr[10],
};
}
const greenplumUrl = url.match(/^jdbc:(pivotal:greenplum):(thin:([0-9a-zA-Z/]*)?@\/\/|\/\/|)([0-9a-zA-Z_\\.-]+)(:([0-9|port]+))?(\/|;)([^]+)(.*)/i);
if (greenplumUrl) {
return {
host: greenplumUrl[4],
port: greenplumUrl[6] === 'port' ? '' : greenplumUrl[6],
databaseName: greenplumUrl[8],
urlInfo: greenplumUrl[9],
};
}
const result = url.match(/^jdbc:(mysql|sqlserver|db2|impala|kylin|phoenix|derby|gbase|gbasedbt-sqli|informix-sqli|h2|postgresql|hive2|vertica|kingbase|presto|redshift|postgresql):(thin:([0-9a-zA-Z/]*)?@|thin:([0-9a-zA-Z/]*)?@\/\/|\/\/|)([0-9a-zA-Z_\\.-]+)(:([0-9|port]+))?(\/|;DatabaseName=)?([^]+)?(.*)/i);
if (result) { if (result) {
return { return {
host: result[5], host: result[5],
port: result[7] === 'port' ? '' : result[7], port: result[7] === 'port' ? '' : result[7],
databaseName: result[9], databaseName: result[9] || '',
urlInfo: result[10], urlInfo: result[10],
}; };
} }
@ -87,7 +108,8 @@ export function splitUrl(host: string, port: string, database: string, baseUrl:
} }
return baseUrl.replace('hostname', host).replace(':port', port ? `:${port}` : '') return baseUrl.replace('hostname', host).replace(':port', port ? `:${port}` : '')
.replace('database', database); .replace('database', database)
.replace('dbname', database);
} }
export function connectionCanEdit(connection: Connection) { export function connectionCanEdit(connection: Connection) {

11
src/modules/constants/constant.ts

@ -197,7 +197,7 @@ export const DESIGN_DRIVER_TYPE = [
]; ];
export const DATA_BASE_TYPES = [ export const DATA_BASE_TYPES = [
{ {
text: 'ADS', text: BI.i18nText('Dec-Dcm_Connection_Analytic_DB'),
databaseType: 'ads', databaseType: 'ads',
driver: 'com.mysql.jdbc.Driver', driver: 'com.mysql.jdbc.Driver',
url: 'jdbc:mysql://hostname:port/database', url: 'jdbc:mysql://hostname:port/database',
@ -446,8 +446,8 @@ export const DATA_BASE_TYPES = [
hasSchema: false, hasSchema: false,
kerberos: false, kerberos: false,
urls: { urls: {
'com.mysql.jdbc.Driver': 'jdbc:mysql://localhost/dbname', 'com.mysql.jdbc.Driver': 'jdbc:mysql://hostname:port/database',
'org.gjt.mm.mysql.Driver': 'jdbc:mysql://localhost/dbname', 'org.gjt.mm.mysql.Driver': 'jdbc:mysql://hostname:port/database',
}, },
}, },
{ {
@ -597,7 +597,7 @@ export const DATA_BASE_TYPES = [
export const CONNECT_CHARSET = [ export const CONNECT_CHARSET = [
{ {
text: '自动', text: BI.i18nText('Dec-Dcm_Connection_Form_Auto'),
value: '', value: '',
}, },
{ {
@ -667,6 +667,7 @@ export const DEFAULT_JDBC_POOL = {
initialSize: 0, initialSize: 0,
maxActive: 50, maxActive: 50,
maxIdle: 10, maxIdle: 10,
minIdle: 0,
maxWait: 10000, maxWait: 10000,
testOnBorrow: true, testOnBorrow: true,
testOnReturn: false, testOnReturn: false,
@ -706,3 +707,5 @@ export const JNDI_FACTORYS = [
]; ];
export const PAGE_SIZE = 50; export const PAGE_SIZE = 50;
export const INT_MAX_VALUE = 2147483647;
export const INT_MIN_VALUE = -2147483648;

5
src/modules/constants/env.ts

@ -1,5 +1,6 @@
const fineServletURL = Dec.fineServletURL; export const fineServletURL = Dec.fineServletURL;
export const ReqPrefix = `${fineServletURL}/v10/config/connection`; export const ReqPath = '/v10/config/connection';
export const ReqPrefix = `${fineServletURL}${ReqPath}`;
export const ImgPrefix = `${fineServletURL}/resources?path=/com/fr/web/resources/dist/images/2x/icon/database/`; export const ImgPrefix = `${fineServletURL}/resources?path=/com/fr/web/resources/dist/images/2x/icon/database/`;
export const PluginImgPrefix = `${fineServletURL}/resources?path=`; export const PluginImgPrefix = `${fineServletURL}/resources?path=`;

127
src/modules/crud/crud.service.ts

@ -1,121 +1,38 @@
import 'es6-promise/auto'; import { ResultType } from './crud.typings.d';
import axios, { AxiosResponse, AxiosError } from 'axios'; import { ReqPath } from '../constants/env';
import { CrudReqOpts, CrudParams, ResultType } from './crud.typings.d';
import { ReqPrefix, errorCode } from '../constants/env';
const defaultHeaders = {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest',
};
export function paramsSerializer(params: { [key: string]: any }) { function getFullUrl(url: string) {
return Object.keys(params || {}) return url ? `${ReqPath}/${url}` : ReqPath;
.map(paramKey => {
const paramValue = params[paramKey];
let value = '';
if (BI.isObject(paramValue)) {
value = encodeURIComponent(JSON.stringify(paramValue));
} else {
value = paramValue;
}
return BI.isNull(value) ? '' : `${paramKey}=${value}`;
})
.filter(v => v !== '')
.join('&');
}
function getCookieByName(name: string):string {
let value = null;
const regExpName = new RegExp(name);
document.cookie.split(';').forEach((item: string) => {
if (item.match(regExpName)) {
value = item.split(`${name}=`)[1];
return false;
}
});
return value;
}
function checkStatus(response: AxiosResponse) {
const status = response.status;
const noLoginErr = [errorCode.LOGIN_INFO_ERROR, errorCode.LOGIN_INFO_NOT_AVAILABLE, errorCode.TIMEOUT];
const resData = status === 200
? typeof response.data === 'string'
? BI.jsonDecode(response.data)
: response.data
: {};
if (noLoginErr.includes(BI.get(resData, 'errorCode'))) {
BI.Msg.alert(BI.i18nText('BI-Basic_Prompt'), BI.i18nText('Dec-Dcm_Login_Error'), () => {
window.location.reload(true);
});
return new Promise(() => {});
}
return resData;
} }
export async function request(reqOptions: CrudReqOpts = {}): Promise<ResultType> { export function requestGet(url: string, data?: any): Promise<ResultType> {
const { url, type, headers, data, params } = reqOptions; return new Promise(resolve => {
Dec.reqGet(getFullUrl(url), '', re => {
return axios resolve(re);
.request({
url,
baseURL: ReqPrefix,
method: type,
headers: {
...defaultHeaders,
...headers,
Authorization: `Bearer ${getCookieByName('fine_auth_token')}`,
'Content-Type': 'application/json;charset=UTF-8',
},
params,
paramsSerializer,
data,
})
.then(checkStatus)
.catch((error: AxiosError) => {
console.log(error);
}); });
}
export function requestGet(url: string, data?: any, params: CrudParams = {}) {
const timeStamp = new Date().getTime();
return request({
url: url.includes('?') ? `${url}&_=${timeStamp}` : `${url}?_=${timeStamp}`,
type: 'GET',
data,
params,
}); });
} }
export function requestPost(url: string, data = {}, params: CrudParams = {}) { export function requestPost(url: string, data = {}): Promise<ResultType> {
return request({ return new Promise(resolve => {
url, Dec.reqPost(getFullUrl(url), data, re => {
type: 'POST', resolve(re);
data, });
params,
}); });
} }
export function requestDelete(url: string, data = {}) { export function requestDelete(url: string, data = {}) {
return request({ return new Promise(resolve => {
url, Dec.reqDelete(getFullUrl(url), data, re => {
type: 'DELETE', resolve(re);
data, });
}); });
} }
export function requestPut(url: string, data = {}, params: CrudParams = {}) { export function requestPut(url: string, data = {}) {
return request({ return new Promise(resolve => {
url, Dec.reqPut(getFullUrl(url), data, re => {
type: 'PUT', resolve(re);
data, });
params,
}); });
} }

2
src/modules/crud/decision.api.ts

@ -96,7 +96,7 @@ export class DecisionApi implements Api {
private sendEditStatusEvent(name: string, type: string): Promise<SocketResult> { private sendEditStatusEvent(name: string, type: string): Promise<SocketResult> {
return new Promise(resolve => { return new Promise(resolve => {
if (Dec && Dec.socket.connected) { if (Dec && Dec.socket.connected) {
Dec.socket.emit(type, BI.encode(name), (re: any) => { Dec.socketEmit(type, BI.encode(name), (re: any) => {
resolve(re); resolve(re);
}); });
} else { } else {

7
src/modules/pages/connection/list/list_item/list_item.model.ts

@ -2,6 +2,8 @@ import { model, Model } from '@core/core';
import { AppModel } from '../../../../app.model'; import { AppModel } from '../../../../app.model';
import { ApiFactory } from '../../../../crud/apiFactory'; import { ApiFactory } from '../../../../crud/apiFactory';
import { ResultType } from '../../../../crud/crud.typings'; import { ResultType } from '../../../../crud/crud.typings';
import { getChartLength } from '../../../../app.service';
import { NAME_MAX_LENGTH } from '../../../../app.constant';
const api = new ApiFactory().create(); const api = new ApiFactory().create();
export const ListItemModelXtype = 'dec.dcm.model.connection.list_item'; export const ListItemModelXtype = 'dec.dcm.model.connection.list_item';
@ -63,6 +65,11 @@ export class ListItemModel extends Model<{
resolve({ errorCode: '1', errorMsg: 'Dec-Dcm_Connection_ConnectionName_Cannt_Null' }); resolve({ errorCode: '1', errorMsg: 'Dec-Dcm_Connection_ConnectionName_Cannt_Null' });
}); });
} }
if (getChartLength(newName) > NAME_MAX_LENGTH) {
return new Promise(resolve => {
resolve({ errorCode: '1', errorMsg: BI.i18nText('Dec-Dcm_Connection_Cannot_Too_Lang', NAME_MAX_LENGTH) });
});
}
const hasNamed = this.model.connections.some(item => item.connectionName === newName); const hasNamed = this.model.connections.some(item => item.connectionName === newName);
if (hasNamed && oldName !== newName) { if (hasNamed && oldName !== newName) {
return new Promise(resolve => { return new Promise(resolve => {

11
src/modules/pages/database/database.ts

@ -140,19 +140,23 @@ export class Datebase extends BI.Widget {
items: [ items: [
{ {
el: { el: {
type: VerticalAdapt, type: Htape,
hgap: 20, hgap: 20,
invisible: true, invisible: true,
items: [ items: [
{ {
type: Label, type: Label,
width: 70,
textAlign: 'left',
text: BI.i18nText('Dec-Dcm_Connection_Type_Filter'), text: BI.i18nText('Dec-Dcm_Connection_Type_Filter'),
title: BI.i18nText('Dec-Dcm_Connection_Type_Filter'),
}, },
{ {
type: MultiSelectItem, type: MultiSelectItem,
width: 80, width: 80,
selected: this.model.isInternal, selected: this.model.isInternal,
text: BI.i18nText('Dec-Dcm_Connection_Support_Inner'), text: BI.i18nText('Dec-Dcm_Connection_Support_Inner'),
title: BI.i18nText('Dec-Dcm_Connection_Support_Inner'),
ref: (_ref: any) => { ref: (_ref: any) => {
this.internalWidget = _ref; this.internalWidget = _ref;
}, },
@ -165,6 +169,7 @@ export class Datebase extends BI.Widget {
width: 80, width: 80,
selected: this.model.isPlugin, selected: this.model.isPlugin,
text: BI.i18nText('Dec-Dcm_Connection_Support_Plugin'), text: BI.i18nText('Dec-Dcm_Connection_Support_Plugin'),
title: BI.i18nText('Dec-Dcm_Connection_Support_Plugin'),
ref: (_ref: any) => { ref: (_ref: any) => {
this.pluginWidget = _ref; this.pluginWidget = _ref;
}, },
@ -175,14 +180,16 @@ export class Datebase extends BI.Widget {
{ {
type: Label, type: Label,
cls: 'bi-tips', cls: 'bi-tips',
textAlign: 'left',
text: BI.i18nText('Dec-Dcm_Connection_Filter_Tip'), text: BI.i18nText('Dec-Dcm_Connection_Filter_Tip'),
title: BI.i18nText('Dec-Dcm_Connection_Filter_Tip'),
}, },
], ],
ref: (_ref: any) => { ref: (_ref: any) => {
this.typeFilterWidget = _ref; this.typeFilterWidget = _ref;
}, },
}, },
height: 20, height: 24,
}, },
{ {
type: ButtonGroup, type: ButtonGroup,

53
src/modules/pages/maintain/forms/components/form.jdbc.ts

@ -4,7 +4,7 @@ import { CollapseXtype, EVENT_CHANGE } from 'src/modules/components/collapse/col
import { FormItemXtype } from '../../components/form_item/form_item'; import { FormItemXtype } from '../../components/form_item/form_item';
import { Connection, ConnectionJDBC, ConnectionPoolJDBC } from 'src/modules/crud/crud.typings'; import { Connection, ConnectionJDBC, ConnectionPoolJDBC } from 'src/modules/crud/crud.typings';
import { connectionType } from '@constants/env'; import { connectionType } from '@constants/env';
import { CONNECT_CHARSET, CONNECTION_LAYOUT } from '@constants/constant'; import { CONNECT_CHARSET, CONNECTION_LAYOUT, INT_MAX_VALUE, INT_MIN_VALUE } from '@constants/constant';
import { getAllDatabaseTypes, getJdbcDatabaseType, resolveUrlInfo, splitUrl } from '../../../../app.service'; import { getAllDatabaseTypes, getJdbcDatabaseType, resolveUrlInfo, splitUrl } from '../../../../app.service';
import { TextCheckerXtype } from '../../../../components/text_checker/text_checker'; import { TextCheckerXtype } from '../../../../components/text_checker/text_checker';
export const FormJdbcXtype = 'dec.dcm.maintain.form.jdbc'; export const FormJdbcXtype = 'dec.dcm.maintain.form.jdbc';
@ -62,6 +62,12 @@ export class FormJdbc extends BI.Widget {
const { host, port, databaseName } = resolveUrlInfo(url); const { host, port, databaseName } = resolveUrlInfo(url);
const { hgap, vgap } = CONNECTION_LAYOUT; const { hgap, vgap } = CONNECTION_LAYOUT;
const valueRangeConfig = {
errorText: BI.i18nText('Dec-Dcm_Connection_Value_Out_Range'),
checker: (value: string) => this.checkValueRange(value),
autoFix: true,
};
return { return {
type: Vertical, type: Vertical,
hgap, hgap,
@ -98,13 +104,12 @@ export class FormJdbc extends BI.Widget {
const value = this.form.driver.getValue(); const value = this.form.driver.getValue();
const connectionData = this.options.formData.connectionData as ConnectionJDBC; const connectionData = this.options.formData.connectionData as ConnectionJDBC;
const connectionType = getJdbcDatabaseType(connectionData.database, connectionData.driver); const connectionType = getJdbcDatabaseType(connectionData.database, connectionData.driver);
if (connectionType.urls) { const url = connectionType.urls ? connectionType.urls[value] : connectionType.url;
this.form.url.setValue(connectionType.urls[value]); this.form.url.setValue(url);
const urlInfo = resolveUrlInfo(connectionType.urls[value]); const urlInfo = resolveUrlInfo(url);
this.form.host.setValue(urlInfo.host); this.form.host.setValue(urlInfo.host);
this.form.database.setValue(urlInfo.databaseName); this.form.database.setValue(urlInfo.databaseName);
this.form.port.setValue(urlInfo.port); this.form.port.setValue(urlInfo.port);
}
}, },
}], }],
}], }],
@ -162,7 +167,7 @@ export class FormJdbc extends BI.Widget {
errorText: BI.i18nText('Dec-Dcm_Connection_Check_Integer'), errorText: BI.i18nText('Dec-Dcm_Connection_Check_Integer'),
checker: (value: string) => this.checkInteger(value), checker: (value: string) => this.checkInteger(value),
autoFix: true, autoFix: true,
}], }, valueRangeConfig],
ref: (_ref: any) => { ref: (_ref: any) => {
this.form.port = _ref; this.form.port = _ref;
}, },
@ -375,6 +380,7 @@ export class FormJdbc extends BI.Widget {
}, },
{ {
type: CollapseXtype, type: CollapseXtype,
bgap: -15,
width: 70, width: 70,
name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Advanced_Setting'), name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Advanced_Setting'),
listeners: [ listeners: [
@ -397,6 +403,7 @@ export class FormJdbc extends BI.Widget {
items: [ items: [
{ {
type: FormItemXtype, type: FormItemXtype,
tgap: 15,
name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Initial_Size'), name: BI.i18nText('Dec-Dcm_Connection_Form_Database_Initial_Size'),
forms: [{ forms: [{
type: TextCheckerXtype, type: TextCheckerXtype,
@ -407,7 +414,7 @@ export class FormJdbc extends BI.Widget {
errorText: BI.i18nText('Dec-Dcm_Connection_Check_Integer'), errorText: BI.i18nText('Dec-Dcm_Connection_Check_Integer'),
checker: (value: string) => this.checkInteger(value), checker: (value: string) => this.checkInteger(value),
autoFix: true, autoFix: true,
}], }, valueRangeConfig],
watermark: BI.i18nText('Dec-Dcm_Connection_Form_Database_Initial_Size'), watermark: BI.i18nText('Dec-Dcm_Connection_Form_Database_Initial_Size'),
ref: (_ref: any) => { ref: (_ref: any) => {
this.form.initialSize = _ref; this.form.initialSize = _ref;
@ -427,7 +434,7 @@ export class FormJdbc extends BI.Widget {
errorText: BI.i18nText('Dec-Dcm_Connection_Check_Integer'), errorText: BI.i18nText('Dec-Dcm_Connection_Check_Integer'),
checker: (value: string) => this.checkInteger(value), checker: (value: string) => this.checkInteger(value),
autoFix: true, autoFix: true,
}], }, valueRangeConfig],
ref: (_ref: any) => { ref: (_ref: any) => {
this.form.maxActive = _ref; this.form.maxActive = _ref;
}, },
@ -446,7 +453,7 @@ export class FormJdbc extends BI.Widget {
errorText: BI.i18nText('Dec-Dcm_Connection_Check_Integer'), errorText: BI.i18nText('Dec-Dcm_Connection_Check_Integer'),
checker: (value: string) => this.checkInteger(value), checker: (value: string) => this.checkInteger(value),
autoFix: true, autoFix: true,
}], }, valueRangeConfig],
ref: (_ref: any) => { ref: (_ref: any) => {
this.form.maxIdle = _ref; this.form.maxIdle = _ref;
}, },
@ -465,7 +472,7 @@ export class FormJdbc extends BI.Widget {
errorText: BI.i18nText('Dec-Dcm_Connection_Check_Integer'), errorText: BI.i18nText('Dec-Dcm_Connection_Check_Integer'),
checker: (value: string) => this.checkInteger(value), checker: (value: string) => this.checkInteger(value),
autoFix: true, autoFix: true,
}], }, valueRangeConfig],
ref: (_ref: any) => { ref: (_ref: any) => {
this.form.minIdle = _ref; this.form.minIdle = _ref;
}, },
@ -485,7 +492,7 @@ export class FormJdbc extends BI.Widget {
errorText: BI.i18nText('Dec-Dcm_Connection_Check_Integer'), errorText: BI.i18nText('Dec-Dcm_Connection_Check_Integer'),
checker: (value: string) => this.checkInteger(value), checker: (value: string) => this.checkInteger(value),
autoFix: true, autoFix: true,
}], }, valueRangeConfig],
ref: (_ref: any) => { ref: (_ref: any) => {
this.form.maxWait = _ref; this.form.maxWait = _ref;
}, },
@ -573,7 +580,7 @@ export class FormJdbc extends BI.Widget {
errorText: BI.i18nText('Dec-Dcm_Connection_Check_Number'), errorText: BI.i18nText('Dec-Dcm_Connection_Check_Number'),
checker: (value: string) => this.checkNumber(value), checker: (value: string) => this.checkNumber(value),
autoFix: true, autoFix: true,
}], }, valueRangeConfig],
ref: (_ref: any) => { ref: (_ref: any) => {
this.form.timeBetweenEvictionRunsMillis = _ref; this.form.timeBetweenEvictionRunsMillis = _ref;
}, },
@ -599,7 +606,7 @@ export class FormJdbc extends BI.Widget {
errorText: BI.i18nText('Dec-Dcm_Connection_Check_Integer'), errorText: BI.i18nText('Dec-Dcm_Connection_Check_Integer'),
checker: (value: string) => this.checkInteger(value), checker: (value: string) => this.checkInteger(value),
autoFix: true, autoFix: true,
}], }, valueRangeConfig],
ref: (_ref: any) => { ref: (_ref: any) => {
this.form.numTestsPerEvictionRun = _ref; this.form.numTestsPerEvictionRun = _ref;
}, },
@ -619,7 +626,7 @@ export class FormJdbc extends BI.Widget {
errorText: BI.i18nText('Dec-Dcm_Connection_Check_Integer'), errorText: BI.i18nText('Dec-Dcm_Connection_Check_Integer'),
checker: (value: string) => this.checkInteger(value), checker: (value: string) => this.checkInteger(value),
autoFix: true, autoFix: true,
}], }, valueRangeConfig],
ref: (_ref: any) => { ref: (_ref: any) => {
this.form.minEvictableIdleTimeMillis = _ref; this.form.minEvictableIdleTimeMillis = _ref;
}, },
@ -650,6 +657,10 @@ export class FormJdbc extends BI.Widget {
return /^[(\-|\+)?\d]+$/.test(value); return /^[(\-|\+)?\d]+$/.test(value);
} }
private checkValueRange(value: string) {
return parseInt(value, 0) <= INT_MAX_VALUE && parseInt(value, 0) >= INT_MIN_VALUE;
}
private getDrivers() { private getDrivers() {
const connectionData = this.options.formData.connectionData as ConnectionJDBC; const connectionData = this.options.formData.connectionData as ConnectionJDBC;
const connectionType = getJdbcDatabaseType(connectionData.database, connectionData.driver); const connectionType = getJdbcDatabaseType(connectionData.database, connectionData.driver);
@ -692,11 +703,13 @@ export class FormJdbc extends BI.Widget {
} }
private onHostPortChange(databaseType) { private onHostPortChange(databaseType) {
const { url = '' } = databaseType; const { urls, url } = databaseType;
const driver = this.form.driver.getValue();
const selectUrl = BI.get(urls, driver) || url;
const host = this.form.host.getValue(); const host = this.form.host.getValue();
const port = this.form.port.getValue(); const port = this.form.port.getValue();
const database = this.form.database.getValue(); const database = this.form.database.getValue();
this.form.url.setValue(splitUrl(host, port, database, url)); this.form.url.setValue(splitUrl(host, port, database, selectUrl));
} }
public setSchemas(schemas: string[]) { public setSchemas(schemas: string[]) {
@ -729,7 +742,7 @@ export class FormJdbc extends BI.Widget {
driver: this.form.driver.getValue(), driver: this.form.driver.getValue(),
url: this.form.url.getValue(), url: this.form.url.getValue(),
user: this.form.user.getValue(), user: this.form.user.getValue(),
password: this.oldPassword === this.form.password.getValue() ? this.oldPassword : BI.encode(this.form.password.getValue()), password: this.oldPassword === this.form.password.getValue() ? this.oldPassword : BI.Providers.getProvider('dec.provider.cipher').getCipher(this.form.password.getValue()),
queryType: '', queryType: '',
newCharsetName: originalCharsetName ? 'gbk' : '', // 后台要求,originalCharsetName不为空时,newCharsetName为gbk newCharsetName: originalCharsetName ? 'gbk' : '', // 后台要求,originalCharsetName不为空时,newCharsetName为gbk
originalCharsetName, originalCharsetName,

9
src/modules/pages/maintain/forms/form.ts

@ -7,6 +7,7 @@ import { connectionType, errorCode } from '@constants/env';
import { ConnectionJDBC, Connection, ResultType } from 'src/modules/crud/crud.typings'; import { ConnectionJDBC, Connection, ResultType } from 'src/modules/crud/crud.typings';
import { DEFAULT_JNDI_DATA, DEFAULT_JDBC_POOL, DATEBASE_FILTER_TYPE } from '@constants/constant'; import { DEFAULT_JNDI_DATA, DEFAULT_JDBC_POOL, DATEBASE_FILTER_TYPE } from '@constants/constant';
import { getJdbcDatabaseType, getChartLength } from '../../../app.service'; import { getJdbcDatabaseType, getChartLength } from '../../../app.service';
import { NAME_MAX_LENGTH } from '../../../app.constant';
export const MaintainFormXtype = 'dec.dcm.maintain.form'; export const MaintainFormXtype = 'dec.dcm.maintain.form';
@shortcut(MaintainFormXtype) @shortcut(MaintainFormXtype)
@store(MaintainFormModelXtype) @store(MaintainFormModelXtype)
@ -186,8 +187,8 @@ export class MaintainForm extends BI.Widget {
return false; return false;
} }
} }
if (getChartLength(value.connectionName) > 200) { if (getChartLength(value.connectionName) > NAME_MAX_LENGTH) {
this.setFromError(BI.i18nText('Dec-Dcm_Connection_Cannot_Too_Lang')); this.setFromError(BI.i18nText('Dec-Dcm_Connection_Cannot_Too_Lang', NAME_MAX_LENGTH));
return false; return false;
} }
@ -220,8 +221,8 @@ export class MaintainForm extends BI.Widget {
return; return;
} }
if (getChartLength(formValue.connectionName) > 200) { if (getChartLength(formValue.connectionName) > NAME_MAX_LENGTH) {
this.setFromError(BI.i18nText('Dec-Dcm_Connection_Cannot_Too_Lang')); this.setFromError(BI.i18nText('Dec-Dcm_Connection_Cannot_Too_Lang', NAME_MAX_LENGTH));
return false; return false;
} }

118
src/request.ts

@ -0,0 +1,118 @@
import 'es6-promise/auto';
import axios, { AxiosResponse, AxiosError } from 'axios';
import { CrudReqOpts, ResultType } from './modules/crud/crud.typings';
import { fineServletURL, errorCode } from './modules/constants/env';
const defaultHeaders = {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest',
};
export function paramsSerializer(params: { [key: string]: any }) {
return Object.keys(params || {})
.map(paramKey => {
const paramValue = params[paramKey];
let value = '';
if (BI.isObject(paramValue)) {
value = encodeURIComponent(JSON.stringify(paramValue));
} else {
value = paramValue;
}
return BI.isNull(value) ? '' : `${paramKey}=${value}`;
})
.filter(v => v !== '')
.join('&');
}
function getCookieByName(name: string):string {
let value = null;
const regExpName = new RegExp(name);
document.cookie.split(';').forEach((item: string) => {
if (item.match(regExpName)) {
value = item.split(`${name}=`)[1];
return false;
}
});
return value;
}
function checkStatus(response: AxiosResponse) {
const status = response.status;
const noLoginErr = [errorCode.LOGIN_INFO_ERROR, errorCode.LOGIN_INFO_NOT_AVAILABLE, errorCode.TIMEOUT];
const resData = status === 200
? typeof response.data === 'string'
? BI.jsonDecode(response.data)
: response.data
: {};
if (noLoginErr.includes(BI.get(resData, 'errorCode'))) {
BI.Msg.alert(BI.i18nText('BI-Basic_Prompt'), BI.i18nText('Dec-Dcm_Login_Error'), () => {
window.location.reload(true);
});
return new Promise(() => {});
}
return resData;
}
export async function request(reqOptions: CrudReqOpts = {}): Promise<ResultType> {
const { url, type, headers, data, params } = reqOptions;
return axios
.request({
url,
baseURL: fineServletURL,
method: type,
headers: {
...defaultHeaders,
...headers,
Authorization: `Bearer ${getCookieByName('fine_auth_token')}`,
'Content-Type': 'application/json;charset=UTF-8',
},
params,
paramsSerializer,
data,
})
.then(checkStatus)
.catch((error: AxiosError) => {
console.log(error);
});
}
Dec.reqGet = (url: string, data: any, callback: (re: any) => void) => {
const timeStamp = new Date().getTime();
request({
url: url.includes('?') ? `${url}&_=${timeStamp}` : `${url}?_=${timeStamp}`,
type: 'GET',
data,
}).then(re => callback(re));
};
Dec.reqPost = (url: string, data: any, callback: (re: any) => void) => {
request({
url,
type: 'POST',
data,
}).then(re => callback(re));
};
Dec.reqDelete = (url: string, data: any, callback: (re: any) => void) => {
request({
url,
type: 'DELETE',
data,
}).then(re => callback(re));
};
Dec.reqPut = (url: string, data: any, callback: (re: any) => void) => {
request({
url,
type: 'PUT',
data,
}).then(re => callback(re));
};

14
types/globals.d.ts vendored

@ -5,4 +5,16 @@ interface Obj {
declare let BI: Obj & import('fineui')._BI; declare let BI: Obj & import('fineui')._BI;
declare const Fix: Obj; declare const Fix: Obj;
declare const DecCst: Obj; declare const DecCst: Obj;
declare const Dec: Obj; declare const Dec: {
fineServletURL: string;
socket: {
connected: boolean;
};
personal: {
username: string;
};
reqGet: (url: string, data: any, callback: (re: any) => void) => void;
reqPost: (url: string, data: any, callback: (re: any) => void) => void;
reqPut: (url: string, data: any, callback: (re: any) => void) => void;
reqDelete: (url: string, data: any, callback: (re: any) => void) => void;
};

2
webpack/webpack.dev.js

@ -36,7 +36,7 @@ chokidar
module.exports = merge(common, { module.exports = merge(common, {
devtool: 'eval-source-map', devtool: 'eval-source-map',
entry: { entry: {
show: ['./src/i18n.ts', './src/index.ts'], show: ['babel-polyfill', './src/i18n.ts', './src/request.ts', './src/index.ts'],
}, },
output: { output: {
path: dirs.DEST, path: dirs.DEST,

15
yarn.lock

@ -606,10 +606,10 @@
"@babel/helper-regex" "^7.4.4" "@babel/helper-regex" "^7.4.4"
regexpu-core "^4.5.4" regexpu-core "^4.5.4"
"@babel/polyfill@7.4.4": "@babel/polyfill@^7.8.3":
version "7.4.4" version "7.8.3"
resolved "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.4.4.tgz#78801cf3dbe657844eeabf31c1cae3828051e893" resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.8.3.tgz#2333fc2144a542a7c07da39502ceeeb3abe4debd"
integrity sha512-WlthFLfhQQhh+A2Gn5NSFl0Huxz36x86Jn+E9OW7ibK8edKPq+KLy4apM1yDpQ8kJOVi1OVjpP4vSDLdrI04dg== integrity sha512-0QEgn2zkCzqGIkSWWAEmvxD7e00Nm9asTtQvi7HdlYvMhjy/J38V/1Y9ode0zEJeIuxAI0uftiAzqc7nVeWUGg==
dependencies: dependencies:
core-js "^2.6.5" core-js "^2.6.5"
regenerator-runtime "^0.13.2" regenerator-runtime "^0.13.2"
@ -3054,11 +3054,16 @@ core-js-compat@^3.1.1:
browserslist "^4.6.6" browserslist "^4.6.6"
semver "^6.3.0" semver "^6.3.0"
core-js@^2.4.0, core-js@^2.5.0, core-js@^2.6.5: core-js@^2.4.0, core-js@^2.5.0:
version "2.6.9" version "2.6.9"
resolved "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2" resolved "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2"
integrity sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A== integrity sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==
core-js@^2.6.5:
version "2.6.11"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c"
integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==
core-util-is@1.0.2, core-util-is@~1.0.0: core-util-is@1.0.2, core-util-is@~1.0.0:
version "1.0.2" version "1.0.2"
resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"

Loading…
Cancel
Save