网友真实露脸自拍10p,成人国产精品秘?久久久按摩,国产精品久久久久久无码不卡,成人免费区一区二区三区

小程序模板網

Node.js+Express+Mysql+Vue+ElementUI 實現(xiàn)登錄注冊列表 增刪改查 全棧開發(fā)一個自己的

發(fā)布時間:2020-05-13 09:48 所屬欄目:小程序開發(fā)教程

 

產品簡介

我的夢想,想做一個很牛逼的產品: 微信小程序《有夢必達》。

有夢必達初衷是一個幫助迷茫的、還沒有夢想的、還在尋找夢想的、有夢想卻還不知道怎么實現(xiàn)的童鞋更好的尋找或實現(xiàn)夢想的微信小程序。

有夢必達的初始設計功能有:登錄、注冊、找回密碼、夢想列表、夢想詳情、推薦課程、收藏、瀏覽記錄、閱讀數(shù)。

產品不夠完善,仍需要完善,不喜勿噴。

開發(fā)流程

備注:如果有同學完全按照此博客開發(fā)產品,可能會遇到坑,例如版本問題導致一些未知bug或者安裝系統(tǒng)限制等等。在我開發(fā)過程中就遇到過很多小問題,不過只要堅持解決問題,這些問題都難不倒我。即使一開始遇到未知bug還是有點慌,但是后面通過各種方法尋找答案,解決完畢時會很自豪。

總體開發(fā)流程如下:

1、有一顆完成夢想的決心

2、購買阿里云域名并且備案

3、購買阿里云服務器Cent Os

4、服務器安裝Node、Npm、Cnpm、Mysql、Nginx并配置、PM2

5、本地安裝Navicat Premium,連接遠程服務器的Mysql、創(chuàng)建數(shù)據表、安裝Xshell連接遠程服務器、Xftp查看服務器文件

6、Node+Express創(chuàng)建功能接口

7、Vue+Element創(chuàng)建后臺管理系統(tǒng)

8、部署后臺管理系統(tǒng)至域名服務器下

9、微信小程序+Vant前端展示

10、發(fā)布微信小程序

一、有一顆完成夢想的決心

如果想做一個產品,就應該把他當做一個夢想來看待,因為有了夢想,就會有沖勁,自己會覺得有意義,從而時刻保持沖勁,有熱情去完成他,而不是三天打魚兩天曬網,頂多堅持幾天就半途而廢,到最后,產品沒完成,自己也覺得自己能力有問題。所以,即使夢想再難,我們也要完成他,即使會慢一點!

二、購買阿里云域名并且備案

此處較為簡單,直接去阿里云官網-購買域名即可 阿里云萬網鏈接地址

備注:購買域名后,需要做域名備案才能在線上訪問(咱們要做就做正規(guī)的) 阿里云首次備案參考鏈接地址

亦可參考其他博客方法備案,能實現(xiàn)備案目的就行

三、購買阿里云服務器Cent Os

四、服務器安裝Node、Npm、Cnpm、Mysql、Nginx并配置、PM2

五、本地安裝Navicat Premium,連接遠程服務器的Mysql、創(chuàng)建數(shù)據表、安裝Xshell連接遠程服務器、Xftp查看服務器文件

由于三、四、五步驟篇幅過長, 直接移駕到開源中國預覽

六、Node+Express創(chuàng)建功能接口

nodejs部分:

1、package.json

{
  "name": "nodeDream",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "parchments",
  "license": "MIT",
  "dependencies": {
    "body-parser": "^1.19.0",
    "cors": "^2.8.5",
    "express": "^4.17.1",
    "jsonwebtoken": "^8.5.1",
    "multer": "^1.4.2",
    "mysql": "^2.17.1",
    "nodemon": "^2.0.2",
    "request": "^2.88.2"
  }
}
復制代碼

2、connect.js

const path = require("path");
const mysql = require("mysql");
const express = require("express");
const app = express();//實例化一個app
const router = express.Router();
const cors = require('cors');
const jwt = require('jsonwebtoken');  //用來生成token
const request = require('request');
const bodyParser = require('body-parser');
app.use(bodyParser.json());//post請求req.body為空的處理 json請求
app.use(bodyParser.urlencoded({extended: false}));// 表單請求

