基于node vue的电商系统 mongodb express框架

news2024/11/16 19:18:53

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

基于node vue的电商系统 mongodb express框架

  • 前言
    • 技术栈
    • 基本功能
      • 普通用户
      • 管理员
  • 一、运行截图?
  • 二、使用步骤
    • 1.前端main.js
    • 2.后端admin路由


前言

技术栈

  • 本项目采用前后端分离的开发方式,使用的技术栈是:Vue+Node+MongoDB
  • 前端:用vue-cli搭建,使用vue全家桶+element-ui
  • 后端:express框架
  • 数据库:mongodb

基本功能

普通用户

  • 注册、登录
  • 根据关键词对商品模糊搜索
  • 根据分类查询商品
  • 商品详情展示
  • 加入购物车及创建订单
  • 商品评论
  • 用户个人中心(修改个人信息及查看订单)

管理员

  • 登录
  • 用户管理
  • 权限管理
  • 商品管理
  • 订单管理
  • 数据统计

提示:以下是本篇文章正文内容,下面案例可供参考

一、运行截图?

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、使用步骤

1.前端main.js

代码如下(示例):

import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'

Vue.config.productionTip = false

//图片懒加载
import LazyLoad from 'vue-lazyload'
Vue.use(LazyLoad, {
  error:require('./assets/img/error.png'),
  // 占位图
  loading:require('./assets/img/loading.png')
})

//引入ElementUI库
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI);

//省市区联动
import VueAreaLinkage from 'vue-area-linkage';
import 'vue-area-linkage/dist/index.css';
Vue.use(VueAreaLinkage);

//引入图标库
import 'assets/fonts/iconfont.css'

//引入全局样式
import 'assets/css/base.css'

//事件总线
Vue.prototype.$bus = new Vue();

new Vue({
    router,
    store,
    render: h => h(App)
}).$mount('#app')

//通过methods里的代码跳转路由需要写下面代码: (不然重复点击会报错)
import Router from 'vue-router'
const routerPush = Router.prototype.replace
Router.prototype.replace = function replace(location) {
  return routerPush.call(this, location).catch(error => error)
}

2.后端admin路由

代码如下(示例):

import express from 'express'
import mongoose from 'mongoose'
import path from 'path'
import md5 from 'blueimp-md5'
import formidable from 'formidable'
import config from '../src/config.js'
import {
	Administrator,
	User,
	Category,
	Goods,
	Comment,
	Order
} from '../db/db'
const router = express.Router();

const S_KEY = 'leavehao@foxmail.com' //盐

//管理员登录
router.post('/login', async (req, res) => {
	let adminName = req.body.adminName;
	let adminPsw = md5(md5(req.body.adminPsw) + S_KEY);
	let result = await Administrator.findOne({
		adminName
	})
	if (result) {
		if (adminPsw === result.password) {
			req.session.admin = adminName;
			res.json({
				status_code: 200,
				message: '登录成功',
			})
		} else {
			res.json({
				status_code: 400,
				message: '密码错误'
			})
		}
	} else {
		res.json({
			status_code: 400,
			message: '用户名不存在'
		})
	}
})

//设置后台访问权限
router.use((req, res, next) => {
	if (!req.session.admin) {
		res.json({
			status_code: 400,
			message: '无权访问'
		})
	}
	next();
})

// 验证登录状态,若未被中间件拦截则为登录状态
router.get('/isadmin', async (req, res) => {
	console.log(req.session.admin)
	if(req.session.admin){
		let result = await Administrator.findOne({
			adminName: req.session.admin
		})
		console.log(result)
		res.json({
			status_code: 200,
			message: '进入管理员界面',
			adminName: req.session.admin,
			role: result.role
		})
	}

})

//退出登录
router.get('/logout', (req, res) => {
	req.session.admin = '';
	res.json({
		status_code: 200,
		message: '已退出登录'
	})
})


/**************************************** 用户管理 *******************************************/

//获取用户列表
router.get('/userlist', async (req, res) => {
	let result;
	if (req.query.userName) {
		result = await User.find({
			userName: {
				$regex: req.query.userName,
				$options: 'gi'
			}
		});
	} else {
		result = await User.find({});
	}
	res.json({
		status_code: 200,
		message: '获取用户列表成功',
		total: result.length,
		users: result
	})
})

