first commit

This commit is contained in:
编码猿
2024-09-27 01:16:36 +08:00
commit f7fc9bbea0
301 changed files with 33825 additions and 0 deletions

View File

@@ -0,0 +1 @@
977e97ad-3d32-417a-8112-4cc8fccb6164

58
node+vue/shop-bend/app.js Executable file
View File

@@ -0,0 +1,58 @@
var createError = require('http-errors');
var express = require('express');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var config = require('./config');
// 导入路由
var CartRouter = require('./routes/cart');
var OrderRouter = require('./routes/order');
var ShopRouter = require('./routes/shop');
var UserRouter = require('./routes/user');
var app = express();
// 跨域请求头设置
app.all("*", function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header(
"Access-Control-Allow-Headers",
"Content-Type,token,Content-Length, Authorization, Accept,X-Requested-With"
);
res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
res.header("X-Powered-By", "bmy");
if (req.method == "OPTIONS") res.sendStatus(200);
else next();
});
// 中间件设置
app.use(logger('dev'));
// 设置 HTTP请求的大小限制 为100mb
app.use(express.json({
limit: config.dev.httpSize
}));
app.use(express.urlencoded({ limit: config.dev.httpSize, extended: false }));
app.use(cookieParser());
// 配置挂载路由
app.use('/api/json/shop/', ShopRouter);
app.use('/api/json/user/', UserRouter);
app.use('/api/json/cart/', CartRouter)
app.use('/api/json/order/', OrderRouter)
// 捕捉404错误
app.use(function (req, res, next) {
next(createError(404));
});
// 错误处理
app.use(function (err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
});
module.exports = app;

View File

@@ -0,0 +1 @@
44ccb1d1-5187-42b2-a1ef-586343d71f3c

90
node+vue/shop-bend/bin/www Executable file
View File

@@ -0,0 +1,90 @@
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('shop-bend:server');
var http = require('http');
var config = require('./../config')
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || config.dev.port);
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
console.log(`Api is run this: ${config.dev.ipAddress}:${config.dev.port}`);
}

1
node+vue/shop-bend/cache/.pydio vendored Normal file
View File

@@ -0,0 +1 @@
c4e4d830-303d-4c00-bb1f-c77d83c90ba3

37
node+vue/shop-bend/cache/index.js vendored Executable file
View File

@@ -0,0 +1,37 @@
const redis = require("redis");
const config = require("../config");
class Redis {
constructor() {
// 创建redis服务
this.client = redis.createClient(config.dev.redis.port, config.dev.redis.host);
// 监听错误
this.client.on("error", function (err) {
console.log("redis 连接失败:" + err);
});
}
/**
* 设置缓存值
* @param {*string} key 名称
* @param {*string} value 数值
*/
Set(key, value) {
this.client.set(key, JSON.stringify(value), redis.print)
}
/**
* 获取缓存数值
* @param {*string} key 名称
*/
Get(key) {
return new Promise((resolve, reject) => {
this.client.expire(key, config.dev.redis.timeout);
this.client.get(key, function (error, result) {
if (error) reject(error)
resolve(JSON.parse(result))
})
})
}
}
module.exports = new Redis()

View File

@@ -0,0 +1 @@
8c41a9e9-d24a-4e24-8b98-acdc9d2838f2

View File

