The reason why I choose Express is because koA is small, microkernel and extensible. So some Web frameworks, such as EggJS of Ali, are based on KOA. Express integrates routing and static middleware, which makes it heavier (I’ve only used Express).

Ok, here’s the technology stack we’ll be using:

  1. express
  2. mysql
  3. sequelize
  4. Jsonwebtoken and Express-JWT (JWT)
  5. Node-schedule (scheduled task)

Project Directory:

├ ─ ─ bin / / / service configuration file ├ ─ ─ db / / / mysql configuration and configuration table ├ ─ ─ controllers / / / module cases ├ ─ ─ public / / / static resources (static) storage is used to upload ├ ─ ─ routes / / / ├── servers ├─ Tool.js ├── app.js ├─ package.jsonCopy the code

Mysql: Mysql: Mysql: Mysql: Mysql: Mysql: Mysql: Mysql: Mysql: Mysql: Mysql: Mysql: Mysql: Mysql

Install required dependency packages

    npm i sequelize boom express-jwt express-validator jsonwebtoken multer -S
Copy the code

Create two table description js files in db directory:

// user const Sequelize = require(' Sequelize ') const db = require('./index') // exports = module db.defineModel('user_list', { u_id: { type: Sequelize.INTEGER, allowNull: false, primaryKey: true, unique: true, autoIncrement: true }, u_name: { type: Sequelize.STRING }, u_email: { type: Sequelize.STRING }, u_capacity: INTEGER(), defaultValue: 10}, // capacity u_password: {type: sequelize.string, defaultValue: 123456 }, u_pic: { type: Sequelize.STRING(), defaultValue: 'https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png'} / / avatars}) / / file const Sequelize = require('sequelize') const db = require('./index') module.exports = db.defineModel('file_list', { f_id: { type: Sequelize.INTEGER, allowNull: false, primaryKey: true, unique: true, autoIncrement: true }, f_name: { type: Sequelize.STRING() }, f_size: { type: Sequelize.STRING() }, f_dow_url: { type: Sequelize.STRING() }, f_type: { type: Sequelize.STRING() }, f_grouping: { type: Sequelize.STRING() }, f_transfer_state: { type: F_history_state: {type: Sequelize.INTEGER, defaultValue: 0}, // 0 not downloaded, 1 downloaded f_history_state: {type: Sequelize. U_id: {type: Sequelize.INTEGER}, u_name: {type: Sequelize. Sequelize.string}}) // create table // user const user_list = require('.. /user_list') user_list.sync({force: true // Add a DROP TABLE before attempting to create a TABLE IF EXISTS - IF enforced, an existing TABLE will be overwritten. }) // file const fileList = require('.. /fileList') fileList.sync({ force: true })Copy the code

Common constants