// 全局配置跨域
app.use(cors());

//本地訪問不了已上傳的圖片,需要開啟靜態(tài)資源路徑訪問
const pathname = __dirname;
//靜態(tài)文件訪問
app.use(express.static(pathname));
// 使用靜態(tài)文件   這樣可以獲取靜態(tài)文件的東西
app.use(express.static('vueDream/dist'))


//校驗token
function verifyToken(req, res, next){
	let secretOrPrivateKey = 'jwtDream';//密鑰
	jwt.verify(req.headers.token, secretOrPrivateKey, function (__err, decode) {
		//時間失效的時候/ 偽造的token
		if (__err) {
			return res.status(401).send({
				code: 401,
				data: null,
				message: "登錄過期,請重新登錄"
			});
		} else {
			next();
		}
	})
}
//這里處理全局攔截,一定要寫在最上面
app.all('*', (req, res, next) => {
	//設置響應頭
    res.header("Access-Control-Allow-Origin", "*"); //*表示允許的域名地址,本地則為'http://localhost'
    res.header("Access-Control-Allow-Headers", "*");
    res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
    res.header("Content-Type", "application/json;charset=utf-8");
	
	//如果是登錄 注冊 找回密碼  需要放行  無需校驗token
	let isLogin = req.url.indexOf('login');
	let isRegister = req.url.indexOf('register');
	let isForgotPassword = req.url.indexOf('forgotPassword');
	let isCollection = req.url.indexOf('collection');
	let isHistory = req.url.indexOf('history');
	// let isWechatLogin = req.url.indexOf('wechatLogin');
	// let isGetWxAccessToken = req.url.indexOf('getWxAccessToken');
	//微信小程序  并且是收藏接口需要校驗token
	let systype = req.headers.systype;
	if(systype === 'wechat'){
		if(isCollection !== -1 || isHistory !== -1){
			verifyToken(req, res, next)
		} else {
			next();
		}
	} else if(systype === 'pc'){
		//pc   登錄注冊找回密碼放行
		if(isLogin !== -1 || isRegister !== -1 || isForgotPassword !== -1){
			next();
		}else{
			verifyToken(req, res, next)
		}
	}
})

//這一步目的是,當訪問根路徑時,把前端代碼讀取出來并顯示
app.get('/', (req, res) => {
	//服務器地址vueDream/dist/index.html
    res.sendFile(path.resolve(__dirname, 'vueDream', 'dist', 'index.html'));
})

//配置mysql
const option = {
	host: "www.yousit",
	// host: "49.985.02.01",
	user: 'admin',
	port: '3306', 
    password: "mmmmmmmm.",
    database: "node",
    connectTimeout: 5000, //連接超時
    //multipleStatements: false //是否允許一個query中包含多條sql語句
}

let pool;
repool();
function Res ({ code = 200, message = '', data = {} }) {
    this.code = code;
    this.message = message;
    this.data = data;
}
function resJson (_res, result) {
    return _res.json(new Res(result))
}

//斷線重連機制
function repool() {
    //創(chuàng)建連接池
    pool = mysql.createPool({
        ...option,
        waitForConnections: true, //當無連接池可用時,等待(true)還是拋錯(false)
        connectionLimit: 200, //連接數(shù)限制
        queueLimit: 0 //最大連接等待數(shù)(0為不限制)
    })
    pool.on('error', err => {
        err.code === 'PROTOCOL_CONNECTION_LOST' && setTimeout(repool, 2000)
    })
    app.all('*', (_,__, next) => {
        pool.getConnection( err => {
            err && setTimeout(repool, 2000) || next()
        })
    })
}

module.exports = { app, pool, router, resJson , jwt , request}復制代碼

3、app.js

const { app, pool } = require('./connect');

//test
app.all('/api', (req, res) => {
    pool.getConnection((err, conn) => {
        res.json({ type: 'test success'})
        pool.releaseConnection(conn) // 釋放連接池,等待別的連接使用
    })
})

