vue,vuex的後臺管理項目架子structure-admin,後端服務nodejs

以前寫過一篇vue初始化項目,構建vuex的後臺管理項目架子,這個structure-admin-web所擁有的功能html

接下來,針對structure-admin-web的不足,進行了補充,開發了具備登錄的structure-admin項目,技術站:主要是node+vue+redis+mysql+es6前端

歡迎訪問structure-admin源碼:structure-adminvue

歡迎訪問weekly源碼:weeklynode

項目地址演示地址:http://weekly.mwcxs.topmysql

  • (公司負責人)帳號:testadmin,密碼:123456
  • (部門經理)帳號:test,密碼:123456
  • (成員)帳號:teststaff,密碼:123456

PS:添加的成員的默認密碼是123456ios

 

接下來:git

1、後端服務nodejs,thinjs的redis配置,操做數據庫es6

2、前端vue+vuex全局路由守衛,axios請求攔截github

3、項目啓動必讀web

 

1、後端服務nodejs,thinjs的redis配置,操做數據庫

我使用的是thinkjs,一個nodejs的框架。

一、首先介紹登錄的控制

邏輯:

(1)已經登錄的,直接根據的路由跳到相應頁面;

(2)已經登錄的,不能跳到登錄頁面,跳到首頁;

(3)沒有登錄的,輸入url必須跳到登錄頁;

(4)退出系統的,必須回到登錄頁,狀態是未登陸

 

1.1 thinkjs的redis的配置文件adapter.js

exports.session = {
    type: 'redis',
    common: {
        cookie: {
            name: 'thinkjs',
            keys: ['werwer', 'werwer'],
            signed: true
        }
    },
    redis: {
        handle: redisSession,
        host: '127.0.0.1',
        port: 6379,
        password: 'a123456'
    }
};

設置的由redis的服務地址host,端口,以及redis的密碼,redis的搭建和配置,參考安裝window下的redis,redis可視化管理工具(Redis Desktop Manager)安裝,基礎使用,實例化項目這篇文章。

 

1.2  在每一次前端請求的路由的時候,都會去redis服務器中去取userInfo的信息

若是爲空,返回前端data爲空,前端在路由過濾中,跳到登錄頁,若是有值就正常返回。 

async __before() { let user = await this.session("userInfo"); if(user) {
            this.user = user;
        } else {
            this.user = '';
        }
    }

這個在nodejs的控制器controller裏,在每一次前端的請求發送到後端的時候,都會去redis的取userInfo的值,

let user = await this.session("userInfo");

這個userInfo的值也是本身在登錄的時候,把登錄成功以後的我的信息加入到redis服務中

 

1.3 在登錄成功的時候講我的信息加到redis服務中

