vue+nodejs+express+mysql 創建一個在線網盤程序

vue+nodejs+express+mysql 創建一個在線網盤程序

目錄

代碼戳這裏--> codecss

第一章 開發環境準備

1.1 開發所用工具簡介

主要開發所用工具:html

  • MySQL、Express、NodeJS、Vue
  • 其餘工具: element-ui、axios

1.2 安裝 MySQL

1.2.1 下載安裝 MySQL

參照: MySQL 安裝 | 菜鳥教程前端

1.2.2 可能出現的問題和解決方案

1.提示:Found option without preceding group in config file:XXX; Fatal error in defaults handling.
解決方法:用電腦的記事本打開my.ini文件,將其另存爲 ANSI 編碼格式並替換原來的my.ini文件vue

2.提示:you must reset your password using ALTER USER statement before executing this statement.
解決方法:從新設置密碼
在 mysql 環境下,輸入alter user user() identified by "123456";退出 sql 從新登陸便可。node

1.3 安裝 vue-cli

  1. 新建一個文件夾cloud-drive,在該文件下中使用 webpack 生成一個 vue 項目

參考代碼以下:mysql

mkdir cloud-drive
cd cloud-drive

cnpm install vue-cli -g
vue init webpack "client" //創建一個名稱爲client的前端項目
cnpm install // 安裝依賴
npm run dev
  1. 在執行npm run dev後,在瀏覽器中輸入http://localhost:8080/#後顯示如下界面,則 client 項目生成完畢!
    vue初始化界面

1.4 安裝 express

1.在cloud-drive下創建一個文件夾,名稱爲 server,用於存放服務端的代碼。webpack

mkdir server
cd server
  1. server文件夾下利用npm init -f生成一個package.json文件.
  2. package.json文件添加啓動項目代碼
...
"scripts": {
    "start": "node src/app.js", // 加入這一條用於啓動程序
    "test": "echo \"Error: no test specified\" && exit 1"
  },

...

4.在server文件夾下建立src文件夾,在src文件夾下建立app.js文件,在app.js寫入如下信息用於測試ios

console.log('Hello World!');
  1. 執行npm start命令,輸出信息如如下表明成功
Hello World!
  1. 安裝 express 框架
npm install express --save
  1. 安裝其餘的依賴
npm install body-parser cors morgan nodemon multer md5 --save
  • body-parser 解析
  • cors 跨域
  • morgan 日誌記錄
  • nodemon 程序調試自啓
  • multer 文件上傳中間件
  • md5 生成 md5 碼模塊 8.將src/app.js用如下內容替代,該內容建立了一個運行於 8081 接口的服務器,創建了一個測試用接口,名稱爲 posts
const express = require('express')
const bodyParser = require('body-parser')
const cors = require('cors')
const morgan = require('morgan')

const app = express()
app.use(morgan('combined'))
app.use(bodyParser.json())
app.use(cors())

app.get('/posts', (req, res) => {
  res.send(
    [{
      title: "Hello World!",
      description: "Hi there! How are you?"
    }]
  )
})

app.listen(process.env.PORT || 8081)

9.修改package.json文件,採用 nodemon 啓動git

