setDatasource.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. <template>
  2. <el-dialog
  3. width="700px"
  4. :title="title"
  5. :visible.sync="setDatasourceVisible"
  6. :append-to-body="true"
  7. :close-on-click-modal="false"
  8. :before-close="handleClose"
  9. class="bs-dialog-wrap bs-el-dialog"
  10. >
  11. <div
  12. v-loading="linkLoading"
  13. element-loading-text="正在测试连接..."
  14. style="padding-right: 80px;"
  15. >
  16. <el-form
  17. ref="dataForm"
  18. class="bs-el-form"
  19. :model="dataForm"
  20. :rules="dataForm.id ? updateRules : rules"
  21. size="small"
  22. label-position="right"
  23. :label-width="dataForm.advanceSettingFlag ? '200px' : '150px'"
  24. >
  25. <el-form-item
  26. label="类型"
  27. prop="sourceType"
  28. >
  29. <el-select
  30. v-model="dataForm.sourceType"
  31. placeholder="请选择类型"
  32. class="bs-el-select"
  33. popper-class="bs-el-select"
  34. clearable
  35. filterable
  36. @change="sourceTypeChange"
  37. >
  38. <el-option
  39. v-for="sourceType in sourceTypeList"
  40. :key="sourceType.id"
  41. :label="sourceType.name"
  42. :value="sourceType.code"
  43. />
  44. </el-select>
  45. </el-form-item>
  46. <el-form-item
  47. label="数据源名称"
  48. prop="sourceName"
  49. >
  50. <el-input
  51. v-model="dataForm.sourceName"
  52. placeholder="请输入数据源名称"
  53. class="bs-el-input"
  54. maxlength="200"
  55. />
  56. </el-form-item>
  57. <el-form-item
  58. label="JDBC URL"
  59. prop="url"
  60. >
  61. <el-input
  62. v-model="dataForm.url"
  63. placeholder="请输入JDBC URL"
  64. class="bs-el-input"
  65. type="textarea"
  66. rows="4"
  67. @keydown.enter.native="textareaKeydown"
  68. />
  69. </el-form-item>
  70. <el-form-item
  71. label="用户名"
  72. prop="username"
  73. >
  74. <el-input
  75. v-model="dataForm.username"
  76. placeholder="请输入用户名"
  77. class="bs-el-input"
  78. />
  79. </el-form-item>
  80. <el-form-item
  81. label="密码"
  82. prop="password"
  83. >
  84. <el-input
  85. v-model="dataForm.password"
  86. :placeholder="dataForm.id ? '请输入密码,不输入代表不更新' : '请输入密码'"
  87. class="bs-el-input"
  88. type="password"
  89. show-password
  90. />
  91. </el-form-item>
  92. <el-form-item
  93. label="备注"
  94. prop="remark"
  95. >
  96. <el-input
  97. v-model="dataForm.remark"
  98. placeholder="请输入备注"
  99. class="bs-el-input"
  100. type="textarea"
  101. rows="4"
  102. maxlength="200"
  103. @keydown.enter.native="textareaKeydown"
  104. />
  105. </el-form-item>
  106. <template v-if="dataForm.advanceSettingFlag">
  107. <el-form-item label="初始化连接数">
  108. <el-input v-model="dataForm.initConnNum" />
  109. </el-form-item>
  110. <el-form-item label="最大活动连接数">
  111. <el-input v-model="dataForm.maxActiveConnNum" />
  112. </el-form-item>
  113. <el-form-item label="最大空闲连接数">
  114. <el-input v-model="dataForm.maxIdleConnNum" />
  115. </el-form-item>
  116. <el-form-item label="最小空闲连接数">
  117. <el-input v-model="dataForm.minIdleConnNum" />
  118. </el-form-item>
  119. <el-form-item label="最大等待时间 (ms)">
  120. <el-input v-model="dataForm.maxWaitConnNum" />
  121. </el-form-item>
  122. <el-form-item label="SQL验证查询">
  123. <el-input
  124. v-model="dataForm.sqlCheck"
  125. type="text"
  126. />
  127. </el-form-item>
  128. <el-form-item label="获取连接前校验">
  129. <el-select
  130. v-model="dataForm.getconnCheckFlag"
  131. clearable
  132. >
  133. <el-option
  134. label="是"
  135. :value="1"
  136. />
  137. <el-option
  138. label="否"
  139. :value="0"
  140. />
  141. </el-select>
  142. </el-form-item>
  143. <el-form-item label="归还连接前校验">
  144. <el-select
  145. v-model="dataForm.returnCheckFlag"
  146. clearable
  147. >
  148. <el-option
  149. label="是"
  150. :value="1"
  151. />
  152. <el-option
  153. label="否"
  154. :value="0"
  155. />
  156. </el-select>
  157. </el-form-item>
  158. <el-form-item label="开启空闲回收器校验">
  159. <el-select
  160. v-model="dataForm.startIdleCheckFlag"
  161. clearable
  162. >
  163. <el-option
  164. label="是"
  165. :value="1"
  166. />
  167. <el-option
  168. label="否"
  169. :value="0"
  170. />
  171. </el-select>
  172. </el-form-item>
  173. <el-form-item label="空闲连接回收器休眠时间 (ms)">
  174. <el-input v-model="dataForm.idleConnDormantTime" />
  175. </el-form-item>
  176. <el-form-item label="空闲连接回收检查数">
  177. <el-input v-model="dataForm.idleConnCheckNum" />
  178. </el-form-item>
  179. <el-form-item label="保持空闲最小时间值 (s)">
  180. <el-input v-model="dataForm.keepIdleMinTime" />
  181. </el-form-item>
  182. </template>
  183. </el-form>
  184. </div>
  185. <span
  186. slot="footer"
  187. class="dialog-footer"
  188. >
  189. <el-button
  190. type="primary"
  191. @click="sourceLinkCheck"
  192. >
  193. 测试
  194. </el-button>
  195. <el-button
  196. class="bs-el-button-default"
  197. @click="handleClose"
  198. >
  199. 取消
  200. </el-button>
  201. <el-button
  202. type="primary"
  203. @click="submitForm"
  204. >
  205. 确定
  206. </el-button>
  207. </span>
  208. </el-dialog>
  209. </template>
  210. <script>
  211. import { checkRepeat, sourceLinkTest, add, update } from 'data-room-ui/js/utils/dataSourceService'
  212. export default {
  213. props: {
  214. appCode: {
  215. type: String,
  216. default: ''
  217. }
  218. },
  219. data () {
  220. return {
  221. setDatasourceVisible: false,
  222. title: '',
  223. linkLoading: false,
  224. sourceTypeList: [
  225. { name: 'Mysql', code: 'mysql' },
  226. { name: 'ClickHouse', code: 'clickhouse' },
  227. { name: 'PostgreSQL', code: 'postgresql' },
  228. { name: 'Oracle', code: 'oracle' },
  229. { name: 'Sqlserver', code: 'sqlserver' }
  230. ],
  231. driverCLassList: [
  232. { code: 'mysqlDriver', name: 'com.mysql.jdbc.Driver' },
  233. { code: 'clickhouseDriver', name: 'ru.yandex.clickhouse.ClickHouseDriver' },
  234. { code: 'oracleDriver', name: 'oracle.jdbc.driver.OracleDriver' },
  235. { code: 'hsqlDriver', name: 'org.hsqldb.jdbc.JDBCDriver' },
  236. { code: 'ibmdb2Driver', name: 'com.ibm.db2.jcc.DB2Driver' },
  237. { code: 'sqlserverDriver', name: 'com.microsoft.sqlserver.jdbc.SQLServerDriver' },
  238. { code: 'postgresqlDriver', name: 'org.postgresql.Driver' },
  239. { code: 'hiveDriver', name: 'org.apache.hive.jdbc.HiveDriver' }
  240. ],
  241. dataForm: {
  242. id: '',
  243. sourceName: '',
  244. sourceType: 'Mysql',
  245. driverClassName: 'com.mysql.jdbc.Driver',
  246. username: '',
  247. password: '',
  248. url: 'jdbc:mysql://localhost:3306/db_name?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8&useSSL=false&useOldAliasMetadataBehavior=true',
  249. remark: ''
  250. },
  251. rules: {
  252. sourceType: [
  253. { required: true, message: '请选择数据源类型', trigger: 'blur' }
  254. ],
  255. sourceName: [
  256. { required: true, message: '请输入数据源名称', trigger: 'blur' },
  257. { validator: this.validateSourceName, trigger: 'blur' }
  258. ],
  259. driverClassName: [
  260. { required: true, message: '请选择连接驱动', trigger: 'blur' }
  261. ],
  262. database: [
  263. { required: true, message: '请输入数据库名称', trigger: 'blur' },
  264. { pattern: /^[^\u4e00-\u9fa5]+$/, message: '数据库名称不能包含汉字' }
  265. ],
  266. host: [
  267. { required: true, message: '请输入主机号', trigger: 'blur' },
  268. {
  269. pattern: /((25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))/,
  270. message: '主机号格式有误'
  271. }
  272. ],
  273. port: [
  274. { required: true, message: '请输入端口', trigger: 'blur' },
  275. { pattern: /^[0-9]*$/, message: '端口号只能为数字' }
  276. ],
  277. username: [
  278. { required: true, message: '请输入用户名', trigger: 'blur' },
  279. { pattern: /^[^\u4e00-\u9fa5]+$/, message: '用户名不能包含汉字' }
  280. ],
  281. password: [
  282. { required: true, message: '请输入密码', trigger: 'blur' }
  283. ],
  284. url: [
  285. { required: true, message: '请输入连接url', trigger: 'blur' }
  286. ],
  287. coding: [
  288. { required: true, message: '请选择编码', trigger: 'blur' }
  289. ]
  290. },
  291. updateRules: {
  292. sourceType: [
  293. { required: true, message: '请选择数据源类型', trigger: 'blur' }
  294. ],
  295. sourceName: [
  296. { required: true, message: '请输入数据源名称', trigger: 'blur' },
  297. { validator: this.validateSourceName, trigger: 'blur' }
  298. ],
  299. driverClassName: [
  300. { required: true, message: '请选择连接驱动', trigger: 'blur' }
  301. ],
  302. database: [
  303. { required: true, message: '请输入数据库名称', trigger: 'blur' },
  304. { pattern: /^[^\u4e00-\u9fa5]+$/, message: '数据库名称不能包含汉字' }
  305. ],
  306. url: [
  307. { required: true, message: '请输入连接url', trigger: 'blur' }
  308. ],
  309. username: [
  310. { required: true, message: '请输入用户名', trigger: 'blur' },
  311. { pattern: /^[^\u4e00-\u9fa5]+$/, message: '用户名不能包含汉字' }
  312. ]
  313. }
  314. }
  315. },
  316. methods: {
  317. // 初始化
  318. init (row) {
  319. // 清除表单验证
  320. if (this.$refs.dataForm) {
  321. this.$refs.dataForm.clearValidate()
  322. }
  323. if (row && row.id) {
  324. this.dataForm = row
  325. }
  326. },
  327. getUrl (driverClassName) {
  328. switch (driverClassName) {
  329. case 'com.mysql.jdbc.Driver':
  330. return 'jdbc:mysql://localhost:3306/db_name?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8&useSSL=false&useOldAliasMetadataBehavior=true'
  331. case 'ru.yandex.clickhouse.ClickHouseDriver':
  332. return 'jdbc:clickhouse://localhost:8123/db_name'
  333. case 'oracle.jdbc.driver.OracleDriver':
  334. return 'jdbc:oracle:thin:@localhost:1521:orcl'
  335. case 'org.hsqldb.jdbc.JDBCDriver':
  336. return 'jdbc:hsqldb:http://localhost:1527/db_name'
  337. case 'com.ibm.db2.jcc.DB2Driver':
  338. return 'jdbc:db2://localhost:5000/db_name'
  339. case 'com.microsoft.sqlserver.jdbc.SQLServerDriver':
  340. return 'jdbc:sqlserver://localhost:1433;databaseName=db_name;encrypt=false'
  341. case 'org.postgresql.Driver':
  342. return 'jdbc:postgresql://localhost:13308/db_name'
  343. case 'org.apache.hive.jdbc.HiveDriver':
  344. return 'jdbc:hive2://localhost:10000/db_name'
  345. }
  346. },
  347. // 名称校验
  348. validateSourceName (rule, value, callback) {
  349. checkRepeat({
  350. id: this.dataForm.id,
  351. sourceName: this.dataForm.sourceName,
  352. moduleCode: this.appCode
  353. }).then(r => {
  354. if (r) {
  355. callback(new Error('数据源名称已存在'))
  356. } else {
  357. callback()
  358. }
  359. })
  360. },
  361. // 数据源类型选择
  362. sourceTypeChange (code) {
  363. if (!this.dataForm.id && code) {
  364. let driverName = ''
  365. driverName = code + 'Driver'
  366. // 从驱动列表中获取驱动的对应的jdbcUrl
  367. this.driverCLassList.forEach(driver => {
  368. if (driverName === driver.code) {
  369. this.dataForm.driverClassName = driver.name
  370. this.queryDriverTemp(driver.name)
  371. }
  372. })
  373. }
  374. },
  375. queryDriverTemp (val) {
  376. this.$set(this.dataForm, 'url', this.getUrl(val))
  377. },
  378. // 阻止文本域回车换行
  379. textareaKeydown () {
  380. const e = window.event || arguments[0]
  381. if (e.key === 'Enter' || e.code === 'Enter' || e.keyCode === 13) {
  382. e.returnValue = false
  383. return false
  384. }
  385. },
  386. // 连接测试
  387. sourceLinkCheck () {
  388. let flag = 0
  389. this.$refs.dataForm.validate((valid) => {
  390. if (!valid) {
  391. flag = 1
  392. return false
  393. } else {
  394. if (flag === 0) {
  395. this.sourceLinkTest(this.dataForm)
  396. }
  397. }
  398. })
  399. },
  400. sourceLinkTest (row) {
  401. this.linkLoading = true
  402. sourceLinkTest(row).then((r) => {
  403. this.$message.success(r)
  404. this.linkLoading = false
  405. }).catch(() => {
  406. this.linkLoading = false
  407. })
  408. },
  409. // 取消重制
  410. handleClose () {
  411. this.$refs.dataForm.resetFields()
  412. this.dataForm = {
  413. id: '',
  414. sourceName: '',
  415. sourceType: 'Mysql',
  416. driverClassName: 'com.mysql.jdbc.Driver',
  417. username: '',
  418. password: '',
  419. url: 'jdbc:mysql://localhost:3306/db_name?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8&useSSL=false&useOldAliasMetadataBehavior=true',
  420. remark: ''
  421. }
  422. this.setDatasourceVisible = false
  423. },
  424. // 保存
  425. submitForm () {
  426. // mysql 需要包含useOldAliasMetadataBehavior
  427. // if (this.dataForm.sourceType == 'Mysql') {
  428. // if (this.dataForm.url.indexOf('useOldAliasMetadataBehavior') == -1) {
  429. // if (this.dataForm.url.indexOf('?') == -1) {
  430. // this.dataForm.url = this.dataForm.url + '?useOldAliasMetadataBehavior=true'
  431. // } else {
  432. // this.dataForm.url = this.dataForm.url + '&useOldAliasMetadataBehavior=true'
  433. // }
  434. // }
  435. // }
  436. this.$refs.dataForm.validate((valid) => {
  437. if (valid) {
  438. if (this.dataForm.id) {
  439. update({
  440. ...this.dataForm,
  441. moduleCode: this.appCode,
  442. editable: this.appCode ? 1 : 0
  443. }).then(() => {
  444. this.$message.success('保存成功')
  445. // 刷新表格
  446. this.$emit('refreshTable')
  447. this.handleClose()
  448. })
  449. } else {
  450. add({
  451. ...this.dataForm,
  452. moduleCode: this.appCode,
  453. editable: this.appCode ? 1 : 0
  454. }).then(() => {
  455. this.$message.success('保存成功')
  456. // 刷新表格
  457. this.$emit('refreshTable')
  458. this.handleClose()
  459. })
  460. }
  461. } else {
  462. return false
  463. }
  464. })
  465. }
  466. }
  467. }
  468. </script>
  469. <style lang="scss" scoped>
  470. @import '../../assets//style/bsTheme.scss';
  471. </style>