@@ -0,0 +1,57 @@
const config = {
dev: {
port: 3080, // 端口配置,网站上线服务器后改这个为 80端口
ipAddress: "http://127.0.0.1",
httpSize: "100mb",
api: {
success: 200, //网络请求成功
error: 404, // 网络请求失败
CodeError: 500 // 服务器内部错误或者异常
},
// 公私钥地址
rsa: {
privateKey: "../config/rsa_private_key.pem",
publicKey: "../config/rsa_public_key.pem",
},
// mysql 数据库连接信息
mysql: {
host: '127.0.0.1',
user: 'root',
password: 'root',
database: 'shop'
},
// redis 连接配置信息
redis: {
host: "127.0.0.1",
port: "6379",
timeout: 60
},
// 后端各api接口的sql语句
sql: {
shop: {
index: "select * from shop_commodity ORDER BY id DESC limit ?,?",
info: "select * from shop_commodity where id = ?",
brand: "select * from shop_commodity where commodity_brand = ?"
},
order: {
addOrder: "insert into shop_order(user_id,commodity_id,order_number,order_status,order_total,order_size) value (?,?,?,?,?,?)",
deleteCarts: "delete from shop_cart where user_id = ? and commodity_id = ?",
selectOrder: "SELECT user_id,commodity_id,order_number,order_status,order_total,order_size, shop_commodity.* FROM shop_order ,shop_commodity WHERE shop_order.commodity_id = shop_commodity.id AND shop_order.user_id = ? AND shop_order.order_status = ? "
},
user: {
add: "insert into shop_user(user_name,user_pwd,user_nicname) value (?,?,?)",
login: "select id,user_name,user_nicname,user_icons,user_money from shop_user where user_name = ? and user_pwd = ?",
setAddress: "UPDATE shop_user SET user_truename = ? , user_addres = ? WHERE id = ? ",
updateMoney: "UPDATE shop_user SET user_money = ? WHERE id = ? "
},
cart: {
add: "insert into shop_cart(commodity_id,user_id,cart_nums) value (?,?,1)",
checkCart: "select * from shop_cart where commodity_id = ? and user_id = ?",
selectCart: "SELECT shop_cart.cart_nums, shop_cart.id AS cid, shop_commodity.* FROM shop_cart ,shop_commodity WHERE shop_cart.commodity_id = shop_commodity.id AND shop_cart.user_id = ?",
deleteCart: "delete from shop_cart where id = ?"
}
}
}
}
module.exports = config

View File

@@ -0,0 +1,15 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCzkEs/kJgaFGIAM/TQRjzUtJ9ve9enk6heGj/JbcvHVOwFYw2q
CNUhuaFE9rYDL+CzX3+cf7inRIJCvSnC0bdGCZ+i943uSudTkqT+guv03jTzvLy2
TD+Bp41/ToNiPWG56p1keHE0Gwsr7o0waIcWrLpFJnzyW/fOYQjboRz7nwIDAQAB
AoGADgMCfDFSTSauBwoG3oG8mXSGxHJLf74b80vlEljJAAL2b+0s0cnip8EOfo0p
4tHHnPekw5eL1zGXYJHWQmeO/3ymZS/nnVq1K5YRM+AtYyUMAiChIt/zWOGXPN6k
yUARaTK/cRZNY2XPPDK0H44eLF2RDE/SObPD0BZ0u9m92aECQQDYSIrYw0klyGJe
ePaV0+2ZtVVhDYN+eYmWHu9/T+aOIPFS5ePUonBftSfcp7pTeJZ3O/eI/4W6pdzz
13MRseUZAkEA1ImPvtbL39A8OtciY16LgDX5O5Vkm5p5+TKRhG5B38bgnOQQHu2d
oJKvxjEJcWDfiJ6/ThHsFHqyvViJ+cIFdwJBAIWlpe62FdA8F9UK6EzDLXIq5DxZ
rmSL06IpMZM5G12+K4EvP26YhdoORjiKiI+l10yMiLRmOQuSDIu9GYTYqZkCQEQ5
/Ij4ju3D/PGuif14JjP8H4u/A1LoHeufDhODCWZ6gzQaCgrDoGwhaoemyi85N8i1
nRfErRJN6P7bYz9nxzUCQDC8yEIcgKczxFIo20k4R+CINyJTB5S6dsVW6gmpiHZK
6+MWkDut4o/Fibwp4jm5Fh9zau597aP5Xnt8mA2LRc8=
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1,6 @@
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzkEs/kJgaFGIAM/TQRjzUtJ9v
e9enk6heGj/JbcvHVOwFYw2qCNUhuaFE9rYDL+CzX3+cf7inRIJCvSnC0bdGCZ+i
943uSudTkqT+guv03jTzvLy2TD+Bp41/ToNiPWG56p1keHE0Gwsr7o0waIcWrLpF
JnzyW/fOYQjboRz7nwIDAQAB
-----END PUBLIC KEY-----

View File

@@ -0,0 +1 @@
6e1b7194-265c-4144-a2cb-64013f9ccde9

37
node+vue/shop-bend/db/index.js Executable file
View File

