提交 bf7c8bb3 authored 作者: taojinlong's avatar taojinlong

refactor: 整理代码

上级 9e87a08a
# 项目说明
> 这是一个极简的 vue admin 管理后台,基于vue-admin-template进行了细节改造,主要是把侧边导航改造为了顶部和侧边两个导航。
>
> 本项目默认开启了css:sourceMap和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)
......@@ -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
......
......@@ -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 {
......
{
"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",
......
<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() {
}
......
......@@ -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 = {
......
......@@ -7,7 +7,6 @@
</template>
<script>
// import Axios from 'axios'
import { get } from '@/api/system/dynamic'
......
......@@ -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 {}
},
......
......@@ -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'
......
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
......
......@@ -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>
<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>
......@@ -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>
<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>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论