//添加用户
router.post('/adduser', (req, res) => {
	const form = new formidable.IncomingForm();
	form.uploadDir = config.uploadsAvatarPath; // 上传图片放置的文件夹
	form.keepExtensions = true; // 保持文件的原始扩展名
	form.parse(req, (err, fields, files) => {
		let avatar;
		if (fields.userSex == '男') {
			avatar = 'http://localhost:' + config.port + '/boy_avatar.svg'
		} else {
			avatar = 'http://localhost:' + config.port + '/girl_avatar.svg'
		}
		if (files.userAvatar) {
			avatar = 'http://localhost:' + config.port + '/avatar_uploads/' + path.basename(files.userAvatar.path);
		}
		let userInfo = {
			userName: fields.userName,
			password: md5(md5(fields.userPsw) + S_KEY), //加密密码
			userEmail: fields.userEmail,
			userPhone: fields.userPhone,
			userSex: fields.userSex,
			userSign: fields.userSign,
			userAdress: fields.userAdress,
			nickName: fields.nickName,
			// userAdress:fields.userAdress.replace(/,/g,''),
			userAvatar: avatar
		}
		User.create(userInfo, (err, doc) => {
			console.log(err, doc)
			if (!err) {
				res.json({
					status_code: 200,
					message: '添加用户成功',
				})
			} else {
				res.json({
					status_code: 400,
					message: '内部错误,添加用户失败',
				})
			}
		})
	})
})

//编辑用户
router.post('/edituser', (req, res) => {
	const form = new formidable.IncomingForm();
	form.uploadDir = config.uploadsAvatarPath; // 上传图片放置的文件夹
	form.keepExtensions = true; // 保持文件的原始扩展名
	form.parse(req, (err, fields, files) => {
		let avatar;
		let userInfo = {
			userName: fields.userName,
			userEmail: fields.userEmail,
			userPhone: fields.userPhone,
			userSex: fields.userSex,
			userSign: fields.userSign,
			userAdress: fields.userAdress,
			nickName: fields.nickName
		}
		if (files.userAvatar) {
			avatar = 'http://localhost:' + config.port + '/avatar_uploads/' + path.basename(files.userAvatar.path);
			userInfo.userAvatar = avatar
		}
		if (fields.userPsw) {
			userInfo.password = md5(md5(fields.userPsw) + S_KEY); //加密密码
		}
		User.updateOne({
			userName: fields.userName
		}, userInfo).then((doc) => {
			res.json({
				status_code: 200,
				message: '修改用户成功',
			})
		}).catch((err) => {
			res.json({
				status_code: 400,
				message: '内部错误,修改用户信息失败',
			})
		})
	})
})

//删除用户
router.get('/deleteuser', (req, res) => {
	let userName = req.query.userName;
	User.findOneAndDelete({
		userName
	}).then((doc) => {
		res.json({
			status_code: 200,
			message: '删除用户成功',
		})
	}).catch((err) => {
		res.json({
			status_code: 400,
			message: '内部错误,删除用户失败',
		})
	})
})

/**************************************** 权限管理 *******************************************/

//获取管理员列表
router.get('/adminlist', async (req, res) => {
	let result;
	if (req.query.adminName) {
		result = await Administrator.find({
			adminName: {
				$regex: req.query.adminName,
				$options: 'gi'
			}
		});
	} else {
		result = await Administrator.find({});
	}
	res.json({
		status_code: 200,
		message: '获取管理员列表成功',
		total: result.length,
		administrators: result
	})
})

//添加管理员
router.post('/addadmin', (req, res) => {
	let regFrom = req.body;
	console.log(regFrom)
	let adminInfo = {
		adminName: regFrom.adminName,
		password: md5(md5(regFrom.adminPsw) + S_KEY), //加密密码
		role: regFrom.adminRole
	}
	Administrator.create(adminInfo, (err, doc) => {
		console.log(err, doc)
		if (!err) {
			res.json({
				status_code: 200,
				message: '添加管理员成功',
			})
		} else {
			res.json({
				status_code: 400,
				message: '内部错误,添加管理员失败',
			})
		}
	})
})