const { env } = require('./env') const UPLOAD_PATH = env === 'dev' ? 'public/upload/users' : 'public/upload/users' module.exports = { CODE_ERROR: -1, CODE_SUCCESS: 200, PWD_SALT: 'admin_imoOC_node ', PRIVATE_KEY:' admin_imoOC_node_shan ', JWT_EXPIRED: 60 * 60, CODE_TOKEN_ERROR: -2, UPLOAD_PATH, TOURIST_PATH: `${UPLOAD_PATH}/tourist` // UPLOAD_URL }Copy the code

Write a return result controller

const { CODE_SUCCESS, CODE_ERROR, CODE_TOKEN_ERROR } = require('.. /tool/constant') class Result {constructor(data, MSG = '! ', options) {this.data = null if (arguments.length === 0) {this.msg = 'Operation succeeded! ' } else if (arguments.length === 1) { this.msg = data } else { this.data = data this.msg = msg if (options) this.options = options } } content() { if (! this.code) { this.code = CODE_SUCCESS } const base = { code: this.code, msg: this.msg } if (this.data) { base.data = this.data } if (this.options) { base.options = this.options } return base } success(res) { this.code = CODE_SUCCESS this.send(res) } fail(res) { this.code = CODE_ERROR this.send(res) } send(res) {  res.send(this.content()) } tokenError(res) { this.code = CODE_TOKEN_ERROR this.send(res) } } module.exports = ResultCopy the code

Database operation encapsulation

/* * * @params option config object * */ function findOne(example, option, cb) {example.findone ({where: option }).then(res => { cb && cb(res) }).catch(err => { cb && cb(err) }) } function findAll(example, option, Cb) {example.findall (option).then(res => {cb && cb(res)})} /* * Create a new data * @params Option configuration object * */ function create(example, option, Cb) {example.create(option).then(list => {cb && cb(list)}).catch(() => {cb && cb(false)}) * */ function findById(example, id, Cb) {example.findById(id).then(list => {cb && cb(list)}).catch(err => {cb && cb(err)})} /* * Update data according to the condition * @params Example: * option = {firstName: "King"}, {where: {firstName: null } } * */ function update(example, option, cb) { example.update(... Then (list => {cb && cb(list)}).catch(err => {cb && cb(err)})} /* * Delete a data item according to the condition * @params Option configuration object * */ function destroy(example, option, cb) { example.destroy(option).then(list => { cb && cb(list) }).catch(err => { cb && cb(err) }) } module.exports = { findOne, create, findById, update, destroy, findAll }Copy the code

Next, let’s implement a logon interface to create a database:

Function errorChecking(next, req, cb) {const err = validationResult(req) if (! Err. IsEmpty ()) {const [{MSG}] = err. Errors next(boom.badRequest(MSG))} else {cb && cb()}} // Query database function login(options, cb) { findOne(UserList, options, data => { cb && cb(data) }) } router.post('/login', [body('password').islength ({min: 5}).withmessage ('password is too long '), body('username').islength ({min: 5}).islength ({min: 5}). 4}).withmessage (' username is too long ')], (req, res, next) => {errorChecking(next, req, () => { Password} = req.body // Development mode password 123456 password = password === '123456'? password : md5(`${password}${PWD_SALT}`) login({ u_name: username, u_password: Password}, user => {// login query database processing middleware if (! User | | user. The length = = = 0) {return new Result (' login failed.) fail (res)} const token = JWT. Sign (/ login/token {username}. PRIVATE_KEY, {expiresIn: JWT_EXPIRED}) new Result({token}, 'login succeeded ').success(res)})}) PRIVATE_KEY, {expiresIn: JWT_EXPIRED}) new Result({token},' login succeeded ').success(res)})})Copy the code

App. js configures routes and uses CORS to solve cross-domain problems

const createError = require('http-errors') const express = require('express') const path = require('path') const cookieParser = require('cookie-parser') const logger = require('morgan') const cors = require('cors') const indexRouter = require('./routes/index') const {scheduleCronstyle} = require('./tool/schedule') const app = express( scheduleCronstyle() app.set('views', path.join(__dirname, 'views')) app.set('view engine', 'jade') app.use(logger('dev')) app.use(express.json()) app.use(express.urlencoded({ extended: false })) app.use(cookieParser()) app.use(express.static(path.join(__dirname, 'public'))) app.use(cors()) app.use('/public', express.static(path.join(__dirname, 'public'))) app.use('/', indexRouter) app.use(function(req, res, next) { next(createError(404)) }) app.use(function(err, req, res, next) { res.locals.message = err.message res.locals.error = req.app.get('env') === 'development' ? err : {} res.status(err.status || 500) res.render('error') }) module.exports = appCopy the code

Let’s test our interface with a project

The login did work

May be a bit of a block, because the project things a little more, a lot of basic things I did not mention, just talk about some of the necessary things, I have sorted out the code, you can go to GitHub Clone down to see the specific source code and then look at the article, may have a better understanding of oh, desktop Baidu cloud source code

Front chapter:

What is electron and how does Vue apply electron

Electron imitation Baidu Cloud desktop version, Vue terminal basic configuration and electronic API package