"scripts": {
    "start": "nodemon src/app.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },

10.使用npm start啓動應用,在瀏覽器中訪問localhost:8081/posts地址,如若成功,應該看到如下信息
後端環境準備成功
至此,後端環境準備完畢github

第二章 數據庫設計和建立

2.1 數據庫和表設計

  • 數據庫名稱:cloud_drive
  • 數據庫表: user 表和 file 表

2.2 user 表

user 表:管理網盤註冊用戶信息

字段 中文釋義 類型 是否爲空 默認值 其餘
uid 用戶 id int(10) unsigned NO 主鍵 null auto_increment
username 用戶名 varchar(20) NO null
password 密碼 varchar(20) NO null

2.3 file 表

file 表:管理用戶上傳文件信息

字段 中文釋義 類型 是否爲空 默認值 其餘
id 文件 id int(10) unsigned NO 主鍵 auto_increment
file_name 文件名稱 varchar(255) NO null
hash_name 使用 hash 算法生成的文件名稱 varchar(255) NO null
upload_time 上傳時間 varchar(255) No null
type 文件類型 varchar(255) No null
size 文件大小 varchar(255) No null
download 下載次數 varchar(255) No null
uid 上傳用戶 id int(10) unsigned No 外鍵 null

2.4 建立數據庫和表所用 sql 語句參考

  1. 建立數據庫cloud_drive和表user語句
DROP DATABASE IF EXISTS cloud_drive;
CREATE DATABASE cloud_drive;
use cloud_drive;
DROP TABLE IF EXISTS user;
CREATE TABLE IF NOT EXISTS `user`(
   `uid` INT UNSIGNED AUTO_INCREMENT COMMENT '用戶id',
   `username` VARCHAR(20) NOT NULL COMMENT '用戶名',
   `password` VARCHAR(20) NOT NULL COMMENT '密碼',
   PRIMARY KEY ( `uid` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT '用戶表';
  1. 建立用戶上傳文件表
use cloud_drive;
DROP TABLE IF EXISTS file;
CREATE TABLE `file`
(
    id int(10) AUTO_INCREMENT COMMENT '文件id',
    file_name varchar(200) NOT NULL COMMENT '文件名稱',
    hash_name varchar(200) NOT NULL COMMENT '文件hash名稱',
    upload_time DateTime NOT NULL COMMENT '上傳時間',
    type varchar(20) NOT NULL COMMENT '文件類型',
    size varchar(20) NOT NULL COMMENT '文件大小',
    download varchar(50) NOT NULL COMMENT '下載次數',
    uid int unsigned COMMENT '用戶id',
    PRIMARY KEY (id),
    foreign key(uid) references user(uid)
)ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT '上傳文件表';

第三章 後臺模塊開發

3.1 建立數據庫鏈接

  1. 建立/server/config/env.js文件
//  數據庫鏈接參數
const env = {
  database: 'cloud_drive',
  username: 'root',
  password: '123456',
  host: 'localhost',
  dialect: 'mysql',
  pool: {
    max: 5,
    min: 0,
    acquire: 30000,
    idle: 10000
  }
};
module.exports = env;
  1. 建立/server/config/db.config.js文件
const env = require('./env.js');

const Sequelize = require('sequelize');
const sequelize = new Sequelize(env.database, env.username, env.password, {
  host: env.host,
  dialect: env.dialect,
  operatorsAliases: false,

  pool: {
    max: env.max,
    min: env.pool.min,
    acquire: env.pool.acquire,
    idle: env.pool.idle
  }
});

const db = {};

db.Sequelize = Sequelize;
db.sequelize = sequelize;

// 引入表模型
db.user = require('../model/user.model')(sequelize, Sequelize);
db.file = require('../model/file.model')(sequelize, Sequelize);

module.exports = db;

3.2 建立表模型

  1. 安裝sequelize-auto模塊,利用sequelize-auto模塊自動生成 user 表模型和 file 表模型
npm install -g sequelize-auto
sequelize-auto -h localhost -d cloud_drive -u root -x 123456 -p 3306 -t user
sequelize-auto -h localhost -d cloud_drive -u root -x 123456 -p 3306 -t file

注意:此處生成的表模型須要根據實際進行調整

2.複製生成的/models/book.js文件,粘貼至/model目錄下,並修改文件名後綴爲.model.js,刪除生成的models目錄

3.3 編寫接口

3.3.1 定義接口

  1. /server/route/user.route.js文件
//  用戶
module.exports = function(app) {
  const user = require('../controller/user.controller');

  //  新增用戶
  app.post('/user/add', user.create);

  //  根據用戶名和密碼查詢用戶
  app.post('/user/validate', user.validate);

  //  修改密碼
  app.put('/user/update/:userId', user.updatePassWord);
};
  1. /server/route/file.route.js文件
//  文件
module.exports = function(app) {
  const file = require('../controller/file.controller');

  //  新增文件
  app.post('/file/add', file.create);

  //  刪除文件
  app.delete('/file/delete/:fileName/:fileId', file.delete);

  // 下載文件
  app.get('/file/download/:fileName/:fileId', file.download);

  // 獲取文件信息列表
  app.post('/file/list', file.findAll);
};

3.3.2 編寫控制器文件

  1. /server/controller/user.controller.js文件
const db = require('../config/db.config.js');
const User = db.user; //  引入表模型
const Sequelize = require('sequelize');
const Op = Sequelize.Op;
//  新增用戶
exports.create = (req, res) => {
  if (req.body.username && req.body.password) {
    User.create(req.body)
      .then(user => {
        let msg = {};
        if (user) {
          msg = {
            flag: 1,
            msg: '註冊成功!',
            uid: user.uid,
            username: user.username
          };
        } else {
          msg = {
            flag: 0,
            msg: '註冊失敗,請稍後註冊'
          };
        }
        res.status(200).json(msg);
      })
      .catch(err => {
        res.status(500).json('Error -> ' + err);
      });
  } else {
    let msg = {
      flag: 0,
      msg: '用戶名或者密碼不能爲空!'
    };
    res.status(200).json(msg);
  }
};

//  驗證用戶名和密碼
exports.validate = (req, res) => {
  if (req.body.username && req.body.password) {
    User.findOne({
      where: {
        [Op.and]: [
          {
            username: req.body.username
          },
          [
            {
              password: req.body.password
            }
          ]
        ]
      },
      attributes: ['uid', 'username']
    })
      .then(user => {
        let msg = {};
        if (user) {
          msg = {
            flag: 1,
            msg: '用戶名和密碼正確!',
            uid: user.uid,
            username: user.username
          };
        } else {
          msg = {
            flag: 0,
            msg: '用戶名或密碼錯誤!'
          };
        }

        res.status(200).json(msg);
      })
      .catch(err => {
        res.status(500).json('Error -> ' + err);
      });
  } else {
    let msg = {
      flag: 0,
      msg: '用戶名或者密碼不能爲空!'
    };
    res.status(200).json(msg);
  }
};

//  修改密碼
exports.updatePassWord = (req, res) => {
  User.findOne({
    where: {
      [Op.and]: [
        {
          uid: req.params.userId
        },
        {
          password: req.body.oldPassword
        }
      ]
    }
  }).then(user => {
    if (user) {
      User.update(
        {
          password: req.body.newPassword
        },
        {
          where: {
            uid: req.params.uid
          }
        }
      ).then(() => {
        let msg = {
          flag: 1,
          msg: '修改密碼成功!'
        };
        res.status(200).json(msg);
      });
    } else {
      let msg = {
        flag: 0,
        msg: '密碼不正確!'
      };
      res.status(200).json(msg);
    }
  });
};
  1. /server/controller/file.controller.js文件
const db = require('../config/db.config.js');
const File = db.file; //  引入表模型
const Sequelize = require('sequelize');
const Op = Sequelize.Op;
const path = require('path');
const fs = require('fs');

//  添加文件
exports.create = (req, res) => {
  let params = {
    file_name: req.files[0].originalname,
    hash_name: req.files[0].filename,
    upload_time: new Date().toLocaleDateString() + ' ' + new Date().toLocaleTimeString(),
    type: path.parse(req.files[0].originalname).ext,
    size: req.files[0].size,
    download: 0,
    uid: req.body.uid
  };
  File.create(params)
    .then(file => {
      if (file) {
        let msg = {
          flag: 1,
          msg: '文件上傳成功!'
        };
        res.status(200).json(msg);
      } else {
        let msg = {
          flag: 0,
          msg: '文件上傳失敗,請稍後從新上傳!'
        };
        res.status(500).json(msg);
      }
    })
    .catch(err => {
      res.status(500).json('Error->' + err);
    });
};

//  刪除文件
exports.delete = (req, res) => {
  const id = req.params.fileId;
  File.destroy({
    where: { id: id }
  })
    .then(_ => {
      //  從資源文件夾從刪除
      let fileName = req.params.fileName;
      let path = `${__dirname}/../resource/${fileName}`;
      fs.unlink(path, err => {
        if (err) {
          let msg = {
            flag: 0,
            msg: '刪除失敗!'
          };
          res.status(200).json(msg);
        } else {
          let msg = {
            flag: 1,
            msg: '刪除成功!'
          };
          res.status(200).json(msg);
        }
      });
    })
    .catch(err => {
      res.status(500).json('Error=>', err);
    });
};

//  下載文件
exports.download = (req, res) => {
  let fileId = req.params.fileId;
  File.findById(fileId).then(file => {
    file
      .increment('download')
      .then(file => {
        let fileName = req.params.fileName;
        let path = `${__dirname}/../resource/${fileName}`;
        res.download(path, fileName);
      })
      .catch(err => {
        res.status(500).json('Error=>', err);
      });
  });
};

//  獲取文件列表信息
exports.findAll = (req, res) => {
  File.findAll({
    where: { uid: req.body.uid }
  })
    .then(file => {
      res.status(200).json(file);
    })
    .catch(err => {
      res.status(500).json('Error=>', err);
    });
};

3.4 接口測試

使用 postman 進行測試(略)

第四章 前端模塊開發

4.1 安裝並引入前端開發所需外部模塊

  1. 安裝axios模塊
  • npm install axios --save
  • 編寫文件src/utils/http.js,並引入封裝好的 axios 類
import axios from 'axios'

let httpInstance = axios.create()

httpInstance.defaults.baseURL = 'http://localhost:8081/'
httpInstance.defaults.timeout = 5000

httpInstance.formurl = (url, data, config) => {
  return httpInstance.post(url, data, {
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    ...config
  })
};

//  request攔截器
httpInstance.interceptors.request.use(
  config => {
    console.log(config)
    return config
  },
  error => {
    return Promise.reject(error)
  }
)
//  reponse攔截器
httpInstance.interceptors.response.use(
  response => {
    if (response.status === 200) {
      return Promise.resolve(response)
    }
  },
  error => {
    return Promise.reject(error)
  }
)
export default httpInstance
  • main.js中引入http.js文件,並將其註冊爲 vue 全局變量
import http from './utils/http'
Vue.prototype.$http = http;
  1. 安裝element-ui模塊
  • npm install element-ui --save
  • main.js中引入element-ui模塊
import ElementUI from 'element-ui'
  import 'element-ui/lib/theme-chalk/index.css'
  Vue.use(ElementUI)

4.2 創建路由

  1. 創建文件 在components 下新建文件以下,並刪除原有的HelloWorld.vue文件。
  • file-list.vue: 已上傳文件列表界面
  • file-upload.vue:上傳文件界面
  • index.vue:登陸註冊界面
  • tab-list.vue:tab 頁
  • user-set.vue:用戶設置界面
  1. 修改路由 在 router/main.js 中將路由修改以下
import Vue from 'vue'
import Router from 'vue-router'
import index from '@/components/index'
import list from '@/components/tab-list'

Vue.use(Router)

const router = new Router({
  routes: [
    {
      path: '/',
      name: 'index',
      component: index
    },
    {
      path: '/tab-list',
      name: 'tab-list',
      component: list
    }
  ]
})
//  校驗登陸
router.beforeEach((to, from, next) => {
  if (to.name === 'tab-list') {
    if (!sessionStorage.username) {
      window.alert('您的登陸信息無效或過時,請從新登陸')
      return window.location.replace('/')
    } else {
      next()
    }
  } else {
    next()
  }
})
export default router
  1. 刪除App.vue文件中如下代碼
<img src="./assets/logo.png">
  1. index.vue中寫入如下代碼:
<template>
  <div>
    Hello World!
  </div>
</template>
<script>
export default {}
</script>
<style scoped>
</style>
  1. 使用npm start運行項目,在瀏覽器中訪問,則會出現npm start的文字

4.3 編寫組件

1.index.vue登陸註冊界面
(1)界面預覽
登陸界面1
登陸界面2
(2)代碼編寫

<template>
  <div class="index">
    <div class="title">
      在線網盤系統
    </div>
    <div class="label">
      Cloud Driver
    </div>
    <div class="btn">
      <el-button type="primary"
        @click="dialogFormVisible = true">登陸/註冊</el-button>
    </div>
    <el-dialog title="登陸/註冊"
      :visible.sync="dialogFormVisible"
      width="400px">
      <el-form :model="form">
        <el-form-item label="用戶名"
          :label-width="formLabelWidth">
          <el-input v-model="form.username"
            autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="密碼"
          :label-width="formLabelWidth">
          <el-input v-model="form.password"
            autocomplete="off"
            type="password"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer"
        class="dialog-footer">
        <el-button @click="signUp">注 冊</el-button>
        <el-button type="primary"
          @click="signIn">登 錄</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
export default {
  name: 'index',
  data () {
    return {
      dialogFormVisible: false,
      form: {
        username: '',
        password: ''
      },
      formLabelWidth: '120px'
    }
  },
  methods: {
    // 登陸
    signIn () {
      this.dialogFormVisible = false
      this.$http
        .post('/user/validate', this.form)
        .then(res => {
          if (res.data.flag === 0) {
            this.$message.error(res.data.msg)
          } else {
            this.$message.success(res.data.msg)
            sessionStorage.setItem('uid', res.data.uid)
            sessionStorage.setItem('username', res.data.username)

            //  跳轉到其餘頁面
            this.$router.push('tab-list')
          }
        })
        .catch(err => {
          console.log(err)
        })
    },
    //  註冊
    signUp () {
      this.dialogFormVisible = false
      this.$http
        .post('/user/add', this.form)
        .then(res => {
          if (res.data.flag === 0) {
            this.$message.error(res.data.msg)
          } else {
            this.$message.success(res.data.msg)
            this.$router.push('tab-list')
          }
        })
        .catch(err => {
          console.log(err)
        })
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.index {
  margin-top: 80px;
  text-align: center;
}
.title {
  font-size: 60px;
}
.label {
  font-size: 40px;
  margin-top: 10px;
}
.btn {
  margin-top: 10px;
}
.dialog-footer {
  text-align: center;
}
</style>
  1. tab-list.vue選項卡切換界面
    (1)界面預覽
    切換選項卡
    (2)代碼
<template>
  <div class="show">
    <base-header></base-header>
    <el-tabs v-model="tabActivedName"
      class="tab"
      @tab-click="handleClick">
      <el-tab-pane v-for="(item, index) in componentList"
        :key="index"
        :label="item.tabLabel"
        :name="item.tabName">
        <component :is="item.compoName"
          v-if="tabActivedName===item.tabName"></component>
      </el-tab-pane>
    </el-tabs>
    <base-footer></base-footer>
  </div>
</template>

<script>
import BaseHeader from '../layout/header';
import BaseFooter from '../layout/footer';
import UploadFile from './file-upload';
import FileList from './file-list';
import userSet from './user-set';
export default {
  name: 'show',
  components: {
    BaseHeader,
    BaseFooter,
    UploadFile,
    FileList,
    userSet
  },
  data () {
    return {
      tabActivedName: 'second',
      componentList: [
        {
          tabName: 'first',
          compoName: 'upload-file',
          tabLabel: '上傳文件'
        },
        {
          tabName: 'second',
          compoName: 'file-list',
          tabLabel: '文件列表'
        },
        {
          tabName: 'third',
          compoName: 'user-set',
          tabLabel: '用戶設置'
        }
      ]
    }
  },
  methods: {
    handleClick (tab, event) {
      console.log(tab, event)
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.tab {
  min-height: 400px;
  padding: 20px 40px;
}
</style>

3.file-upload文件上傳組件
(1)界面預覽
文件上傳
(2)代碼

<template>
  <el-upload drag
    multiple
    action="http://localhost:8081/file/add"
    :data="userInfo"
    :on-success="dealSuccess"
    :on-error="dealError">
    <i class="el-icon-upload"></i>
    <div class="el-upload__text">將文件拖到此處,或<em>點擊上傳</em></div>
  </el-upload>
</template>
<script>
export default {
  data () {
    return {
      userInfo: {
        uid: sessionStorage.getItem('uid')
      }
    }
  },
  methods: {
    dealSuccess () {
      this.$message.success('上傳文件成功!')
    },
    dealError () {
      this.$message.error('上傳文件失敗,請從新上傳!')
    }
  }
}
</script>
<style scoped>
</style>
  1. file-list.vue文件上傳列表組件
    (1)界面預覽
    文件列表界面
    (2)代碼
<template>
  <div>
    <el-table :data="tableData"
      :cell-style="{'text-align':'center'}"
      :header-cell-style="{'text-align':'center'}"
      style="width: 100%">
      <el-table-column type="index">
      </el-table-column>
      <el-table-column prop="file_name"
        label="文件名"
        width="180px">
      </el-table-column>
      <el-table-column prop="size"
        label="文件大小"
        width="180px"
        :formatter="dealSize">
      </el-table-column>
      <el-table-column prop="upload_time"
        label="上傳時間"
        width="180px"
        :formatter="dealTime">
      </el-table-column>
      <el-table-column prop="download"
        label="下載次數"
        width="180px">
      </el-table-column>
      <el-table-column prop="type"
        label="類型"
        width="180px">
      </el-table-column>
      <el-table-column label="操做">
        <template slot-scope="scope">
          <a :href="getFile(scope.row)">
            <el-button size="mini"
              type="info"
              @click="handleDownload">下載</el-button>
          </a>
          <el-button size="mini"
            type="danger"
            @click="handleDelete(scope.$index, scope.row)">刪除</el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
export default {
  data () {
    return {
      tableData: []
    }
  },
  methods: {
    handleDelete (index, row) {
      this.$http
        .delete(`/file/delete/${row.hash_name}/${row.id}`)
        .then(res => {
          this.$message.success(res.data.msg)
          this.refreshFileList()
        })
        .catch(err => {
          console.log('Error=>', err)
        })
    },
    handleDownload () {
      setTimeout(() => {
        this.refreshFileList()
      }, 1000)
    },
    refreshFileList () {
      this.getFileList()
    },
    getFileList () {
      let params = {
        uid: sessionStorage.getItem('uid')
      }
      this.$http
        .post('/file/list', params)
        .then(res => {
          if (res.data.code === 0) {
            this.$message.error(res.data.msg)
          } else {
            this.tableData = res.data
          }
        })
        .catch(err => {
          console.log(err)
        })
    },
    getFile (data) {
      let url = `http://localhost:8081/file/download/${data.hash_name}/${
        data.id
      }`
      return url
    },
    dealSize (row, column) {
      let fileSize = (row.size / 1024).toFixed(2)
      return `${fileSize}kb`
    },
    dealTime (row, column) {
      return this.formatTime(row.upload_time)
    },
    formatTime (value) {
      var date = new Date(value)
      var Y = date.getFullYear()
      var M =
        date.getMonth() + 1 < 10
          ? `0${date.getMonth() + 1}`
          : date.getMonth() + 1
      var D = date.getDate() < 10 ? `0${date.getDate()}` : date.getDate()
      var h = date.getHours() < 10 ? `0${date.getHours()}` : date.getHours()
      var m =
        date.getMinutes() < 10 ? `0${date.getMinutes()}` : date.getMinutes()
      var s =
        date.getSeconds() < 10 ? `0${date.getSeconds()}` : date.getSeconds()
      return `${Y}-${M}-${D} ${h}:${m}:${s}`
    }
  },
  mounted () {
    this.getFileList()
  }
}
</script>
  1. user-set.vue用戶設置組件
<template>
  <div>
    <el-form :model="ruleForm"
      status-icon
      :rules="rules"
      ref="ruleForm"
      label-width="100px"
      class="change-password">
      <el-form-item label="原密碼"
        prop="oldPass">
        <el-input type="password"
          v-model="ruleForm.oldPass"
          autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item label="新密碼"
        prop="newPass">
        <el-input type="password"
          v-model="ruleForm.newPass"
          autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item label="確認新密碼"
        prop="checkNewPass">
        <el-input type="password"
          v-model="ruleForm.checkNewPass"
          autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary"
          @click="submitForm('ruleForm')">提交</el-button>
        <el-button @click="resetForm('ruleForm')">重置</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>
<script>
export default {
  data () {
    //  驗證原密碼
    let validateOldPass = (rule, value, callback) => {
      if (value === '') {
        callback(new Error('請輸入密碼'))
      } else {
        if (this.ruleForm.oldPass !== '') {
          this.$refs.ruleForm.validateField('newPass')
        }
        callback()
      }
    }
    //  驗證新密碼
    var validateNewPass = (rule, value, callback) => {
      if (value === '') {
        callback(new Error('請輸入新密碼'))
      } else if (value === this.ruleForm.oldPass) {
        callback(new Error('新舊密碼不能相同!'))
      } else {
        callback()
      }
    }
    //  驗證再次輸入密碼

    var validateCheckNewPass = (rule, value, callback) => {
      if (value === '') {
        callback(new Error('請再次輸入密碼'))
      } else if (value !== this.ruleForm.newPass) {
        callback(new Error('兩次輸入密碼不一致!!'))
      } else {
        callback()
      }
    }

    return {
      ruleForm: {
        oldPass: '',
        newPass: '',
        checkNewPass: ''
      },
      rules: {
        oldPass: [{ validator: validateOldPass, trigger: 'blur' }],
        newPass: [{ validator: validateNewPass, trigger: 'blur' }],
        checkNewPass: [{ validator: validateCheckNewPass, trigger: 'blur' }]
      }
    }
  },
  methods: {
    submitForm (formName) {
      this.$refs[formName].validate(valid => {
        if (valid) {
          let params = {
            oldPassword: this.ruleForm.oldPass,
            newPassword: this.ruleForm.newPass
          }
          this.$http
            .put(`/user/update/${sessionStorage.uid}`, params)
            .then(res => {
              this.$message.success('修改密碼成功!請從新登陸')
              sessionStorage.clear()
              setTimeout(() => {
                this.$router.push({ path: '/' })
              }, 1000)
            })
            .catch(err => {
              console.log('Error=>', err)
            })
        } else {
          console.log('error submit!!')
          return false
        }
      })
    },
    resetForm (formName) {
      this.$refs[formName].resetFields()
    }
  }
}
</script>
<style scoped>
.change-password {
  width: 400px;
  margin: 10px auto;
}
</style>
相關文章
相關標籤/搜索