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:
- express
- mysql
- sequelize
- Jsonwebtoken and Express-JWT (JWT)
- 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