Vue2 + node.js项目

1、Vue2

vue2主要功能包括登入、退出、用户权限、表格的增删改查、文件下载。

Vue2项目地址https://gitee.com/www6/finance1.git

2、node.js编写后端接口

2.1、项目初始化

后端地址https://gitee.com/www6/finance-backend.git

创建项目

javascript 复制代码
npm install -g koa-generator  //安装koa-generator
koa2 创建项目名

在utils/index.js封装token

javascript 复制代码
var jwt = require('jsonwebtoken');
const { secret, tokenExpires } = require('../conf');

exports.createToken = (user) => {
  return jwt.sign(user, secret, {
    expiresIn: tokenExpires,
  });
};

exports.vertifyToken = (token) => {
  try {
    var decoed = jwt.verify(token, secret);
  } catch (e) {
  } finally {
    return decoed;
  }
};
exports.getUser = (token) => {
  return jwt.decode(token, secret);
};

响应处理

javascript 复制代码
// 响应处理  app.js
app.context.success = function (data) {
  this.body = {
    code: 20000,
    data,
  };
};
app.context.faild = function (data) {
  this.body = {
    code: 102,
    data,
  };
};
app.context.tokenExpires = function (data) {
  this.body = {
    code: 603,
    data,
  };
};

创建成功之后,接着下一步。

2.2、建立Mysql链接

根目录新建models/db.js文件

javascript 复制代码
var mysql = require('mysql');
const { db } = require('../conf');
var pool = mysql.createPool(db);

exports.query = function(sql,params=[]) {
 if (!params) {
     console.log('当前查询参数没有值,请查看',params);
 }
 return new Promise((resolve,reject)=>{
    pool.getConnection(function (err, connection) {
        if (err) throw err; // not connected!
    
        // Use the connection
        connection.query(sql,params, function (error, results, fields) {
            // 调试log
            console.log(`${sql}==>${params}=数据=>${results}`);
            connection.release();
            // Handle error after the release.
            if (error) {
                console.log('db出现异常:',error)
                return reject(error)
            }
            resolve(results);
    
            // Don't use the connection here, it has been returned to the pool.
        });
    });

 });
}

根目录下新建conf.js文件

javascript 复制代码
exports.db = {
  connectionLimit: 10,
  host: "localhost",
  user: "xxx",
  password: "xxx",
  database: "xxx",
};

exports.secret = "xxx";

exports.tokenExpires = 6000 * 3;

exports.whiteList = ["/user/login", "/user/logout"];

2.3、登入

新建routes/user.js文件

javascript 复制代码
const router = require('koa-router')()
const { doLogin} = require('../controllers/user');

router.prefix('/user')
.post('/login',doLogin)

module.exports = router

新建controllers/user.js文件

javascript 复制代码
const {findUserByAccount} = require('../models/user');
const { createToken, vertifyToken, getUser } = require('../utils');

exports.doLogin = async (ctx, next) => {
  let { account, password } = ctx.request.body;

  if (!account || !password) {
    return ctx.faild('必须传递用户名和密码');
  }

  const res = await findUserByAccount(account);

  if (res.length === 0) {
    return ctx.faild('用户名或者密码不存在');
  }

  let user = res[0];
  if (user.password != password) {
    return ctx.faild('用户名或者密码不存在');
  }
  const saveUser = {
    id: user.id,
    account: user.account,
    // 权限
    type: user.role_id,
  };

  // 生成token
  const token = createToken(saveUser);
  ctx.success({
    token,
  });
};


;

新建models/user.js文件

javascript 复制代码
const { query } = require('../models/db');

exports.findUserByAccount = account => query('select * from user where account = ?',[account]);

2.4、中间件处理

javascript 复制代码
const { whiteList } = require('../conf');
const { vertifyToken, getUser } = require('../utils');

exports.checkLogin = async (ctx, next) => {
  // 非登录、退出
  // 需要检查的
  if (!whiteList.includes(ctx.url)) {
    const { token } = ctx.headers;
    let tokenIndex = ctx.blackTokenList.indexOf(token);
    // 验证token
    if (!vertifyToken(token)) {
      // 弹出这个元素,不允许访问,重新获取token
      ctx.blackTokenList.splice(tokenIndex, 1);
      return ctx.tokenExpires('无效token,请登录再试!');
    } else {
      // 黑名单: 退出后的token
      if (tokenIndex !== -1) return ctx.tokenExpires('token已经失效');
      // 解析token并存储到ctx的上面, ctx.state 本次请求的共享数据
      ctx.state.user = getUser(token);
    }
  }

  await next();
};
javascript 复制代码
// app.js全局引入

const { responseHandler, checkLogin } = require('./middlewares');
app.use(checkLogin);

2.5、用户详情

javascript 复制代码
router.prefix('/user')
.get('/info',getInfo)

exports.getInfo = async (ctx) => {
  const user = ctx.state.user;
  if (!user) return ctx.faild('用户信息获取失败!');
  const { id } = user;
  const res = await findUserById(id);
  const dbUser = res[0];

  if (!dbUser) return ctx.faild('用户信息不存在,或者已经被删除');

  ctx.success({
    info: '获取成功!',
    roles: [{ name: dbUser.role_name }],
  });
};

exports.findUserById = id => query('select * from user where id = ?',[id]);

2.6、退出

javascript 复制代码
router.prefix('/user')
.post('/logout',logout)


// 退出后的token  在app.js全局添加
app.context.blackTokenList = [];


exports.logout = async (ctx) => {
  ctx.blackTokenList.push(ctx.headers.token);
  return ctx.tokenExpires('退出成功');
};
相关推荐
GuWenyue7 分钟前
提示词彻底过时?一套上下文工程方案,3步让LLM落地生产,代码直接复用
前端·javascript·人工智能
柒和远方11 分钟前
Phase 7.3 复盘:后台任务不只是“扔进队列”,还要能被看见
前端·后端·架构
2501_9437823515 分钟前
【共创季稿事节】 倒计时器:时分秒选择器与定时器的协同工作
前端·华为·harmonyos·鸿蒙·鸿蒙系统
奶油mm23 分钟前
公司技术债堆积如山,我一人之力用 Vue3 偷换了整个前端架构
前端·vue.js
用户9385156350724 分钟前
深入理解 JavaScript 中的 this 与数据存储的奥秘
前端·javascript
JNX_SEMI1 小时前
AT2659 L1频段多模卫星导航低噪声放大器技术解析
前端·单片机·嵌入式硬件·物联网·硬件工程
Profile排查笔记3 小时前
指纹浏览器环境异常排查:Fingerprint、Profile、Proxy、Session 和 Task Log 怎么看
前端·人工智能·后端·自动化
京韵养生记3 小时前
【无标题】
java·服务器·前端
格子软件3 小时前
2026年分布式GEO代理流量调度:源码级状态机防重挂实战
java·vue.js·人工智能·spring boot·分布式·vue
万亿少女的梦1683 小时前
基于Spring Boot的社区管理系统设计与实现
java·spring boot·mysql·vue·系统设计