diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..4e1edd14 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = tab +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false diff --git a/.gitignore b/.gitignore index 5d947ca8..af757930 100644 --- a/.gitignore +++ b/.gitignore @@ -1,18 +1,25 @@ -# Build and Release Folders -bin-debug/ -bin-release/ -[Oo]bj/ -[Bb]in/ +.DS_Store +node_modules +/dist -# Other files and folders -.settings/ -# Executables -*.swf -*.air -*.ipa -*.apk +# local env files +.env.local +.env.*.local -# Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties` -# should NOT be excluded as they contain compiler settings and other important -# information for Eclipse / Flash Builder. +# Log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +package-lock.json \ No newline at end of file diff --git a/README.en.md b/README.en.md deleted file mode 100644 index 2c500233..00000000 --- a/README.en.md +++ /dev/null @@ -1,36 +0,0 @@ -# SCUI - -#### Description -SCUI - -#### Software Architecture -Software architecture description - -#### Installation - -1. xxxx -2. xxxx -3. xxxx - -#### Instructions - -1. xxxx -2. xxxx -3. xxxx - -#### Contribution - -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request - - -#### Gitee Feature - -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) -4. The most valuable open source project [GVP](https://gitee.com/gvp) -5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 00000000..e9558405 --- /dev/null +++ b/babel.config.js @@ -0,0 +1,5 @@ +module.exports = { + presets: [ + '@vue/cli-plugin-babel/preset' + ] +} diff --git a/package.json b/package.json new file mode 100644 index 00000000..236011e9 --- /dev/null +++ b/package.json @@ -0,0 +1,54 @@ +{ + "name": "element-plus-starter", + "version": "0.1.0", + "private": true, + "scripts": { + "serve": "vue-cli-service serve", + "build": "vue-cli-service build", + "lint": "vue-cli-service lint" + }, + "dependencies": { + "axios": "^0.21.0", + "core-js": "^3.6.5", + "element-plus": "latest", + "less": "^3.12.2", + "less-loader": "^7.1.0", + "nprogress": "^0.2.0", + "vue": "^3.0.0", + "vue-router": "^4.0.0-0", + "vuex": "^4.0.0-0" + }, + "devDependencies": { + "@vue/cli-plugin-babel": "~4.5.0", + "@vue/cli-plugin-eslint": "~4.5.0", + "@vue/cli-service": "~4.5.0", + "@vue/compiler-sfc": "^3.0.0", + "babel-eslint": "^10.1.0", + "eslint": "^6.7.2", + "eslint-plugin-vue": "^7.0.0-0" + }, + "eslintConfig": { + "root": true, + "env": { + "node": true + }, + "extends": [ + "plugin:vue/vue3-essential", + "eslint:recommended" + ], + "parserOptions": { + "parser": "babel-eslint" + }, + "rules": { + "indent": 0, + "no-tabs": 0, + "no-mixed-spaces-and-tabs": 0, + "vue/no-unused-components": "off" + } + }, + "browserslist": [ + "> 1%", + "last 2 versions", + "not dead" + ] +} diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 00000000..2d1691e9 Binary files /dev/null and b/public/favicon.ico differ diff --git a/public/index.html b/public/index.html new file mode 100644 index 00000000..c2ef4d60 --- /dev/null +++ b/public/index.html @@ -0,0 +1,18 @@ + + + + + + + + Welcome to Element Plus + + + +
+ + + diff --git a/public/json/user.json b/public/json/user.json new file mode 100644 index 00000000..881cb815 --- /dev/null +++ b/public/json/user.json @@ -0,0 +1,68 @@ +{ + "code": 200, + "data": { + "userInfo" : { + "userName":"Admin" + }, + "menuList" : [ + { + "name": "组件", + "path": "/vab", + "meta": { + "icon":"el-icon-takeaway-box" + }, + "children": [ + { + "path": "/vab/list", + "name": "列表", + "meta": {}, + "component": "list" + }, + { + "path": "/vab/show", + "name": "详情", + "meta": {}, + "component": "show" + }, + { + "path": "/vab/lala", + "name": "404", + "meta": {}, + "component": "lala" + } + ] + }, + { + "name": "其他", + "path": "/other", + "meta": { + "icon":"el-icon-more" + }, + "children": [ + { + "path": "/other/1", + "name": "other1", + "meta": {}, + "component": "list" + } + ] + }, + { + "name": "配置", + "path": "/setting", + "meta": { + "icon":"el-icon-setting" + }, + "children": [ + { + "path": "/setting/1", + "name": "setting1", + "meta": {}, + "component": "lala" + } + ] + } + ] + }, + "message": "" +} diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 00000000..7aa61808 --- /dev/null +++ b/src/App.vue @@ -0,0 +1,14 @@ + + + + + \ No newline at end of file diff --git a/src/api/index.js b/src/api/index.js new file mode 100644 index 00000000..5cb2466d --- /dev/null +++ b/src/api/index.js @@ -0,0 +1,13 @@ +import config from "@/config"; +import http from "@/utils/request"; + + +const api = { + user: { + info: async function(){ + return await http.get(`${config.apiUrl}/json/user.json`); + } + } +} + +export default api; diff --git a/src/assets/logo.png b/src/assets/logo.png new file mode 100644 index 00000000..ed6cb27e Binary files /dev/null and b/src/assets/logo.png differ diff --git a/src/components/HelloWorld.vue b/src/components/HelloWorld.vue new file mode 100644 index 00000000..d1674196 --- /dev/null +++ b/src/components/HelloWorld.vue @@ -0,0 +1,32 @@ + + + + + + diff --git a/src/config/index.js b/src/config/index.js new file mode 100644 index 00000000..5b3dbdd0 --- /dev/null +++ b/src/config/index.js @@ -0,0 +1,14 @@ +module.exports = { + //标题 + title: "VUE", + //版本号 + version: "1.0", + //接口地址 + apiUrl: "", + //是否开启多标签 + tags: false, + //布局 + layout: "default", + //主题 + theme: "default", +}; diff --git a/src/layout/components/NavMenu.vue b/src/layout/components/NavMenu.vue new file mode 100644 index 00000000..72cb595e --- /dev/null +++ b/src/layout/components/NavMenu.vue @@ -0,0 +1,27 @@ + + + \ No newline at end of file diff --git a/src/layout/components/head.vue b/src/layout/components/head.vue new file mode 100644 index 00000000..d93c5943 --- /dev/null +++ b/src/layout/components/head.vue @@ -0,0 +1,14 @@ + + + diff --git a/src/layout/components/side.vue b/src/layout/components/side.vue new file mode 100644 index 00000000..98c71fa9 --- /dev/null +++ b/src/layout/components/side.vue @@ -0,0 +1,80 @@ + + + diff --git a/src/layout/components/tags.vue b/src/layout/components/tags.vue new file mode 100644 index 00000000..225413e1 --- /dev/null +++ b/src/layout/components/tags.vue @@ -0,0 +1,170 @@ + + + + + diff --git a/src/layout/index.vue b/src/layout/index.vue new file mode 100644 index 00000000..cb2af925 --- /dev/null +++ b/src/layout/index.vue @@ -0,0 +1,32 @@ + + + diff --git a/src/main.js b/src/main.js new file mode 100644 index 00000000..a8c5a124 --- /dev/null +++ b/src/main.js @@ -0,0 +1,20 @@ +import ElementPlus from 'element-plus' +import 'element-plus/lib/theme-chalk/index.css' +import { createApp } from 'vue' +import App from './App.vue' +import config from "./config"; +import router from './router' +import store from './store' +import tool from './utils/tool' +import api from './api' + +const app = createApp(App); + +app.config.globalProperties.$CONFIG = config; +app.config.globalProperties.$TOOL = tool; +app.config.globalProperties.$API = api; + +app.use(store); +app.use(router); +app.use(ElementPlus, { size: 'small', zIndex: 3000 }); +app.mount('#app'); diff --git a/src/router/index.js b/src/router/index.js new file mode 100644 index 00000000..31a33240 --- /dev/null +++ b/src/router/index.js @@ -0,0 +1,126 @@ +import {createRouter, createWebHashHistory} from 'vue-router'; +import { ElNotification } from 'element-plus'; +import NProgress from 'nprogress' +import 'nprogress/nprogress.css' +import tool from '@/utils/tool'; + +//系统路由 +const routes = [{ + path: "/", + name: "layout", + component: () => import(/* webpackChunkName: "layout" */ '@/layout'), + redirect: '/dashboard', + children: [ + { + path: "/home", + name: "首页", + component: () => import(`@/views/other/empty`), + meta: { + icon: "el-icon-platform-eleme" + }, + children: [ + { + path: "/dashboard", + name: "控制台", + meta: { + affix: true + }, + component: () => import(/* webpackChunkName: "home" */ '@/views/home'), + } + ] + } + ] + }, + { + path: "/login", + name: "登录", + component: () => import(/* webpackChunkName: "login" */ '@/views/login'), + } +] + +//系统路由 +const routes_404 = { + path: "/:pathMatch(.*)*", + name: "404", + hidden: true, + component: () => import(/* webpackChunkName: "404" */ '@/views/other/404'), +} + +const router = createRouter({ + history: createWebHashHistory(), + routes: routes +}) + +//判断是否已加载过API路由 +var isGetApiRouter = false; + +router.beforeEach(async (to, from, next) => { + NProgress.start() + + let userInfo = tool.data.get("user"); + + if(to.path === "/login"){ + next(); + return false; + } + + if(!userInfo){ + next({ + path: '/login' + }); + return false; + } + + //加载API路由 + if(!isGetApiRouter){ + var apiRouter = filterAsyncRouter(userInfo.menuList); + apiRouter.forEach(item => { + router.addRoute("layout", item) + }) + router.addRoute(routes_404) + if (to.matched.length == 0) { + router.push(to.path); + } + isGetApiRouter = true; + } + next(); +}); + +router.afterEach(() => { + NProgress.done() +}); + +router.onError((error) => { + NProgress.done(); + ElNotification.error({ + title: '路由错误', + message: error + }); +}); + + +//转换 +function filterAsyncRouter(routerMap) { + const accessedRouters = [] + routerMap.filter(itemRouter => { + accessedRouters.push({ + path: itemRouter.path, + name: itemRouter.name, + meta: itemRouter.meta, + children: filterAsyncRouter(itemRouter.children || []), + component: loadComponent(itemRouter.component) + }) + }) + return accessedRouters +} +function loadComponent(component){ + if(component){ + return () => import(/* webpackChunkName: "[request]" */ `@/views/${component}`) + }else{ + return () => import(`@/views/other/empty`) + } + +} + + +export default router diff --git a/src/store/index.js b/src/store/index.js new file mode 100644 index 00000000..c5b3ede3 --- /dev/null +++ b/src/store/index.js @@ -0,0 +1,8 @@ +import { createStore } from 'vuex'; +import tagsView from './modules/tagsView'; + +export default createStore({ + modules: { + tagsView + } +}); diff --git a/src/store/modules/tagsView.js b/src/store/modules/tagsView.js new file mode 100644 index 00000000..3dd02ad8 --- /dev/null +++ b/src/store/modules/tagsView.js @@ -0,0 +1,24 @@ +export default { + state: { + visitedViews: [], + cachedViews: [] + }, + mutations: { + ADD_VISITED_VIEWS: (state, view) => { + if (state.visitedViews.some(v => v.path === view.path)) return + state.visitedViews.push(Object.assign({}, view, { + title: view.meta.title || 'no-name' + })) + if (!view.meta.noCache) { + state.cachedViews.push(view.name) + } + }, + }, + actions: { + addVisitedViews({ + commit + }, view) { + commit('ADD_VISITED_VIEWS', view) + }, + } +} diff --git a/src/style/style.less b/src/style/style.less new file mode 100644 index 00000000..c2c46acd --- /dev/null +++ b/src/style/style.less @@ -0,0 +1,47 @@ +#app, body, html {width: 100%;height: 100%;background-color: #f8f8f8;font-size: 12px;} +* {margin: 0;padding: 0;box-sizing: border-box;outline: none;} + +/* 全局滚动条样式 */ +.scrollable {-webkit-overflow-scrolling: touch;} +::-webkit-scrollbar {width: 5px;height: 5px;} +::-webkit-scrollbar-thumb {background-color: rgba(50, 50, 50, 0.3);} +::-webkit-scrollbar-thumb:hover {background-color: rgba(50, 50, 50, 0.6);} +::-webkit-scrollbar-track {background-color: rgba(50, 50, 50, 0.1);} +::-webkit-scrollbar-track:hover {background-color: rgba(50, 50, 50, 0.2);} + +.aminui-side-split {position: absolute;top:0px;left:0px;bottom:0px;width:65px;background: #333;z-index: 90;} +.adminui-side-split-scroll {position: absolute;top:0px;left:0px;bottom:0px;right:0px;overflow: auto;overflow-x:hidden;} +.aminui-side-split li {cursor: pointer;width: 65px;height: 65px;color: #fff;text-align: center;display: flex;flex-direction: column;align-items: center;justify-content: center;} +.aminui-side-split li i {font-size: 16px;} +.aminui-side-split li p {margin-top:5px;} +.aminui-side-split li:hover {background: #444;} +.aminui-side-split li.active {background: #09f;} + +.adminui-side-split-scroll::-webkit-scrollbar-thumb {background-color: rgba(255, 255, 255, 0.4);border-radius:5px;} +.adminui-side-split-scroll::-webkit-scrollbar-thumb:hover {background-color: rgba(255, 255, 255, 0.5);} +.adminui-side-split-scroll::-webkit-scrollbar-track {background-color: rgba(255, 255, 255, 0);} +.adminui-side-split-scroll::-webkit-scrollbar-track:hover {background-color: rgba(255, 255, 255, 0);} + + +.aminui-side {position: absolute;z-index: 80;top:0px;left:65px;bottom:0px;width:210px;background: #fff;box-shadow: 2px 0 8px 0 rgba(29,35,41,.05);border-right: 1px solid #e6e6e6;} +.adminui-side-scroll {position: absolute;top:0px;left:0px;bottom:0px;right:0px;overflow: auto;overflow-x:hidden;} + + +.aminui-body {position: absolute;z-index: 70;top:0px;left:275px;bottom:0px;right:0px;} + +.adminui-header {height: 50px;border-bottom: 1px solid #ebeef5;background: #fff;box-shadow: 0 1px 4px rgba(0,21,41,.08);} +.adminui-tags {height:35px;background: #fff;border-bottom: 1px solid #e6e6e6;box-shadow: 0 1px 4px rgba(0,21,41,.08);} +.adminui-tags li {cursor: pointer;display: inline-block;float: left;height:34px;line-height: 34px;} +.adminui-tags li a {display: inline-block;padding:0 10px;width:100%;height:100%;color: #999;text-decoration:none;} +.adminui-tags li i {margin-left:10px;padding:3px;} +.adminui-tags li i:hover {background: #ff5722;color: #fff;} +.adminui-tags li:hover {background: #ecf5ff;} +.adminui-tags li.active {background: #09f;} +.adminui-tags li.active a {color: #fff;} + + +.adminui-main {position: absolute;top:85px;left:0px;right:0px;bottom:0px;overflow: auto;} + + +.el-menu {border: none!important;} +.el-menu-item.is-active {background: #ecf5ff;} \ No newline at end of file diff --git a/src/utils/request.js b/src/utils/request.js new file mode 100644 index 00000000..cea0bce4 --- /dev/null +++ b/src/utils/request.js @@ -0,0 +1,78 @@ +import axios from 'axios'; +import { ElNotification } from 'element-plus'; + +axios.defaults.baseURL = '' + +axios.defaults.timeout = 10000 + +// HTTP request 拦截器 +axios.interceptors.request.use( + (config) => { + return config; + }, + (error) => { + return Promise.reject(error); + } +); + +// HTTP response 拦截器 +axios.interceptors.response.use( + (response) => { + return response; + }, + (error) => { + if(error.response.status == 404){ + ElNotification.error({ + title: '请求错误', + message: "Status:404,正在请求不存在的服务器记录!" + }); + } + if(error.response.status == 500){ + ElNotification.error({ + title: '请求错误', + message: "Status:500,服务器发生错误!" + }); + } + + return Promise.reject(error.response); + } +); + +var http = { + + /** get 请求 + * @param {接口地址} url + * @param {请求参数} params + */ + get: function(url, params) { + return new Promise((resolve, reject) => { + axios.get(url, { + params: params + }) + .then((response) => { + resolve(response.data); + }) + .catch((error) => { + reject(error); + }); + }) + }, + + /** post 请求 + * @param {接口地址} url + * @param {请求参数} params + */ + post: function(url, params) { + return new Promise((resolve, reject) => { + axios.post(url, params) + .then((response) => { + resolve(response.data); + }) + .catch((error) => { + reject(error); + }); + }) + } +} + +export default http; diff --git a/src/utils/tool.js b/src/utils/tool.js new file mode 100644 index 00000000..5725b87f --- /dev/null +++ b/src/utils/tool.js @@ -0,0 +1,20 @@ +const tool = { + /* localStorage */ + data : { + set : function(table, settings){ + var _set = JSON.stringify(settings) + return localStorage.setItem(table, _set); + }, + get : function(table){ + return JSON.parse(localStorage.getItem(table)); + }, + remove : function(table){ + return localStorage.removeItem(table); + }, + clear : function(){ + return localStorage.clear(); + } + } +} + +export default tool diff --git a/src/views/home.vue b/src/views/home.vue new file mode 100644 index 00000000..3c8cb80b --- /dev/null +++ b/src/views/home.vue @@ -0,0 +1,9 @@ + + + + + diff --git a/src/views/list.vue b/src/views/list.vue new file mode 100644 index 00000000..c9426247 --- /dev/null +++ b/src/views/list.vue @@ -0,0 +1,10 @@ + + + + + diff --git a/src/views/login.vue b/src/views/login.vue new file mode 100644 index 00000000..fd62fe1e --- /dev/null +++ b/src/views/login.vue @@ -0,0 +1,24 @@ + + + diff --git a/src/views/other/404.vue b/src/views/other/404.vue new file mode 100644 index 00000000..601c9249 --- /dev/null +++ b/src/views/other/404.vue @@ -0,0 +1,9 @@ + + + + + diff --git a/src/views/other/empty.vue b/src/views/other/empty.vue new file mode 100644 index 00000000..9c72bc89 --- /dev/null +++ b/src/views/other/empty.vue @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/src/views/show.vue b/src/views/show.vue new file mode 100644 index 00000000..72fd5fd7 --- /dev/null +++ b/src/views/show.vue @@ -0,0 +1,20 @@ + + + + + \ No newline at end of file