//检查管理员名是否已注册
router.get('/checkname', async (req, res) => {
	let adminName = req.query.adminName;
	let isNameReg = await Administrator.findOne({
		adminName
	})
	if (isNameReg) {
		res.json({
			status_code: 400,
			message: '该名称已注册'
		})
	} else {
		res.json({
			status_code: 200,
			message: '该名称可以使用'
		})
	}
})

//编辑管理员
router.post('/editadmin', async (req, res) => {
	let regFrom = req.body;
	console.log(regFrom);
	let adminInfo = {
		adminName: regFrom.adminName,
		role: regFrom.adminRole
	}
	if (regFrom.adminPsw) {
		adminInfo.password = md5(md5(regFrom.adminPsw) + S_KEY); //加密密码
	}
	Administrator.updateOne({
		adminName: regFrom.adminName
	}, adminInfo).then((doc) => {
		res.json({
			status_code: 200,
			message: '修改管理员信息成功',
		})
	}).catch((err) => {
		res.json({
			status_code: 400,
			message: '内部错误,修改管理员信息失败',
		})
	})
})

//删除管理员
router.get('/deleteadmin', (req, res) => {
	let adminName = req.query.adminName;
	Administrator.findOneAndDelete({
		adminName
	}).then((doc) => {
		res.json({
			status_code: 200,
			message: '删除管理员成功',
		})
	}).catch((err) => {
		res.json({
			status_code: 400,
			message: '内部错误,删除管理员失败',
		})
	})
})

/**************************************** 商品管理 *******************************************/

//获取分类列表
router.get('/catelist', async (req, res) => {
	let result;
	if (req.query.cateId) {
		result = await Category.find({
			cateId: req.query.cateId
		}).sort('cateId');
	} else {
		result = await Category.find({}).sort('cateId');
	}
	res.json({
		status_code: 200,
		message: '获取分类列表成功',
		total: result.length,
		categories: result
	})
})

//检查分类ID是否已存在
router.get('/checkcateid', async (req, res) => {
	let cateId = req.query.cateId;
	let isIdReg = await Category.findOne({
		cateId
	})
	if (isIdReg) {
		res.json({
			status_code: 400,
			message: '此ID已被使用'
		})
	} else {
		res.json({
			status_code: 200,
			message: '此ID可以使用'
		})
	}
})

//检查分类名称是否已存在
router.get('/checkcatename', async (req, res) => {
	let cateName = req.query.cateName;
	let isIdReg = await Category.findOne({
		cateName
	})
	if (isIdReg) {
		res.json({
			status_code: 400,
			message: '此名称已被使用'
		})
	} else {
		res.json({
			status_code: 200,
			message: '此名称可以使用'
		})
	}
})

//添加分类
router.post('/addcate', (req, res) => {
	let regFrom = req.body;
	console.log(regFrom)
	let cateInfo = {
		cateId: regFrom.cateId,
		cateName: regFrom.cateName,
		cateCounts: 0,
		cateSales: 0
	}
	Category.create(cateInfo, (err, doc) => {
		console.log(err, doc)
		if (!err) {
			res.json({
				status_code: 200,
				message: '添加分类成功',
			})
		} else {
			res.json({
				status_code: 400,
				message: '内部错误,添加分类失败',
			})
		}
	})
})

//编辑分类
router.post('/editcate', async (req, res) => {
	let editFrom = req.body;
	Category.updateOne({cateId: editFrom.cateId}, editFrom).then((doc) => {
		res.json({status_code: 200,message: '修改分类信息成功',})
	}).catch((err) => {
		res.json({status_code: 400,message: '内部错误,修改分类信息失败',})
	})
})

//删除分类
router.get('/deletecate', (req, res) => {
	let cateId = req.query.cateId;
	Category.findOneAndDelete({
		cateId
	}).then(async (doc) => {
		//删除商品下评论
		let result = await Goods.find({
			goodsCategory: cateId
		})
		console.log('result', result)
		for (let i = 0; i < result.length; i++) {
			await Comment.deleteMany({
				goodsId: result[i].goodsId
			})
		}
		//删除分类下所有商品
		await Goods.deleteMany({
			goodsCategory: cateId
		})
		res.json({
			status_code: 200,
			message: '删除分类成功',
		})
	}).catch((err) => {
		res.json({
			status_code: 400,
			message: '内部错误,删除分类失败',
		})
	})
})

