以前寫過一篇vue初始化項目,構建vuex的後臺管理項目架子,這個structure-admin-web所擁有的功能html
接下來,針對structure-admin-web的不足,進行了補充,開發了具備登錄的structure-admin項目,前端
技術站:主要是node+vue+redis+mysql+es6vue
歡迎訪問structure-admin源碼:structure-adminnode
同步更新到sau交流學習社區:https://www.mwcxs.top/page/42...mysql
接下來:ios
1、後端服務nodejs,thinjs的redis配置,操做數據庫git
2、前端vue+vuex全局路由守衛,axios請求攔截es6
3、項目啓動必讀github
我使用的是thinkjs3,一個nodejs的框架。web
邏輯:
(1)已經登錄的,直接根據的路由跳到相應頁面;
(2)已經登錄的,不能跳到登錄頁面,跳到首頁;
(3)沒有登錄的,輸入url必須跳到登錄頁;
(4)退出系統的,必須回到登錄頁,狀態是未登陸
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)安裝,基礎使用,實例化項目這篇文章。
若是爲空,返回前端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服務中
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的服務中沒有值,就不會跳轉到其餘頁面
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 添加子查詢的結果數據
更新數據
模型提供了下列的方法來更新數據:
update 更新單條數據
updateMany 更新多條數據
thenUpdate 條件式更新
increment 字段增長值
decrement 字段減小值
刪除數據
模型提供了下列的方法來刪除數據:
delete 刪除數據
用項目的代碼舉栗子:
(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...
剛纔簡單的說了一下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 }] } ]
統一處理全部的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, }
一、首先你的環境是nodejs,不會安裝配置參考:http://www.mwcxs.top/page/420...
二、clone下來項目
git clone https://github.com/saucxs/structure-admin.git
三、分別針對前端vue的structure-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)前端vue的structure-admin-web的啓動
npm run dev
(2)和node後端structure-admin-node的啓動
npm start
八、這樣就能夠啓動
(1)登錄頁
(2)寫週報頁面
structure-admin架子線上地址:http://structure_admin.mwcxs.top
測試帳號:test,密碼:123456
九、該架子搭的週報企業管理系統
在PC端,歡迎訪問:http://weekly.mwcxs.top,
(公司負責人)帳號:testadmin,密碼:123456(部門經理)帳號:test,密碼:123456(成員)帳號:teststaff,密碼:123456