@@ -0,0 +1,37 @@
/**
* mysql 数据库连接&操作的基础类
*/
const mysql = require('mysql');
const config = require("../config")
class DB {
constructor() {
// 创建数据库链接
this.db = mysql.createConnection(config.dev.mysql);
// 链接数据库
this.db.connect();
}
/**
* 执行数据库操作
* @param {*string} sql 数据库语句
* @param {*array} par sql语句的参数
*/
query(sql, par = []) {
var status;
return new Promise((resolve, reject) => {
this.db.query(sql, par, function (error, results, fields) {
if (error) reject(error)
results.length == 0 ? resolve({
status: config.dev.api.error,
data: "没有数据..."
}) : resolve({
status: config.dev.api.success,
data: results
});
});
})
}
}
module.exports = new DB()

3
node+vue/shop-bend/index.http Executable file
View File

@@ -0,0 +1,3 @@
GET http://127.0.0.1:3000/api/json/shop/index HTTP/1.1
content-type: application/json
token : "csLYAGBfv5VvkH/R623nXPvoPsVtdielryGPtLGi2VUHyeuHKlmz31aNzbKZm5IXWTA5ek/1O/4JTq11iw3gmJy/eYxdzgZQwMgHx28z/eg7VMs9s8hbN2xa7+/UdTiSjteluqs5Bwk1lMjqWosfphIOagYLU7gE1/l+z494Qxw="

14
node+vue/shop-bend/index.js Executable file
View File

@@ -0,0 +1,14 @@
/**
* 公共依赖导入
*/
const express = require('express');
const router = express.Router();
const mysql = require("./db")
const utils = require("./utils")
const Ver = require("./utils/ver")
const redis = require("./cache")
const config = require("./config")
module.exports = { express, router, mysql, Ver, redis, config, utils }

27
node+vue/shop-bend/package.json Executable file
View File

@@ -0,0 +1,27 @@
{
"name": "shop-bend",
"version": "1.2.1",
"private": true,
"scripts": {
"dev": "./node_modules/.bin/node-dev ./bin/www",
"start": "pm2 start ./bin/www --watch -i max --name be",
"restart": "pm2 restart ./bin/www",
"stop": "pm2 stop be",
"list": "pm2 list",
"log": "pm2 logs"
},
"dependencies": {
"cookie-parser": "~1.4.3",
"debug": "~2.6.9",
"express": "~4.16.0",
"http-errors": "~1.6.2",
"morgan": "~1.9.0",
"node-rsa": "^1.0.1"
},
"devDependencies": {
"md5": "^2.2.1",
"mysql": "^2.16.0",
"node-dev": "^3.1.3",
"redis": "^2.8.0"
}
}

View File

@@ -0,0 +1 @@
e3a7d513-22f1-4c5a-9073-8bad84db8b6c

View File

@@ -0,0 +1,68 @@
const _ = require("..");
/**
* 用户收藏商品
* userid: 用户id
* shopid: 商品id
* http://127.0.0.1:3000/api/json/cart/addCart
*/
_.router.post('/addCart', _.Ver.Verification, async (req, res, next) => {
let params = JSON.parse(req.unparams)
let userid = params.userid,
shopid = params.shopid,
list = await _.mysql.query(_.config.dev.sql.cart.add, [shopid, userid]);
res.json({
status: list.status,
data: _.utils.public_encrypt(list.data)
})
});
/**
* 检查商品是否被收藏过
* userid: 用户id
* shopid: 商品id
* http://127.0.0.1:3000/api/json/cart/checkCart
*/
_.router.post('/checkCart', _.Ver.Verification, async (req, res, next) => {
let params = JSON.parse(req.unparams)
let userid = params.userid,
shopid = params.shopid,
list = await _.mysql.query(_.config.dev.sql.cart.checkCart, [shopid, userid]);
res.json({
status: list.status,
data: _.utils.public_encrypt(list.data)
})
});
/**
* 查找用户的购物车数据
* userid: 用户id
* http://127.0.0.1:3000/api/json/cart/selectCart
*/
_.router.post('/selectCart', _.Ver.Verification, async (req, res, next) => {
let params = JSON.parse(req.unparams)
let userid = params.userid,
list = await _.mysql.query(_.config.dev.sql.cart.selectCart, [userid]);
res.json({
status: list.status,
data: _.utils.public_encrypt(list.data)
})
});
/**
* 删除用户购物车的商品
* cid: 购物车表的id前端的cid字段
* http://127.0.0.1:3000/api/json/cart/deleteCart
*/
_.router.post('/deleteCart', _.Ver.Verification, async (req, res, next) => {
let params = JSON.parse(req.unparams)
let cid = params.cid,
list = await _.mysql.query(_.config.dev.sql.cart.deleteCart, [cid]);
res.json({
status: list.status,
data: _.utils.public_encrypt(list.data)
})
});
module.exports = _.router;