//获取商品列表
router.get('/goodslist', async (req, res) => {
	let result;
	if (req.query.goodsCategory) {
		if (req.query.goodsId) {
			let resultId = await Goods.find({
				goodsId: req.query.goodsId,
				goodsCategory: req.query.goodsCategory
			}).sort('goodsCategory');
			let resultName = await Goods.find({
				goodsName: {
					$regex: req.query.goodsId,
					$options: 'gi'
				},
				goodsCategory: req.query.goodsCategory
			}).sort('goodsCategory');
			if (resultId.length != 0) {
				result = resultId
			} else {
				result = resultName
			}
		} else {
			result = await Goods.find({
				goodsCategory: req.query.goodsCategory
			}).sort('goodsCategory');
		}
	} else {
		if (req.query.goodsId) {
			let resultId = await Goods.find({
				goodsId: req.query.goodsId
			}).sort('goodsCategory');
			let resultName = await Goods.find({
				goodsName: {
					$regex: req.query.goodsId,
					$options: 'gi'
				}
			}).sort('goodsCategory');
			if (resultId.length != 0) {
				result = resultId
			} else {
				result = resultName
			}
		} else {
			result = await Goods.find({}).sort('goodsCategory');
		}
	}
	res.json({
		status_code: 200,
		message: '获取分类列表成功',
		total: result.length,
		goods: result
	})
})

//获取商品的分类
router.get('/goodscate', async (req, res) => {
	let result = await Category.findOne({cateId: req.query.cateId});
	res.json({
		status_code: 200,
		message: '获取分类信息成功',
		goodsCate: result.cateName
	})
})

//检查商品ID是否已存在
router.get('/checkgoodsid', async (req, res) => {
	let goodsId = req.query.goodsId;
	let isIdReg = await Goods.findOne({
		goodsId
	})
	console.log(isIdReg)
	if (isIdReg) {
		res.json({
			status_code: 400,
			message: '此ID已被使用'
		})
	} else {
		res.json({
			status_code: 200,
			message: '此ID可以使用'
		})
	}
})

//添加商品
router.post('/addgoods', (req, res) => {
	const form = new formidable.IncomingForm();
	form.uploadDir = config.uploadsGoodsPath; // 上传图片放置的文件夹
	form.keepExtensions = true; // 保持文件的原始扩展名
	form.parse(req, (err, fields, files) => {
		let goodsInfo = {
			goodsId: fields.goodsId,
			shortName: fields.shortName,
			goodsName: fields.goodsName,
			goodsPrice: fields.goodsPrice,
			normalPrice: fields.normalPrice,
			salesTips: fields.salesTips,
			goodsCategory: fields.goodsCategory,
			goodsCounts: Number(fields.goodsCounts),
			goodsImg: 'http://localhost:' + config.port + '/uploads/' + path.basename(files.goodsImg.path),
			goodsComments: 0
		}
		Goods.create(goodsInfo, async (err, doc) => {
			//更新商品分类里的商品数量
			let result = await Goods.find({
				goodsCategory: fields.goodsCategory
			});
			Category.updateOne({
				cateId: fields.goodsCategory
			}, {
				cateCounts: result.length
			}).then(doc => console.log('doc', doc)).catch(err => console.log('err', err))

			if (!err) {
				res.json({
					status_code: 200,
					message: '添加商品成功',
				})
			} else {
				res.json({
					status_code: 400,
					message: '内部错误,添加商品失败',
				})
			}
		})
	})
})

