├── front-end ├── run-build.sh ├── postcss.config.js ├── src │ ├── assets │ │ ├── imgs │ │ │ ├── login-bg.jpg │ │ │ └── logo.svg │ │ └── css │ │ │ ├── common.scss │ │ │ └── admin.scss │ ├── views │ │ ├── pages │ │ │ └── index.pug │ │ ├── includes │ │ │ ├── toM.js │ │ │ └── rem.js │ │ └── layout.pug │ ├── state │ │ └── vuex-store.js │ ├── public │ │ └── func.js │ ├── renders │ │ └── index.vue │ ├── js │ │ └── index.js │ ├── components │ │ ├── common │ │ │ ├── header.vue │ │ │ └── login.vue │ │ ├── user │ │ │ ├── user-form.vue │ │ │ └── user-list.vue │ │ ├── admin.vue │ │ └── goods │ │ │ ├── goods-form.vue │ │ │ └── goods-list.vue │ └── routes │ │ └── router.js ├── .babelrc ├── package.json ├── webpack.config.js └── element-variables.css ├── .gitignore ├── .idea ├── dictionaries │ └── baimifan.xml ├── watcherTasks.xml ├── vcs.xml ├── inspectionProfiles │ └── Project_Default.xml ├── jsLibraryMappings.xml ├── modules.xml ├── codeStyleSettings.xml ├── vue-admin.iml ├── deployment.xml ├── webServers.xml ├── misc.xml └── workspace.xml ├── back-end ├── configs │ └── db.js ├── sql │ ├── sql.js │ ├── func.js │ └── vue_admin.sql ├── package.json ├── app.js ├── api.js ├── utils │ └── upload.js ├── routes │ └── router.js ├── controls │ ├── goods.js │ └── user.js └── package-lock.json └── README.md /front-end/run-build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | npm run build -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | npm-debug.log 5 | yarn-error.log 6 | -------------------------------------------------------------------------------- /front-end/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | require('autoprefixer') 4 | ] 5 | } -------------------------------------------------------------------------------- /.idea/dictionaries/baimifan.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /front-end/src/assets/imgs/login-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/win5do/vue-fb-demo/HEAD/front-end/src/assets/imgs/login-bg.jpg -------------------------------------------------------------------------------- /front-end/src/views/pages/index.pug: -------------------------------------------------------------------------------- 1 | extends ../layout.pug 2 | 3 | block title 4 | title 后台 5 | 6 | block content 7 | #app -------------------------------------------------------------------------------- /back-end/configs/db.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | host: '39.108.4.6', 3 | port: 3306, 4 | user: 'wf', 5 | password: 'wf', 6 | database: 'vue_admin' 7 | }; -------------------------------------------------------------------------------- /back-end/sql/sql.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | queryAll: 'SELECT * FROM ??', 3 | queryById: 'SELECT * FROM ?? WHERE id=?', 4 | del: 'DELETE FROM ?? WHERE id=?', 5 | }; -------------------------------------------------------------------------------- /.idea/watcherTasks.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /front-end/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "latest", 5 | { 6 | "es2015": { 7 | "modules": false 8 | } 9 | } 10 | ] 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/jsLibraryMappings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /front-end/src/views/includes/toM.js: -------------------------------------------------------------------------------- 1 | // 判断是否为移动端 2 | if (/AppleWebKit.*Mobile/i.test(navigator.userAgent) || 3 | /Android|iPhone|Windows Phone|webOS|iPod|BlackBerry/i.test(navigator.userAgent)) { 4 | window.location.href = "dist/m/views/index.html"; 5 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #vue-admin 2 | 3 | [迈出全栈的第一步](https://segmentfault.com/a/1190000009246144) 4 | 5 | ```bash 6 | # front-end 7 | npm run dev 8 | npm run build 9 | 10 | localhost:8888/dist/ 11 | 12 | # back-end 13 | nodemon app 14 | 15 | localhost:9999/api/ 16 | ``` 17 | 18 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/codeStyleSettings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 9 | -------------------------------------------------------------------------------- /front-end/src/state/vuex-store.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import Vuex from 'vuex'; 3 | Vue.use(Vuex); 4 | 5 | export default new Vuex.Store({ 6 | state: { 7 | user: null, 8 | goodsDetail: null 9 | }, 10 | mutations: { 11 | user (state, payload) { 12 | state.user = payload; 13 | }, 14 | } 15 | }); -------------------------------------------------------------------------------- /front-end/src/views/layout.pug: -------------------------------------------------------------------------------- 1 | doctype html 2 | html 3 | head 4 | meta(charset="utf-8") 5 | meta(http-equiv="X-UA-Compatible" content="IE=edge,chrome=1") 6 | meta(name="renderer" content="webkit") 7 | meta(name="viewport" content="width=device-width, initial-scale=1") 8 | meta(name="keywords" content="") 9 | meta(name="description" content="") 10 | block title 11 | body 12 | block content -------------------------------------------------------------------------------- /front-end/src/public/func.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | 3 | export default { 4 | ajaxGet (api, cb) { 5 | axios.get(api) 6 | .then(cb) 7 | .catch(err => { 8 | console.log(err); 9 | }) 10 | }, 11 | ajaxPost (api, post, cb) { 12 | axios.post(api, post) 13 | .then(cb) 14 | .catch(err => { 15 | console.log(err); 16 | }) 17 | }, 18 | } -------------------------------------------------------------------------------- /.idea/vue-admin.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /back-end/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-admin-back-end", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "dev": "node app" 8 | }, 9 | "author": "5f", 10 | "license": "ISC", 11 | "dependencies": { 12 | "bcryptjs": "^2.4.3", 13 | "body-parser": "^1.17.1", 14 | "express": "^4.15.2", 15 | "express-session": "^1.15.2", 16 | "moment": "^2.18.1", 17 | "multer": "^1.3.0", 18 | "mysql": "^2.14.0" 19 | }, 20 | "devDependencies": {} 21 | } 22 | -------------------------------------------------------------------------------- /front-end/src/renders/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /back-end/app.js: -------------------------------------------------------------------------------- 1 | let express = require('express'); 2 | let bodyParser = require('body-parser'); 3 | let path = require('path'); 4 | let session = require('express-session'); 5 | let router = require('./routes/router'); 6 | 7 | let port = process.env.PORT || 9999; 8 | let app = express(); 9 | 10 | app.use(bodyParser.urlencoded({extended: true})); 11 | app.use(bodyParser.json()); 12 | 13 | app.use(session({ 14 | secret: 'fuckupig', 15 | cookie: {maxAge: 3600000}, 16 | resave: true, 17 | saveUninitialized: true, 18 | })); 19 | 20 | app.use(router); 21 | 22 | app.listen(port, () => { 23 | console.log(`devServer start on port:${ port}`); 24 | }); -------------------------------------------------------------------------------- /front-end/src/views/includes/rem.js: -------------------------------------------------------------------------------- 1 | // rem大小适配 2 | !(function (doc, win) { 3 | var docEle = doc.documentElement, 4 | evt = 'onorientationchange' in window ? 'orientationchange' : 'resize', 5 | fn = function () { 6 | var width = docEle.clientWidth; 7 | if (width > 750) { 8 | width && (docEle.style.fontSize = 75 + 'px'); 9 | } else { 10 | width && (docEle.style.fontSize = 75 * (width / 750) + 'px'); 11 | } 12 | }; 13 | fn(); 14 | win.addEventListener(evt, fn, false); 15 | doc.addEventListener('DOMContentLoaded', fn, false); 16 | }(document, window)); -------------------------------------------------------------------------------- /back-end/api.js: -------------------------------------------------------------------------------- 1 | let path = '/api'; 2 | 3 | module.exports = { 4 | // goods 5 | goodsList: path + '/goods/list', 6 | goodsDetail: path + '/goods/detail', 7 | goodsDelete: path + '/goods/delete', 8 | goodsAdd: path + '/goods/add', 9 | goodsDeleteMulti: path + '/goods/delete-multi', 10 | goodsUploadImg: path + '/goods/upload-img', 11 | 12 | // user 13 | userList: path + '/user/list', 14 | userDelete: path + '/user/delete', 15 | userAdd: path + '/user/add', 16 | userDeleteMulti: path + '/user/delete-multi', 17 | userLogin: path + '/user/login', 18 | userLogout: path + '/user/logout', 19 | userAutoLogin: path + '/user/auto-login', 20 | userChangeRole: path + '/user/change-role', 21 | }; -------------------------------------------------------------------------------- /back-end/sql/func.js: -------------------------------------------------------------------------------- 1 | let mysql = require('mysql'); 2 | let db = require('../configs/db'); 3 | let pool = mysql.createPool(db); 4 | 5 | module.exports = { 6 | connPool (sql, val, cb) { 7 | pool.getConnection((err, conn) => { 8 | let q = conn.query(sql, val, (err, rows) => { 9 | 10 | if (err) { 11 | console.log(err); 12 | } 13 | 14 | console.log(a); 15 | 16 | cb(err, rows); 17 | 18 | conn.release(); 19 | }); 20 | }); 21 | }, 22 | 23 | // json格式 24 | writeJson(res, code = 200, msg = 'ok', data = null) { 25 | let obj = {code, msg, data}; 26 | 27 | if (!data) { 28 | delete obj.data; 29 | } 30 | 31 | res.send(obj); 32 | }, 33 | }; -------------------------------------------------------------------------------- /back-end/utils/upload.js: -------------------------------------------------------------------------------- 1 | let fs = require('fs'); 2 | let path = require('path'); 3 | let moment = require('moment'); 4 | let multer = require('multer'); 5 | 6 | let storage = multer.diskStorage({ 7 | destination: function (req, file, cb) { 8 | 9 | let t = moment().format('YYYY-M-D'); 10 | let distPath = `../uploads/${t}`; 11 | 12 | if (!fs.existsSync('../uploads')) { 13 | fs.mkdirSync('../uploads'); 14 | } 15 | 16 | if (!fs.existsSync(distPath)) { 17 | fs.mkdirSync(distPath); 18 | } 19 | 20 | cb(null, distPath); 21 | }, 22 | 23 | filename: function (req, file, cb) { 24 | let ext = path.extname(file.originalname); 25 | cb(null, file.fieldname + '-' + Date.now() + ext); 26 | } 27 | }); 28 | 29 | let upload = multer({storage: storage}); 30 | 31 | module.exports = upload; -------------------------------------------------------------------------------- /front-end/src/assets/css/common.scss: -------------------------------------------------------------------------------- 1 | html, body { 2 | font: normal 400 14px/1.5 "Microsoft Yahei", Helvetica, arial, sans-serif; 3 | color: #000; 4 | background: #F9F9F9; 5 | width: 100%; 6 | height: 100%; 7 | } 8 | 9 | * { 10 | box-sizing: border-box; 11 | } 12 | 13 | a { 14 | text-decoration: none; 15 | color: #000; 16 | } 17 | 18 | li { 19 | list-style: none; 20 | } 21 | 22 | img { 23 | width: auto; 24 | height: auto; 25 | } 26 | 27 | @mixin clearfix { 28 | &:before { 29 | content: ''; 30 | display: table; 31 | } 32 | &:after { 33 | content: ''; 34 | display: table; 35 | clear: both; 36 | overflow: hidden; 37 | } 38 | } 39 | 40 | @function toRem($px, $base: 75) { 41 | @return $px / $base * 1rem; 42 | } 43 | 44 | html { 45 | font-size: 16px; 46 | } 47 | 48 | .wrap { 49 | min-width: 1000px; 50 | margin: 0 auto; 51 | } 52 | 53 | button { 54 | border: none; 55 | background: none; 56 | font: inherit; 57 | } -------------------------------------------------------------------------------- /front-end/src/js/index.js: -------------------------------------------------------------------------------- 1 | import "minireset.css"; 2 | import axios from "axios"; 3 | import ElementUI from "element-ui"; 4 | import Vue from "vue"; 5 | import Index from "../renders/index.vue"; 6 | import router from "../routes/router"; 7 | import store from "../state/vuex-store"; 8 | import "../assets/css/admin.scss"; 9 | import func from "../public/func"; 10 | import api from "../../../back-end/api"; 11 | 12 | Vue.use(ElementUI); 13 | Vue.prototype.$http = axios; 14 | Vue.prototype.api = api; 15 | Vue.prototype.func = func; 16 | 17 | let vm = new Vue({ 18 | el: '#app', 19 | router, 20 | store, 21 | render: h => h(Index), 22 | }); 23 | 24 | //router.beforeEach((to, from, next) => { 25 | // vm.func.ajaxGet(vm.api.userAutoLogin, res => { 26 | // if (res.data.code === 200) { 27 | // vm.$store.commit('user', res.data.user); 28 | // 29 | // } else { 30 | // vm.$router.push('/'); 31 | // } 32 | // }); 33 | // 34 | // next(); 35 | //}); -------------------------------------------------------------------------------- /back-end/routes/router.js: -------------------------------------------------------------------------------- 1 | let express = require('express'); 2 | let goods = require('../controls/goods'); 3 | let user = require('../controls/user'); 4 | let api = require('../api'); 5 | let upload = require('../utils/upload'); 6 | 7 | 8 | let router = express.Router(); 9 | 10 | // goods 11 | router.get(api.goodsList, goods.fetchAll); 12 | 13 | router.post(api.goodsDetail, goods.fetchById); 14 | router.post(api.goodsAdd, goods.addOne); 15 | router.post(api.goodsDelete, goods.deleteOne); 16 | router.post(api.goodsDeleteMulti, goods.deleteMulti); 17 | router.post(api.goodsUploadImg, upload.single('avatar'),goods.uploadGoodsImg); // 图片上传 18 | 19 | // user 20 | router.get(api.userList, user.fetchAll); 21 | router.get(api.userLogout, user.logout); 22 | router.get(api.userAutoLogin, user.autoLogin); // 自动登录 23 | 24 | router.post(api.userAdd, user.addOne); 25 | router.post(api.userDelete, user.deleteOne); 26 | router.post(api.userDeleteMulti, user.deleteMulti); 27 | router.post(api.userLogin, user.login); // 登录 28 | router.post(api.userChangeRole, user.controlVisit, user.changeRole); // 更改权限 29 | 30 | module.exports = router; -------------------------------------------------------------------------------- /front-end/src/components/common/header.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/deployment.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /front-end/src/routes/router.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import Router from "vue-router"; 3 | import Admin from "../components/admin.vue"; 4 | import Login from "../components/common/login.vue"; 5 | import GoodsForm from "../components/goods/goods-form.vue"; 6 | import GoodsList from "../components/goods/goods-list.vue"; 7 | import UserForm from "../components/user/user-form.vue"; 8 | import UserList from "../components/user/user-list.vue"; 9 | 10 | Vue.use(Router); 11 | 12 | export default new Router({ 13 | routes: [ 14 | { 15 | path: '/admin', 16 | redirect: '/admin/goods-list', 17 | component: Admin, 18 | children: [ 19 | { 20 | path: '/admin/goods-list', 21 | component: GoodsList, 22 | }, 23 | { 24 | path: '/admin/goods-form', 25 | component: GoodsForm, 26 | }, 27 | { 28 | path: '/admin/user-list', 29 | component: UserList, 30 | }, 31 | { 32 | path: '/admin/user-form', 33 | component: UserForm, 34 | }, 35 | ] 36 | }, 37 | { 38 | path: '/', 39 | component: Login, 40 | }, 41 | ] 42 | }); -------------------------------------------------------------------------------- /.idea/webServers.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 30 | 31 | -------------------------------------------------------------------------------- /front-end/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-admin-front-end", 3 | "description": "vue-admin", 4 | "version": "0.0.1", 5 | "author": "win5do ", 6 | "private": true, 7 | "scripts": { 8 | "dev": "cross-env NODE_ENV=development webpack-dev-server --open --colors", 9 | "build": "cross-env NODE_ENV=production webpack --progress --hide-modules" 10 | }, 11 | "dependencies": { 12 | "animate.css": "^3.5.2", 13 | "axios": "^0.16.1", 14 | "element-ui": "^1.3.2", 15 | "minireset.css": "^0.0.3", 16 | "vue": "^2.3.3", 17 | "vue-router": "^2.5.3", 18 | "vueditor": "^0.2.4", 19 | "vuex": "^2.3.1" 20 | }, 21 | "devDependencies": { 22 | "babel-core": "^6.24.1", 23 | "babel-loader": "^7.0.0", 24 | "babel-preset-latest": "^6.24.1", 25 | "cross-env": "^5.0.0", 26 | "css-loader": "^0.28.1", 27 | "element-theme-default": "^1.3.2", 28 | "expose-loader": "^0.7.3", 29 | "extract-text-webpack-plugin": "^2.1.0", 30 | "file-loader": "^0.11.1", 31 | "glob": "^7.1.1", 32 | "html-loader": "^0.4.5", 33 | "html-webpack-plugin": "^2.28.0", 34 | "node-sass": "^4.5.2", 35 | "postcss-loader": "^2.0.5", 36 | "pug": "^2.0.0-rc.1", 37 | "pug-loader": "^2.3.0", 38 | "sass-loader": "^6.0.5", 39 | "style-loader": "^0.17.0", 40 | "url-loader": "^0.5.8", 41 | "vue-loader": "^12.0.4", 42 | "vue-template-compiler": "^2.3.3", 43 | "webpack": "^2.5.1", 44 | "webpack-dev-server": "^2.4.5" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /front-end/src/components/user/user-form.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | -------------------------------------------------------------------------------- /front-end/src/components/admin.vue: -------------------------------------------------------------------------------- 1 | 39 | 40 | -------------------------------------------------------------------------------- /front-end/src/assets/css/admin.scss: -------------------------------------------------------------------------------- 1 | @import "common"; 2 | 3 | #app { 4 | width: 100%; 5 | height: 100%; 6 | } 7 | 8 | // login 9 | 10 | .login { 11 | width: 100%; 12 | height: 100%; 13 | position: relative; 14 | background: url("../imgs/login-bg.jpg") no-repeat center; 15 | background-size: cover; 16 | .login-form { 17 | width: 400px; 18 | position: absolute; 19 | left: 50%; 20 | top: 50%; 21 | transform: translate(-50%, -50%); 22 | .el-form-item__label { 23 | color: #fff; 24 | } 25 | } 26 | } 27 | 28 | // header 29 | header { 30 | width: 100%; 31 | height: 60px; 32 | background: #444; 33 | } 34 | 35 | .header-wrap { 36 | height: 100%; 37 | display: flex; 38 | flex-flow: nowrap row; 39 | justify-content: space-between; 40 | align-items: center; 41 | padding: 0 20px; 42 | } 43 | 44 | .header-links { 45 | display: flex; 46 | flex-flow: nowrap row; 47 | justify-content: center; 48 | align-items: center; 49 | .btn { 50 | flex-flow: nowrap row; 51 | justify-content: center; 52 | align-items: center; 53 | display: flex; 54 | height: 100%; 55 | padding: 0 20px; 56 | color: #fff; 57 | } 58 | } 59 | 60 | // admin 61 | .admin { 62 | height: 100%; 63 | min-width: 1200px; 64 | display: flex; 65 | flex-flow: column nowrap; 66 | 67 | .admin-main { 68 | display: flex; 69 | flex-flow: row nowrap; 70 | flex: auto; 71 | 72 | .admin-main-right { 73 | width: 200px; 74 | flex: none; 75 | 76 | .top-menu { 77 | background: #666; 78 | border-radius: 0; 79 | height: 100%; 80 | } 81 | } 82 | } 83 | 84 | .admin-main-left { 85 | flex: auto; 86 | padding: 20px; 87 | overflow-y: auto; 88 | } 89 | } 90 | 91 | .admin-list { 92 | .btns { 93 | margin: 20px 0; 94 | text-align: center; 95 | } 96 | .el-table__empty-block { 97 | height: auto; 98 | } 99 | } 100 | 101 | .form-contain { 102 | width: 50%; 103 | margin: 0 auto; 104 | } -------------------------------------------------------------------------------- /front-end/src/components/common/login.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | -------------------------------------------------------------------------------- /back-end/controls/goods.js: -------------------------------------------------------------------------------- 1 | let sql = require('../sql/sql'); 2 | let moment = require('moment'); 3 | let func = require('../sql/func'); 4 | let path = require('path'); 5 | 6 | function formatData(rows) { 7 | return rows.map(row => { 8 | let date = moment(row.create_time).format('YYYY-MM-DD'); 9 | return Object.assign({}, row, {create_time: date}); 10 | }); 11 | } 12 | 13 | 14 | module.exports = { 15 | // 获取商品列表 16 | fetchAll (req, res) { 17 | func.connPool(sql.queryAll, 'goods', rows => { 18 | rows = formatData(rows); 19 | res.json({code: 200, msg: 'ok', goods: rows}); 20 | }); 21 | }, 22 | 23 | // 获取商品详情 24 | fetchById (req, res) { 25 | let id = req.body.id; 26 | 27 | func.connPool(sql.queryById, ['goods', id], rows => { 28 | rows = formatData(rows); 29 | res.json({code: 200, msg: 'ok', goods: rows[0]}); 30 | }); 31 | 32 | }, 33 | 34 | // 添加|更新 商品 35 | addOne (req, res) { 36 | let id = req.body.id; 37 | console.log(id); 38 | let name = req.body.name; 39 | let price = req.body.price; 40 | let query, arr; 41 | 42 | if (id) { 43 | // 更新 44 | query = 'UPDATE goods SET name=?, price=? WHERE id=?'; 45 | arr = [name, price, id]; 46 | } else { 47 | // 新增 48 | query = 'INSERT INTO goods(name, price) VALUES(?,?)'; 49 | arr = [name, price]; 50 | } 51 | 52 | func.connPool(query, arr, rows => { 53 | res.send({code: 200, msg: 'done'}); 54 | 55 | }); 56 | 57 | }, 58 | 59 | 60 | // 删除商品 61 | deleteOne (req, res) { 62 | 63 | let id = req.body.id; 64 | 65 | func.connPool(sql.del, ['goods', id], rows => { 66 | res.send({code: 200, msg: 'done'}); 67 | 68 | }); 69 | 70 | }, 71 | 72 | // 批量删除 73 | deleteMulti (req, res) { 74 | let id = req.body.id; 75 | 76 | func.connPool('DELETE FROM goods WHERE id IN ?', [[id]], rows => { 77 | res.send({code: 200, msg: 'done'}); 78 | 79 | }); 80 | 81 | }, 82 | 83 | uploadGoodsImg (req, res) { 84 | let absolutePath = path.resolve(__dirname, req.file.path); 85 | let a = 2; 86 | 87 | func.connPool('UPDATE goods SET imgs = ? WHERE id = ?', [absolutePath, 60], (err, rows) => { 88 | console.log(a); 89 | res.send({code: 200, msg: 'done', url: absolutePath}); 90 | }, res); 91 | }, 92 | }; -------------------------------------------------------------------------------- /back-end/sql/vue_admin.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Navicat MySQL Data Transfer 3 | 4 | Source Server : wf 5 | Source Server Version : 50718 6 | Source Host : 39.108.4.6:3306 7 | Source Database : vue_admin 8 | 9 | Target Server Type : MYSQL 10 | Target Server Version : 50718 11 | File Encoding : 65001 12 | 13 | Date: 2017-05-14 23:29:49 14 | */ 15 | 16 | SET FOREIGN_KEY_CHECKS=0; 17 | 18 | -- ---------------------------- 19 | -- Table structure for goods 20 | -- ---------------------------- 21 | DROP TABLE IF EXISTS `goods`; 22 | CREATE TABLE `goods` ( 23 | `id` int(11) NOT NULL AUTO_INCREMENT, 24 | `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 25 | `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 26 | `name` varchar(50) NOT NULL DEFAULT 'noname', 27 | `price` float(10,2) NOT NULL DEFAULT '0.00', 28 | `inventory` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '库存', 29 | `category` varchar(50) DEFAULT '' COMMENT '分类', 30 | `imgs` varchar(50) DEFAULT '', 31 | `onsale` tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT '是否上架', 32 | PRIMARY KEY (`id`), 33 | UNIQUE KEY `id` (`id`) USING BTREE 34 | ) ENGINE=InnoDB AUTO_INCREMENT=60 DEFAULT CHARSET=utf8; 35 | 36 | -- ---------------------------- 37 | -- Records of goods 38 | -- ---------------------------- 39 | INSERT INTO `goods` VALUES ('41', '2017-05-09 16:39:57', '2017-05-09 16:39:57', '女盆友', '5555555.00', '0', null, null, '0'); 40 | INSERT INTO `goods` VALUES ('42', '2017-05-09 16:40:09', '2017-05-09 16:40:09', '大妹子', '5666666.00', '0', null, null, '0'); 41 | INSERT INTO `goods` VALUES ('59', '2017-05-14 20:28:18', '2017-05-14 20:28:18', 'dasdas', '1564564.00', '0', null, null, '0'); 42 | 43 | -- ---------------------------- 44 | -- Table structure for user 45 | -- ---------------------------- 46 | DROP TABLE IF EXISTS `user`; 47 | CREATE TABLE `user` ( 48 | `id` int(11) NOT NULL AUTO_INCREMENT, 49 | `user_name` varchar(40) NOT NULL DEFAULT '', 50 | `password` varchar(100) NOT NULL DEFAULT '', 51 | `role` tinyint(3) NOT NULL DEFAULT '0' COMMENT '用户权限', 52 | `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 53 | `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 54 | PRIMARY KEY (`id`), 55 | UNIQUE KEY `id` (`id`) USING BTREE 56 | ) ENGINE=InnoDB AUTO_INCREMENT=35 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; 57 | 58 | -- ---------------------------- 59 | -- Records of user 60 | -- ---------------------------- 61 | INSERT INTO `user` VALUES ('26', 'root', '$2a$10$RREavyfC7Pm1EXYIjcZS6.Ec3qMVveuwMm.GcXoCZOSMbNkxfYVLW', '100', '2017-05-09 23:14:07', '2017-05-09 23:14:07'); 62 | INSERT INTO `user` VALUES ('27', '666', '$2a$10$soVuVqbLSWwliu/6MT0xQ.3VLbXK2FRZhij/50Ni3E5SGwGaVb.ou', '1', '2017-05-09 23:38:06', '2017-05-13 14:47:04'); 63 | INSERT INTO `user` VALUES ('34', 'test', '$2a$10$ozwCHpePh3Cl64bomQY2nOb9XpzM7zlMA5KJG5CEhISTAh7zitFsy', '10', '2017-05-13 14:58:47', '2017-05-14 21:08:47'); 64 | SET FOREIGN_KEY_CHECKS=1; 65 | -------------------------------------------------------------------------------- /front-end/src/components/goods/goods-form.vue: -------------------------------------------------------------------------------- 1 | 52 | 53 | -------------------------------------------------------------------------------- /front-end/src/components/goods/goods-list.vue: -------------------------------------------------------------------------------- 1 | 58 | 59 | -------------------------------------------------------------------------------- /back-end/controls/user.js: -------------------------------------------------------------------------------- 1 | let sql = require('../sql/sql'); 2 | let moment = require('moment'); 3 | let bcrypt = require('bcryptjs'); 4 | let func = require('../sql/func'); 5 | 6 | function formatData(rows) { 7 | return rows.map(row => { 8 | let date = moment(row.create_time).format('YYYY-MM-DD'); 9 | let obj = {}; 10 | 11 | switch (row.role) { 12 | case 1: 13 | obj.role = '普通用户'; 14 | break; 15 | case 10: 16 | obj.role = '管理员'; 17 | break; 18 | case 100: 19 | obj.role = '超级管理员'; 20 | } 21 | 22 | delete row.password; 23 | 24 | return Object.assign({}, row, {create_time: date}, obj); 25 | }); 26 | } 27 | 28 | module.exports = { 29 | 30 | fetchAll (req, res) { 31 | func.connPool(sql.queryAll, 'user', rows => { 32 | rows = formatData(rows); 33 | res.json({code: 200, msg: 'ok', users: rows}); 34 | }); 35 | 36 | }, 37 | 38 | // 添加用户 39 | addOne (req, res) { 40 | let name = req.body.name; 41 | let pass = req.body.pass; 42 | let role = req.body.role; 43 | let query = 'INSERT INTO user(user_name, password, role) VALUES(?, ?, ?)'; 44 | 45 | // 密码加盐 46 | bcrypt.hash(pass, 10, (err, hash) => { 47 | if (err) console.log(err); 48 | 49 | pass = hash; 50 | 51 | let arr = [name, pass, role]; 52 | 53 | func.connPool(query, arr, rows => { 54 | res.json({code: 200, msg: 'done'}); 55 | }); 56 | 57 | }); 58 | 59 | }, 60 | 61 | 62 | // 删除用户 63 | deleteOne (req, res) { 64 | 65 | let id = req.body.id; 66 | 67 | func.connPool(sql.del, ['user', id], rows => { 68 | res.json({code: 200, msg: 'done'}); 69 | }); 70 | 71 | }, 72 | 73 | // 批量删除 74 | deleteMulti (req, res) { 75 | let id = req.body.id; 76 | 77 | func.connPool('DELETE FROM user WHERE id IN ?', [[id]], rows => { 78 | res.json({code: 200, msg: 'done'}); 79 | }); 80 | 81 | }, 82 | 83 | // 登录 84 | login (req, res) { 85 | let user_name = req.body.user_name; 86 | let pass = req.body.pass; 87 | 88 | func.connPool('SELECT * from user where user_name = ?', [user_name], rows => { 89 | 90 | if (!rows.length) { 91 | res.json({code: 400, msg: '用户名不存在'}); 92 | return; 93 | } 94 | 95 | let password = rows[0].password; 96 | bcrypt.compare(pass, password, (err, sure) => { 97 | if (sure) { 98 | let user = { 99 | user_id: rows[0].user_id, 100 | user_name: rows[0].user_name, 101 | role: rows[0].role, 102 | }; 103 | 104 | req.session.login = user; 105 | 106 | res.json({code: 200, msg: '登录成功', user: user}); 107 | } else { 108 | res.json({code: 400, msg: '密码错误'}); 109 | } 110 | }); 111 | 112 | }); 113 | 114 | }, 115 | 116 | 117 | // 自动登录 118 | autoLogin (req, res) { 119 | let user = req.session.login; 120 | if (user) { 121 | res.json({code: 200, msg: '自动登录', user: user}); 122 | 123 | } else { 124 | res.json({code: 400, msg: 'not found'}); 125 | } 126 | }, 127 | 128 | // 注销 129 | logout (req, res) { 130 | req.session.login = null; 131 | 132 | res.json({code: 200, msg: '注销'}); 133 | }, 134 | 135 | // 权限控制 136 | controlVisit (req, res, next) { 137 | if (req.session.login.role && req.session.login.role < 10) { 138 | res.json({code: 400, msg: '权限不够'}); 139 | return; 140 | } 141 | 142 | next(); 143 | }, 144 | 145 | // 权限变更 146 | changeRole (req, res) { 147 | let role = req.session.login.role; 148 | let change_role = req.body.change_role; 149 | 150 | if (role !== 100 && change_role === 100) { 151 | res.json({code: 400, msg: '权限不够'}); 152 | return; 153 | } 154 | 155 | let user_id = req.body.id; 156 | 157 | func.connPool('UPDATE user SET role= ? WHERE id = ?', [change_role, user_id], rows => { 158 | console.log(rows); 159 | if (rows.affectedRows) { 160 | res.json({code: 200, msg: 'done'}); 161 | } 162 | }); 163 | 164 | }, 165 | 166 | }; -------------------------------------------------------------------------------- /back-end/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-admin-back-end", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "bcryptjs": { 8 | "version": "2.4.3", 9 | "resolved": "http://registry.npm.taobao.org/bcryptjs/download/bcryptjs-2.4.3.tgz", 10 | "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=" 11 | }, 12 | "body-parser": { 13 | "version": "1.17.2", 14 | "resolved": "http://registry.npm.taobao.org/body-parser/download/body-parser-1.17.2.tgz", 15 | "integrity": "sha1-+IkqvI+eYn1Crtr7yma/WrmRBO4=" 16 | }, 17 | "core-util-is": { 18 | "version": "1.0.2", 19 | "resolved": "http://registry.npm.taobao.org/core-util-is/download/core-util-is-1.0.2.tgz", 20 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 21 | }, 22 | "express": { 23 | "version": "4.15.3", 24 | "resolved": "http://registry.npm.taobao.org/express/download/express-4.15.3.tgz", 25 | "integrity": "sha1-urZdDwOqgMNYQIly/HAPkWlEtmI=" 26 | }, 27 | "express-session": { 28 | "version": "1.15.3", 29 | "resolved": "http://registry.npm.taobao.org/express-session/download/express-session-1.15.3.tgz", 30 | "integrity": "sha1-21RfBDWnsbIorgLagZf2UUFzXGc=" 31 | }, 32 | "inherits": { 33 | "version": "2.0.3", 34 | "resolved": "http://registry.npm.taobao.org/inherits/download/inherits-2.0.3.tgz", 35 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 36 | }, 37 | "moment": { 38 | "version": "2.18.1", 39 | "resolved": "http://registry.npm.taobao.org/moment/download/moment-2.18.1.tgz", 40 | "integrity": "sha1-w2GT3Tzhwu7SrbfIAtu8d6gbHA8=" 41 | }, 42 | "multer": { 43 | "version": "1.3.0", 44 | "resolved": "http://registry.npm.taobao.org/multer/download/multer-1.3.0.tgz", 45 | "integrity": "sha1-CSsmcPaEb6SRSWXvyM+Uwg/sbNI=" 46 | }, 47 | "mysql": { 48 | "version": "2.14.0", 49 | "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.14.0.tgz", 50 | "integrity": "sha1-MlzBFW6CRuVyEYd0u/QG6qkYn/0=", 51 | "requires": { 52 | "bignumber.js": "4.0.2", 53 | "readable-stream": "2.3.3", 54 | "safe-buffer": "5.1.1", 55 | "sqlstring": "2.2.0" 56 | }, 57 | "dependencies": { 58 | "bignumber.js": { 59 | "version": "4.0.2", 60 | "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-4.0.2.tgz", 61 | "integrity": "sha1-LR3DfuWWiGfs6pC22k0W5oYI0h0=" 62 | }, 63 | "isarray": { 64 | "version": "1.0.0", 65 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 66 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 67 | }, 68 | "readable-stream": { 69 | "version": "2.3.3", 70 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", 71 | "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", 72 | "requires": { 73 | "core-util-is": "~1.0.0", 74 | "inherits": "~2.0.3", 75 | "isarray": "~1.0.0", 76 | "process-nextick-args": "~1.0.6", 77 | "safe-buffer": "~5.1.1", 78 | "string_decoder": "~1.0.3", 79 | "util-deprecate": "~1.0.1" 80 | } 81 | }, 82 | "safe-buffer": { 83 | "version": "5.1.1", 84 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", 85 | "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" 86 | }, 87 | "string_decoder": { 88 | "version": "1.0.3", 89 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", 90 | "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", 91 | "requires": { 92 | "safe-buffer": "~5.1.0" 93 | } 94 | } 95 | } 96 | }, 97 | "process-nextick-args": { 98 | "version": "1.0.7", 99 | "resolved": "http://registry.npm.taobao.org/process-nextick-args/download/process-nextick-args-1.0.7.tgz", 100 | "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" 101 | }, 102 | "sqlstring": { 103 | "version": "2.2.0", 104 | "resolved": "http://registry.npm.taobao.org/sqlstring/download/sqlstring-2.2.0.tgz", 105 | "integrity": "sha1-wxNcTqirzX5+50GklmqJHYak8ZE=" 106 | }, 107 | "util-deprecate": { 108 | "version": "1.0.2", 109 | "resolved": "http://registry.npm.taobao.org/util-deprecate/download/util-deprecate-1.0.2.tgz", 110 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 111 | } 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | true 8 | 9 | false 10 | true 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 43 | 44 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 90 | 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /front-end/src/components/user/user-list.vue: -------------------------------------------------------------------------------- 1 | 72 | 73 | -------------------------------------------------------------------------------- /front-end/webpack.config.js: -------------------------------------------------------------------------------- 1 | let path = require('path'); 2 | let webpack = require('webpack'); 3 | let ExtractTextPlugin = require('extract-text-webpack-plugin'); 4 | let HtmlWebpackPlugin = require('html-webpack-plugin'); 5 | let glob = require('glob'); 6 | 7 | // js名必须与html的fileName对应 8 | let entry = (() => { 9 | let obj = {}; 10 | getEntry('src/views/pages/*.pug').forEach(fileName => { 11 | obj[fileName] = './src/js/' + fileName + '.js'; 12 | }); 13 | 14 | return obj; 15 | })(); 16 | 17 | 18 | module.exports = { 19 | entry: entry, 20 | output: { 21 | path: path.resolve(__dirname, './dist'), 22 | publicPath: '/', 23 | filename: 'js/[name].js', 24 | // chunkFilename: 'js/[name][id].chunk.js', // 公共代码块 25 | }, 26 | externals: { 27 | // 'vue': 'Vue', 28 | // 'jquery': 'jQuery', 29 | }, 30 | module: { 31 | rules: [ 32 | { 33 | test: /\.vue$/, 34 | loader: 'vue-loader', 35 | options: { 36 | loaders: { 37 | scss: ExtractTextPlugin.extract({ 38 | fallback: 'vue-style-loader', 39 | use: 'css-loader!sass-loader', 40 | }), 41 | } 42 | } 43 | }, 44 | { 45 | test: /\.js$/, 46 | loader: 'babel-loader', 47 | exclude: /node_modules/ 48 | }, 49 | // 不要使用options配置url-loader webpack会报错 50 | { 51 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 52 | loader: 'url-loader?limit=10000&name=img/[name].[hash:7].[ext]', 53 | }, 54 | { 55 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 56 | loader: 'file-loader?limit=10000&name=img/[name].[hash:7].[ext]', 57 | }, 58 | { 59 | test: /\.scss$/, 60 | loader: ExtractTextPlugin.extract({ 61 | fallback: 'style-loader', 62 | use: 'css-loader!postcss-loader!sass-loader' 63 | }) 64 | }, 65 | { 66 | test: /\.css$/, 67 | loader: ExtractTextPlugin.extract({ 68 | fallback: 'style-loader', 69 | use: 'css-loader!postcss-loader' 70 | }) 71 | }, 72 | { 73 | test: /\.html$/, 74 | loader: 'html-loader?attrs=img:src img:data-src' 75 | }, 76 | { 77 | test: /\.pug$/, 78 | loader: 'pug-loader' 79 | }, 80 | ] 81 | }, 82 | resolve: { 83 | extensions: ['.js', '.vue', '.json'], 84 | alias: { 85 | // 'vue$': '../node_modules/vue' 86 | } 87 | }, 88 | devServer: { 89 | port: 8888, 90 | historyApiFallback: true, 91 | stats: 'minimal', // 输入精简信息 92 | overlay: true, // 将错误显示在html之上 93 | proxy: { 94 | '/api': { 95 | target: 'http://localhost:9999', 96 | secure: false, 97 | changeOrigin: true, 98 | // pathRewrite: {'^/api': ''}, 99 | } 100 | } 101 | }, 102 | performance: { 103 | hints: false 104 | }, 105 | devtool: '#eval-source-map', 106 | plugins: [ 107 | new webpack.HotModuleReplacementPlugin(), // 热加载 108 | 109 | // new webpack.ProvidePlugin({ 110 | // $: 'jquery', 111 | // jQuery: 'jquery', 112 | // }), 113 | 114 | new ExtractTextPlugin('css/[name].css'), //单独使用link标签加载css并设置路径,相对于output配置中的publicPath 115 | 116 | ], 117 | }; 118 | 119 | if (process.env.NODE_ENV === 'production') { 120 | module.exports.devtool = '#source-map'; 121 | // http://vue-loader.vuejs.org/en/workflow/production.html 122 | module.exports.plugins = (module.exports.plugins || []).concat([ 123 | new webpack.DefinePlugin({ 124 | 'process.env': { 125 | NODE_ENV: '"production"' 126 | } 127 | }), 128 | new webpack.optimize.UglifyJsPlugin({ 129 | sourceMap: true, 130 | compress: { 131 | warnings: false 132 | } 133 | }), 134 | new webpack.LoaderOptionsPlugin({ 135 | minimize: true 136 | }) 137 | ]); 138 | } 139 | 140 | console.log(1); 141 | 142 | // 自动生存htmlPlugins 143 | getEntry('src/views/pages/*.pug').forEach(fileName => { 144 | let conf = { 145 | filename: fileName + '.html', //生成的html存放路径,相对于path 146 | template: 'src/views/pages/' + fileName + '.pug', //html模板路径 147 | inject: true, 148 | hash: true, 149 | minify: { 150 | removeComments: true, 151 | minifyJS: true, 152 | }, 153 | chunks: [fileName], 154 | }; 155 | module.exports.plugins.push(new HtmlWebpackPlugin(conf)); 156 | 157 | 158 | console.log(2); 159 | }); 160 | 161 | // 获取文件名函数 162 | function getEntry(viewsPath) { 163 | let files = glob.sync(viewsPath); 164 | let entries = []; 165 | let entry, basename, extname; 166 | 167 | for (let i = 0; i < files.length; i++) { 168 | entry = files[i]; 169 | extname = path.extname(entry); // 扩展名 eg: .html 170 | basename = path.basename(entry, extname); // eg: index 171 | entries.push(basename); 172 | } 173 | return entries; 174 | } -------------------------------------------------------------------------------- /front-end/src/assets/imgs/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Shape Copy 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /front-end/element-variables.css: -------------------------------------------------------------------------------- 1 | :root { 2 | 3 | /* Transition 4 | -------------------------- */ 5 | --all-transition: all .3s cubic-bezier(.645,.045,.355,1); 6 | --fade-transition: opacity 300ms cubic-bezier(0.23, 1, 0.32, 1); 7 | --fade-linear-transition: opacity 200ms linear; 8 | --md-fade-transition: transform 300ms cubic-bezier(0.23, 1, 0.32, 1) 100ms, opacity 300ms cubic-bezier(0.23, 1, 0.32, 1) 100ms; 9 | --border-transition-base: border-color .2s cubic-bezier(.645,.045,.355,1); 10 | --color-transition-base: color .2s cubic-bezier(.645,.045,.355,1); 11 | 12 | /* Colors 13 | -------------------------- */ 14 | --color-primary: #c6914f; 15 | 16 | --color-success: #13ce66; 17 | --color-warning: #f7ba2a; 18 | --color-danger: #ff4949; 19 | --color-info: #50bfff; 20 | 21 | --color-secondary: color(var(--color-primary) s(99%) l(*0.9)); 22 | --color-white: #fff; 23 | --color-dark-white: color(var(--color-white) blend(var(--color-primary) 2%)); 24 | --color-black: #000; 25 | 26 | --color-base-black: color(var(--color-primary) h(+6) s(33%) l(18%)); 27 | --color-light-black: color(var(--color-base-black) h(+5) s(27%) l(27%)); 28 | --color-extra-light-black: color(var(--color-base-black) h(+2) s(19%) l(35%)); 29 | 30 | --color-base-silver: color(var(--color-base-black) h(+3) s(16%) l(58%)); 31 | --color-light-silver: color(var(--color-base-black) h(+3) s(23%) l(67%)); 32 | --color-extra-light-silver: color(var(--color-base-black) s(26%) l(80%)); 33 | 34 | --color-base-gray: color(var(--color-base-black) s(28%) l(86%)); 35 | --color-light-gray: color(var(--color-base-black) h(+10) s(33%) l(92%)); 36 | --color-extra-light-gray: color(var(--color-base-black) h(+6) s(33%) l(95%)); 37 | 38 | /* Link 39 | -------------------------- */ 40 | --link-color: var(--color-extra-light-black); 41 | --link-hover-color: var(--color-primary); 42 | 43 | /* Border 44 | -------------------------- */ 45 | --border-width-base: 1px; 46 | --border-style-base: solid; 47 | --border-color-base: var(--color-extra-light-silver); 48 | --border-color-hover: var(--color-base-silver); 49 | --border-base: var(--border-width-base) var(--border-style-base) var(--border-color-base); 50 | --border-radius-base: 4px; 51 | --border-radius-small: 2px; 52 | --border-radius-circle: 100%; 53 | 54 | /* Box-shadow 55 | -------------------------- */ 56 | --box-shadow-base: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04); 57 | --box-shadow-dark: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .12); 58 | 59 | /* Fill 60 | -------------------------- */ 61 | --fill-base: var(--color-white); 62 | 63 | /* Font 64 | -------------------------- */ 65 | --font-size-base: 14px; 66 | --font-color-base: var(--color-base-black); 67 | --font-color-disabled-base: #bbb; 68 | 69 | /* Size 70 | -------------------------- */ 71 | --size-base: 14px; 72 | 73 | /* z-index 74 | -------------------------- */ 75 | --index-normal: 1; 76 | --index-top: 1000; 77 | --index-popper: 2000; 78 | 79 | /* Disable base 80 | -------------------------- */ 81 | --disabled-fill-base: var(--color-extra-light-gray); 82 | --disabled-color-base: #bbb; 83 | --disabled-border-base: var(--color-base-gray); 84 | 85 | /* Icon 86 | -------------------------- */ 87 | --icon-color: #666; 88 | 89 | /* Checkbox 90 | -------------------------- */ 91 | --checkbox-font-size: 14px; 92 | --checkbox-color: var(--color-base-black); 93 | --checkbox-input-height: 18px; 94 | --checkbox-input-width: 18px; 95 | --checkbox-input-border-radius: var(--border-radius-base); 96 | --checkbox-input-fill: var(--color-white); 97 | --checkbox-input-border: var(--border-base); 98 | --checkbox-input-border-color: var(--border-color-base); 99 | --checkbox-icon-color: var(--color-white); 100 | 101 | --checkbox-disabled-input-border-color: var(--disabled-border-base); 102 | --checkbox-disabled-input-fill: var(--disabled-fill-base); 103 | --checkbox-disabled-icon-color: var(--disabled-fill-base); 104 | 105 | --checkbox-disabled-checked-input-fill: var(--disabled-border-base); 106 | --checkbox-disabled-checked-input-border-color: var(--disabled-border-base); 107 | --checkbox-disabled-checked-icon-color: var(--color-white); 108 | 109 | --checkbox-checked-input-border-color: var(--color-secondary); 110 | --checkbox-checked-input-fill: var(--color-primary); 111 | --checkbox-checked-icon-color: var(--fill-base); 112 | 113 | --checkbox-input-border-color-hover: var(--color-primary); 114 | 115 | /* Radio 116 | -------------------------- */ 117 | --radio-font-size: 14px; 118 | --radio-color: var(--color-base-black); 119 | --radio-input-height: 18px; 120 | --radio-input-width: 18px; 121 | --radio-input-border-radius: var(--border-radius-circle); 122 | --radio-input-fill: var(--color-white); 123 | --radio-input-border: var(--border-base); 124 | --radio-input-border-color: var(--border-color-base); 125 | --radio-icon-color: var(--color-white); 126 | 127 | --radio-disabled-input-border-color: var(--disabled-border-base); 128 | --radio-disabled-input-fill: var(--disabled-fill-base); 129 | --radio-disabled-icon-color: var(--disabled-fill-base); 130 | 131 | --radio-disabled-checked-input-fill: var(--disabled-border-base); 132 | --radio-disabled-checked-input-border-color: var(--disabled-border-base); 133 | --radio-disabled-checked-icon-color: var(--color-white); 134 | 135 | --radio-checked-input-border-color: var(--color-primary); 136 | --radio-checked-input-fill: var(--color-white); 137 | --radio-checked-icon-color: var(--color-primary); 138 | 139 | --radio-input-border-color-hover: var(--color-primary); 140 | 141 | --radio-button-font-size: var(--font-size-base); 142 | --radio-button-checked-fill: var(--color-primary); 143 | --radio-button-checked-color: var(--color-white); 144 | --radio-button-checked-border-color: var(--color-primary); 145 | 146 | /* Select 147 | -------------------------- */ 148 | --select-border-color-hover: var(--border-color-hover); 149 | --select-disabled-border: var(--disabled-border-base); 150 | --select-font-size: var(--font-size-base); 151 | --select-close-hover-color: var(--color-light-silver); 152 | 153 | --select-input-color: var(--color-extra-light-silver); 154 | --select-multiple-input-color: #666; 155 | --select-input-focus-background: var(--color-primary); 156 | --select-input-font-size: 12px; 157 | 158 | --select-tag-height: 24px; 159 | --select-tag-color: var(--color-white); 160 | --select-tag-background: var(--color-primary); 161 | 162 | --select-option-color: var(--link-color); 163 | --select-option-disabled-color: var(--color-extra-light-silver); 164 | --select-option-disabled-background: var(--color-white); 165 | --select-option-height: 36px; 166 | --select-option-hover-background: var(--color-light-gray); 167 | --select-option-selected: var(--color-primary); 168 | --select-option-selected-hover: shade(var(--color-primary), 0.12); 169 | 170 | --select-group-color: #999; 171 | --select-group-height: 30px; 172 | --select-group-font-size: 12px; 173 | 174 | --select-dropdown-background: var(--color-white); 175 | --select-dropdown-shadow: var(--box-shadow-base); 176 | --select-dropdown-empty-color: #999; 177 | --select-dropdown-max-height: 274px; 178 | --select-dropdown-padding: 6px 0; 179 | --select-dropdown-empty-padding: 10px 0; 180 | --select-dropdown-border: solid 1px var(--disabled-border-base); 181 | 182 | /* Alert 183 | -------------------------- */ 184 | --alert-padding: 8px 16px; 185 | --alert-border-radius: var(--border-radius-base); 186 | --alert-title-font-size: 13px; 187 | --alert-description-font-size: 12px; 188 | --alert-close-font-size: 12px; 189 | --alert-close-customed-font-size: 13px; 190 | 191 | --alert-success-color: var(--color-success); 192 | --alert-info-color: var(--color-info); 193 | --alert-warning-color: var(--color-warning); 194 | --alert-danger-color: var(--color-danger); 195 | 196 | --alert-icon-size: 16px; 197 | --alert-icon-large-size: 28px; 198 | 199 | /* Message Box 200 | -------------------------- */ 201 | --msgbox-width: 420px; 202 | --msgbox-border-radius: 3px; 203 | --msgbox-font-size: 16px; 204 | --msgbox-content-font-size: 14px; 205 | --msgbox-content-color: var(--link-color); 206 | --msgbox-error-font-size: 12px; 207 | 208 | --msgbox-success-color: var(--color-success); 209 | --msgbox-info-color: var(--color-info); 210 | --msgbox-warning-color: var(--color-warning); 211 | --msgbox-danger-color: var(--color-danger); 212 | 213 | /* Message 214 | -------------------------- */ 215 | --message-shadow: var(--box-shadow-base); 216 | --message-min-width: 300px; 217 | --message-padding: 10px 12px; 218 | --message-content-color: var(--border-color-hover); 219 | --message-close-color: var(--color-extra-light-silver); 220 | --message-close-hover-color: var(--color-light-silver); 221 | 222 | --message-success-color: var(--color-success); 223 | --message-info-color: var(--color-info); 224 | --message-warning-color: var(--color-warning); 225 | --message-danger-color: var(--color-danger); 226 | 227 | /* Notification 228 | -------------------------- */ 229 | --notification-width: 330px; 230 | --notification-padding: 20px; 231 | --notification-shadow: var(--box-shadow-base); 232 | --notification-icon-size: 40px; 233 | --notification-font-size: var(--font-size-base); 234 | --notification-color: var(--border-color-hover); 235 | --notification-title-font-size: 16px; 236 | --notification-title-color: var(--color-base-black); 237 | 238 | --notification-close-color: var(--color-extra-light-silver); 239 | --notification-close-hover-color: var(--color-light-silver); 240 | 241 | --notification-success-color: var(--color-success); 242 | --notification-info-color: var(--color-info); 243 | --notification-warning-color: var(--color-warning); 244 | --notification-danger-color: var(--color-danger); 245 | 246 | /* Input 247 | -------------------------- */ 248 | --input-font-size: var(--font-size-base); 249 | --input-color: var(--font-color-base); 250 | --input-width: 140px; 251 | --input-height: 36px; 252 | --input-border: var(--border-base); 253 | --input-border-color: var(--border-color-base); 254 | --input-border-radius: var(--border-radius-base); 255 | --input-border-color-hover: var(--border-color-hover); 256 | --input-fill: var(--color-white); 257 | --input-fill-disabled: var(--disabled-fill-base); 258 | --input-color-disabled: var(--font-color-disabled-base); 259 | --input-icon-color: var(--color-extra-light-silver); 260 | --input-placeholder-color: var(--color-light-silver); 261 | --input-max-width: 314px; 262 | 263 | --input-hover-border: var(--border-color-hover); 264 | 265 | --input-focus-border: var(--color-primary); 266 | --input-focus-fill: var(--color-white); 267 | 268 | --input-disabled-fill: var(--disabled-fill-base); 269 | --input-disabled-border: var(--disabled-border-base); 270 | --input-disabled-color: var(--disabled-color-base); 271 | --input-disabled-placeholder-color: var(--color-extra-light-silver); 272 | 273 | --input-large-font-size: 16px; 274 | --input-large-height: 42px; 275 | 276 | --input-small-font-size: 13px; 277 | --input-small-height: 30px; 278 | 279 | --input-mini-font-size: 12px; 280 | --input-mini-height: 22px; 281 | 282 | /* Cascader 283 | -------------------------- */ 284 | --cascader-menu-fill: var(--fill-base); 285 | --cascader-menu-font-size: var(--font-size-base); 286 | --cascader-menu-radius: var(--border-radius-base); 287 | --cascader-menu-border: var(--border-base); 288 | --cascader-menu-border-color: var(--border-color-base); 289 | --cascader-menu-border-width: var(--border-width-base); 290 | --cascader-menu-color: var(--font-color-base); 291 | --cascader-menu-option-color-active: var(--color-secondary); 292 | --cascader-menu-option-fill-active: rgba(var(--color-secondary), 0.12); 293 | --cascader-menu-option-color-hover: var(--font-color-base); 294 | --cascader-menu-option-fill-hover: rgba(var(--color-black), 0.06); 295 | --cascader-menu-option-color-disabled: #999; 296 | --cascader-menu-option-fill-disabled: rgba(var(--color-black), 0.06); 297 | --cascader-menu-option-empty-color: #666; 298 | --cascader-menu-group-color: #999; 299 | --cascader-menu-shadow: 0 1px 2px rgba(var(--color-black), 0.14), 0 0 3px rgba(var(--color-black), 0.14); 300 | --cascader-menu-option-pinyin-color: #999; 301 | --cascader-menu-submenu-shadow: 1px 1px 2px rgba(var(--color-black), 0.14), 1px 0 2px rgba(var(--color-black), 0.14); 302 | 303 | /* Group 304 | -------------------------- */ 305 | --group-option-flex: 0 0 (1/5) * 100%; 306 | --group-option-offset-bottom: 12px; 307 | --group-option-fill-hover: rgba(var(--color-black), 0.06); 308 | --group-title-color: var(--color-black); 309 | --group-title-font-size: var(--font-size-base); 310 | --group-title-width: 66px; 311 | 312 | /* Tab 313 | -------------------------- */ 314 | --tab-font-size: var(--font-size-base); 315 | --tab-border-line: 1px solid #e4e4e4; 316 | --tab-header-color-active: var(--color-secondary); 317 | --tab-header-color-hover: var(--font-color-base); 318 | --tab-header-color: var(--font-color-base); 319 | --tab-header-fill-active: rgba(var(--color-black), 0.06); 320 | --tab-header-fill-hover: rgba(var(--color-black), 0.06); 321 | --tab-vertical-header-width: 90px; 322 | --tab-vertical-header-count-color: var(--color-white); 323 | --tab-vertical-header-count-fill: var(--color-secondary); 324 | 325 | /* Button 326 | -------------------------- */ 327 | --button-font-size: 14px; 328 | --button-border-radius: var(--border-radius-base); 329 | --button-padding-vertical: 10px; 330 | --button-padding-horizontal: 15px; 331 | 332 | --button-large-font-size: 16px; 333 | --button-large-padding-vertical: 11px; 334 | --button-large-padding-horizontal: 19px; 335 | 336 | --button-small-font-size: 12px; 337 | --button-small-padding-vertical: 7px; 338 | --button-small-padding-horizontal: 9px; 339 | 340 | --button-mini-font-size: 12px; 341 | --button-mini-padding-vertical: 4px; 342 | --button-mini-padding-horizontal: 4px; 343 | 344 | --button-default-color: var(--color-base-black); 345 | --button-default-fill: var(--color-white); 346 | --button-default-border: #c4c4c4; 347 | 348 | --button-ghost-color: #666; 349 | --button-ghost-fill: transparent; 350 | --button-ghost-border: none; 351 | 352 | --button-disabled-color: var(--color-extra-light-silver); 353 | --button-disabled-fill: var(--color-extra-light-gray); 354 | --button-disabled-border: var(--disabled-border-base); 355 | 356 | --button-primary-border: var(--color-primary); 357 | --button-primary-color: var(--color-white); 358 | --button-primary-fill: var(--color-primary); 359 | 360 | --button-success-border: var(--color-success); 361 | --button-success-color: var(--color-white); 362 | --button-success-fill: var(--color-success); 363 | 364 | --button-warning-border: var(--color-warning); 365 | --button-warning-color: var(--color-white); 366 | --button-warning-fill: var(--color-warning); 367 | 368 | --button-danger-border: var(--color-danger); 369 | --button-danger-color: var(--color-white); 370 | --button-danger-fill: var(--color-danger); 371 | 372 | --button-info-border: var(--color-info); 373 | --button-info-color: var(--color-white); 374 | --button-info-fill: var(--color-info); 375 | 376 | --button-hover-tint-percent: 20%; 377 | --button-active-shade-percent: 10%; 378 | 379 | 380 | /* cascader 381 | -------------------------- */ 382 | --cascader-height: 200px; 383 | 384 | /* Switch 385 | -------------------------- */ 386 | --switch-on-color: var(--color-primary); 387 | --switch-off-color: var(--color-extra-light-silver); 388 | --switch-disabled-color: var(--color-light-gray); 389 | --switch-disabled-text-color: var(--color-dark-white); 390 | 391 | --switch-font-size: var(--font-size-base); 392 | --switch-core-border-radius: 12px; 393 | --switch-width: 46px; 394 | --switch-height: 22px; 395 | --switch-button-size: 16px; 396 | 397 | /* Dialog 398 | -------------------------- */ 399 | --dialog-background-color: var(--color-secondary); 400 | --dialog-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); 401 | --dialog-tiny-width: 30%; 402 | --dialog-small-width: 50%; 403 | --dialog-large-width: 90%; 404 | --dialog-close-color: var(--color-extra-light-silver); 405 | --dialog-close-hover-color: var(--color-primary); 406 | --dialog-title-font-size: 16px; 407 | --dialog-font-size: 14px; 408 | 409 | /* Table 410 | -------------------------- */ 411 | --table-border-color: color(var(--border-color-base) h(-3) s(27%) l(90%)); 412 | --table-text-color: var(--color-base-black); 413 | --table-header-background: var(--color-extra-light-gray); 414 | 415 | /* Pagination 416 | -------------------------- */ 417 | --pagination-font-size: 13px; 418 | --pagination-fill: var(--color-white); 419 | --pagination-color: var(--link-color); 420 | --pagination-border-radius: 2px; 421 | --pagination-button-color: var(--color-light-silver); 422 | --pagination-button-size: 28px; 423 | --pagination-button-disabled-color: #e4e4e4; 424 | --pagination-button-disabled-fill: var(--color-white); 425 | --pagination-border-color: var(--disabled-border-base); 426 | --pagination-hover-fill: var(--color-primary); 427 | --pagination-hover-color: var(--color-white); 428 | 429 | /* Popover 430 | -------------------------- */ 431 | --popover-fill: var(--color-white); 432 | --popover-font-size: 12px; 433 | --popover-border-color: var(--disabled-border-base); 434 | --popover-arrow-size: 6px; 435 | --popover-padding: 10px; 436 | --popover-title-font-size: 13px; 437 | --popover-title-color: var(--color-base-black); 438 | 439 | /* Tooltip 440 | -------------------------- */ 441 | --tooltip-fill: var(--color-base-black); 442 | --tooltip-color: var(--color-white); 443 | --tooltip-font-size: 12px; 444 | --tooltip-border-color: var(--color-base-black); 445 | --tooltip-arrow-size: 6px; 446 | --tooltip-padding: 10px; 447 | 448 | /* Tag 449 | -------------------------- */ 450 | --tag-padding: 0 5px; 451 | --tag-fill: var(--border-color-hover); 452 | --tag-color: var(--color-white); 453 | --tag-close-color: #666; 454 | --tag-font-size: 12px; 455 | --tag-border-radius: 4px; 456 | 457 | --tag-gray-fill: var(--color-light-gray); 458 | --tag-gray-border: var(--color-light-gray); 459 | --tag-gray-color: var(--link-color); 460 | 461 | --tag-primary-fill: rgba(var(--color-primary),0.10); 462 | --tag-primary-border: rgba(var(--color-primary),0.20); 463 | --tag-primary-color: var(--color-primary); 464 | 465 | --tag-success-fill: rgba(18,206,102,0.10); 466 | --tag-success-border: rgba(18,206,102,0.20); 467 | --tag-success-color: var(--color-success); 468 | 469 | --tag-warning-fill: rgba(247,186,41,0.10); 470 | --tag-warning-border: rgba(247,186,41,0.20); 471 | --tag-warning-color: var(--color-warning); 472 | 473 | --tag-danger-fill: rgba(255,73,73,0.10); 474 | --tag-danger-border: rgba(255,73,73,0.20); 475 | --tag-danger-color: var(--color-danger); 476 | 477 | /* Dropdown 478 | -------------------------- */ 479 | --dropdown-menu-box-shadow: var(--box-shadow-dark); 480 | --dropdown-menuItem-hover-fill: var(--color-light-gray); 481 | --dropdown-menuItem-hover-color: var(--link-color); 482 | 483 | /* Badge 484 | -------------------------- */ 485 | --badge-fill: var(--color-danger); 486 | --badge-radius: 10px; 487 | --badge-font-size: 12px; 488 | --badge-padding: 6px; 489 | --badge-size: 18px; 490 | 491 | /* Card 492 | --------------------------*/ 493 | --card-border-color: var(--disabled-border-base); 494 | --card-border-radius: 4px; 495 | --card-padding: 20px; 496 | 497 | /* Slider 498 | --------------------------*/ 499 | --slider-main-background-color: var(--color-primary); 500 | --slider-runway-background-color: var(--color-light-gray); 501 | --slider-button-hover-color: shade(var(--color-primary), 0.12); 502 | --slider-stop-background-color: var(--color-extra-light-silver); 503 | --slider-disable-color: var(--color-extra-light-silver); 504 | 505 | --slider-margin: 16px 0; 506 | --slider-border-radius: 3px; 507 | --slider-height: 4px; 508 | --slider-button-size: 12px; 509 | --slider-button-wrapper-size: 36px; 510 | --slider-button-wrapper-offset: -16px; 511 | 512 | /* Steps 513 | --------------------------*/ 514 | --steps-border-color: var(--disabled-border-base); 515 | --steps-border-radius: 4px; 516 | --steps-padding: 20px; 517 | 518 | /* Menu 519 | --------------------------*/ 520 | --menu-item-color: var(--link-color); 521 | --menu-item-fill: var(--color-extra-light-gray); 522 | --menu-item-hover-fill: var(--disabled-border-base); 523 | 524 | --dark-menu-item-color: var(--link-color); 525 | --dark-menu-item-fill: var(--color-light-black); 526 | --dark-menu-item-hover-fill: var(--link-color); 527 | 528 | /* Rate 529 | --------------------------*/ 530 | --rate-height: 20px; 531 | --rate-font-size: var(--font-size-base); 532 | --rate-icon-size: 18px; 533 | --rate-icon-margin: 6px; 534 | --rate-icon-color: var(--color-extra-light-silver); 535 | 536 | /* DatePicker 537 | --------------------------*/ 538 | --datepicker-color: var(--link-color); 539 | --datepicker-off-color: #ddd; 540 | --datepicker-header-color: var(--border-color-hover); 541 | --datepicker-icon-color: var(--color-light-silver); 542 | --datepicker-border-color: var(--disabled-border-base); 543 | --datepicker-inner-border-color: #e4e4e4; 544 | --datepicker-cell-hover-color: var(--color-light-gray); 545 | --datepicker-inrange-color: tint(var(--color-primary), 0.8); 546 | --datepicker-inrange-hover-color: tint(var(--color-primary), 0.64); 547 | --datepicker-active-color: var(--color-primary); 548 | --datepicker-text-hover-color: var(--color-primary); 549 | 550 | /* Loading 551 | --------------------------*/ 552 | --loading-spinner-size: 42px; 553 | --loading-fullscreen-spinner-size: 50px; 554 | 555 | /* Scrollbar 556 | --------------------------*/ 557 | --scrollbar-background-color: rgba(var(--color-light-silver), .3); 558 | --scrollbar-hover-background-color: rgba(var(--color-light-silver), .5); 559 | 560 | /* Carousel 561 | --------------------------*/ 562 | --carousel-arrow-font-size: 12px; 563 | --carousel-arrow-size: 36px; 564 | --carousel-arrow-background: rgba(31, 45, 61, 0.11); 565 | --carousel-arrow-hover-background: rgba(31, 45, 61, 0.23); 566 | --carousel-indicator-width: 30px; 567 | --carousel-indicator-height: 2px; 568 | --carousel-indicator-padding-horizontal: 4px; 569 | --carousel-indicator-padding-vertical: 12px; 570 | --carousel-indicator-out-color: var(--border-color-hover); 571 | 572 | /* Collapse 573 | --------------------------*/ 574 | --collapse-border-color: color(var(--border-color-base) h(-3) s(27%) l(90%)); 575 | --collapse-header-height: 43px; 576 | --collapse-border-radius: 0; 577 | --collapse-header-padding: 20px; 578 | --collapse-header-fill: var(--color-white); 579 | --collapse-header-color: var(--color-extra-light-black); 580 | --collapse-header-size: 13px; 581 | --collapse-content-fill: var(--color-dark-white); 582 | --collapse-content-size: 13px; 583 | --collapse-content-color: var(--color-base-black); 584 | } 585 | -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | req.se 80 | this 81 | Id 82 | UPDAT 83 | 204 84 | \.status\(\d{3}\) 85 | ('done') 86 | 'done' 87 | '权限不够' 88 | stat 89 | sta 90 | res.status === 201 91 | handleEdit 92 | vm 93 | form 94 | changeRole 95 | push 96 | btns 97 | to 98 | host 99 | - 100 | '.*' 101 | func 102 | (api 103 | .send 104 | I 105 | var 106 | express 107 | VAR 108 | des 109 | 110 | 111 | ) 112 | ); 113 | ?? 114 | rows 115 | created_time 116 | done 117 | goods 118 | 用户 119 | role 120 | user 121 | 'user-list' 122 | vm 123 | ({code:200,msg:'done'}) 124 | {code:200,msg:'done'} 125 | {code: 400, msg: '权限不够'} 126 | res.data.code === 200 127 | this 128 | path 129 | / 130 | api. 131 | this.func 132 | (this.api 133 | .json 134 | let 135 | 136 | 137 | 138 | 145 | 146 | 147 | 148 | 149 | 150 | 205 | 206 | 207 | 208 | 209 | true 210 | DEFINITION_ORDER 211 | 212 | 213 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | BashSupport 226 | 227 | 228 | 229 | 230 | BashAddShebang 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 264 | 265 | 268 | 269 | 270 | 271 | 274 | 275 | 278 | 279 | 282 | 283 | 286 | 287 | 288 | 289 | 292 | 293 | 296 | 297 | 300 | 301 | 302 | 303 | 306 | 307 | 310 | 311 | 314 | 315 | 316 | 317 | 320 | 321 | 324 | 325 | 328 | 329 | 332 | 333 | 334 | 335 | 338 | 339 | 342 | 343 | 346 | 347 | 350 | 351 | 352 | 353 | 356 | 357 | 360 | 361 | 364 | 365 | 368 | 369 | 370 | 371 | 374 | 375 | 378 | 379 | 382 | 383 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 430 | 431 | 432 | 433 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 480 | 481 | project 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | project 498 | 499 | 500 | true 501 | 502 | 503 | 504 | DIRECTORY 505 | 506 | false 507 | 508 | 509 | 510 | 511 | 513 | 514 | C:\Users\WIN5DO\AppData\Roaming\Subversion 515 | 516 | 517 | 518 | 519 | 1493304123183 520 | 560 | 561 | 1493306950866 562 | 567 | 568 | 1493339834334 569 | 574 | 575 | 1493532113957 576 | 581 | 582 | 1493547664051 583 | 588 | 589 | 1493547914515 590 | 595 | 596 | 1493651136071 597 | 602 | 603 | 1493915915216 604 | 609 | 610 | 1494693709983 611 | 616 | 617 | 1494743457757 618 | 623 | 624 | 1494767973688 625 | 630 | 631 | 1494775843035 632 | 637 | 640 | 641 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 701 | 702 | 704 | 705 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 720 | 721 | 722 | 723 | 724 | remoteDeploymentFS://<8c748c1c-3be7-4428-bc5c-985156be3e8c>/home/back-end/app.js 725 | 13 726 | 728 | 729 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | 777 | 778 | 779 | 780 | 781 | 782 | 783 | 784 | 785 | 786 | 787 | 788 | 789 | 790 | 791 | 792 | 793 | 794 | 795 | 796 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 | 805 | 806 | 807 | 808 | 809 | 810 | 811 | 812 | 813 | 814 | 815 | 816 | 817 | 818 | 819 | 820 | 821 | 822 | 823 | 824 | 825 | 826 | 827 | 828 | 829 | 830 | 831 | 832 | 833 | 834 | 835 | 836 | 837 | 838 | 839 | 840 | 841 | 842 | 843 | 844 | 845 | 846 | 847 | 848 | 849 | 850 | 851 | 852 | 853 | 854 | 855 | 856 | 857 | 858 | 859 | 860 | 861 | 862 | 863 | 864 | 865 | 866 | 867 | 868 | 869 | 870 | 871 | 872 | 873 | 874 | 875 | 876 | 877 | 878 | 879 | 880 | 881 | 882 | 883 | 884 | 885 | 886 | 887 | 888 | 889 | 890 | 891 | 892 | 893 | 894 | 895 | 896 | 897 | 898 | 899 | 900 | 901 | 902 | 903 | 904 | 905 | 906 | 907 | 908 | 909 | 910 | 911 | 912 | 913 | 914 | 915 | 916 | 917 | 918 | 919 | 920 | 921 | 922 | 923 | 924 | 925 | 926 | 927 | 928 | 929 | 930 | 931 | 932 | 933 | 934 | 935 | 936 | 937 | 938 | 939 | 940 | 941 | 942 | 943 | 944 | 945 | 946 | 947 | 948 | 949 | 950 | 951 | 952 | 953 | 954 | 955 | 956 | 957 | 958 | 959 | 960 | 961 | 962 | 963 | 964 | 965 | 966 | 967 | 968 | 969 | 970 | 971 | 972 | 973 | 974 | 975 | 976 | 977 | 978 | 979 | 980 | 981 | 982 | 983 | 984 | 985 | 986 | 987 | 988 | 989 | 990 | 991 | 992 | 993 | 994 | 995 | 996 | 997 | 998 | 999 | 1000 | 1001 | 1002 | 1003 | 1004 | 1005 | 1006 | 1007 | 1008 | 1009 | 1010 | 1011 | 1012 | 1013 | 1014 | 1015 | 1016 | 1017 | 1018 | 1019 | 1020 | 1021 | 1022 | --------------------------------------------------------------------------------