setDatasource.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  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.code"
  41. :label="sourceType.label"
  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. dataForm: {
  225. id: '',
  226. sourceName: '',
  227. sourceType: 'mysql',
  228. driverClassName: 'com.mysql.jdbc.Driver',
  229. username: '',
  230. password: '',
  231. url: 'jdbc:mysql://localhost:3306/db_name?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8&useSSL=false&useOldAliasMetadataBehavior=true',
  232. remark: ''
  233. },
  234. rules: {
  235. sourceType: [
  236. { required: true, message: '请选择数据源类型', trigger: 'blur' }
  237. ],
  238. sourceName: [
  239. { required: true, message: '请输入数据源名称', trigger: 'blur' },
  240. { validator: this.validateSourceName, trigger: 'blur' }
  241. ],
  242. driverClassName: [
  243. { required: true, message: '请选择连接驱动', trigger: 'blur' }
  244. ],
  245. database: [
  246. { required: true, message: '请输入数据库名称', trigger: 'blur' },
  247. { pattern: /^[^\u4e00-\u9fa5]+$/, message: '数据库名称不能包含汉字' }
  248. ],
  249. host: [
  250. { required: true, message: '请输入主机号', trigger: 'blur' },
  251. {
  252. 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)))/,
  253. message: '主机号格式有误'
  254. }
  255. ],
  256. port: [
  257. { required: true, message: '请输入端口', trigger: 'blur' },
  258. { pattern: /^[0-9]*$/, message: '端口号只能为数字' }
  259. ],
  260. username: [
  261. { required: true, message: '请输入用户名', trigger: 'blur' },
  262. { pattern: /^[^\u4e00-\u9fa5]+$/, message: '用户名不能包含汉字' }
  263. ],
  264. password: [
  265. { required: true, message: '请输入密码', trigger: 'blur' }
  266. ],
  267. url: [
  268. { required: true, message: '请输入连接url', trigger: 'blur' }
  269. ],
  270. coding: [
  271. { required: true, message: '请选择编码', trigger: 'blur' }
  272. ]
  273. },
  274. updateRules: {
  275. sourceType: [
  276. { required: true, message: '请选择数据源类型', trigger: 'blur' }
  277. ],
  278. sourceName: [
  279. { required: true, message: '请输入数据源名称', trigger: 'blur' },
  280. { validator: this.validateSourceName, trigger: 'blur' }
  281. ],
  282. driverClassName: [
  283. { required: true, message: '请选择连接驱动', trigger: 'blur' }
  284. ],
  285. database: [
  286. { required: true, message: '请输入数据库名称', trigger: 'blur' },
  287. { pattern: /^[^\u4e00-\u9fa5]+$/, message: '数据库名称不能包含汉字' }
  288. ],
  289. url: [
  290. { required: true, message: '请输入连接url', trigger: 'blur' }
  291. ],
  292. username: [
  293. { required: true, message: '请输入用户名', trigger: 'blur' },
  294. { pattern: /^[^\u4e00-\u9fa5]+$/, message: '用户名不能包含汉字' }
  295. ]
  296. }
  297. }
  298. },
  299. computed: {
  300. sourceTypeList () {
  301. return window.BS_CONFIG?.sourceTypeList || [
  302. { label: 'Mysql', code: 'mysql', name: 'com.mysql.jdbc.Driver', url: 'jdbc:mysql://localhost:3306/db_name?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8&useSSL=false&useOldAliasMetadataBehavior=true' },
  303. { label: 'ClickHouse', code: 'clickhouse', name: 'ru.yandex.clickhouse.ClickHouseDriver', url: 'jdbc:clickhouse://localhost:8123/db_name' },
  304. { label: 'PostgreSQL', code: 'postgresql', name: 'org.postgresql.Driver', url: 'jdbc:postgresql://localhost:13308/db_name' },
  305. { label: 'Oracle', code: 'oracle', name: 'oracle.jdbc.driver.OracleDriver', url: 'jdbc:oracle:thin:@localhost:1521:orcl' },
  306. { label: 'Sqlserver', code: 'sqlserver', name: 'com.microsoft.sqlserver.jdbc.SQLServerDriver', url: 'jdbc:sqlserver://localhost:1433;databaseName=db_name' }
  307. ]
  308. }
  309. },
  310. methods: {
  311. // 初始化
  312. init (row) {
  313. // 清除表单验证
  314. if (this.$refs.dataForm) {
  315. this.$refs.dataForm.clearValidate()
  316. }
  317. if (row && row.id) {
  318. this.dataForm = row
  319. }
  320. },
  321. // 名称校验
  322. validateSourceName (rule, value, callback) {
  323. checkRepeat({
  324. id: this.dataForm.id,
  325. sourceName: this.dataForm.sourceName,
  326. moduleCode: this.appCode
  327. }).then(r => {
  328. if (r) {
  329. callback(new Error('数据源名称已存在'))
  330. } else {
  331. callback()
  332. }
  333. })
  334. },
  335. // 数据源类型选择
  336. sourceTypeChange (code) {
  337. if (!this.dataForm.id && code) {
  338. this.dataForm.driverClassName = this.sourceTypeList.find(item => item.code === code)?.name
  339. this.$set(this.dataForm, 'url', this.sourceTypeList.find(item => item.code === code)?.url)
  340. }
  341. },
  342. // 阻止文本域回车换行
  343. textareaKeydown () {
  344. const e = window.event || arguments[0]
  345. if (e.key === 'Enter' || e.code === 'Enter' || e.keyCode === 13) {
  346. e.returnValue = false
  347. return false
  348. }
  349. },
  350. // 连接测试
  351. sourceLinkCheck () {
  352. let flag = 0
  353. this.$refs.dataForm.validate((valid) => {
  354. if (!valid) {
  355. flag = 1
  356. return false
  357. } else {
  358. if (flag === 0) {
  359. this.sourceLinkTest(this.dataForm)
  360. }
  361. }
  362. })
  363. },
  364. sourceLinkTest (row) {
  365. this.linkLoading = true
  366. sourceLinkTest(row).then((r) => {
  367. this.$message.success(r)
  368. this.linkLoading = false
  369. }).catch(() => {
  370. this.linkLoading = false
  371. })
  372. },
  373. // 取消重制
  374. handleClose () {
  375. this.$refs.dataForm.resetFields()
  376. this.dataForm = {
  377. id: '',
  378. sourceName: '',
  379. sourceType: 'mysql',
  380. driverClassName: 'com.mysql.jdbc.Driver',
  381. username: '',
  382. password: '',
  383. url: 'jdbc:mysql://localhost:3306/db_name?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8&useSSL=false&useOldAliasMetadataBehavior=true',
  384. remark: ''
  385. }
  386. this.setDatasourceVisible = false
  387. },
  388. // 保存
  389. submitForm () {
  390. // mysql 需要包含useOldAliasMetadataBehavior
  391. // if (this.dataForm.sourceType == 'Mysql') {
  392. // if (this.dataForm.url.indexOf('useOldAliasMetadataBehavior') == -1) {
  393. // if (this.dataForm.url.indexOf('?') == -1) {
  394. // this.dataForm.url = this.dataForm.url + '?useOldAliasMetadataBehavior=true'
  395. // } else {
  396. // this.dataForm.url = this.dataForm.url + '&useOldAliasMetadataBehavior=true'
  397. // }
  398. // }
  399. // }
  400. this.$refs.dataForm.validate((valid) => {
  401. if (valid) {
  402. if (this.dataForm.id) {
  403. update({
  404. ...this.dataForm,
  405. moduleCode: this.appCode,
  406. editable: this.appCode ? 1 : 0
  407. }).then(() => {
  408. this.$message.success('保存成功')
  409. // 刷新表格
  410. this.$emit('refreshTable')
  411. this.handleClose()
  412. })
  413. } else {
  414. add({
  415. ...this.dataForm,
  416. moduleCode: this.appCode,
  417. editable: this.appCode ? 1 : 0
  418. }).then(() => {
  419. this.$message.success('保存成功')
  420. // 刷新表格
  421. this.$emit('refreshTable')
  422. this.handleClose()
  423. })
  424. }
  425. } else {
  426. return false
  427. }
  428. })
  429. }
  430. }
  431. }
  432. </script>
  433. <style lang="scss" scoped>
  434. @import '../../assets//style/bsTheme.scss';
  435. </style>