//编辑商品
router.post('/editgoods', (req, res) => {
	const form = new formidable.IncomingForm();
	form.uploadDir = config.uploadsGoodsPath; // 上传图片放置的文件夹
	form.keepExtensions = true; // 保持文件的原始扩展名
	form.parse(req, (err, fields, files) => {
		console.log(fields, files)
		let goodsInfo = {
			goodsId: fields.goodsId,
			shortName: fields.shortName,
			goodsName: fields.goodsName,
			goodsPrice: fields.goodsPrice,
			normalPrice: fields.normalPrice,
			salesTips: fields.salesTips,
			goodsCategory: fields.goodsCategory,
			goodsCounts: Number(fields.goodsCounts),
		}
		if (files.goodsImg) {
			goodsInfo.userAvatar = 'http://localhost:' + config.port + '/uploads/' + path.basename(files.goodsImg.path);
		}
		Goods.updateOne({
			goodsId: fields.goodsId
		}, goodsInfo).then(async (doc) => {
			//更新编辑前商品分类里的商品数量
			let resultOld = await Goods.find({
				goodsCategory: fields.goodsOldCate
			});
			Category.updateOne({
				cateId: fields.goodsOldCate
			}, {
				cateCounts: resultOld.length
			}).then(doc => console.log('doc', doc)).catch(err => console.log('err', err));
			//更新编辑后商品分类里的商品数量
			let result = await Goods.find({
				goodsCategory: fields.goodsCategory
			});
			Category.updateOne({
				cateId: fields.goodsCategory
			}, {
				cateCounts: result.length
			}).then(doc => console.log('doc', doc)).catch(err => console.log('err', err));
			res.json({
				status_code: 200,
				message: '修改商品成功',
			})
		}).catch((err) => {
			console.log(err)
			res.json({
				status_code: 400,
				message: '内部错误,修改商品信息失败',
			})
		})
	})
})

//删除商品
router.get('/deletegoods', (req, res) => {
	let goodsId = req.query.goodsId;
	let goodsCategory = req.query.goodsCategory;
	Goods.findOneAndDelete({
		goodsId
	}).then(async (doc) => {
		//删除该商品下所有评论
		Comment.deleteMany({
			goodsId
		}).then(doc => console.log(doc))
		//更新删除后商品分类里的商品数量
		let result = await Goods.find({
			goodsCategory
		});
		Category.updateOne({
			cateId: goodsCategory
		}, {
			cateCounts: result.length
		}).then(doc => console.log('doc', doc)).catch(err => console.log('err', err));
		res.json({
			status_code: 200,
			message: '删除商品成功',
		})
	}).catch((err) => {
		res.json({
			status_code: 400,
			message: '内部错误,删除商品失败',
		})
	})
})

/**************************************** 订单管理 *******************************************/

//获取订单列表
router.get('/orderlist', async (req, res) => {
	let result;
	if (req.query.userName) {
		let resultId = [];
		if (req.query.userName.length == 24) {
			resultId = await Order.find({
				_id: mongoose.Types.ObjectId(req.query.userName)
			}).sort('-orderTime');
		}
		let resultName = await Order.find({
			userName: {
				$regex: req.query.userName,
				$options: 'gi'
			}
		}).sort('-orderTime');
		if (resultId.length != 0) {
			result = resultId
		} else {
			result = resultName
		}
	} else {
		result = await Order.find({}).sort('-orderTime');
	}
	res.json({
		status_code: 200,
		message: '获取订单列表成功',
		total: result.length,
		orders: result
	})
})

//编辑订单信息
router.post('/editorder', async (req, res) => {
	let editFrom = req.body;
	console.log(editFrom);
	Order.updateOne({
		_id: mongoose.Types.ObjectId(editFrom._id)
	}, editFrom).then((doc) => {
		res.json({
			status_code: 200,
			message: '修改订单信息成功',
		})
	}).catch((err) => {
		console.log(err)
		res.json({
			status_code: 400,
			message: '内部错误,修改订单信息失败',
		})
	})
})

//删除订单
router.get('/deleteorder', (req, res) => {
	Order.findOneAndDelete({
		_id: mongoose.Types.ObjectId(req.query._id)
	}).then((doc) => {
		res.json({
			status_code: 200,
			message: '删除订单成功',
		})
	}).catch((err) => {
		res.json({
			status_code: 400,
			message: '内部错误,删除订单失败',
		})
	})
})

/**************************************** 数据统计 *******************************************/

//获取数据统计数据
router.get('/datalist', async (req, res) => {
	let result = await Category.find({}).sort('cateId');
	let xAxisData =[];
	let seriesData = [];
	for (let i = 0; i < result.length; i++) {
		xAxisData.push(result[i].cateName);
		seriesData.push(result[i].cateSales);
	}
	let option = {
		title: {
			text: '各分类月销量'
		},
		tooltip: {},
		legend: {
			data: ['销量']
		},
		xAxis: {
			data: xAxisData
		},
		yAxis: {},
		series: [{
			name: '销量',
			type: 'bar',
			data: seriesData
		}]
	};
	console.log(xAxisData,seriesData,option)
	res.json({
		status_code: 200,
		message: '获取数据统计信息成功',
		option: option
	})
})