async loginAction() {
        let {username, password} = this.post();try {
            let user = await this.model('user').where({
                username,
            }).find();
            if(user.password && user.password == password) {
                // login success
                await this.session('userInfo',{username, userId:user.id}); return this.success("登錄成功");
            } else {
                return this.fail("用戶名或密碼錯誤")
            }
        }
        catch(e) {
            console.log(e);
            return this.fail("登陸失敗")
        }

這個就是將我的信息加入到redis中

await this.session('userInfo',{username, userId:user.id});

WEB 請求中常常經過 session 來維持會話的,框架經過 think-session 和 Adapter 來支持 session 功能。

 

二、介紹登出(退出)的控制

 async logoutAction() {
        try {
            await this.session(null); return this.success("登出成功");
        } catch(e) {
            return this.fail(`登出失敗${e}`)
        }
    }

這個就是前端發的請求登出,直接將redis的置空,根據前端路由跳轉到登錄頁,這時候redis的服務中沒有值,就不會跳轉到其餘頁面

 

三、數據庫的配置adapter.js

exports.model = {
  type: 'mysql',
  common: {
    logConnect: true,
    logSql: true,
    logger: msg => think.logger.info(msg)
  },
  mysql: {
    handle: mysql,
    database: 'example', prefix: 'example_', encoding: 'utf8', host: '127.0.0.1', port: '3306', user: 'root', password: '123456', dateStrings: true
  }
};

common部分是配置是否將sql的語句的操做日誌打出來,這樣便於咱們在開發的時候的調試和修改bug

 

四、操做數據庫

項目開發中,常常須要操做數據庫(如:增刪改查等功能),手工拼寫 SQL 語句很是麻煩,同時還要注意 SQL 注入等安全問題。爲此框架提供了模型功能,方便操做數據庫。

Mysql 的 Adapter 爲 think-model-mysql,底層基於 mysql 庫實現,使用鏈接池的方式鏈接數據庫,默認鏈接數爲 1。

登錄的接口來講明:this.model說明使用封裝好的model,find是查找單條數據,在user的這張表中查找username值爲前端傳來的username的值,返回的值賦給user中。

async loginAction() {
        let {username, password} = this.post();
        try {
            let user = await this.model('user').where({ username, }).find(); if(user.password && user.password == password) {
                // login success
                await this.session('userInfo',{username, userId:user.id});
                return this.success("登錄成功");
            } else {
                return this.fail("用戶名或密碼錯誤")
            }
        }
        catch(e) {
            console.log(e);
            return this.fail("登陸失敗")
        }

think.Model 基類提供了豐富的方法進行 CRUD 操做,下面來一一介紹。

查詢數據

模型提供了多種方法來查詢數據,如:

  • find 查詢單條數據
  • select 查詢多條數據
  • count 查詢總條數
  • countSelect 分頁查詢數據
  • max 查詢字段的最大值
  • avg 查詢字段的平均值
  • min 查詢字段的最小值
  • sum 對字段值進行求和
  • getField 查詢指定字段的值

同時模型支持經過下面的方法指定 SQL 語句中的特定條件,如:

  • where 指定 SQL 語句中的 where 條件
  • limit / page 指定 SQL 語句中的 limit
  • field / fieldReverse 指定 SQL 語句中的 field
  • order 指定 SQL 語句中的 order
  • group 指定 SQL 語句中的 group
  • join 指定 SQL 語句中的 join
  • union 指定 SQL 語句中的 union
  • having 指定 SQL 語句中的 having
  • cache 設置查詢緩存

添加數據

模型提供了下列的方法來添加數據:

  • add 添加單條數據
  • thenAdd where 條件不存在時添加
  • addMany 添加多條數據
  • selectAdd 添加子查詢的結果數據

更新數據

模型提供了下列的方法來更新數據:

刪除數據

模型提供了下列的方法來刪除數據:

用項目的代碼舉栗子:

(1)查詢單條數據,用find(),條件爲:工號(usernum)爲180909,用戶名(username)爲saucxs ,而且填寫時間(time)爲這周的時間範圍的時間戳,返回的是對象object

 let weekly = await this.model('week').where({
     usernum: '180909', 
   username: 'saucxs',
   time: {
'>': startWeekStamp, '<': endWeekStamp} }).find();

解讀:model('week')的意思,取得是week的數據表

 

(2)查詢多條數據,用select(),條件:公司id(company_id)爲data的數據,返回的是數組array

let department = await this.model('department').where({company_id: 'data'}).select();

 

(3)查詢表中的具體的列數據,用field()

departmentMemberList = await this.model('user').field('id, company_id, company_name, department_id, department_name, email, role, role_name, username, usernum,telephone').where({
          company_id: this.user.company_id,
          role: {'>=': this.user.role}
        }).find();

解讀:this.user.company_id取的是登錄用戶的公司id,{'>=': this.user.role}爲比登錄用戶的角色

 

(4)分頁查詢,用page(page, pagesize)和countSelect(),返回的數據是對象

departmentMemberList = await this.model('user').field('id, company_id, company_name, department_id, department_name, email, role, role_name, username, usernum,telephone').where({
          company_id: this.user.company_id,
          role: {'>=': this.user.role}
        }).order("department_id asc , role asc").page(page, pagesize).countSelect();

解讀:返回的對象,以下圖所示:(count是總條數,currentPage爲當前頁,data是數據的數組,pageSize爲每一頁展現幾條,totalPages爲總共有多少頁)

 

(5)排序,倒序(desc)和正序(asc),用order("參數1 asc,參數2 desc」)

departmentMemberList = await this.model('user').field('id, company_id, company_name, department_id, department_name, email, role, role_name, username, usernum,telephone').where({
          company_id: this.user.company_id,
          role: {'>=': this.user.role}
        }).order("department_id asc , role asc").page(page, pagesize).countSelect();

 

(6)刪除,用delete(),條件用where

 await this.model('department').where({company_id, department_id}).delete();

 

(7)新增,用add(),沒有where

  await this.model('department').add({ company_id: this.user.company_id, company_name: this.user.company_name, department_id, department_name });

 

(8)改,用update(),條件where

 await this.model('user').where({id}).update({ usernum, username, telephone, role, role_name,email, company_id, company_name, department_id, department_name });

 

手動執行 SQL 語句

有時候模型包裝的方法不能知足全部的狀況,這時候須要手工指定 SQL 語句,能夠經過下面的方法進行:

  • query 手寫 SQL 語句查詢
  • execute 手寫 SQL 語句執行

具體的能夠參考thinkJS的官方文檔的數據操做這塊:https://thinkjs.org/zh-cn/doc/3.0/relation_model.html

 

2、前端vue+vuex全局路由守衛,axios請求攔截

剛纔簡單的說了一下nodejs的後端啓動的服務,封裝的接口,而前端調用這個接口使用的是url是:模塊名/控制器名/方法名,這個能夠在配置文件中修改定義的方法

一、全局路由守衛

全局路由守衛是每一次都會判斷是否登錄(也就是判斷redis服務中是否有值)。已經登錄(後端返回的用戶權限信息),則判斷當前要跳轉的路由,用戶是否有權限訪問,能夠考慮在用戶登錄以後將用戶權限把路由過濾一遍生成菜單,菜單保存到vuex中。

/*路由處理*/
router.beforeEach((to, from, next) => {
  let menuId;
  let auditResult;
  let applicationVerifyFlag;
  let key = to.meta.key;
  if (key) {
    store.dispatch("getUserInfo", {}).then(response => {if(!response.data){
        if (to.path !== '/login') {
          return next('/login');
        }
        next();
      }else{
        if (to.path == '/login') {
          return next('/writeWeekly');
        }
        store.commit("USER_INFO", response.data);
        next();
      }
    });
  } else {
   next();
  }
});

根據這個key來判斷是否有權限,取得是路由中meta的key的值。

  routes: [
    {
      path: '/login',
      name: 'login',
      meta: { key: '0' },
      component: login
    },
    {
      path: '/',
      name: 'home',
      component: home,
      children: [{
        path: '/writeWeekly',
        name: 'writeWeekly',
        meta: { key: '1' },
        component: writeWeekly
      }]
    }
  ]

 

二、axios請求攔截

統一處理全部的http請求和響應的,經過配置http request interceptors爲http頭部增長Authorization字段,其內容爲Token,經過配置http response interceptors,當後端接口返回401 Unauthorized(未受權),讓用戶從新登陸。

// 開發環境調試用戶信息
axios.interceptors.request.use(config => {
    if (process.env.NODE_ENV === 'development') {
      config.headers["username"] = "189090909";
    }
    return config;
});

axios.interceptors.response.use(
  response => {
    let data = response.data;
    console.log(data, 'data');
    if (!data.data) { // 登錄成功的回調地址
      return data; } else { return data; }
  },
  error => ({
    code: -1,
    msg: "網絡異常"
  })
);

 

對全部的請求進行了封裝。

// get請求配置
let getConfig = {
    url: '',
    baseURL: serveUrl,
    headers: {
    'X-Requested-With': 'XMLHttpRequest'
  },
  paramsSerializer(params) {
    return Qs.stringify(params, {
      arrayFormat: 'brackets'
    })
  },
  timeout: 5000
}

// post請求配置
let postConfig = {
    url: '',
    baseURL: serveUrl,
    headers: {
      'Content-Type': 'application/json',
      'X-Requested-With': 'XMLHttpRequest'
    },
    transformRequest: [function (data) {
      return JSON.stringify(data.params || {})
    }],
    timeout: 5000
}

export {
    serveUrl,
    getConfig,
    postConfig,
  }

 

3、項目啓動必讀

一、首先你的環境是nodejs,不會安裝配置參考:http://www.mwcxs.top/page/420.html

二、clone下來項目

git clone https://github.com/saucxs/structure-admin.git

三、分別針對前端vuestructure-admin-web的文件夾和node後端structure-admin-node,安裝相應依賴

npm install

四、安裝redis(能夠考慮安裝RedisDesktopManager)

參考:安裝window下的redis,redis可視化管理工具(Redis Desktop Manager)安裝,基礎使用,實例化項目

五、安裝mysql,這個就不贅述

六、修改nodejs的後端的配置文件adapter.js,config.js這兩個文件中

adapter.js

exports.cache = {
    type: 'redis',
    common: {
        timeout: 24 * 60 * 60 * 1000 // millisecond
    },
    redis: {
        handle: redisCache,
        host: '127.0.0.1',
        port: 6379,
        password: 'a123456' //redis安裝時候設置的祕密
    }
};
//
//
exports.model = {
type: 'mysql',
common: {
logConnect: true,
logSql: true,
logger: msg => think.logger.info(msg)
},
mysql: {
handle: mysql,
database: 'weekly',
prefix: 'week_',
encoding: 'utf8',
host: '127.0.0.1', //本地數據庫
port: '3306',     //數據庫端口
user: 'root', //數據庫的用戶名
password: '123456', //數據庫該用戶名的密碼
dateStrings: true
}
};

七、分別對先後端分離的項目啓動

(1)前端vuestructure-admin-web的啓動

npm run dev

 

(2)和node後端structure-admin-node的啓動

npm start

 

八、這樣就能夠啓動

(1)登錄頁

(2)寫週報頁面

 

九、該項目架子搭的週報企業管理系統

在PC端,歡迎訪問:http://weekly.mwcxs.top

  • (公司負責人)帳號:testadmin,密碼:123456
  • (部門經理)帳號:test,密碼:123456
  • (成員)帳號:teststaff,密碼:123456
相關文章
相關標籤/搜索