View File

@@ -0,0 +1,57 @@
const _ = require("..");
/**
* 提交订单
* brand: 商品的分类(品牌)
* http://127.0.0.1:3000/api/json/order/addOrder
*/
_.router.post('/addOrder', _.Ver.Verification, async (req, res, next) => {
let params = JSON.parse((JSON.parse(req.unparams)).order),
totals = JSON.parse(req.unparams).orderTotal,
money = JSON.parse(req.unparams).money;
let order_number = _.utils.Timemap()
// 插入到订单表
for (var i = 0; i < params.length; i++) {
await _.mysql.query(_.config.dev.sql.order.addOrder, [params[i].uid, params[i].sid, order_number, '1', params[i].total, params[i].size]);
}
// 删除购物车数据
for (var i = 0; i < params.length; i++) {
await _.mysql.query(_.config.dev.sql.order.deleteCarts, [params[i].uid, params[i].sid]);
}
await _.mysql.query(_.config.dev.sql.user.updateMoney, [money - totals, params[0].uid]);
res.json({
status: 200,
data: _.utils.public_encrypt([
{
orderNumber: order_number
}
])
})
});
/**
* 查看订单状态
* userid: 用户id
* status: 订单状态id
* http://127.0.0.1:3000/api/json/order/checkOrder
*/
_.router.post('/checkOrder', _.Ver.Verification, async (req, res, next) => {
let params = JSON.parse(req.unparams)
let userid = params.userid,
status = params.status,
list = await _.mysql.query(_.config.dev.sql.order.selectOrder, [userid, status]);
res.json({
status: list.status,
data: _.utils.public_encrypt(list.data)
})
});
module.exports = _.router;

View File

@@ -0,0 +1,56 @@
const _ = require("..")
/**
* 进入商品的详情页面
* id: 商品的id
* http://127.0.0.1:3000/api/json/shop/info
*/
_.router.get('/info', _.Ver.Verification, async (req, res, next) => {
let id = (JSON.parse(req.unparams)).id,
list = await _.mysql.query(_.config.dev.sql.shop.info, [id]);
res.json({
status: list.status,
data: _.utils.public_encrypt(list.data)
})
});
/**
* 首页接口,实现分页
* page: 前端提供, 如果用户第一次访问app让前端加密一个空的对象
* http://127.0.0.1:3000/api/json/shop/index
*/
_.router.get('/index', _.Ver.Verification, async (req, res, next) => {
let params = JSON.parse(req.unparams),
pages = 0,
totalPage = 15;
params.hasOwnProperty("page") ? pages = params.page : pages = 0;
let startPage = pages * totalPage
list = await _.mysql.query(_.config.dev.sql.shop.index, [startPage, totalPage]);
_.redis.Set(req.url, _.utils.public_encrypt(list.data))
res.json({
status: list.status,
data: _.utils.public_encrypt(list.data)
})
});
/**
* 进入商品的详情页面
* brand: 商品的分类(品牌)
* http://127.0.0.1:3000/api/json/shop/class
*/
_.router.get('/class', _.Ver.Verification, async (req, res, next) => {
let brand = (JSON.parse(req.unparams)).brand,
list = await _.mysql.query(_.config.dev.sql.shop.brand, [brand]);
res.json({
status: list.status,
data: _.utils.public_encrypt(list.data)
})
});
module.exports = _.router;

View File