export default router;


---

# 源码
https://pan.baidu.com/s/1ADfDdHbOYui8vwOTzwCbUA?pwd=8767 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/366603.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

行业分析| OA系统中的实时通讯

前言 当前实时通讯市场中有QQ、MSN、网络电话以及视频会议等&#xff0c;同时也有各个互联网巨头推出的基于自身平台的实时通讯工具&#xff0c;比如&#xff0c;百度hi&#xff0c;淘宝旺旺等&#xff0c;相对而言其与纯粹的实时通讯工具不同&#xff0c;基于自身平台的实时通…

点击化学 PEG 试剂1858242-47-3,Propargyl丙炔基-PEG1-乙酸活性酯

Propargyl-PEG1-Acetic acid-NHS ester&#xff0c;丙炔基-聚乙二醇-乙酸琥珀酰亚胺酯&#xff0c;丙炔基-PEG1-乙酸活性酯&#xff0c;丙炔基-PEG1-乙酸-NHS 酯产品规格&#xff1a;1.CAS号&#xff1a;1858242-47-32.分子式&#xff1a;C9H9NO53.分子量&#xff1a;211.174.包…

ChatGPT商业前景如何?人工智能未来会如何发展?

ChatGPT不仅在互联网和多个行业引发人们的关注&#xff0c;在投资界还掀起了机构对人工智能领域的投资热潮。人工智能聊天程序ChatGPT在去年11月亮相之后&#xff0c;在推出仅两个月后&#xff0c;今年1月份的月活用户已达到了1亿&#xff0c;成为史上增长最快的消费者应用程序…

【selenium 自动化测试】如何搭建自动化测试环境,搭建环境过程应该注意的问题

最近也有很多人私下问我&#xff0c;selenium学习难吗&#xff0c;基础入门的学习内容很多是3以前的版本资料&#xff0c;对于有基础的人来说&#xff0c;3到4的差别虽然有&#xff0c;但是不足以影响自己&#xff0c;但是对于没有学过的人来说&#xff0c;通过资料再到自己写的…

UA-DETRAC数据集转YOLO格式

一&#xff1a; 数据集下载 链接&#xff1a;&#xff08;后续添加&#xff09; 二&#xff1a; 处理标注文件 先处理标注文件&#xff0c;UA-DETRAC提供的标注文件格式是VOC格式&#xff0c;需要先转为XML格式&#xff0c;然后再将每个XML文件转为YOLO文件。 下面提供两个代…

git 本地新建分支并进行合并

由于新的要求 不允许在线上直接clone下的git分支进行开发&#xff0c;只能本地新建分支再往线上分支合并远程库clone到本地库 git clone 需要下载的git地址注意我下载下来的是dev分支 根据实际情况进行分析git clone https://gitee.com/hello.git本地创建新的分支 git checkout…

Keil编译头文件iec_std_functions.h错误解决

Keil 编译IEC61131-3库&#xff0c;头文件&#xff0c;大量出现以下错误&#xff1b; cast to type &#xff1f; is not allowed compiling resource1.c... ..\PLC\rts\matiec\lib\C\iec_std_functions.h(192): error: #119: cast to type "TIME" is not allowed…

公派访问学者的申请条件

知识人网海外访问学者申请老师为大家分享公派访问学者申请的基本条件以及哪些人员的申请是暂不受理的&#xff0c;供大家参考&#xff1a;一、 申请人基本条件&#xff1a;1.热爱社会主义祖国&#xff0c;具有良好的思想品德和政治素质&#xff0c;无违法违纪记录。2.具有良好专…

Java常见问题总结五

1、垃圾回收方式 SerialGC(串行垃圾回收):为单线程环境设计且使用一个线程进行垃圾回收&#xff0c;会暂停所有的用户线程。 ParalleGC(并行垃圾回收)&#xff1a;对过GC线程并行工作&#xff0c;此时用户线程是停止的。 ConcMarkSweep(CMS)&#xff1a;用户线程和GC线程同时执…

Tatuk GIS Developer Kernel for .NET 最新Crack

