refactor: 整理代码

This commit is contained in:
taojinlong 2021-11-24 18:49:41 +08:00
parent 9e87a08a5b
commit bf7c8bb333
16 changed files with 309 additions and 664 deletions

View File

@ -1,128 +0,0 @@
# 项目说明
> 这是一个极简的 vue admin 管理后台基于vue-admin-template进行了细节改造主要是把侧边导航改造为了顶部和侧边两个导航。
>
> 本项目默认开启了csssourceMap和devtool('source-map'),便于在开发中调试,除非编译速度过慢,否则开发环境不建议修改。
## IDE
编辑器建议使用VS Code格式化时可以统一代码风格配置项建议统一设置为默认不自动保存手动保存后自动修复部分错误。具体参数如下
```js
{
"emmet.triggerExpansionOnTab": true,
"files.autoSave": "off",
"vetur.format.defaultFormatterOptions": {
"js-beautify-html": {
"wrap_attributes": "force-aligned"
},
"prettyhtml": {
"printWidth": 100,
"singleQuote": false,
"wrapAttributes": false,
"sortAttributes": true
},
"prettier": {
"semi": false,
"singleQuote": true
}
},
"eslint.run": "onSave",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
}
```
## 目录结构
```bash
├── build # 构建相关
├── mock # 项目mock 模拟数据
├── public # 静态资源
│ │── favicon.ico # favicon图标
│ └── index.html # html模板
├── src # 源代码
│ ├── api # 所有请求
│ ├── assets # 主题 字体等静态资源
│ ├── components # 全局公用组件
│ ├── directive # 全局指令
│ ├── filters # 全局 filter
│ ├── icons # 项目所有 svg icons
│ ├── lang # 国际化 language
│ ├── layout # 全局 layout
│ ├── router # 路由
│ ├── store # 全局 store管理
│ ├── styles # 全局样式
│ ├── utils # 全局公用方法
│ ├── vendor # 公用vendor
│ ├── views # views 所有页面
│ ├── App.vue # 入口页面
│ ├── main.js # 入口文件 加载组件 初始化等
│ └── permission.js # 权限管理
├── tests # 测试
├── .env.xxx # 环境变量配置
├── .eslintrc.js # eslint 配置项
├── .babelrc # babel-loader 配置
├── .travis.yml # 自动化CI配置
├── vue.config.js # vue-cli 配置
├── postcss.config.js # postcss 配置
└── package.json # package.json
```
## 构建步骤
```bash
# 克隆项目
git clone 项目地址
# 进入项目目录
cd admin-web
# 安装依赖
npm install
# 建议不要直接使用 cnpm 安装依赖,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题
npm install --registry=https://registry.npm.taobao.org
# 启动服务
npm run dev
```
浏览器访问 [http://localhost:9528](http://localhost:9528)
## 发布
```bash
# 构建测试环境
npm run build:stage
# 构建生产环境
npm run build:prod
```
## 其它
```bash
# 预览发布环境效果
npm run preview
# 预览发布环境效果 + 静态资源分析
npm run preview -- --report
# 代码格式检查
npm run lint
# 代码格式检查并自动修复
npm run lint -- --fix
```
更多信息请参考花裤衩大佬的vue-element-admin [使用文档](https://panjiachen.github.io/vue-element-admin-site/zh/)
[线上地址](http://panjiachen.github.io/vue-admin-template)
[国内访问](https://panjiachen.gitee.io/vue-admin-template)

View File

@ -13,7 +13,7 @@ const data = Mock.mock({
export default [
{
url: '/vue-admin-template/table/list',
url: '/dataease/table/list',
type: 'get',
response: config => {
const items = data.items

View File

@ -26,7 +26,7 @@ const users = {
export default [
// user login
{
url: '/vue-admin-template/user/login',
url: '/dataease/user/login',
type: 'post',
response: config => {
const { username } = config.body
@ -49,7 +49,7 @@ export default [
// get user info
{
url: '/vue-admin-template/user/info\.*',
url: '/dataease/user/info\.*',
type: 'get',
response: config => {
const { token } = config.query
@ -72,7 +72,7 @@ export default [
// user logout
{
url: '/vue-admin-template/user/logout',
url: '/dataease/user/logout',
type: 'post',
response: _ => {
return {

View File

@ -1,9 +1,7 @@
{
"name": "vue-admin-template",
"version": "4.2.1",
"description": "A vue admin template with Element UI & axios & iconfont & permission control & lint",
"author": "Pan <panfree23@gmail.com>",
"license": "MIT",
"name": "dataease",
"version": "1.5.0",
"description": "dataease front",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
@ -23,10 +21,10 @@
"css-color-function": "^1.3.3",
"echarts": "^5.0.1",
"element-resize-detector": "^1.2.3",
"element-ui": "2.15.6",
"element-ui": "2.15.7",
"file-save": "^0.2.0",
"file-saver": "^2.0.5",
"fit2cloud-ui": "1.5.0-beta.0",
"fit2cloud-ui": "1.5.4",
"html2canvasde": "^v1.1.4-de",
"jquery": "^3.1.1",
"js-base64": "^3.7.2",

View File

@ -1,7 +1,7 @@
<template>
<div id="app">
<router-view />
<plugin-com v-show="false" ref="de-theme" component-name="ThemeSetting" />
<router-view/>
<plugin-com v-show="false" ref="de-theme" component-name="ThemeSetting"/>
</div>
</template>
@ -10,7 +10,7 @@ import PluginCom from '@/views/system/plugin/PluginCom'
export default {
name: 'App',
components: { PluginCom },
components: {PluginCom},
beforeCreate() {
}

View File

@ -10,11 +10,6 @@ const data = Mock.mock({
}]
})
export function getList(params) {
// return request({
// url: '/vue-admin-template/table/list',
// method: 'get',
// params
// })
return new Promise((resolve, reject) => {
const items = data.items
const result = {

View File

@ -7,7 +7,6 @@
</template>
<script>
// import Axios from 'axios'
import { get } from '@/api/system/dynamic'

View File

@ -51,8 +51,6 @@ export default {
}
},
data() {
// To fix https://github.com/PanJiaChen/vue-admin-template/issues/237
// TODO: refactor with render function
this.onlyOneChild = null
return {}
},

View File

@ -3,8 +3,7 @@ import Cookies from 'js-cookie'
import '@/styles/index.scss' // global css
import ElementUI from 'element-ui'
import Fit2CloudUI from 'fit2cloud-ui'
// import axios from 'axios'
// import VueAxios from 'vue-axios'
import i18n from './lang' // internationalization
import App from './App'
import store from './store'

View File

@ -1,19 +1,17 @@
import axios from 'axios'
// import { MessageBox, Message } from 'element-ui'
import store from '@/store'
import { $alert, $error } from './message'
import { getToken, getIdToken } from '@/utils/auth'
import {$alert, $error} from './message'
import {getToken, getIdToken} from '@/utils/auth'
import Config from '@/settings'
import i18n from '@/lang'
import { tryShowLoading, tryHideLoading } from './loading'
import { getLinkToken, setLinkToken } from '@/utils/auth'
// import router from '@/router'
// const interruptTokenContineUrls = Config.interruptTokenContineUrls
import {tryShowLoading, tryHideLoading} from './loading'
import {getLinkToken, setLinkToken} from '@/utils/auth'
const TokenKey = Config.TokenKey
const RefreshTokenKey = Config.RefreshTokenKey
const LinkTokenKey = Config.LinkTokenKey
import Cookies from 'js-cookie'
// create an axios instance
const getTimeOut = () => {
let time = 10
@ -46,23 +44,18 @@ const getTimeOut = () => {
const time = getTimeOut()
let service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
timeout: time ? time * 1000 : 10000
})
// request interceptor
service.interceptors.request.use(
config => {
// do something before request is sent
const idToken = getIdToken()
if (idToken) {
config.headers[Config.IdTokenKey] = idToken
}
if (store.getters.token) {
// let each request carry token
// ['X-Token'] is a custom headers key
// please modify it according to the actual situation
config.headers[TokenKey] = getToken()
}
let linkToken = null
@ -78,15 +71,12 @@ service.interceptors.request.use(
const lang = i18n.locale.replace('_', '-')
config.headers['Accept-Language'] = lang
}
// 增加loading
config.loading && tryShowLoading(store.getters.currentPath)
return config
},
error => {
error.config.loading && tryHideLoading(store.getters.currentPath)
// do something with request error
return Promise.reject(error)
}
)
@ -111,7 +101,6 @@ service.interceptors.response.use(response => {
let msg
if (error.response) {
checkAuth(error.response)
// checkPermission(error.response)
msg = error.response.data.message || error.response.data
} else {
msg = error.message

View File

@ -13,13 +13,13 @@ export default {
</script>
<style scoped>
.custom-position {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
flex-flow: row nowrap;
color: #9ea6b2;
}
.custom-position {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
flex-flow: row nowrap;
color: #9ea6b2;
}
</style>

View File

@ -1,10 +1,11 @@
<template>
<de-container v-loading="$store.getters.loadingMap[$store.getters.currentPath]">
<de-aside-container style="padding: 0 0;">
<ds-tree ref="dsTree" :datasource="datasource" @switch-main="switchMain" />
<ds-tree ref="dsTree" :datasource="datasource" @switch-main="switchMain"/>
</de-aside-container>
<de-main-container>
<component :is="component" v-if="!!component" :params="param" @refresh-type="refreshType" @switch-component="switchMain" />
<component :is="component" v-if="!!component" :params="param" @refresh-type="refreshType"
@switch-component="switchMain"/>
</de-main-container>
</de-container>
</template>
@ -16,9 +17,10 @@ import DeAsideContainer from '@/components/dataease/DeAsideContainer'
import DsTree from './DsTree'
import DsForm from './form'
import DataHome from './DataHome'
export default {
name: 'DsMain',
components: { DeMainContainer, DeContainer, DeAsideContainer, DsTree, DataHome },
components: {DeMainContainer, DeContainer, DeAsideContainer, DsTree, DataHome},
data() {
return {
component: DataHome,
@ -26,19 +28,15 @@ export default {
param: null
}
},
computed: {
},
watch: {
},
computed: {},
watch: {},
mounted() {
// this.clear()
},
methods: {
// main
switchMain(param) {
const { component, componentParam } = param
const {component, componentParam} = param
this.component = DataHome
this.param = null
this.$nextTick(() => {
@ -66,14 +64,15 @@ export default {
</script>
<style scoped>
.ms-aside-container {
height: calc(100vh - 56px);
padding: 0px;
min-width: 260px;
max-width: 460px;
}
.ms-main-container {
height: calc(100vh - 56px);
padding: 0px;
}
.ms-aside-container {
height: calc(100vh - 56px);
padding: 0px;
min-width: 260px;
max-width: 460px;
}
.ms-main-container {
height: calc(100vh - 56px);
padding: 0px;
}
</style>

View File

@ -5,10 +5,11 @@
<span class="title-text">
{{ $t('commons.datasource') }}
</span>
<el-button v-permission="['datasource:add']" icon="el-icon-plus" type="text" size="mini" style="float: right;" @click="addFolder" />
<el-button v-permission="['datasource:add']" icon="el-icon-plus" type="text" size="mini" style="float: right;"
@click="addFolder"/>
</el-row>
<el-divider />
<el-divider/>
<el-row>
<el-form>
<el-form-item class="form-item">
@ -39,18 +40,21 @@
<span slot-scope="{ node, data }" class="custom-tree-node-list father">
<span style="display: flex;flex: 1;width: 0;">
<span v-if="data.type !== 'folder' && data.status !== 'Error'">
<svg-icon icon-class="datasource" class="ds-icon-scene" />
<svg-icon icon-class="datasource" class="ds-icon-scene"/>
</span>
<span v-if="data.status === 'Error'">
<svg-icon icon-class="exclamationmark" class="ds-icon-scene" />
<el-tooltip v-if="data.status === 'Error'" style="margin-left: 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;" effect="dark" :content="$t('datasource.in_valid')" placement="right">
<svg-icon icon-class="exclamationmark" class="ds-icon-scene"/>
<el-tooltip v-if="data.status === 'Error'"
style="margin-left: 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;"
effect="dark" :content="$t('datasource.in_valid')" placement="right">
<el-button type="text" :style="!!data.msgNode ? {'color': 'red'} : {}"> {{ data.name }} </el-button>
</el-tooltip>
</span>
<span v-if="data.type === 'folder'">
<i class="el-icon-folder" />
<i class="el-icon-folder"/>
</span>
<span v-if=" data.status !== 'Error'" style="margin-left: 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">
<span v-if=" data.status !== 'Error'"
style="margin-left: 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">
{{ data.name }}
</span>
@ -87,7 +91,7 @@
</el-col>
</template>
<script>
import { listDatasource, listDatasourceByType, delDs } from '@/api/system/datasource'
import {listDatasource, listDatasourceByType, delDs} from '@/api/system/datasource'
export default {
name: 'DsTree',
@ -135,7 +139,7 @@ export default {
listDatasourceByType(datasource.type).then(res => {
typeData = this.buildTree(res.data)
for (let index = 0; index < this.tData.length; index++) {
if(typeData[0].id === this.tData[index].id){
if (typeData[0].id === this.tData[index].id) {
this.tData[index].children = typeData[0].children
}
}
@ -156,7 +160,12 @@ export default {
if (!(element.type in types)) {
types[element.type] = []
// newArr.push(...element, ...{ children: types[element.type] })
newArr.push({ id: element.type, name: this.transTypeToName(element.type), type: 'folder', children: types[element.type] })
newArr.push({
id: element.type,
name: this.transTypeToName(element.type),
type: 'folder',
children: types[element.type]
})
}
types[element.type].push(element)
// newArr.children.push({ id: element.id, label: element.name })
@ -183,7 +192,7 @@ export default {
return 'Doris'
} else if (type === 'mongo') {
return 'MongoDB'
}else if (type === 'redshift') {
} else if (type === 'redshift') {
return 'AWS Redshift'
} else if (type === 'hive') {
return 'Apache Hive'
@ -194,7 +203,7 @@ export default {
this.switchMain('DsForm')
},
addFolderWithType(data) {
this.switchMain('DsForm', { type: data.id })
this.switchMain('DsForm', {type: data.id})
},
nodeClick(node, data) {
if (node.type === 'folder') return
@ -202,7 +211,7 @@ export default {
},
clickFileMore(param) {
const { optType, data } = param
const {optType, data} = param
switch (optType) {
case 'edit':
this.edit(data)
@ -215,13 +224,13 @@ export default {
}
},
beforeClickFile(optType, data, node) {
return { optType, data, node }
return {optType, data, node}
},
edit(row) {
this.switchMain('DsForm', row)
},
showInfo(row) {
const param = { ...row.data, ...{ showModel: 'show' }}
const param = {...row.data, ...{showModel: 'show'}}
this.switchMain('DsForm', param)
},
_handleDelete(datasource) {
@ -266,100 +275,106 @@ export default {
}
</script>
<style lang="scss" scoped>
.el-divider--horizontal {
margin: 12px 0
}
.el-divider--horizontal {
margin: 12px 0
}
.search-input {
padding: 12px 0;
}
.search-input {
padding: 12px 0;
}
.custom-tree-container{
margin-top: 10px;
}
.custom-tree-container {
margin-top: 10px;
}
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right:8px;
}
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right: 8px;
}
.custom-tree-node-list {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding:0 8px;
}
.custom-tree-node-list {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding: 0 8px;
}
.tree-list>>>.el-tree-node__expand-icon.is-leaf{
display: none;
}
.tree-list > > > .el-tree-node__expand-icon.is-leaf {
display: none;
}
.custom-position {
flex: 1;
display: flex;
align-items: center;
font-size: 14px;
flex-flow: row nowrap;
}
.custom-position {
flex: 1;
display: flex;
align-items: center;
font-size: 14px;
flex-flow: row nowrap;
}
.form-item {
margin-bottom: 0;
}
.form-item {
margin-bottom: 0;
}
.title-css {
height: 26px;
}
.title-css {
height: 26px;
}
.title-text {
line-height: 26px;
}
.title-text {
line-height: 26px;
}
.dialog-css >>> .el-dialog__header {
padding: 20px 20px 0;
}
.dialog-css > > > .el-dialog__header {
padding: 20px 20px 0;
}
.dialog-css >>> .el-dialog__body {
padding: 10px 20px 20px;
}
.dialog-css > > > .el-dialog__body {
padding: 10px 20px 20px;
}
.form-item>>>.el-form-item__label{
font-size: 12px;
}
.form-item > > > .el-form-item__label {
font-size: 12px;
}
.scene-title{
width: 100%;
display: flex;
}
.scene-title-name{
width: 100%;
overflow: hidden;
display: inline-block;
white-space: nowrap;
text-overflow: ellipsis;
}
.father .child {
/*display: none;*/
visibility: hidden;
}
.father:hover .child {
/*display: inline;*/
visibility: visible;
}
.tree-style {
padding: 10px 15px;
height: 100%;
overflow-y: auto;
}
.msg-node-class {
.scene-title {
width: 100%;
display: flex;
}
.scene-title-name {
width: 100%;
overflow: hidden;
display: inline-block;
white-space: nowrap;
text-overflow: ellipsis;
}
.father .child {
/*display: none;*/
visibility: hidden;
}
.father:hover .child {
/*display: inline;*/
visibility: visible;
}
.tree-style {
padding: 10px 15px;
height: 100%;
overflow-y: auto;
}
.msg-node-class {
color: red;
> > > i {
color: red;
>>> i{
color: red;
}
}
}
</style>

View File

@ -1,20 +1,26 @@
<template>
<layout-content :header="formType=='add' ? $t('datasource.create') : $t('datasource.modify')">
<template v-slot:header>
<el-icon name="back" class="back-button" @click.native="backToList" />
{{ params && params.id && params.showModel && params.showModel === 'show' && !canEdit ? $t('datasource.show_info') : formType=='add' ? $t('datasource.create') : $t('datasource.modify') }}
<el-icon name="back" class="back-button" @click.native="backToList"/>
{{
params && params.id && params.showModel && params.showModel === 'show' && !canEdit ? $t('datasource.show_info') : formType == 'add' ? $t('datasource.create') : $t('datasource.modify')
}}
</template>
<div>
<el-form ref="dsForm" :model="form" :rules="rule" size="small" :disabled="params && params.id && params.showModel && params.showModel === 'show' && !canEdit " label-width="auto" label-position="right">
<el-form ref="dsForm" :model="form" :rules="rule" size="small"
:disabled="params && params.id && params.showModel && params.showModel === 'show' && !canEdit "
label-width="auto" label-position="right">
<el-form-item :label="$t('commons.name')" prop="name">
<el-input v-model="form.name" autocomplete="off" />
<el-input v-model="form.name" autocomplete="off"/>
</el-form-item>
<el-form-item :label="$t('commons.description')" prop="desc">
<el-input v-model="form.desc" autocomplete="off" />
<el-input v-model="form.desc" autocomplete="off"/>
</el-form-item>
<el-form-item :label="$t('datasource.type')" prop="type">
<el-select v-model="form.type" :placeholder="$t('datasource.please_choose_type')" class="select-width" :disabled="formType=='modify' || (formType==='add' && params && !!params.type)" @change="changeType()">
<el-select v-model="form.type" :placeholder="$t('datasource.please_choose_type')" class="select-width"
:disabled="formType=='modify' || (formType==='add' && params && !!params.type)"
@change="changeType()">
<el-option
v-for="item in allTypes"
:key="item.name"
@ -24,40 +30,49 @@
</el-select>
</el-form-item>
<el-form-item v-if="form.configuration.dataSourceType=='jdbc'" :label="$t('datasource.host')" prop="configuration.host">
<el-input v-model="form.configuration.host" autocomplete="off" />
<el-form-item v-if="form.configuration.dataSourceType=='jdbc'" :label="$t('datasource.host')"
prop="configuration.host">
<el-input v-model="form.configuration.host" autocomplete="off"/>
</el-form-item>
<el-form-item v-if="form.configuration.dataSourceType=='es'" :label="$t('datasource.datasource_url')" prop="configuration.url">
<el-input v-model="form.configuration.url" :placeholder="$t('datasource.please_input_datasource_url')" autocomplete="off" />
<el-form-item v-if="form.configuration.dataSourceType=='es'" :label="$t('datasource.datasource_url')"
prop="configuration.url">
<el-input v-model="form.configuration.url" :placeholder="$t('datasource.please_input_datasource_url')"
autocomplete="off"/>
</el-form-item>
<el-form-item v-if="form.configuration.dataSourceType=='jdbc'" :label="$t('datasource.data_base')" prop="configuration.dataBase">
<el-input v-model="form.configuration.dataBase" autocomplete="off" />
<el-form-item v-if="form.configuration.dataSourceType=='jdbc'" :label="$t('datasource.data_base')"
prop="configuration.dataBase">
<el-input v-model="form.configuration.dataBase" autocomplete="off"/>
</el-form-item>
<el-form-item v-if="form.type=='oracle'" :label="$t('datasource.oracle_connection_type')" prop="configuration.connectionType">
<el-form-item v-if="form.type=='oracle'" :label="$t('datasource.oracle_connection_type')"
prop="configuration.connectionType">
<el-radio v-model="form.configuration.connectionType" label="sid">{{ $t('datasource.oracle_sid') }}</el-radio>
<el-radio v-model="form.configuration.connectionType" label="serviceName">{{ $t('datasource.oracle_service_name') }}</el-radio>
<el-radio v-model="form.configuration.connectionType" label="serviceName">
{{ $t('datasource.oracle_service_name') }}
</el-radio>
</el-form-item>
<el-form-item v-if="form.configuration.dataSourceType=='jdbc'" :label="$t('datasource.user_name')">
<el-input v-model="form.configuration.username" autocomplete="off" />
<el-input v-model="form.configuration.username" autocomplete="off"/>
</el-form-item>
<el-form-item v-if="form.configuration.dataSourceType=='jdbc'" :label="$t('datasource.password')">
<el-input v-model="form.configuration.password" autocomplete="off" show-password />
<el-input v-model="form.configuration.password" autocomplete="off" show-password/>
</el-form-item>
<el-form-item v-if="form.configuration.dataSourceType=='es'" :label="$t('datasource.user_name')" >
<el-input v-model="form.configuration.esUsername" autocomplete="off" />
<el-form-item v-if="form.configuration.dataSourceType=='es'" :label="$t('datasource.user_name')">
<el-input v-model="form.configuration.esUsername" autocomplete="off"/>
</el-form-item>
<el-form-item v-if="form.configuration.dataSourceType=='es'" :label="$t('datasource.password')" >
<el-input v-model="form.configuration.esPassword" autocomplete="off" show-password />
<el-form-item v-if="form.configuration.dataSourceType=='es'" :label="$t('datasource.password')">
<el-input v-model="form.configuration.esPassword" autocomplete="off" show-password/>
</el-form-item>
<el-form-item v-if="form.configuration.dataSourceType=='jdbc' && form.type!=='oracle'" :label="$t('datasource.extra_params')" >
<el-input v-model="form.configuration.extraParams" autocomplete="off" />
<el-form-item v-if="form.configuration.dataSourceType=='jdbc' && form.type!=='oracle'"
:label="$t('datasource.extra_params')">
<el-input v-model="form.configuration.extraParams" autocomplete="off"/>
</el-form-item>
<el-form-item v-if="form.configuration.dataSourceType=='jdbc'" :label="$t('datasource.port')" prop="configuration.port" >
<el-input v-model="form.configuration.port" autocomplete="off" type="number" min="0" />
<el-form-item v-if="form.configuration.dataSourceType=='jdbc'" :label="$t('datasource.port')"
prop="configuration.port">
<el-input v-model="form.configuration.port" autocomplete="off" type="number" min="0"/>
</el-form-item>
<el-form-item v-if="form.type=='oracle' || form.type=='sqlServer' || form.type=='pg' || form.type=='redshift'">
<el-button icon="el-icon-plus" size="mini" @click="getSchema()">
@ -65,8 +80,10 @@
</el-button>
</el-form-item>
<el-form-item v-if="form.type=='oracle' || form.type=='sqlServer' || form.type=='pg' || form.type=='redshift'" :label="$t('datasource.schema')">
<el-select filterable v-model="form.configuration.schema" :placeholder="$t('datasource.please_choose_schema')" class="select-width">
<el-form-item v-if="form.type=='oracle' || form.type=='sqlServer' || form.type=='pg' || form.type=='redshift'"
:label="$t('datasource.schema')">
<el-select filterable v-model="form.configuration.schema" :placeholder="$t('datasource.please_choose_schema')"
class="select-width">
<el-option
v-for="item in schemas"
:key="item"
@ -77,27 +94,35 @@
</el-form-item>
<el-collapse v-if="form.configuration.dataSourceType=='jdbc'">
<el-collapse-item :title="$t('datasource.priority')" name="1">
<el-form-item :label="$t('datasource.initial_pool_size')" prop="configuration.initialPoolSize">
<el-input v-model="form.configuration.initialPoolSize" autocomplete="off" type="number" min="0" size="small" />
<el-input v-model="form.configuration.initialPoolSize" autocomplete="off" type="number" min="0"
size="small"/>
</el-form-item>
<el-form-item :label="$t('datasource.min_pool_size')" prop="configuration.minPoolSize">
<el-input v-model="form.configuration.minPoolSize" autocomplete="off" type="number" min="0" />
<el-input v-model="form.configuration.minPoolSize" autocomplete="off" type="number" min="0"/>
</el-form-item>
<el-form-item :label="$t('datasource.max_pool_size')" prop="configuration.maxPoolSize">
<el-input v-model="form.configuration.maxPoolSize" autocomplete="off" type="number" min="0" />
<el-input v-model="form.configuration.maxPoolSize" autocomplete="off" type="number" min="0"/>
</el-form-item>
</el-collapse-item>
</el-collapse>
</el-form>
<div v-if="canEdit" slot="footer" class="dialog-footer">
<el-button v-if="formType==='add'?true: hasDataPermission('manage',params.privileges)" @click="validaDatasource">{{ $t('commons.validate') }}</el-button>
<el-button v-if="formType==='add'?true: hasDataPermission('manage',params.privileges)" type="primary" @click="save">{{ $t('commons.save') }}</el-button>
<el-button v-if="formType==='add'?true: hasDataPermission('manage',params.privileges)"
@click="validaDatasource">{{ $t('commons.validate') }}
</el-button>
<el-button v-if="formType==='add'?true: hasDataPermission('manage',params.privileges)" type="primary"
@click="save">{{ $t('commons.save') }}
</el-button>
</div>
<div v-else slot="footer" class="dialog-footer">
<el-button v-if="formType==='add'?true: hasDataPermission('manage',params.privileges)" @click="validaDatasource">{{ $t('commons.validate') }}</el-button>
<el-button v-if="formType==='add'?true: hasDataPermission('manage',params.privileges)" type="primary" @click="changeEdit">{{ $t('commons.edit') }}</el-button>
<el-button v-if="formType==='add'?true: hasDataPermission('manage',params.privileges)"
@click="validaDatasource">{{ $t('commons.validate') }}
</el-button>
<el-button v-if="formType==='add'?true: hasDataPermission('manage',params.privileges)" type="primary"
@click="changeEdit">{{ $t('commons.edit') }}
</el-button>
</div>
</div>
</layout-content>
@ -105,12 +130,12 @@
<script>
import LayoutContent from '@/components/business/LayoutContent'
import { addDs, editDs, getSchema, validateDs, validateDsById } from '@/api/system/datasource'
import { $confirm } from '@/utils/message'
import {addDs, editDs, getSchema, validateDs, validateDsById} from '@/api/system/datasource'
import {$confirm} from '@/utils/message'
export default {
name: 'DsForm',
components: { LayoutContent },
components: {LayoutContent},
props: {
params: {
type: Object,
@ -132,37 +157,92 @@ export default {
}
},
rule: {
name: [{ required: true, message: this.$t('datasource.input_name'), trigger: 'blur' },
{ min: 2, max: 25, message: this.$t('datasource.input_limit_2_25', [2, 25]), trigger: 'blur' }],
desc: [{ min: 0, max: 50, message: this.$t('datasource.input_limit_0_50'), trigger: 'blur' }],
type: [{ required: true, message: this.$t('datasource.please_choose_type'), trigger: 'change' }],
'configuration.dataBase': [{ required: true, message: this.$t('datasource.please_input_data_base'), trigger: 'blur' }],
'configuration.connectionType': [{ required: true, message: this.$t('datasource.please_select_oracle_type'), trigger: 'blur' }],
'configuration.username': [{ required: true, message: this.$t('datasource.please_input_user_name'), trigger: 'blur' }],
'configuration.password': [{ required: true, message: this.$t('datasource.please_input_password'), trigger: 'change' }],
'configuration.host': [{ required: true, message: this.$t('datasource.please_input_host'), trigger: 'change' }],
'configuration.url': [{ required: true, message: this.$t('datasource.please_input_url'), trigger: 'change' }],
'configuration.port': [{ required: true, message: this.$t('datasource.please_input_port'), trigger: 'change' }],
'configuration.initialPoolSize': [{ required: true, message: this.$t('datasource.please_input_initial_pool_size'), trigger: 'change' }],
'configuration.minPoolSize': [{ required: true, message: this.$t('datasource.please_input_min_pool_size'), trigger: 'change' }],
'configuration.maxPoolSize': [{ required: true, message: this.$t('datasource.please_input_max_pool_size'), trigger: 'change' }],
'configuration.maxIdleTime': [{ required: true, message: this.$t('datasource.please_input_max_idle_time'), trigger: 'change' }],
'configuration.acquireIncrement': [{ required: true, message: this.$t('datasource.please_input_acquire_increment'), trigger: 'change' }],
'configuration.connectTimeout': [{ required: true, message: this.$t('datasource.please_input_connect_timeout'), trigger: 'change' }]
name: [{required: true, message: this.$t('datasource.input_name'), trigger: 'blur'},
{min: 2, max: 25, message: this.$t('datasource.input_limit_2_25', [2, 25]), trigger: 'blur'}],
desc: [{min: 0, max: 50, message: this.$t('datasource.input_limit_0_50'), trigger: 'blur'}],
type: [{required: true, message: this.$t('datasource.please_choose_type'), trigger: 'change'}],
'configuration.dataBase': [{
required: true,
message: this.$t('datasource.please_input_data_base'),
trigger: 'blur'
}],
'configuration.connectionType': [{
required: true,
message: this.$t('datasource.please_select_oracle_type'),
trigger: 'blur'
}],
'configuration.username': [{
required: true,
message: this.$t('datasource.please_input_user_name'),
trigger: 'blur'
}],
'configuration.password': [{
required: true,
message: this.$t('datasource.please_input_password'),
trigger: 'change'
}],
'configuration.host': [{required: true, message: this.$t('datasource.please_input_host'), trigger: 'change'}],
'configuration.url': [{required: true, message: this.$t('datasource.please_input_url'), trigger: 'change'}],
'configuration.port': [{required: true, message: this.$t('datasource.please_input_port'), trigger: 'change'}],
'configuration.initialPoolSize': [{
required: true,
message: this.$t('datasource.please_input_initial_pool_size'),
trigger: 'change'
}],
'configuration.minPoolSize': [{
required: true,
message: this.$t('datasource.please_input_min_pool_size'),
trigger: 'change'
}],
'configuration.maxPoolSize': [{
required: true,
message: this.$t('datasource.please_input_max_pool_size'),
trigger: 'change'
}],
'configuration.maxIdleTime': [{
required: true,
message: this.$t('datasource.please_input_max_idle_time'),
trigger: 'change'
}],
'configuration.acquireIncrement': [{
required: true,
message: this.$t('datasource.please_input_acquire_increment'),
trigger: 'change'
}],
'configuration.connectTimeout': [{
required: true,
message: this.$t('datasource.please_input_connect_timeout'),
trigger: 'change'
}]
},
allTypes: [
{ name: 'mysql', label: 'MySQL', type: 'jdbc', extraParams: 'characterEncoding=UTF-8&connectTimeout=5000&useSSL=false&allowPublicKeyRetrieval=true'},
{ name: 'hive', label: 'Apache Hive', type: 'jdbc', extraParams: ''},
{ name: 'oracle', label: 'Oracle', type: 'jdbc'},
{ name: 'sqlServer', label: 'SQL Server', type: 'jdbc', extraParams: ''},
{ name: 'pg', label: 'PostgreSQL', type: 'jdbc', extraParams: '' },
{ name: 'es', label: 'Elasticsearch', type: 'es' },
{ name: 'mariadb', label: 'MariaDB', type: 'jdbc', extraParams: 'characterEncoding=UTF-8&connectTimeout=5000&useSSL=false&allowPublicKeyRetrieval=true' },
{ name: 'ds_doris', label: 'Doris', type: 'jdbc', extraParams: 'characterEncoding=UTF-8&connectTimeout=5000&useSSL=false&allowPublicKeyRetrieval=true' },
{ name: 'ck', label: 'ClickHouse', type: 'jdbc', extraParams: '' },
{ name: 'redshift', label: 'AWS Redshift', type: 'jdbc' },
{ name: 'mongo', label: 'MongoDB', type: 'jdbc', extraParams: '' }
],
{
name: 'mysql',
label: 'MySQL',
type: 'jdbc',
extraParams: 'characterEncoding=UTF-8&connectTimeout=5000&useSSL=false&allowPublicKeyRetrieval=true'
},
{name: 'hive', label: 'Apache Hive', type: 'jdbc', extraParams: ''},
{name: 'oracle', label: 'Oracle', type: 'jdbc'},
{name: 'sqlServer', label: 'SQL Server', type: 'jdbc', extraParams: ''},
{name: 'pg', label: 'PostgreSQL', type: 'jdbc', extraParams: ''},
{name: 'es', label: 'Elasticsearch', type: 'es'},
{
name: 'mariadb',
label: 'MariaDB',
type: 'jdbc',
extraParams: 'characterEncoding=UTF-8&connectTimeout=5000&useSSL=false&allowPublicKeyRetrieval=true'
},
{
name: 'ds_doris',
label: 'Doris',
type: 'jdbc',
extraParams: 'characterEncoding=UTF-8&connectTimeout=5000&useSSL=false&allowPublicKeyRetrieval=true'
},
{name: 'ck', label: 'ClickHouse', type: 'jdbc', extraParams: ''},
{name: 'redshift', label: 'AWS Redshift', type: 'jdbc'},
{name: 'mongo', label: 'MongoDB', type: 'jdbc', extraParams: ''}
],
schemas: [],
canEdit: false,
originConfiguration: {}
@ -315,7 +395,7 @@ export default {
}
},
backToList() {
this.$emit('switch-component', { })
this.$emit('switch-component', {})
},
refreshType(form) {
this.$emit('refresh-type', form)
@ -338,6 +418,7 @@ export default {
.el-input {
width: 300px;
}
.el-select {
width: 300px;
}

View File

@ -1,8 +1,7 @@
<template>
<!-- <de-container v-loading="$store.getters.loadingMap[$store.getters.currentPath]" style="background-color: #f7f8fa"> -->
<de-container v-loading="$store.getters.loadingMap[$store.getters.currentPath]">
<de-main-container>
<ds-main ref="dsMain" />
<ds-main ref="dsMain"/>
</de-main-container>
</de-container>
</template>
@ -12,9 +11,10 @@ import DeMainContainer from '@/components/dataease/DeMainContainer'
import DeContainer from '@/components/dataease/DeContainer'
import DsMain from './DsMain'
import bus from '@/utils/bus'
export default {
name: 'Panel',
components: { DeMainContainer, DeContainer, DsMain },
components: {DeMainContainer, DeContainer, DsMain},
data() {
return {
component: DsMain,
@ -40,9 +40,6 @@ export default {
if (panelShareTypeIds.includes(routerParam.msgType)) { //
if (routerParam.sourceParam) {
try {
// const msgParam = JSON.parse(routerParam.sourceParam)
// this.param = msgParam.id
// this.component = ViewTable
this.$nextTick(() => {
this.$refs.dsMain && this.$refs.dsMain.msg2Current && this.$refs.dsMain.msg2Current(routerParam.sourceParam)
})
@ -58,16 +55,5 @@ export default {
</script>
<style scoped>
.ms-aside-container {
height: calc(100vh - 56px);
padding: 0px;
min-width: 260px;
max-width: 460px;
}
.ms-main-container {
height: calc(100vh - 56px);
padding: 0;
}
</style>

View File

@ -1,286 +0,0 @@
<template>
<layout-content v-loading="$store.getters.loadingMap[$store.getters.currentPath]">
<complex-table
:data="data"
:columns="columns"
:search-config="searchConfig"
:pagination-config="paginationConfig"
@select="select"
@search="search"
>
<template #toolbar>
<!-- <fu-table-button v-permission="['datasource:add']" icon="el-icon-circle-plus-outline" :label="$t('datasource.create')" @click="create" /> -->
<el-button v-permission="['datasource:add']" icon="el-icon-circle-plus-outline" @click="create">{{ $t('datasource.create') }}</el-button>
</template>
<!-- <el-table-column type="selection" fix /> -->
<el-table-column prop="name" :label="$t('commons.name')" />
<el-table-column prop="desc" :label="$t('commons.description')" />
<el-table-column prop="type" :label="$t('datasource.type')">
<template slot-scope="scope">
<span v-if="scope.row.type ==='mysql'">MySQL</span>
<span v-if="scope.row.type ==='sqlServer'">SQL Server</span>
</template>
</el-table-column>
<fu-table-operations :buttons="buttons" :label="$t('commons.operating')" fix />
</complex-table>
<!-- add datasource form -->
<el-dialog
:close-on-click-modal="false"
:title="formType=='add' ? $t('datasource.create') : $t('datasource.modify')"
:visible.sync="dialogVisible"
width="30%"
:destroy-on-close="true"
@closed="closeFunc"
>
<el-form ref="createDatasource" :model="form" label-position="right" label-width="100px" size="small">
<el-form-item
:label="$t('commons.name')"
prop="name"
:rules="[{required: true, message: this.$t('datasource.input_name'), trigger: 'blur'},
{min: 2, max: 25, message: this.$t('commons.input_limit', [2, 25]), trigger: 'blur'}]"
>
<el-input v-model="form.name" autocomplete="off" />
</el-form-item>
<el-form-item
:label="$t('commons.description')"
prop="desc"
:rules="[{required: true, message: this.$t('datasource.input_desc'), trigger: 'blur'},
{min: 2, max: 50, message: this.$t('commons.input_limit', [2, 50]), trigger: 'blur'}]"
>
<el-input v-model="form.desc" autocomplete="off" type="textarea" />
</el-form-item>
<el-form-item :label="$t('datasource.type')" prop="type" :rules="{required: true, message: $t('datasource.please_choose_type'), trigger: 'change'}">
<el-select v-model="form.type" :placeholder="$t('datasource.please_choose_type')" class="select-width" @change="changeType()">
<el-option
v-for="item in allTypes"
:key="item.name"
:label="item.name"
:value="item.name"
/>
</el-select>
</el-form-item>
<el-form-item v-show="form.configuration.dataSourceType=='jdbc'" :label="$t('datasource.data_base')" prop="configuration.dataBase" :rules="{required: true, message: $t('datasource.please_input_data_base'), trigger: 'blur'}">
<el-input v-model="form.configuration.dataBase" autocomplete="off" />
</el-form-item>
<el-form-item v-show="form.configuration.dataSourceType=='jdbc'" :label="$t('datasource.user_name')" prop="configuration.username" :rules="{required: true, message: $t('datasource.please_input_user_name'), trigger: 'blur'}">
<el-input v-model="form.configuration.username" autocomplete="off" />
</el-form-item>
<el-form-item v-show="form.configuration.dataSourceType=='jdbc'" :label="$t('datasource.password')" prop="configuration.password" :rules="{required: true, message: $t('datasource.please_input_password'), trigger: 'change'}">
<el-input v-model="form.configuration.password" autocomplete="off" />
</el-form-item>
<el-form-item v-show="form.configuration.dataSourceType=='jdbc'" :label="$t('datasource.host')" prop="configuration.host" :rules="{required: true, message: $t('datasource.please_input_host'), trigger: 'change'}">
<el-input v-model="form.configuration.host" autocomplete="off" />
</el-form-item>
<el-form-item v-show="form.configuration.dataSourceType=='jdbc'" :label="$t('datasource.port')" prop="configuration.port" :rules="{required: true, message: $t('datasource.please_input_port'), trigger: 'change'}">
<el-input v-model="form.configuration.port" autocomplete="off" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="dialogVisible = false">{{ $t('commons.cancel') }}</el-button>
<el-button type="primary" @click="validaDatasource('createDatasource')">{{ $t('commons.validate') }}</el-button>
<el-button type="primary" @click="saveDatasource('createDatasource')">{{ $t('commons.confirm') }}</el-button>
</div>
</el-dialog>
</layout-content>
</template>
<script>
import LayoutContent from '@/components/business/LayoutContent'
import ComplexTable from '@/components/business/complex-table'
import { hasDataPermission } from '@/utils/permission'
import { formatCondition } from '@/utils/index'
import { dsGrid, addDs, editDs, delDs, validateDs } from '@/api/system/datasource'
export default {
name: 'DEDatasource',
components: {
LayoutContent,
ComplexTable
},
data() {
return {
formType: 'add',
dialogVisible: false,
data: [],
form: { configuration: {}},
allTypes: [{ name: 'mysql', type: 'jdbc' }, { name: 'sqlServer', type: 'jdbc' }],
rule: {
name: [
{ required: true, message: this.$t('organization.input_name'), trigger: 'blur' },
{ min: 2, max: 25, message: this.$t('commons.input_limit', [2, 25]), trigger: 'blur' }
],
desc: [
{ required: true, message: this.$t('organization.input_name'), trigger: 'blur' },
{ max: 50, message: this.$t('commons.input_limit', [0, 50]), trigger: 'blur' }
]
},
header: '',
columns: [],
buttons: [
{
label: this.$t('commons.edit'), icon: 'el-icon-edit', type: 'primary', click: this.edit,
show: true,
disabled: (row) => {
return !hasDataPermission('manage', row.privileges)
}
}, {
label: this.$t('commons.delete'), icon: 'el-icon-delete', type: 'danger', click: this._handleDelete,
show: true,
disabled: (row) => {
return !hasDataPermission('manage', row.privileges)
}
}
],
searchConfig: {
useQuickSearch: true,
quickPlaceholder: this.$t('commons.search_by_name'),
combine: false,
components: [
{ field: 'name', label: this.$t('commons.name'), component: 'FuComplexInput' },
{
field: 'type',
label: this.$t('datasource.type'),
component: 'FuComplexSelect',
options: [{ label: 'MySQL', value: 'mysql' }, { label: 'SQL Server', value: 'sqlServer' }],
multiple: false
}
// { field: 'deptId', label: '', component: conditionTable }
]
},
paginationConfig: {
currentPage: 1,
pageSize: 10,
total: 0
}
}
},
mounted() {
this.search()
},
methods: {
select(selection) {
// console.log(selection)
},
// create() {
// this.formType = 'add'
// this.dialogVisible = true
// },
create() {
this.$router.push({ name: 'datasource-form' })
},
// edit(row) {
// this.formType = 'modify'
// this.dialogVisible = true
// this.form = Object.assign({}, row)
// this.form.configuration = JSON.parse(this.form.configuration)
// },
edit(row) {
this.$router.push({ name: 'datasource-form', params: row })
},
_handleDelete(datasource) {
this.$confirm(this.$t('datasource.delete_warning'), '', {
confirmButtonText: this.$t('commons.confirm'),
cancelButtonText: this.$t('commons.cancel'),
type: 'warning'
}).then(() => {
delDs(datasource.id).then(res => {
this.$success(this.$t('commons.delete_success'))
this.search()
})
}).catch(() => {
this.$message({
type: 'info',
message: this.$t('commons.delete_cancelled')
})
})
},
saveDatasource(createDatasourceForm) {
this.$refs[createDatasourceForm].validate(valid => {
if (valid) {
const method = this.formType === 'add' ? addDs : editDs
this.form.configuration = JSON.stringify(this.form.configuration)
method(this.form).then(res => {
this.$success(this.$t('commons.save_success'))
this.search()
this.dialogVisible = false
})
} else {
return false
}
})
},
validaDatasource(datasourceForm) {
this.$refs[datasourceForm].validate(valid => {
if (valid) {
const data = JSON.parse(JSON.stringify(this.form))
data.configuration = JSON.stringify(data.configuration)
validateDs(data).then(res => {
this.$success(this.$t('datasource.validate_success'))
})
} else {
return false
}
})
},
changeType() {
for (let i = 0; i < this.allTypes.length; i++) {
if (this.allTypes[i].name === this.form.type) {
this.form.configuration.dataSourceType = this.allTypes[i].type
}
}
},
quick_condition(condition) {
const result = {}
if (condition && condition.quick) {
for (const [key, value] of Object.entries(condition)) {
if (`${key}` === 'quick') {
const v_new = Object.assign({}, value)
v_new['field'] = 'name'
result['name'] = v_new
} else {
result[`${key}`] = value
}
}
return result
}
return Object.assign({}, condition)
},
search(condition) {
const temp_param = this.quick_condition(condition)
const temp = formatCondition(temp_param)
const param = temp || {}
const { currentPage, pageSize } = this.paginationConfig
dsGrid(currentPage, pageSize, param).then(response => {
this.data = response.data.listObject
this.paginationConfig.total = response.data.itemCount
})
},
closeFunc() {
this.formType = 'add'
// this.search()
this.form = { configuration: {}}
this.dialogVisible = false
}
}
}
</script>
<style scoped>
</style>