//引入上傳路由
const multerUpload = require('./routes/upload');
const user = require('./routes/user');
const dreamList = require('./routes/dream');
const collectionList = require('./routes/collection');
const historyList = require('./routes/history');
//使用路由
app.use('/upload', multerUpload);
app.use('/user', user);
app.use('/dream', dreamList);
app.use('/collection', collectionList);
app.use('/history', historyList);

//查看鏈接成功
app.get('/api/test', function (req, res) {
    res.json({ message: "連接成功" })
});

//開啟監(jiān)聽
app.listen(8888, () => {
	console.log("服務器端口8888開啟中...");
})復制代碼

express接口部分:

1、其中列表增刪改查接口

//夢想接口
const {app, pool, router, resJson, jwt } = require('../connect');

// 查詢
/* 
  按分頁顯示賬號列表的路由 /getData
*/
app.post("/api/dream/getData", (req, res) => {
		//后期需要補充校驗
		console.log("前端傳過來的",req.body)
		// 接收前端參數(shù)
		let { pageSize, pageNo , name , userId} = req.body;
		// 默認值
		pageSize = pageSize ? pageSize : 5;
		pageNo = pageNo ? pageNo : 1;
		name = name ? name : null;
		   
		// 構造sql語句 (查詢所有數(shù)據 按照時間排序)
		let sqlStr = `select * from dream`;
		// 執(zhí)行sql語句
		pool.getConnection((err, conn) => {
			conn.query(sqlStr, (err, data) => {
			  if (err) throw err;
			  // 計算數(shù)據總條數(shù)
			  let total = data.length;
		   
			  // 分頁條件 (跳過多少條)
			  let n = (pageNo - 1) * pageSize;
			  //   sqlStr += ` limit ${n}, ${pageSize}`;//表示從pageNo條數(shù)據取,取pageSize條數(shù)據  此處空格不能去掉不然無響應
			  // 拼接分頁的sql語句
				if(name){
					sqlStr += ` where name like '%${name}%'`;
					// 執(zhí)行sql語句 (查詢對應頁碼的數(shù)據)
					conn.query(sqlStr, (_err, _data) => {
					  if (_err) throw _err;
					  res.send({
						  code: 1,
						  data: {
							  rows: _data,
							  total: _data.length,
							  pageNo: pageNo,
							  pageSize: pageSize,
						  },
						  message: '查詢成功!'
					  });
					});
				}else{
					sqlStr += ` limit ${n} , ${pageSize}`;
					conn.query(sqlStr, (_err, data) => {
					  if (_err) throw _err;
					  res.send({
						  code: 1,
						  data: {
							  rows: data,
							  total: total,
							  pageNo: pageNo,
							  pageSize: pageSize,
						  },
						  message: '查詢成功!'
					  });
					});
				}
			});
			pool.releaseConnection(conn) // 釋放連接池,等待別的連接使用
		})
  });

//添加接口
app.post('/api/dream/add', (req, res) => {
    //后期需要補充校驗
    const data = req.body;
    const name = req.body.name;
    const sqlSameName = `select name from dream where name='${name}'`;
    //先查詢數(shù)據庫 dream 表里是否有前端傳來的name值了 如果有返回重復提示 否則插入數(shù)據庫
	pool.getConnection((err, conn) => {
		conn.query(sqlSameName, data, (_err, _results) => {
			if(_err){console.log(_err); return false;}
			//根據查詢表結果個數(shù)判斷,如果1為數(shù)據庫已經存在此名稱,不可插入   0代表數(shù)據庫不存在此名稱,可插入
			if(_results.length > 0){
				return res.json({
					code: 0, 
					message: "不可重復添加!", 
					data: null
				})
			}else{
				const sqlStr = 'insert into dream set ?';
				conn.query(sqlStr, data, (err, results) => {
					console.log(data)
					if (err) throw err;
					res.json({
						code: 1,
						message: '添加成功',
						data: results
					});
				})
			}
		})
        pool.releaseConnection(conn) // 釋放連接池,等待別的連接使用
    })
});