Tatuk GIS Developer Kernel for .NET 是一个地理SDK&#xff0c;它是受控代码和 .NET GIS SDK&#xff0c;用于为用户 Windows 操作系统创建 GIS 专业软件的过程。它被认为是一个完全用于 Win Forms 的 .NET CIL&#xff0c;WPF 的框架是为 C# 以及 VB.NET、VC、oxygen 以及最…

StarRocks携手零洞科技,助力碧桂园物业企业微信数字化项目

作者&#xff1a;零洞科技大数据部零洞科技有限公司&#xff08;以下简称“零洞”&#xff09;&#xff0c;是碧桂园集团的核心联盟企业&#xff0c;致力于成为国内领先的数智空间解决方案服务商&#xff0c;业务场景覆盖户内及户外&#xff0c;在智慧家居板块&#xff0c;打造…

【C语言】字符分类函数+内存函数

目录 1.字符函数 1.1字符分类函数 1.2.字符转换函数 //统一字符串中的大小写 2.内存处理函数 2.1内存拷贝函数memcpy //模拟实现memcpy 2.2内存移动函数memmove //模拟实现memmove 2.3内存比较函数memcmp 2.4内存设置函数memset 1.字符函数 1.1字符分类函数 头文…

【微信小程序】-- 宿主环境 通信模型 运行机制介绍(五)

&#x1f48c; 所属专栏&#xff1a;【微信小程序开发教程】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#…

NFTScan x TiDB丨一栈式 HTAP 数据库为 Web3 数据服务提供毫秒级多维查询

导读 NFTScan 是一家多链 NFT 数据基础设施服务商&#xff0c;为 Web3 用户提供高效简洁的 NFT 资产搜索查询服务&#xff0c;为 Web3 开发者和新一代金融科技公司提供专业的 NFT API 数据服务。 TiDB 作为一种分布式 HTAP 数据库&#xff0c;可以同时满足海量数据存储和高并…

I2C实验

目录 一、I2C简介 二、硬件原理 1、看原理图&#xff0c;找到I2C 2、查看使用设备 3、查看使用的IO 4、查数据手册看复用位 三、查看寄存器 1、I2C Address Register (I2Cx_IADR) 2、I2C Frequency Divider Register (I2Cx_IFDR) 3、I2C Control Register (I2Cx_I2CR) …

【C++】哈希表

1. unordered系列关联式容器 在C98中&#xff0c;STL提供了底层为红黑树结构的一系列关联式容器&#xff0c;在查询时效率可达到 &#xff0c;即最差情况下需要比较红黑树的高度次&#xff0c;当树中的节点非常多时&#xff0c;查询效率也不理想。最好的查询是&#xff0c;进行…

TCP/IP网络协议介绍及原理分析

一.应用层协议对于应用层而言&#xff0c;协议是开发者自己进行定义的&#xff0c;开发者根据自定义的格式规范对数据进行编码和解析。但是从原理上进行分析&#xff0c;其核心主要包括两点内容&#xff1a;①确定客户端和服务端交互的内容&#xff08;协议的内容&#xff09;②…

记一次docker虚拟机横向移动渗透测试

本次渗透在几个docker虚拟机间多次横向移动&#xff0c;最终找到了一个可以进行docker逃逸的出口&#xff0c;拿下服务器。渗透过程曲折但充满了乐趣&#xff0c;入口是172.17.0.6的docker虚拟机&#xff0c;然后一路横向移动&#xff0c;最终在172.17.0.2出实现了docker逃逸&a…

【免费教程】地下水环境监测技术规范HJ/T164-2020解读使用教程

地下水环境监测技术规范依据《中华人民共和国环境保护法》第十一条“国务院环境保护行政主管部门建立监测制度、制订监测规范”和《中华人民共和国水污染防治法》的要求&#xff0c;积极开展地下水环境监测&#xff0c;掌握地下水环境质量&#xff0c;保护地下水水质&#xff0…

常青科技冲刺A股上市:研发费用率较低,关联方曾拆出资金达1亿元

近日&#xff0c;江苏常青树新材料科技股份有限公司&#xff08;下称“常青科技”或“常青树科技”&#xff09;递交招股书&#xff0c;准备在上海证券交易所主板上市。本次冲刺上市&#xff0c;常青科技计划募资8.50亿元&#xff0c;光大证券为其保荐机构。 据招股书介绍&…