@@ -0,0 +1,60 @@
const _ = require("..")
/**
* 进入商品的详情页面
* phone: 用户名字(手机号)
* nickname: 昵称
* pwd: 密码
* http://127.0.0.1:3000/api/json/user/addUser
*/
_.router.post('/addUser', _.Ver.Verification, async (req, res, next) => {
let params = JSON.parse(req.unparams)
let phone = params.phone,
nickname = params.nickname,
pwd = params.pwd,
list = await _.mysql.query(_.config.dev.sql.user.add, [phone, _.utils.md5Text(pwd), nickname]);
res.json({
status: list.status,
data: _.utils.public_encrypt(list.data)
})
});
/**
* 进入商品的详情页面
* phone: 用户名字(手机号)
* pwd: 密码
* http://127.0.0.1:3000/api/json/user/login
*/
_.router.post('/login', _.Ver.Verification, async (req, res, next) => {
let params = JSON.parse(req.unparams)
let phone = params.phone,
pwd = params.pwd,
list = await _.mysql.query(_.config.dev.sql.user.login, [phone, _.utils.md5Text(pwd)]);
res.json({
status: list.status,
data: _.utils.public_encrypt(list.data)
})
});
/**
* 进入商品的详情页面
* phone: 用户名字(手机号)
* pwd: 密码
* http://127.0.0.1:3000/api/json/user/setAddress
*/
_.router.post('/setAddress', _.Ver.Verification, async (req, res, next) => {
let params = JSON.parse(req.unparams)
let truename = params.truename,
address = params.address,
uid = params.uid,
list = await _.mysql.query(_.config.dev.sql.user.setAddress, [truename, address, uid]);
res.json({
status: list.status,
data: _.utils.public_encrypt(list.data)
})
});
module.exports = _.router;

View File

@@ -0,0 +1 @@
83d864a2-4667-4ed1-8e48-e4663cb53c47

View File

@@ -0,0 +1,73 @@
const fs = require("fs");
const path = require("path");
const config = require("../config");
const NodeRSA = require('node-rsa');
const md5 = require('md5');
class Utils {
constructor() {
// 私钥
this.rsa_private_key = this.ReadFile(this.GetRsaPath(config.dev.rsa.privateKey))
// 公钥
this.rsa_public_key = this.ReadFile(this.GetRsaPath(config.dev.rsa.publicKey))
}
/**
* 前端 使用RSA的私钥进行加密 rsa_private_key
*/
encrypt(text) {
return (new NodeRSA(this.rsa_private_key)).encryptPrivate(text, 'base64')
}
/**
* 前端 使用私钥解密json数据给前端
*/
Private_decrypted(text) {
return (new NodeRSA(this.rsa_private_key)).decrypt(text, 'utf8')
}
/**
* 后端 使用RSA的公钥进行解密 rsa_public_key
*/
decrypted(text) {
return (new NodeRSA(this.rsa_public_key)).decryptPublic(text, 'utf8')
}
/**
* 后端 使用公钥加密json数据给前端
*/
public_encrypt(text) {
return (new NodeRSA(this.rsa_public_key)).encrypt(text, 'base64')
}
/**
* 同步读取文件
* @param {*string} path 图片的地址
*/
ReadFile(path) {
return fs.readFileSync(path).toString("utf-8")
}
/**
* 获取RSA文件地址
* @param {*string} url 获取公私钥文件地址
*/
GetRsaPath(url) {
return path.join(__dirname, url)
}
/**
* md5加密
* @param {*string} text 需要被加密的字符串
*/
md5Text(text) {
return md5(text)
}
Timemap() {
return Date.parse(new Date())
}
}
module.exports = new Utils()

29
node+vue/shop-bend/utils/ver.js Executable file
View File

@@ -0,0 +1,29 @@
const utils = require("./index")
const cache = require("../cache")
const config = require("../config")
module.exports = {
/**
* 路由拦截器拦截路由验证是否有token参数redis中是否已经有数据缓存
*/
async Verification(req, res, next) {
// 验证请求头是否包含token
if (req.headers.hasOwnProperty("token")) {
// 验证redis是否有缓存没有则去获取mysq然后缓存有直接读取缓存
if (await cache.Get(req.url) == null) {
req.unparams = utils.decrypted(req.headers.token)
next()
} else {
res.json({
status: config.dev.api.success,
cache: true,
data: await cache.Get(req.url)
})
}
} else {
res.json({
status: config.dev.api.CodeError,
data: "缺少必填参数请求头token"
})
}
}
}

10
node+vue/shop-bend/笔记.md Executable file
View File

@@ -0,0 +1,10 @@
## RSA 非对称加密
私钥 公钥
1前端传递参数给后端的时候先将数据 object 转换为 "key=value&key=value" 然后通过私钥对数据进行加密放到请求头中token传递给后端
2后端拿到请求头通过公钥解密重新排列数据为 object 然后查询计算完成拿到数据后端再用公钥加密json数据然后返回给前端
3前端通过私钥解密后端的json渲染页面