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


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

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

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

歡迎訪問weekly源碼:weekly

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

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

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

 

接下來:

一、后端服務nodejs,thinjs的redis配置,操作數據庫

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

三、項目啟動必讀

 

一、后端服務nodejs,thinjs的redis配置,操作數據庫

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

1、首先介紹登陸的控制

邏輯:

(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 功能。

 

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

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

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

 

3、數據庫的配置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

 

4、操作數據庫

項目開發中,經常需要操作數據庫(如:增刪改查等功能),手工拼寫 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

 

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

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

1、全局路由守衛

全局路由守衛是每一次都會判斷是否登陸(也就是判斷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
      }]
    }
  ]

 

2、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,
  }

 

三、項目啟動必讀

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

2、clone下來項目

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

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

npm install

4、安裝redis(可以考慮安裝RedisDesktopManager)

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

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

6、修改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
}
};

7、分別對前后端分離的項目啟動

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

npm run dev

 

(2)和node后端structure-admin-node的啟動

npm start

 

8、這樣就可以啟動

(1)登陸頁

(2)寫周報頁面

 

9、該項目架子搭的周報企業管理系統

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

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM