diff --git a/private/i18n.ts b/private/i18n.ts index 8f00670..1a530af 100644 --- a/private/i18n.ts +++ b/private/i18n.ts @@ -61,6 +61,11 @@ export default { 'Dec-Dcm_Connection_Form_Password': '密码', 'Dec-Dcm_Connection_Form_Principal': '客户端principal', 'Dec-Dcm_Connection_Form_KeyPath': 'keytab密钥路径', + 'Dec-Dcm_Connection_Form_Krb5File': 'krb5.conf文件', + 'Dec-Dcm_Connection_File_Upload_Success': ' 已成功上传并校验成功', + 'Dec-Dcm_Connection_File_Upload_Error': '检测异常', + 'Dec-Dcm_Connection_File_Upload_ErrorCode': '错误代码', + 'Dec-Dcm_Connection_File_Upload_ErrorMsg': '错误详情', 'Dec-Dcm_Connection_Form_Pool_Properties': '连接池属性', 'Dec-Dcm_Connection_Form_SQL_Validation_Query': 'SQL验证查询', 'Dec-Dcm_Connection_Form_Connection-Check': '获取连接前校验', @@ -306,4 +311,7 @@ export default { 'Dec-Connection_Lic_Limit_Approach_Tip': '当前数据连接数量超过注册lic限制({}个),所有数据连接都不可用,请删除多余的数据连接', 'Dec-Connection_Lic_Limit_Approach_Prevent_Tip': '当前数据连接数量已经达到注册lic限制({}个),无法新增', 'Dec-Dcm_Connection_Check_Fetch_Size_Range': '请输入0-1000000之间的值', + 'Dec-Dcm_Connection_File_Upload_ErrorTip1':'参考', + 'Dec-Dcm_Connection_File_Upload_ErrorTip2': 'kerberos配置', + 'Dec-Dcm_Connection_File_Upload_ErrorTip3': '取帮助或联系技术支持', }; diff --git a/src/modules/components/file_upload/file_upload.less b/src/modules/components/file_upload/file_upload.less new file mode 100644 index 0000000..83c51ce --- /dev/null +++ b/src/modules/components/file_upload/file_upload.less @@ -0,0 +1,13 @@ +.data-conf-file { + .x-icon{ + width: 48px; + height: 48px; + } +} + +.data-keytab-file { + .x-icon{ + width: 48px; + height: 48px; + } +} diff --git a/src/modules/components/file_upload/file_upload.model.ts b/src/modules/components/file_upload/file_upload.model.ts new file mode 100644 index 0000000..78d0a75 --- /dev/null +++ b/src/modules/components/file_upload/file_upload.model.ts @@ -0,0 +1,35 @@ +import { model, Model } from '@core/core'; + +type UploadParam = { + keytabPath: string; + krb5ConfPath: string; + principal: string; +} + +@model() +export class FileUploadModel extends Model { + static xtype = 'dec.dcm.model.components.file_upload'; + + private options: { + inter: string; + } + + state() { + return { + uploadUrl: '', + fileName: '', + }; + } + + actions = { + setFileInfo: (params: UploadParam) => { + var inter = this.options.inter; + + this.model.uploadUrl = Dec.Utils.getEncodeURL(Dec.fineServletURL + inter, "", params); + }, + + setFileName:(v: string) => { + this.model.fileName = v; + } + } +} diff --git a/src/modules/components/file_upload/file_upload.ts b/src/modules/components/file_upload/file_upload.ts new file mode 100644 index 0000000..56265be --- /dev/null +++ b/src/modules/components/file_upload/file_upload.ts @@ -0,0 +1,328 @@ +import { shortcut, store } from '@core/core'; +import { SignEditor, MultiLayerSingleLevelTree, SearchEditor, Button, Editor, Label } from '@fui/core'; +import { FileUploadModel } from './file_upload.model'; +import { ApiFactory } from 'src/modules/crud/apiFactory'; +import './file_upload.less'; + +const api = new ApiFactory().create(); + +@shortcut() +@store(FileUploadModel, { + props(this: FileUpload) { + return this.options; + }, +}) +export class FileUpload extends BI.Widget { + public static xtype = "dec.dcm.components.file_upload"; + public static EVENT_CHECK_SUCCESS = 'EVENT_CHECK_SUCCESS'; + public static EVENT_CLEAR_FILE = 'EVENT_CLEAR_FILE'; + + public props = { + watermark: '', + value: '', + processId: '', + disabled: false, + inter: '', + access: '', + iconCls: '' + }; + + model: FileUploadModel['model']; + store: FileUploadModel['store']; + watch = { + uploadUrl: function () { + this.uploader.setUrl(this.model.uploadUrl); + }, + }; + + public textEditor: SignEditor; + public keywordEditor: SearchEditor; + public fileTree: MultiLayerSingleLevelTree; + public sureButton: Button; + public infoLabel: Label; + + public render() { + const { width, watermark, value, processId, inter } = this.options; + var self = this; + var processName = BI.concat("process-", processId); + var processClass = BI.concat(".process-", processId); + this.setFileInfo({ + keytabPath: '', + principal:'', + krb5ConfPath: '', + }); + + return { + type: BI.VerticalLayout.xtype, + items:[{ + type: BI.FloatLeftLayout.xtype, + items: [ + { + type: BI.SignEditor.xtype, + cls: 'bi-border bi-focus-shadow', + width: 300, + height: 22, + watermark, + disabled: true, + value, + ref: (_ref: SignEditor) => { + this.textEditor = _ref; + }, + listeners: [ + { + eventName: BI.SignEditor.EVENT_CHANGE, + action: () => { + const value = this.textEditor.getValue(); + this.setValue(value); + }, + }, + ], + }, { + type: BI.Button.xtype, + width: 100, + _lgap: 10, + iconCls: "upload-font", + level: "ignore", + ghost: true, + ref: (_ref: Button) => { + this.uploadButton = _ref; + }, + text: BI.i18nText('Dec-Basic_Choose_File'), + handler: () => { + self.uploader.select(); + }, + }, + ], + }, { + type: BI.FloatLeftLayout.xtype, + tgap: 8, + invisible: true, + ref: (_ref) => { + this.fileInfo = _ref; + }, + items: [ + { + type: BI.VerticalLayout.xtype, + cls: "bi-border", + items: [{ + type: BI.HTapeLayout.xtype, + height: 68, + width: 300, + items: [{ + el: { + type: BI.IconLabel.xtype, + cls: this.options.iconCls, + }, + width: 48, + lgap: 8, + }, { + el: { + type: BI.VerticalLayout.xtype, + items : [{ + type: BI.Label.xtype, + width: 200, + height: 20, + textAlign: "left", + ref: (_ref: Label) => { + this.fileName = _ref; + }, + },{ + type: BI.VerticalAdaptLayout.xtype, + items: [{ + type: BI.Label.xtype, + cls: "bi-tips", + height: 20, + rgap: 3, + ref: (_ref: Label) => { + this.fileSize = _ref; + }, + }, { + type: BI.Label.xtype, + cls: "bi-tips", + height: 20, + ref: (_ref: Label) => { + this.fileModified = _ref; + }, + }] + + }], + + }, + tgap: 14, + lgap: 4, + }, { + el: { + type: BI.IconButton.xtype, + cls: "default-delete-font", + handler: function () { + NProgress.set(0.0); + self.xhr.abort(); + self.uploadButton.setEnable(true); + self.fileInfo.setVisible(false); + self.store.setFileName(''); + self.clearInfo(); + self.fireEvent(FileUpload.EVENT_CLEAR_FILE); + + }, + }, + rgap: 10, + }] + }, { + type: BI.VerticalLayout.xtype, + cls: processName, + width: 300, + height: 1, + }] + + }, { + el :{ + type: BI.VerticalLayout.xtype, + cls: "bi-error", + ref: (_ref: any) => { + this.errorInfo = _ref; + }, + invisible: true, + items : [{ + type: BI.Label.xtype, + height: 20, + textAlign: "left", + ref: (_ref: Label) => { + this.errorCode = _ref; + }, + },{ + type: BI.Label.xtype, + height: 20, + textAlign: "left", + ref: (_ref: Label) => { + this.errorMsg = _ref; + }, + }, { + type: "bi.vertical_adapt", + rgap: 5, + items: [ + { + type: "bi.label", + text: BI.i18nText('Dec-Dcm_Connection_File_Upload_ErrorTip1'), + },{ + type: "bi.text_button", + cls: "bi-high-light bi-high-light-border-bottom", + text: BI.i18nText('Dec-Dcm_Connection_File_Upload_ErrorTip2'), + handler: function () { + window.open(Dec.system[DecCst.Hyperlink.DECISION_HYPERLINK_CONFIG][DecCst.Hyperlink.KERBEROS_CONF_HELP]); + }, + },{ + type: "bi.label", + text: BI.i18nText('Dec-Dcm_Connection_File_Upload_ErrorTip3'), + } + ], + },], + }, + vgap: 4, + lgap: 8, + } + ], + }, { + type: BI.MultifileEditor.xtype, + ref: (ref:any) => { + self.uploader = ref; + }, + url: this.model.uploadUrl, + accept: this.options.accept, + listeners: [ + { + // 选择文件 + eventName: BI.MultifileEditor.EVENT_CHANGE, + action: function (files) { + self.options.attachId = ''; + var fileInfo = files.files[0]; + self.setInfo(fileInfo); + self.store.setFileName(fileInfo.fileName); + this.upload(); + NProgress.configure({ parent: processClass, minimum: 0.0 }); + }, + }, + { + // 上传进度刷新 + eventName: BI.MultifileEditor.EVENT_PROGRESS, + action: function (progress) { + var rate = progress.loaded/progress.total; + NProgress.set(rate); + }, + }, + { + // 开始上传文件 + eventName: BI.MultifileEditor.EVENT_UPLOADSTART, + action: function (progressEvent, xhr) { + self.xhr = xhr; + }, + }, + { + // 上传文件完毕 + eventName: BI.MultifileEditor.EVENT_UPLOADED, + action: function () { + var uploadedInfo = this.getValue(); + var failed = BI.some(uploadedInfo, function (index, file) { + if (file.data.errorCode) { + BI.Msg.toast(uploadedInfo[0].filename + BI.i18nText('Dec-Dcm_Connection_File_Upload_Error'), { + level: "error", + }); + self.setErrorInfo(file.data) + return true; + } + }); + var key = self.options.processId +'Path'; + !failed && self.setValue(uploadedInfo[0].data.kerberosInfo[key]); + !failed && self.fireEvent(FileUpload.EVENT_CHECK_SUCCESS, uploadedInfo[0].data); + !failed && BI.Msg.toast(uploadedInfo[0].filename + BI.i18nText('Dec-Dcm_Connection_File_Upload_Success'),{ + level: "success" + }); + }, + }, + ], + }] + + }; + } + + public getValue(): string { + return this.options.value; + } + + public setValue(value: string) { + this.options.value = value; + this.textEditor.text.setTitle(value); + this.textEditor.setValue(value); + } + + public setInfo(info: any) { + this.uploadButton.setEnable(false); + this.fileInfo.setVisible(true); + this.textEditor.setValue(info.fileName); + this.fileName.setText(info.fileName); + this.fileSize.setText(Dec.Utils.getByteWidthUnit(info.size)); + this.fileModified.setText(BI.getDate(info.lastModified).print("%Y-%X-%d %H:%M:%S")) + } + + public clearInfo() { + this.uploadButton.setEnable(true); + this.fileInfo.setVisible(false); + this.textEditor.setValue(''); + this.options.attachId = ''; + } + + public setErrorInfo(errorInfo: any) { + this.errorInfo.setVisible(true); + this.errorCode.setText(BI.i18nText("Dec-Dcm_Connection_File_Upload_ErrorCode") + ":"+ errorInfo.errorCode); + this.errorMsg.setText(BI.i18nText("Dec-Dcm_Connection_File_Upload_ErrorMsg") + ":" + errorInfo.errorMessage); + } + + public setEnable(v) { + this.uploadButton._setEnable(v); + } + + public setFileInfo(params) { + this.store.setFileInfo(params); + } +} + +BI.shortcut("dec.dcm.components.file_upload", FileUpload); diff --git a/src/modules/crud/crud.typings.d.ts b/src/modules/crud/crud.typings.d.ts index 43d6dee..339f02a 100644 --- a/src/modules/crud/crud.typings.d.ts +++ b/src/modules/crud/crud.typings.d.ts @@ -192,6 +192,10 @@ export type ConnectionJDBC ={ * 秘钥路径 */ keyPath?: string; + /** + * krb5.conf文件 + */ + krb5Path?: string; /** * fetchSize */ diff --git a/src/modules/crud/decision.api.ts b/src/modules/crud/decision.api.ts index 7301526..5a5c8ce 100644 --- a/src/modules/crud/decision.api.ts +++ b/src/modules/crud/decision.api.ts @@ -120,6 +120,10 @@ export class DecisionApi implements Api { return Dec.system[DecCst.Hyperlink.DECISION_HYPERLINK_CONFIG][name]; } + changePrincipal(value: any) { + return requestPost(`switch/principal`, value); + } + private sendEditStatusEvent(name: string, type: string): Promise { return new Promise(resolve => { if (Dec && Dec.socket.connected) { diff --git a/src/modules/pages/maintain/forms/components/form.jdbc.ts b/src/modules/pages/maintain/forms/components/form.jdbc.ts index 4e6c4a6..1f39f08 100644 --- a/src/modules/pages/maintain/forms/components/form.jdbc.ts +++ b/src/modules/pages/maintain/forms/components/form.jdbc.ts @@ -11,6 +11,7 @@ import { FileChooser } from '../../../../components/file_chooser/file_chooser'; import { ApiFactory } from 'src/modules/crud/apiFactory'; import { Editor, Label, TextAreaEditor, TextEditor, TextValueCombo, VerticalLayout, MultiSelectItem } from '@fui/core'; import { DriverSelector } from '../../components/driverselector/driverselector'; +import { FileUpload } from '../../../../components/file_upload/file_upload'; const api = new ApiFactory().create(); @@ -37,6 +38,7 @@ export class FormJdbc extends BI.Widget { formPassword: FormItem; formPrincipal: FormItem; formKeyPath: FormItem; + formKrb5File: FormItem; labelTips: Label; form = { @@ -50,6 +52,7 @@ export class FormJdbc extends BI.Widget { authType: null, principal: null, keyPath: null, + krb5Path: null, originalCharsetName: null, schema: null, url: null, @@ -99,6 +102,7 @@ export class FormJdbc extends BI.Widget { authType, principal, keyPath, + krb5Path, fetchSize, // ssh usingSsh = false, @@ -316,9 +320,10 @@ export class FormJdbc extends BI.Widget { const type = this.form.authType.getValue()[0]; this.formPrincipal.setVisible(!!type); this.formKeyPath.setVisible(!!type); + this.formKrb5File.setVisible(!!type); + this.form.krb5Path.setEnable(!type); this.formUser.setVisible(!type); this.formPassword.setVisible(!type); - this.labelTips.setVisible(!!type); }, }, ], @@ -373,6 +378,55 @@ export class FormJdbc extends BI.Widget { }, ], }, + // keytab密钥路径 + { + type: FormItem.xtype, + name: BI.i18nText('Dec-Dcm_Connection_Form_KeyPath'), + invisible: !authType, + ref: (_ref: FormItem) => { + this.formKeyPath = _ref; + }, + forms: [ + { + type: FileUpload.xtype, + $value: 'key-path', + processId: "keytab", + allowBlank: true, + value: keyPath, + accept: '.keytab', + inter: '/v10/config/connection/upload/keytab?', + iconCls: "data-keytab-file", + watermark: BI.i18nText('Dec-Dcm_Connection_Form_KeyPath'), + ref: (_ref: FileUpload) => { + this.form.keyPath = _ref; + }, + listeners: [ + { + eventName: FileUpload.EVENT_CHECK_SUCCESS, + action: (value) => { + var principalsItems = BI.map(value.principals, function(index, item) { + return { + text: item, + value: item + } + }) + this.form.principal.populate(principalsItems); + this.form.principal.setValue(principalsItems[0].value); + this.setKerberos(); + this.form.krb5Path.setEnable(true); + }, + }, { + eventName: FileUpload.EVENT_CLEAR_FILE, + action: () => { + this.form.krb5Path.setEnable(false); + this.form.principal.populate(); + this.form.principal.setValue(); + } + } + ] + }, + ], + }, // 客户端principal { type: FormItem.xtype, @@ -383,52 +437,57 @@ export class FormJdbc extends BI.Widget { }, forms: [ { - type: BI.TextEditor.xtype, + type: BI.TextValueCombo.xtype, $value: 'principal', width: 300, - allowBlank: true, value: principal, - watermark: BI.i18nText('Dec-Dcm_Connection_Form_Principal'), ref: (_ref: TextEditor) => { this.form.principal = _ref; }, - }, + listeners: [ + { + eventName: BI.Combo.EVENT_CHANGE, + action: () => { + this.changePrincipal(); + this.setKerberos(); + }, + }, + ], + } ], }, - // keytab密钥路径 + // krb5.conf文件 { type: FormItem.xtype, - name: BI.i18nText('Dec-Dcm_Connection_Form_KeyPath'), + name: BI.i18nText('Dec-Dcm_Connection_Form_Krb5File'), invisible: !authType, ref: (_ref: FormItem) => { - this.formKeyPath = _ref; + this.formKrb5File = _ref; }, forms: [ { - type: BI.Editor.xtype, - $value: 'key-path', - cls: 'bi-border', - width: 300, - height: 20, + type: FileUpload.xtype, + $value: 'krb5-file', + processId: "krb5Conf", allowBlank: true, - value: keyPath, - watermark: BI.i18nText('Dec-Dcm_Connection_Form_KeyPath'), - ref: (_ref: Editor) => { - this.form.keyPath = _ref; + value: krb5Path, + iconCls: "data-conf-file", + watermark: BI.i18nText('Dec-Dcm_Connection_Form_Krb5File'), + ref: (_ref: FileUpload) => { + this.form.krb5Path = _ref; }, - }, - ], - }, - // 关于krb5的提示 - { - type: BI.Label.xtype, - cls: 'bi-tips', - textAlign: 'left', - invisible: true, - text: BI.i18nText('Dec-Dcm_Connection_JDBC_Warning'), - ref: (_ref: Label) => { - this.labelTips = _ref; - }, + inter: '/v10/config/connection/upload/krb5?', + accept: '.conf', + listeners: [ + { + eventName: FileUpload.EVENT_CHECK_SUCCESS, + action: () => { + this.setKerberos(); + }, + } + ] + } + ] }, // 编码 { @@ -1266,6 +1325,30 @@ export class FormJdbc extends BI.Widget { } } + public setKerberos() { + const KerberosParams = BI.extend({},{ + keytabPath: this.form.keyPath.getValue(), + krb5ConfPath: this.form.krb5Path.getValue(), + principal: this.form.principal.getValue()[0] + }); + this.form.krb5Path.setFileInfo(KerberosParams); + this.form.keyPath.setFileInfo(KerberosParams); + } + + public changePrincipal() { + var self = this; + const KerberosParams = BI.extend({},{ + keytabPath: this.form.keyPath.getValue(), + krb5ConfPath: this.form.krb5Path.getValue(), + principal: this.form.principal.getValue()[0] + }); + api.changePrincipal(KerberosParams).then(res =>{ + self.form.keyPath.setValue(res.data.keytabPath); + self.form.krb5Path.setValue(res.data.krb5ConfPath); + }); + + } + public validation(): boolean { const driver = this.form.driver.validation(); const sshSet = !this.form.usingSsh.isSelected() || (this.form.sshIp.getValue() !== '' && this.form.sshPort.getValue() !== ''); @@ -1297,8 +1380,9 @@ export class FormJdbc extends BI.Widget { host: this.form.host.getValue(), authType: this.form.authType.getValue()[0] || '', creator: Dec ? Dec.personal.username : '', - principal: this.form.principal.getValue(), + principal: this.form.principal.getValue()[0], keyPath: this.form.keyPath.getValue(), + krb5Path: this.form.krb5Path.getValue(), fetchSize: BI.isEmptyString(this.form.fetchSize.getValue()) ? -2 : BI.parseInt(this.form.fetchSize.getValue()), // ssh usingSsh: this.form.usingSsh.isSelected(),