OnePsycho 5 years ago
parent
commit
1c9bd9343c

+ 0 - 5
build/webpack.dev.conf.js

@@ -57,11 +57,6 @@ const devWebpackConfig = merge(baseWebpackConfig, {
             favicon: './favicon.ico'
         }),
         // copy custom static assets
-        new CopyWebpackPlugin([{
-            from: path.resolve(__dirname, '../static'),
-            to: config.dev.assetsSubDirectory,
-            ignore: ['.*']
-        }])
     ]
 })
 

+ 1 - 8
build/webpack.prod.conf.js

@@ -108,14 +108,7 @@ const webpackConfig = merge(baseWebpackConfig, {
       minChunks: 3
     }),
 
-    // copy custom static assets
-    new CopyWebpackPlugin([
-      {
-        from: path.resolve(__dirname, '../static'),
-        to: config.build.assetsSubDirectory,
-        ignore: ['.*']
-      }
-    ])
+
   ]
 })
 

File diff suppressed because it is too large
+ 12833 - 0
package-lock.json


+ 9 - 2
package.json

@@ -7,9 +7,11 @@
   "scripts": {
     "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
     "start": "npm run dev",
-    "build": "node build/build.js"
+    "build": "node build/build.js",
+    "deploy": "node ./upload/upload.js"
   },
   "dependencies": {
+    "ajv": "^6.10.2",
     "echarts": "^4.2.0-rc.2",
     "element-ui": "^2.3.2",
     "http-proxy-middleware": "^0.18.0",
@@ -54,7 +56,12 @@
     "webpack": "^3.6.0",
     "webpack-bundle-analyzer": "^2.9.0",
     "webpack-dev-server": "^2.9.1",
-    "webpack-merge": "^4.1.0"
+    "webpack-merge": "^4.1.0",
+    "eslint": "^5.16.0",
+    "eslint-plugin-vue": "^5.0.0",
+    "compressing": "^1.4.0",
+    "inquirer": "^7.0.0",
+    "node-ssh": "^6.0.0"
   },
   "engines": {
     "node": ">= 6.0.0",

+ 1 - 2
src/api/axiosFun.js

@@ -31,8 +31,7 @@ const req = (method, url, params) => {
         method: method,
         url: url,
         headers: {
-            'Content-Type': 'application/x-www-form-urlencoded',
-            token: localStorage.getItem('logintoken')
+            'Content-Type': 'application/x-www-form-urlencoded'
         },
         data: params,
         traditional: true,

+ 1 - 1
src/api/userMG.js

@@ -12,7 +12,7 @@ export const loginout = () => { return axios.delete("/api/login?&token=" + local
  * 用户管理 
  **/
 // 用户管理-获取用户列表
-export const userList = (params) => { return req("post", "/api/User/list", params) };
+export const userList = (params) => { return req("post", "https://hystkj.com/test/list", params) };
 // 用户管理-保存(添加编辑)
 export const userSave = (params) => { return req("post", "/api/User/save", params) };
 // 用户管理-删除用户

+ 40 - 40
src/components/leftnav.vue

@@ -85,46 +85,46 @@ export default {
               url: 'system/user',
               menus: null
             },
-            {
-              menuid: 174,
-              icon: 'icon-cms-manage',
-              menuname: '菜单管理',
-              hasThird: 'N',
-              url: 'system/Module',
-              menus: null
-            },
-            {
-              menuid: 73,
-              icon: 'icon-news-manage',
-              menuname: '角色管理',
-              hasThird: 'N',
-              url: 'system/Role',
-              menus: null
-            },
-            {
-              menuid: 74,
-              icon: 'icon-cs-manage',
-              menuname: '公司管理',
-              hasThird: 'N',
-              url: 'system/Dept',
-              menus: null
-            },
-            {
-              menuid: 75,
-              icon: 'icon-promotion-manage',
-              menuname: '系统环境变量',
-              hasThird: 'N',
-              url: 'system/Variable',
-              menus: null
-            },
-            {
-              menuid: 76,
-              icon: 'icon-cms-manage',
-              menuname: '权限管理',
-              hasThird: 'N',
-              url: 'system/Permission',
-              menus: null
-            }
+            // {
+            //   menuid: 174,
+            //   icon: 'icon-cms-manage',
+            //   menuname: '菜单管理',
+            //   hasThird: 'N',
+            //   url: 'system/Module',
+            //   menus: null
+            // },
+            // {
+            //   menuid: 73,
+            //   icon: 'icon-news-manage',
+            //   menuname: '角色管理',
+            //   hasThird: 'N',
+            //   url: 'system/Role',
+            //   menus: null
+            // },
+            // {
+            //   menuid: 74,
+            //   icon: 'icon-cs-manage',
+            //   menuname: '公司管理',
+            //   hasThird: 'N',
+            //   url: 'system/Dept',
+            //   menus: null
+            // },
+            // {
+            //   menuid: 75,
+            //   icon: 'icon-promotion-manage',
+            //   menuname: '系统环境变量',
+            //   hasThird: 'N',
+            //   url: 'system/Variable',
+            //   menus: null
+            // },
+            // {
+            //   menuid: 76,
+            //   icon: 'icon-cms-manage',
+            //   menuname: '权限管理',
+            //   hasThird: 'N',
+            //   url: 'system/Permission',
+            //   menus: null
+            // }
           ]
         },
         {

+ 1 - 0
src/router/index.js

@@ -55,6 +55,7 @@ Vue.use(Router);
 
 // 导出路由 
 export default new Router({
+    mode: 'history',
     routes: [{
         path: '/',
         name: '',

+ 18 - 237
src/views/system/user.vue

@@ -33,37 +33,23 @@
     <el-table size="small" @selection-change="selectChange" :data="userData" highlight-current-row v-loading="loading" border element-loading-text="拼命加载中" style="width: 100%;">
       <el-table-column align="center" type="selection" width="50">
       </el-table-column>
-      <el-table-column align="center" sortable prop="deptName" label="公司" width="120">
+      <el-table-column align="center" sortable prop="id" label="编号">
       </el-table-column>
-      <el-table-column align="center" sortable prop="userName" label="用户名" width="120">
+      <el-table-column align="center" sortable prop="nickName" label="微信昵称">
       </el-table-column>
-      <el-table-column align="center" sortable prop="userRealName" label="姓名" width="120">
+      <el-table-column align="center" sortable prop="openid" label="openId">
       </el-table-column>
-      <el-table-column align="center" sortable prop="userMobile" label="手机号" width="120">
-      </el-table-column>
-      <el-table-column align="center" sortable prop="userSex" label="性别" min-width="50">
-      </el-table-column>
-      <el-table-column align="center" sortable prop="userEmail" label="邮件" min-width="120">
-      </el-table-column>
-      <el-table-column align="center" sortable prop="editTime" label="修改时间" min-width="120">
+      <el-table-column align="center" sortable prop="avatarUrl" label="微信头像">
         <template slot-scope="scope">
-          <div>{{scope.row.editTime|timestampToTime}}</div>
+          <div><img :src="scope.row.avatarUrl" style="border-radius:20px;width:60px"></div>
         </template>
       </el-table-column>
-      <el-table-column align="center" sortable prop="isLock" label="状态" min-width="50">
-        <template slot-scope="scope">
-          <el-switch v-model="scope.row.isLock=='N'?nshow:fshow" active-color="#13ce66" inactive-color="#ff4949" @change="editType(scope.$index, scope.row)">
-          </el-switch>
-        </template>
+      <el-table-column align="center" sortable prop="time" label="登录时间">
       </el-table-column>
-      <el-table-column label="操作" min-width="300">
+      <el-table-column label="操作">
         <template slot-scope="scope">
           <el-button size="mini" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
           <el-button size="mini" type="danger" @click="deleteUser(scope.$index, scope.row)">删除</el-button>
-          <el-button size="mini" type="success" @click="resetpwd(scope.$index, scope.row)">重置密码</el-button>
-          <el-button size="mini" type="success" @click="dataAccess(scope.$index, scope.row)">数据权限</el-button>
-          <el-button size="mini" type="success" @click="offlineUser(scope.$index, scope.row)">下线</el-button>
-          <el-button size="mini" type="success" @click="refreshCache(scope.$index, scope.row)">刷新缓存</el-button>
         </template>
       </el-table-column>
     </el-table>
@@ -220,6 +206,7 @@ export default {
       },
       //用户数据
       userData: [],
+      originList:[],
       // 数据权限
       UserDept: [],
       defaultProps: {
@@ -252,7 +239,7 @@ export default {
    * 创建完毕
    */
   created() {
-    this.getdata(this.formInline)
+    this.getdata()
   },
 
   /**
@@ -262,221 +249,15 @@ export default {
     // 获取数据方法
     getdata(parameter) {
       this.loading = true
-      // 模拟数据开始
-      let res = {
-        code: 0,
-        msg: null,
-        count: 12,
-        data: [
-          {
-            addUser: '1',
-            editUser: '1',
-            addTime: null,
-            editTime: 1527411068000,
-            userId: 1,
-            systemNo: 'pmd',
-            userName: 'root',
-            userPassword: 'e10adc3949ba59abbe56e057f20f883e',
-            userRealName: '超级管理员',
-            userSex: '女',
-            userMobile: '138123456789',
-            userEmail: '111@qq.com',
-            isLock: 'N',
-            deptId: 1,
-            deptName: 'xxxx',
-            roleId: 1
-          },
-          {
-            addUser: '1',
-            editUser: '1',
-            addTime: null,
-            editTime: 1527410579000,
-            userId: 3,
-            systemNo: 'mc',
-            userName: 'zengzhuo',
-            userPassword: 'e10adc3949ba59abbe56e057f20f883e',
-            userRealName: '系统管理员',
-            userSex: 'M',
-            userMobile: '18616988966',
-            userEmail: '222@qq.com',
-            isLock: 'N',
-            deptId: 2,
-            deptName: 'xxxx',
-            roleId: 101
-          },
-          {
-            addUser: '1',
-            editUser: '4',
-            addTime: null,
-            editTime: 1527411586000,
-            userId: 4,
-            systemNo: 'ec',
-            userName: 'admin',
-            userPassword: '59ba8b7dda9ff79186311a5a9fa155ca',
-            userRealName: '超级管理员',
-            userSex: '女',
-            userMobile: '138123456789',
-            userEmail: 'huangxuekun@founder.com',
-            isLock: 'N',
-            deptId: 2,
-            deptName: 'xxxx',
-            roleId: 3
-          },
-          {
-            addUser: null,
-            editUser: null,
-            addTime: 1526275128000,
-            editTime: 1526284402000,
-            userId: 28,
-            systemNo: null,
-            userName: 'eee111',
-            userPassword: 'e10adc3949ba59abbe56e057f20f883e',
-            userRealName: '123111',
-            userSex: '男',
-            userMobile: '12354342345',
-            userEmail: '111232@qq.com',
-            isLock: 'N',
-            deptId: 4,
-            deptName: 'zxxxxx',
-            roleId: 1
-          },
-          {
-            addUser: null,
-            editUser: null,
-            addTime: 1526284533000,
-            editTime: 1526284533000,
-            userId: 37,
-            systemNo: null,
-            userName: 'ces',
-            userPassword: 'e10adc3949ba59abbe56e057f20f883e',
-            userRealName: 'sesfg',
-            userSex: '男',
-            userMobile: '12312312312',
-            userEmail: '122111111',
-            isLock: 'N',
-            deptId: 1,
-            deptName: 'xxxx',
-            roleId: 1
-          },
-          {
-            addUser: null,
-            editUser: null,
-            addTime: 1526285228000,
-            editTime: 1526285228000,
-            userId: 43,
-            systemNo: null,
-            userName: '22',
-            userPassword: 'e10adc3949ba59abbe56e057f20f883e',
-            userRealName: '22',
-            userSex: '男',
-            userMobile: '222',
-            userEmail: '222',
-            isLock: 'N',
-            deptId: 1,
-            deptName: 'xxxx',
-            roleId: 1
-          },
-          {
-            addUser: null,
-            editUser: null,
-            addTime: 1526448593000,
-            editTime: 1526448593000,
-            userId: 58,
-            systemNo: null,
-            userName: '1',
-            userPassword: 'e10adc3949ba59abbe56e057f20f883e',
-            userRealName: '1',
-            userSex: '女',
-            userMobile: '13607118810',
-            userEmail: '1@qq.com',
-            isLock: 'N',
-            deptId: 1,
-            deptName: 'xxxx',
-            roleId: 1
-          },
-          {
-            addUser: null,
-            editUser: null,
-            addTime: 1526452698000,
-            editTime: 1526520341000,
-            userId: 60,
-            systemNo: null,
-            userName: '222222222',
-            userPassword: 'e10adc3949ba59abbe56e057f20f883e',
-            userRealName: '222222222222',
-            userSex: '男',
-            userMobile: '13607118810',
-            userEmail: '111@qq.com',
-            isLock: 'N',
-            deptId: 1,
-            deptName: 'xxxx',
-            roleId: 1
-          },
-          {
-            addUser: null,
-            editUser: null,
-            addTime: 1526452731000,
-            editTime: 1526452731000,
-            userId: 61,
-            systemNo: null,
-            userName: '33333333333333',
-            userPassword: 'e10adc3949ba59abbe56e057f20f883e',
-            userRealName: '4444444444444444444',
-            userSex: '女',
-            userMobile: '13607118810',
-            userEmail: 'qqq@qq.com',
-            isLock: 'N',
-            deptId: 1,
-            deptName: 'xxxx',
-            roleId: 2
-          },
-          {
-            addUser: null,
-            editUser: null,
-            addTime: 1526452756000,
-            editTime: 1527128981000,
-            userId: 62,
-            systemNo: null,
-            userName: '211111111',
-            userPassword: 'e10adc3949ba59abbe56e057f20f883e',
-            userRealName: '21111111111',
-            userSex: '男',
-            userMobile: '13601478451',
-            userEmail: '222222@qq.com',
-            isLock: 'N',
-            deptId: 17,
-            deptName: 'v',
-            roleId: 2
-          }
-        ]
-      }
-      this.loading = false
-      this.userData = res.data
-      // 分页赋值
-      this.pageparm.currentPage = this.formInline.page
-      this.pageparm.pageSize = this.formInline.limit
-      this.pageparm.total = res.count
-      // 模拟数据结束
-
-      /***
-       * 调用接口,注释上面模拟数据 取消下面注释
-       */
-      // 获取用户列表
-      // userList(parameter).then(res => {
-      //   this.loading = false
-      //   if (res.success == false) {
-      //     this.$message({
-      //       type: 'info',
-      //       message: res.msg
-      //     })
-      //   } else {
-      //     this.userData = res.data
-      //     // 分页赋值
-      //     this.pageparm.currentPage = this.formInline.page
-      //     this.pageparm.pageSize = this.formInline.limit
-      //     this.pageparm.total = res.count
-      //   }
-      // })
+      //获取用户列表
+      userList({}).then(res => {
+          this.loading = false
+          // this.originList = res.reverse()
+          this.userData = res.reverse()
+          // 分页赋值
+          this.pageparm.currentPage = this.formInline.page
+          this.pageparm.pageSize = this.formInline.limit
+      })
     },
     // 分页插件事件
     callFather(parm) {

+ 0 - 0
static/.gitkeep


BIN
static/gif.gif


BIN
static/交易订单.png


BIN
static/商品管理.png


BIN
static/展开与压缩.png


BIN
static/支付配置.png


BIN
static/用户管理.png


BIN
static/登录.png


BIN
static/编辑.png


BIN
static/角色管理.png


+ 16 - 0
upload/config.js

@@ -0,0 +1,16 @@
+module.exports = Object.freeze({
+  development: {//测试
+    SERVER_PATH: '39.108.193.144', // ssh地址 服务器地址
+    SSH_USER: 'root', // ssh 用户名
+    //方式一 用秘钥登录服务器(推荐), private 本机私钥文件地址(需要在服务器用户目录 一般是 /root/.ssh/authorized_keys 配置公钥 并该文件权限为 600, (.ssh文件夹一般默认隐藏)
+    // PRIVATE_KEY: 'C:/Users/Html5/.ssh/id_rsa', 
+    PASSWORD: 'Zxj56295650!', //方式二 用密码连接服务器
+    PATH: '/www/myAdmin' // 需要上传的服务器目录地址 如 /usr/local/nginx/html
+  },
+  production: {//正式
+    SERVER_PATH: '39.108.193.144', 
+    SSH_USER: 'root',
+    PASSWORD: 'Zxj56295650!', 
+    PATH: '/www/myAdmin' 
+  }
+})

+ 937 - 0
upload/spinner_style.js

@@ -0,0 +1,937 @@
+const style = {
+	"dots": {
+		"interval": 80,
+		"frames": [
+			"⠋",
+			"⠙",
+			"⠹",
+			"⠸",
+			"⠼",
+			"⠴",
+			"⠦",
+			"⠧",
+			"⠇",
+			"⠏"
+		]
+	},
+	"dots2": {
+		"interval": 80,
+		"frames": [
+			"⣾",
+			"⣽",
+			"⣻",
+			"⢿",
+			"⡿",
+			"⣟",
+			"⣯",
+			"⣷"
+		]
+	},
+	"dots3": {
+		"interval": 80,
+		"frames": [
+			"⠋",
+			"⠙",
+			"⠚",
+			"⠞",
+			"⠖",
+			"⠦",
+			"⠴",
+			"⠲",
+			"⠳",
+			"⠓"
+		]
+	},
+	"dots4": {
+		"interval": 80,
+		"frames": [
+			"⠄",
+			"⠆",
+			"⠇",
+			"⠋",
+			"⠙",
+			"⠸",
+			"⠰",
+			"⠠",
+			"⠰",
+			"⠸",
+			"⠙",
+			"⠋",
+			"⠇",
+			"⠆"
+		]
+	},
+	"dots5": {
+		"interval": 80,
+		"frames": [
+			"⠋",
+			"⠙",
+			"⠚",
+			"⠒",
+			"⠂",
+			"⠂",
+			"⠒",
+			"⠲",
+			"⠴",
+			"⠦",
+			"⠖",
+			"⠒",
+			"⠐",
+			"⠐",
+			"⠒",
+			"⠓",
+			"⠋"
+		]
+	},
+	"dots6": {
+		"interval": 80,
+		"frames": [
+			"⠁",
+			"⠉",
+			"⠙",
+			"⠚",
+			"⠒",
+			"⠂",
+			"⠂",
+			"⠒",
+			"⠲",
+			"⠴",
+			"⠤",
+			"⠄",
+			"⠄",
+			"⠤",
+			"⠴",
+			"⠲",
+			"⠒",
+			"⠂",
+			"⠂",
+			"⠒",
+			"⠚",
+			"⠙",
+			"⠉",
+			"⠁"
+		]
+	},
+	"dots7": {
+		"interval": 80,
+		"frames": [
+			"⠈",
+			"⠉",
+			"⠋",
+			"⠓",
+			"⠒",
+			"⠐",
+			"⠐",
+			"⠒",
+			"⠖",
+			"⠦",
+			"⠤",
+			"⠠",
+			"⠠",
+			"⠤",
+			"⠦",
+			"⠖",
+			"⠒",
+			"⠐",
+			"⠐",
+			"⠒",
+			"⠓",
+			"⠋",
+			"⠉",
+			"⠈"
+		]
+	},
+	"dots8": {
+		"interval": 80,
+		"frames": [
+			"⠁",
+			"⠁",
+			"⠉",
+			"⠙",
+			"⠚",
+			"⠒",
+			"⠂",
+			"⠂",
+			"⠒",
+			"⠲",
+			"⠴",
+			"⠤",
+			"⠄",
+			"⠄",
+			"⠤",
+			"⠠",
+			"⠠",
+			"⠤",
+			"⠦",
+			"⠖",
+			"⠒",
+			"⠐",
+			"⠐",
+			"⠒",
+			"⠓",
+			"⠋",
+			"⠉",
+			"⠈",
+			"⠈"
+		]
+	},
+	"dots9": {
+		"interval": 80,
+		"frames": [
+			"⢹",
+			"⢺",
+			"⢼",
+			"⣸",
+			"⣇",
+			"⡧",
+			"⡗",
+			"⡏"
+		]
+	},
+	"dots10": {
+		"interval": 80,
+		"frames": [
+			"⢄",
+			"⢂",
+			"⢁",
+			"⡁",
+			"⡈",
+			"⡐",
+			"⡠"
+		]
+	},
+	"dots11": {
+		"interval": 100,
+		"frames": [
+			"⠁",
+			"⠂",
+			"⠄",
+			"⡀",
+			"⢀",
+			"⠠",
+			"⠐",
+			"⠈"
+		]
+	},
+	"dots12": {
+		"interval": 80,
+		"frames": [
+			"⢀⠀",
+			"⡀⠀",
+			"⠄⠀",
+			"⢂⠀",
+			"⡂⠀",
+			"⠅⠀",
+			"⢃⠀",
+			"⡃⠀",
+			"⠍⠀",
+			"⢋⠀",
+			"⡋⠀",
+			"⠍⠁",
+			"⢋⠁",
+			"⡋⠁",
+			"⠍⠉",
+			"⠋⠉",
+			"⠋⠉",
+			"⠉⠙",
+			"⠉⠙",
+			"⠉⠩",
+			"⠈⢙",
+			"⠈⡙",
+			"⢈⠩",
+			"⡀⢙",
+			"⠄⡙",
+			"⢂⠩",
+			"⡂⢘",
+			"⠅⡘",
+			"⢃⠨",
+			"⡃⢐",
+			"⠍⡐",
+			"⢋⠠",
+			"⡋⢀",
+			"⠍⡁",
+			"⢋⠁",
+			"⡋⠁",
+			"⠍⠉",
+			"⠋⠉",
+			"⠋⠉",
+			"⠉⠙",
+			"⠉⠙",
+			"⠉⠩",
+			"⠈⢙",
+			"⠈⡙",
+			"⠈⠩",
+			"⠀⢙",
+			"⠀⡙",
+			"⠀⠩",
+			"⠀⢘",
+			"⠀⡘",
+			"⠀⠨",
+			"⠀⢐",
+			"⠀⡐",
+			"⠀⠠",
+			"⠀⢀",
+			"⠀⡀"
+		]
+	},
+	"line": {
+		"interval": 130,
+		"frames": [
+			"-",
+			"\\",
+			"|",
+			"/"
+		]
+	},
+	"line2": {
+		"interval": 100,
+		"frames": [
+			"⠂",
+			"-",
+			"–",
+			"—",
+			"–",
+			"-"
+		]
+	},
+	"pipe": {
+		"interval": 100,
+		"frames": [
+			"┤",
+			"┘",
+			"┴",
+			"└",
+			"├",
+			"┌",
+			"┬",
+			"┐"
+		]
+	},
+	"simpleDots": {
+		"interval": 400,
+		"frames": [
+			".  ",
+			".. ",
+			"...",
+			"   "
+		]
+	},
+	"simpleDotsScrolling": {
+		"interval": 200,
+		"frames": [
+			".  ",
+			".. ",
+			"...",
+			" ..",
+			"  .",
+			"   "
+		]
+	},
+	"star": {
+		"interval": 70,
+		"frames": [
+			"✶",
+			"✸",
+			"✹",
+			"✺",
+			"✹",
+			"✷"
+		]
+	},
+	"star2": {
+		"interval": 80,
+		"frames": [
+			"+",
+			"x",
+			"*"
+		]
+	},
+	"flip": {
+		"interval": 70,
+		"frames": [
+			"_",
+			"_",
+			"_",
+			"-",
+			"`",
+			"`",
+			"'",
+			"´",
+			"-",
+			"_",
+			"_",
+			"_"
+		]
+	},
+	"hamburger": {
+		"interval": 100,
+		"frames": [
+			"☱",
+			"☲",
+			"☴"
+		]
+	},
+	"growVertical": {
+		"interval": 120,
+		"frames": [
+			"▁",
+			"▃",
+			"▄",
+			"▅",
+			"▆",
+			"▇",
+			"▆",
+			"▅",
+			"▄",
+			"▃"
+		]
+	},
+	"growHorizontal": {
+		"interval": 120,
+		"frames": [
+			"▏",
+			"▎",
+			"▍",
+			"▌",
+			"▋",
+			"▊",
+			"▉",
+			"▊",
+			"▋",
+			"▌",
+			"▍",
+			"▎"
+		]
+	},
+	"balloon": {
+		"interval": 140,
+		"frames": [
+			" ",
+			".",
+			"o",
+			"O",
+			"@",
+			"*",
+			" "
+		]
+	},
+	"balloon2": {
+		"interval": 120,
+		"frames": [
+			".",
+			"o",
+			"O",
+			"°",
+			"O",
+			"o",
+			"."
+		]
+	},
+	"noise": {
+		"interval": 100,
+		"frames": [
+			"▓",
+			"▒",
+			"░"
+		]
+	},
+	"bounce": {
+		"interval": 120,
+		"frames": [
+			"⠁",
+			"⠂",
+			"⠄",
+			"⠂"
+		]
+	},
+	"boxBounce": {
+		"interval": 120,
+		"frames": [
+			"▖",
+			"▘",
+			"▝",
+			"▗"
+		]
+	},
+	"boxBounce2": {
+		"interval": 100,
+		"frames": [
+			"▌",
+			"▀",
+			"▐",
+			"▄"
+		]
+	},
+	"triangle": {
+		"interval": 50,
+		"frames": [
+			"◢",
+			"◣",
+			"◤",
+			"◥"
+		]
+	},
+	"arc": {
+		"interval": 100,
+		"frames": [
+			"◜",
+			"◠",
+			"◝",
+			"◞",
+			"◡",
+			"◟"
+		]
+	},
+	"circle": {
+		"interval": 120,
+		"frames": [
+			"◡",
+			"⊙",
+			"◠"
+		]
+	},
+	"squareCorners": {
+		"interval": 180,
+		"frames": [
+			"◰",
+			"◳",
+			"◲",
+			"◱"
+		]
+	},
+	"circleQuarters": {
+		"interval": 120,
+		"frames": [
+			"◴",
+			"◷",
+			"◶",
+			"◵"
+		]
+	},
+	"circleHalves": {
+		"interval": 50,
+		"frames": [
+			"◐",
+			"◓",
+			"◑",
+			"◒"
+		]
+	},
+	"squish": {
+		"interval": 100,
+		"frames": [
+			"╫",
+			"╪"
+		]
+	},
+	"toggle": {
+		"interval": 250,
+		"frames": [
+			"⊶",
+			"⊷"
+		]
+	},
+	"toggle2": {
+		"interval": 80,
+		"frames": [
+			"▫",
+			"▪"
+		]
+	},
+	"toggle3": {
+		"interval": 120,
+		"frames": [
+			"□",
+			"■"
+		]
+	},
+	"toggle4": {
+		"interval": 100,
+		"frames": [
+			"■",
+			"□",
+			"▪",
+			"▫"
+		]
+	},
+	"toggle5": {
+		"interval": 100,
+		"frames": [
+			"▮",
+			"▯"
+		]
+	},
+	"toggle6": {
+		"interval": 300,
+		"frames": [
+			"ဝ",
+			"၀"
+		]
+	},
+	"toggle7": {
+		"interval": 80,
+		"frames": [
+			"⦾",
+			"⦿"
+		]
+	},
+	"toggle8": {
+		"interval": 100,
+		"frames": [
+			"◍",
+			"◌"
+		]
+	},
+	"toggle9": {
+		"interval": 100,
+		"frames": [
+			"◉",
+			"◎"
+		]
+	},
+	"toggle10": {
+		"interval": 100,
+		"frames": [
+			"㊂",
+			"㊀",
+			"㊁"
+		]
+	},
+	"toggle11": {
+		"interval": 50,
+		"frames": [
+			"⧇",
+			"⧆"
+		]
+	},
+	"toggle12": {
+		"interval": 120,
+		"frames": [
+			"☗",
+			"☖"
+		]
+	},
+	"toggle13": {
+		"interval": 80,
+		"frames": [
+			"=",
+			"*",
+			"-"
+		]
+	},
+	"arrow": {
+		"interval": 100,
+		"frames": [
+			"←",
+			"↖",
+			"↑",
+			"↗",
+			"→",
+			"↘",
+			"↓",
+			"↙"
+		]
+	},
+	"arrow2": {
+		"interval": 80,
+		"frames": [
+			"⬆️ ",
+			"↗️ ",
+			"➡️ ",
+			"↘️ ",
+			"⬇️ ",
+			"↙️ ",
+			"⬅️ ",
+			"↖️ "
+		]
+  },
+	"arrow3": {
+		"interval": 120,
+		"frames": [
+			"▹▹▹▹▹",
+			"▸▹▹▹▹",
+			"▹▸▹▹▹",
+			"▹▹▸▹▹",
+			"▹▹▹▸▹",
+			"▹▹▹▹▸"
+		]
+  },
+  "arrow4": {
+		"interval": 80,
+		"frames": [
+      "[>            ]",
+      "[>>>          ]",
+      "[>>>>>        ]",
+      "[>>>>>>>      ]",
+      "[>>>>>>>>>    ]",
+      "[>>>>>>>>>>>  ]",
+      "[>>>>>>>>>>>>>]"
+		]
+	},
+	"bouncingBar": {
+		"interval": 80,
+		"frames": [
+			"[    ]",
+			"[=   ]",
+			"[==  ]",
+			"[=== ]",
+			"[ ===]",
+			"[  ==]",
+			"[   =]",
+			"[    ]",
+			"[   =]",
+			"[  ==]",
+			"[ ===]",
+			"[====]",
+			"[=== ]",
+			"[==  ]",
+			"[=   ]"
+		]
+	},
+	"bouncingBall": {
+		"interval": 80,
+		"frames": [
+			"( ●    )",
+			"(  ●   )",
+			"(   ●  )",
+			"(    ● )",
+			"(     ●)",
+			"(    ● )",
+			"(   ●  )",
+			"(  ●   )",
+			"( ●    )",
+			"(●     )"
+		]
+	},
+	"smiley": {
+		"interval": 200,
+		"frames": [
+			"😄 ",
+			"😝 "
+		]
+	},
+	"monkey": {
+		"interval": 300,
+		"frames": [
+			"🙈 ",
+			"🙈 ",
+			"🙉 ",
+			"🙊 "
+		]
+	},
+	"hearts": {
+		"interval": 100,
+		"frames": [
+			"💛 ",
+			"💙 ",
+			"💜 ",
+			"💚 ",
+			"❤️ "
+		]
+	},
+	"clock": {
+		"interval": 100,
+		"frames": [
+			"🕛 ",
+			"🕐 ",
+			"🕑 ",
+			"🕒 ",
+			"🕓 ",
+			"🕔 ",
+			"🕕 ",
+			"🕖 ",
+			"🕗 ",
+			"🕘 ",
+			"🕙 ",
+			"🕚 "
+		]
+	},
+	"earth": {
+		"interval": 180,
+		"frames": [
+			"🌍 ",
+			"🌎 ",
+			"🌏 "
+		]
+	},
+	"moon": {
+		"interval": 80,
+		"frames": [
+			"🌑 ",
+			"🌒 ",
+			"🌓 ",
+			"🌔 ",
+			"🌕 ",
+			"🌖 ",
+			"🌗 ",
+			"🌘 "
+		]
+	},
+	"runner": {
+		"interval": 140,
+		"frames": [
+			"🚶 ",
+			"🏃 "
+		]
+	},
+	"pong": {
+		"interval": 80,
+		"frames": [
+			"▐⠂       ▌",
+			"▐⠈       ▌",
+			"▐ ⠂      ▌",
+			"▐ ⠠      ▌",
+			"▐  ⡀     ▌",
+			"▐  ⠠     ▌",
+			"▐   ⠂    ▌",
+			"▐   ⠈    ▌",
+			"▐    ⠂   ▌",
+			"▐    ⠠   ▌",
+			"▐     ⡀  ▌",
+			"▐     ⠠  ▌",
+			"▐      ⠂ ▌",
+			"▐      ⠈ ▌",
+			"▐       ⠂▌",
+			"▐       ⠠▌",
+			"▐       ⡀▌",
+			"▐      ⠠ ▌",
+			"▐      ⠂ ▌",
+			"▐     ⠈  ▌",
+			"▐     ⠂  ▌",
+			"▐    ⠠   ▌",
+			"▐    ⡀   ▌",
+			"▐   ⠠    ▌",
+			"▐   ⠂    ▌",
+			"▐  ⠈     ▌",
+			"▐  ⠂     ▌",
+			"▐ ⠠      ▌",
+			"▐ ⡀      ▌",
+			"▐⠠       ▌"
+		]
+	},
+	"shark": {
+		"interval": 120,
+		"frames": [
+			"▐|\\____________▌",
+			"▐_|\\___________▌",
+			"▐__|\\__________▌",
+			"▐___|\\_________▌",
+			"▐____|\\________▌",
+			"▐_____|\\_______▌",
+			"▐______|\\______▌",
+			"▐_______|\\_____▌",
+			"▐________|\\____▌",
+			"▐_________|\\___▌",
+			"▐__________|\\__▌",
+			"▐___________|\\_▌",
+			"▐____________|\\▌",
+			"▐____________/|▌",
+			"▐___________/|_▌",
+			"▐__________/|__▌",
+			"▐_________/|___▌",
+			"▐________/|____▌",
+			"▐_______/|_____▌",
+			"▐______/|______▌",
+			"▐_____/|_______▌",
+			"▐____/|________▌",
+			"▐___/|_________▌",
+			"▐__/|__________▌",
+			"▐_/|___________▌",
+			"▐/|____________▌"
+		]
+	},
+	"dqpb": {
+		"interval": 100,
+		"frames": [
+			"d",
+			"q",
+			"p",
+			"b"
+		]
+	},
+	"weather": {
+		"interval": 100,
+		"frames": [
+			"☀️ ",
+			"☀️ ",
+			"☀️ ",
+			"🌤 ",
+			"⛅️ ",
+			"🌥 ",
+			"☁️ ",
+			"🌧 ",
+			"🌨 ",
+			"🌧 ",
+			"🌨 ",
+			"🌧 ",
+			"🌨 ",
+			"⛈ ",
+			"🌨 ",
+			"🌧 ",
+			"🌨 ",
+			"☁️ ",
+			"🌥 ",
+			"⛅️ ",
+			"🌤 ",
+			"☀️ ",
+			"☀️ "
+		]
+	},
+	"christmas": {
+		"interval": 400,
+		"frames": [
+			"🌲",
+			"🎄"
+		]
+	},
+	"grenade": {
+		"interval": 80,
+		"frames": [
+			"،   ",
+			"′   ",
+			" ´ ",
+ 			" ‾ ",
+			"  ⸌",
+			"  ⸊",
+			"  |",
+			"  ⁎",
+			"  ⁕",
+			" ෴ ",
+			"  ⁓",
+			"   ",
+			"   ",
+			"   "
+		]
+	},
+	"point": {
+		"interval": 125,
+		"frames": [
+			"∙∙∙",
+			"●∙∙",
+			"∙●∙",
+			"∙∙●",
+			"∙∙∙"
+		]
+	},
+	"layer": {
+		"interval": 150,
+		"frames": [
+			"-",
+			"=",
+			"≡"
+		]
+	},
+	"betaWave": {
+		"interval": 80,
+		"frames": [
+			"ρββββββ",
+			"βρβββββ",
+			"ββρββββ",
+			"βββρβββ",
+			"ββββρββ",
+			"βββββρβ",
+			"ββββββρ"
+		]
+	}
+}
+module.exports = style;

+ 172 - 0
upload/upload.js

@@ -0,0 +1,172 @@
+const chalk = require('chalk') //命令行颜色
+const ora = require('ora') // 加载流程动画
+const spinner_style = require('./spinner_style') //加载动画样式
+const shell = require('shelljs') // 执行shell命令
+const node_ssh = require('node-ssh') // ssh连接服务器
+const inquirer = require('inquirer') //命令行交互
+const zipFile = require('compressing')// 压缩zip
+const fs = require('fs') // nodejs内置文件模块
+const path = require('path') // nodejs内置路径模块
+const CONFIG = require('./config') // 配置
+
+const SSH = new node_ssh();
+let config; // 用于保存 inquirer 命令行交互后选择正式|测试版的配置
+
+//logs
+const defaultLog = log => console.log(chalk.blue(`---------------- ${log} ----------------`));
+const errorLog = log => console.log(chalk.red(`---------------- ${log} ----------------`));
+const successLog = log => console.log(chalk.green(`---------------- ${log} ----------------`));
+
+//文件夹目录
+const distDir = path.resolve(__dirname, '../dist'); //待打包
+const distZipPath = path.resolve(__dirname, `../dist.zip`); //打包后地址(dist.zip是文件名,不需要更改, 主要在config中配置 PATH 即可)
+
+
+//项目打包代码 npm run build 
+const compileDist = async () => {
+  const loading = ora( defaultLog('项目开始打包') ).start();
+  loading.spinner = spinner_style.arrow4;
+  shell.cd(path.resolve(__dirname, '../'));
+  const res = await shell.exec('npm run build'); //执行shell 打包命令
+  loading.stop();
+  if(res.code === 0) {
+    successLog('项目打包成功!');
+  } else {
+    errorLog('项目打包失败, 请重试!');
+    process.exit(); //退出流程
+  }
+}
+
+//压缩代码
+const zipDist = async ()=>{
+  defaultLog('项目开始压缩');
+  try {
+    await zipFile.zip.compressDir(distDir, distZipPath)
+    successLog('压缩成功!');
+  } catch (error) {
+    errorLog(error);
+    errorLog('压缩失败, 退出程序!');
+    process.exit(); //退出流程
+  }
+}
+
+//连接服务器
+const connectSSH = async ()=>{
+  const loading = ora( defaultLog('正在连接服务器') ).start();
+  loading.spinner = spinner_style.arrow4;
+  try {
+    await SSH.connect({
+      host: config.SERVER_PATH,
+      username: config.SSH_USER,
+      // privateKey: config.PRIVATE_KEY, //秘钥登录(推荐) 方式一
+      password: config.PASSWORD // 密码登录 方式二
+    });
+    successLog('SSH连接成功!'); 
+  } catch (error) {
+    errorLog(error);
+    errorLog('SSH连接失败!');
+    process.exit(); //退出流程
+  }
+  loading.stop();
+}
+
+//线上执行命令
+/**
+ * 
+ * @param {String} command 命令操作 如 ls
+ */
+const runCommand = async (command)=> {
+  const result = await SSH.exec(command, [], { cwd: config.PATH})
+  // defaultLog(result);
+}
+
+//清空线上目标目录里的旧文件
+const clearOldFile = async () =>{
+  const commands = ['ls', 'rm -rf *'];
+  await Promise.all(commands.map(async (it)=>{
+    return await runCommand(it);
+  }));
+}
+
+//传送zip文件到服务器
+const uploadZipBySSH = async () =>{
+  //连接ssh
+  await connectSSH();
+  //线上目标文件清空
+  await clearOldFile();
+  const loading = ora( defaultLog('准备上传文件') ).start();
+  loading.spinner = spinner_style.arrow4;
+  try {
+    await SSH.putFiles([{ local: distZipPath, remote: config.PATH + '/dist.zip' }]); //local 本地 ; remote 服务器 ;
+    successLog('上传成功!'); 
+    loading.text = '正在解压文件';
+    await runCommand('unzip ./dist.zip'); //解压
+    await runCommand(`rm -rf ${config.PATH}/dist.zip`); //解压完删除线上压缩包
+    //将目标目录的dist里面文件移出到目标文件  
+    //举个例子 假如我们部署在 /test/html 这个目录下 只有一个网站, 那么上传解压后的文件在 /test/html/dist 里
+    //需要将 dist 目录下的文件 移出到 /test/html ;  多网站情况, 如 /test/html/h5  或者 /test/html/admin 都和上面同样道理
+    await runCommand(`mv -f ${config.PATH}/dist/*  ${config.PATH}`); 
+    await runCommand(`rm -rf ${config.PATH}/dist`); //移出后删除 dist 文件夹
+    SSH.dispose(); //断开连接
+  } catch (error) {
+    errorLog(error);
+    errorLog('上传失败!');
+    process.exit(); //退出流程
+  }
+  loading.stop();
+}
+
+
+
+//------------发布程序---------------
+const runUploadTask = async () => {
+  console.log(chalk.yellow(`--------->  欢迎使用 OnePsycho.com 2020年自动部署工具  <---------`));
+  //打包
+  await compileDist();
+  //压缩
+  await zipDist();
+  //连接服务器上传文件
+  await uploadZipBySSH(); 
+  successLog('大吉大利, 部署成功!'); 
+  process.exit();
+}
+
+// 开始前的配置检查
+/**
+ * 
+ * @param {Object} conf 配置对象
+ */
+const checkConfig = (conf) =>{
+  const checkArr = Object.entries(conf);
+  checkArr.map(it=>{
+    const key = it[0];
+    if(key === 'PATH' && conf[key] === '/') { //上传zip前会清空目标目录内所有文件
+      errorLog('PATH 不能是服务器根目录!'); 
+      process.exit(); //退出流程
+    }
+    if(!conf[key]) {
+      errorLog(`配置项 ${key} 不能为空`); 
+      process.exit(); //退出流程
+    }
+  })
+}
+
+// 执行交互后 启动发布程序
+inquirer
+  .prompt([{
+    type: 'list',
+    message: '请选择发布环境',
+    name: 'env',
+    choices: [{
+      name: '测试环境',
+      value: 'development'
+    },{
+      name: '正式环境',
+      value: 'production'
+    }]
+  }])
+  .then(answers => {
+    config = CONFIG[answers.env];
+    checkConfig(config); // 检查
+    runUploadTask(); // 发布
+  });