//修改
app.post('/api/dream/edit', function (req, res) {
    //后期需要補充校驗
    const data = req.body;
    const id = req.body.id;
    // let { name, collectionStatus, price, age, experience, education, analysis, introduce, duty, ask, coverImagePath, planImagePathArray, viedoUrl}  = req.body;
    let { name, coverImagePath, content, viedoUrl , recommend}  = req.body;
    let modSql = `update dream set 
					name='${name}', 
					coverImagePath='${coverImagePath}', 
					content='${content}', 
					viedoUrl='${viedoUrl}',
					recommend='${recommend}'
					where id ='${id}'`;
	let nameSql = `select * from dream where name='${name}' and id !='${id}'`;
	//先查詢數(shù)據庫 dream 表里是否有前端傳來的name值了 如果有返回重復提示 否則更新數(shù)據庫
	pool.getConnection((err, conn) => {
		conn.query(nameSql, data, (err, results) => {
			console.log(results)
			if(results.length >= 1){
				return res.json({
					code: 0, 
					message: "名稱已經存在!", 
					data: null
				})
			}else{
				conn.query(modSql, data, (err, results) => {
					res.json({
						code: 1,
						message: '修改成功',
						data: results
					});
				})
			}
		})
        pool.releaseConnection(conn) // 釋放連接池,等待別的連接使用
    })
});
//查看
app.post('/api/dream/show', function (req, res) {
    //后期需要補充校驗
    let data = req.body;
	//id是商品id
    let { id , userId}  = req.body;
    let modSql = `select * from dream where id='${id}'`;
	pool.getConnection((err, conn) => {
		conn.query(modSql, data, (err, results) => {
			if (err) {
				console.log("查詢失敗原因",err)
				return res.json({
					code: 0, 
					message: "查詢失敗", 
					affectedRows: err
				})
			}
			// 1.查詢出當前readCount
			results[0].readCount = results[0].readCount+1;
			let newReadCount = results[0].readCount;
			
			// 2.更新列表的id readCount
			let sqlDreamCountStr = `update dream set readCount='${newReadCount}' where id ='${id}'`;
			conn.query(sqlDreamCountStr, data, (_err, _data) => {
			  if (_err) throw _err;
			  console.log('更新列表的id readCount成功');
			});
			
			// 返回
			res.json({
				code: 1,
				message: '查詢成功',
				data: results
			});
		})
        pool.releaseConnection(conn) // 釋放連接池,等待別的連接使用
    })
});

//  刪除
app.post('/api/dream/del', (req, res) => {
    //后期需要補充校驗
    console.log(req.body)
    // let sqlStr = `DELETE FROM dream WHERE id = ${req.body.id}`;//單個刪除
    let sqlStr = `DELETE FROM dream WHERE id in (${req.body})`;
	pool.getConnection((err, conn) => {
		conn.query( sqlStr, (err , results) => {
			if(err) {
				console.log(err);
			}else {
				res.json({
					code: 1,
					message: '刪除成功',
					data: results
				});
			}
		})
        pool.releaseConnection(conn) // 釋放連接池,等待別的連接使用
    })
})

module.exports = router;復制代碼

2、更多功能接口 請前往github預覽

七、Vue+Element創(chuàng)建后臺管理系統(tǒng)

以vue-admin-template作為基礎后臺框架, 查看vue-admin-template地址 ,搭建我的小程序后臺管理系統(tǒng),為實現(xiàn)登錄、注冊、用戶列表增刪改查、夢想列表增刪改查、夢想詳情、收藏、收藏列表增刪改查、瀏覽記錄等功能

八、部署后臺管理系統(tǒng)至域名服務器下

九、成果展示


易優(yōu)小程序(企業(yè)版)+靈活api+前后代碼開源 碼云倉庫:starfork
本文地址:http://www.xiuhaier.com/wxmini/doc/course/25124.html 復制鏈接 如需定制請聯(lián)系易優(yōu)客服咨詢:800182392 點擊咨詢
QQ在線咨詢
AI智能客服 ×