从0到1:培训老师预约小程序开发笔记二

背景调研

培训老师预约小程序: 教师和学生可以更便捷地安排课程,并提升教学质量和学习效果,使之成为管理和提升教学效果的强大工具。培训老师可以在小程序上设置自己的可预约时间,学员可以根据老师的日程安排选择合适的时间进行预约。这样可以提高预约的效率,减少沟通成本,方便双方的安排

功能规划

    1. 首页展示:展示最新的公告通知、老师推荐等内容,吸引用户关注。
    1. 老师列表:列出所有开课的老师信息,包括老师的个人简介、星级等,方便用户选择合适的老师。
    1. 预约功能:用户可以根据自己的需求选择老师,并进行预约。
    1. 预约管理:用户可以查看自己的预约记录,包括已完成的预约和待核销的预约,也可以取消预约。
  • 后台端:可以添加和设定老师的基本信息,账号,登陆密码等。

  • 老师端:可以编辑自己的个人资料(头像,简介,标签集等),设定预约时段排期(可预约时段,各时段人数限定), 在现场核销用户的预约码。

  • 顾客端:选择自己需要的老师和时段,下单预约,预约成功后出示预约码给老师或者工作人员核销。

概要设计

在这里插入图片描述

数据库设计


MeetModel.DB_STRUCTURE = {_pid: 'string|true',MEET_ID: 'string|true',MEET_ADMIN_ID: 'string|true|comment=添加的管理员',MEET_TITLE: 'string|true|comment=标题',MEET_JOIN_FORMS: 'array|true|default=[]|comment=表单字段设置',MEET_DAYS: 'array|true|default=[]|comment=最近一次修改保存的可用日期',MEET_CATE_ID: 'string|true|comment=分类编号',MEET_CATE_NAME: 'string|true|comment=分类冗余', MEET_FORMS: 'array|true|default=[]',MEET_OBJ: 'object|true|default={}',  MEET_CANCEL_SET: 'int|true|default=1|comment=取消设置 0=不允,1=允许,2=仅开始前可取消',MEET_STATUS: 'int|true|default=1|comment=状态 0=未启用,1=使用中,9=停止预约,10=已关闭',MEET_ORDER: 'int|true|default=9999',MEET_VOUCH: 'int|true|default=0',MEET_QR: 'string|false',MEET_PHONE: 'string|false|comment=登录手机',MEET_PASSWORD: 'string|false|comment=登录密码',MEET_TOKEN: 'string|false|comment=当前登录token',MEET_TOKEN_TIME: 'int|true|default=0|comment=当前登录token time',MEET_MINI_OPENID: 'string|false|comment=小程序openid',MEET_LOGIN_CNT: 'int|true|default=0|comment=登录次数',MEET_LOGIN_TIME: 'int|false|comment=最近登录时间',MEET_ADD_TIME: 'int|true',MEET_EDIT_TIME: 'int|true',MEET_ADD_IP: 'string|false',MEET_EDIT_IP: 'string|false',
};UserModel.DB_STRUCTURE = {_pid: 'string|true',USER_ID: 'string|true',USER_MINI_OPENID: 'string|true|comment=小程序openid',USER_STATUS: 'int|true|default=1|comment=状态 0=待审核,1=正常,8=审核未过,9=禁用',USER_CHECK_REASON: 'string|false|comment=审核未过的理由',USER_NAME: 'string|false|comment=用户昵称',USER_MOBILE: 'string|false|comment=联系电话',USER_FORMS: 'array|true|default=[]',USER_OBJ: 'object|true|default={}',USER_LOGIN_CNT: 'int|true|default=0|comment=登录次数',USER_LOGIN_TIME: 'int|false|comment=最近登录时间',USER_ADD_TIME: 'int|true',USER_ADD_IP: 'string|false',USER_EDIT_TIME: 'int|true',USER_EDIT_IP: 'string|false',
}

核心代码

class MeetService extends BaseProjectService {constructor() {super();this._log = new LogUtil(projectConfig.MEET_LOG_LEVEL);}/*** 抛出异常* @param {*} msg * @param {*} code */AppError(msg) {this._log.error(msg);super.AppError(msg);}_meetLog(meet, func = '', msg = '') {let str = '';str = `[MEET=${meet.MEET_TITLE}][${func}] ${msg}`;this._log.debug(str);}/** 统一获取Meet(某天) */async getMeetOneDay(meetId, day, where, fields = '*') {let meet = await MeetModel.getOne(where, fields);if (!meet) return meet;meet.MEET_DAYS_SET = await this.getDaysSet(meetId, day, day);return meet;}/** 获取日期设置 */async getDaysSet(meetId, startDay, endDay = null) {let where = {DAY_MEET_ID: meetId}if (startDay && endDay && endDay == startDay)where.day = startDay;else if (startDay && endDay)where.day = ['between', startDay, endDay];else if (!startDay && endDay)where.day = ['<=', endDay];else if (startDay && !endDay)where.day = ['>=', startDay];let orderBy = {'day': 'asc'}let list = await DayModel.getAllBig(where, 'day,dayDesc,times', orderBy, 1000);for (let k = 0; k < list.length; k++) {delete list[k]._id;}return list;}// 按时段统计某时段报名情况async statJoinCnt(meetId, timeMark) {let whereDay = {DAY_MEET_ID: meetId,day: this.getDayByTimeMark(timeMark)};let day = await DayModel.getOne(whereDay, 'times');if (!day) return;let whereJoin = {JOIN_MEET_TIME_MARK: timeMark,JOIN_MEET_ID: meetId};let ret = await JoinModel.groupCount(whereJoin, 'JOIN_STATUS');let stat = { //统计数据succCnt: ret['JOIN_STATUS_1'] || 0, //1=预约成功,cancelCnt: ret['JOIN_STATUS_10'] || 0, //10=已取消, adminCancelCnt: ret['JOIN_STATUS_99'] || 0, //99=后台取消};let times = day.times;for (let j in times) {if (times[j].mark === timeMark) {let data = {['times.' + j + '.stat']: stat}await DayModel.edit(whereDay, data);return;}}}// 预约前检测async beforeJoin(userId, meetId, timeMark) {await this.checkMeetRules(userId, meetId, timeMark);}// 根据日期获取其所在天设置getDaySetByDay(meet, day) {for (let k = 0; k < meet.MEET_DAYS_SET.length; k++) {if (meet.MEET_DAYS_SET[k].day == day)return dataUtil.deepClone(meet.MEET_DAYS_SET[k]);}return null;}// 根据时段标识获取其所在天 getDayByTimeMark(timeMark) {return timeMark.substr(1, 4) + '-' + timeMark.substr(5, 2) + '-' + timeMark.substr(7, 2);}// 根据时段标识获取其所在天设置getDaySetByTimeMark(meet, timeMark) {let day = this.getDayByTimeMark(timeMark);for (let k = 0; k < meet.MEET_DAYS_SET.length; k++) {if (meet.MEET_DAYS_SET[k].day == day)return dataUtil.deepClone(meet.MEET_DAYS_SET[k]);}return null;}// 根据时段标识获取其所在时段设置getTimeSetByTimeMark(meet, timeMark) {let day = this.getDayByTimeMark(timeMark);for (let k = 0; k < meet.MEET_DAYS_SET.length; k++) {if (meet.MEET_DAYS_SET[k].day != day) continue;for (let j in meet.MEET_DAYS_SET[k].times) {if (meet.MEET_DAYS_SET[k].times[j].mark == timeMark)return dataUtil.deepClone(meet.MEET_DAYS_SET[k].times[j]);}}return null;}// 预约时段人数和状态控制校验async checkMeetTimeControll(meet, timeMark, meetPeopleCnt = 1) {if (!meet) this.AppError('预约时段设置错误, 预约项目不存在');let daySet = this.getDaySetByTimeMark(meet, timeMark); // 当天设置let timeSet = this.getTimeSetByTimeMark(meet, timeMark); // 预约时段设置if (!daySet || !timeSet) this.AppError('预约时段设置错误day&time');let statusDesc = timeSet.status == 1 ? '开启' : '关闭';let limitDesc = '';if (timeSet.isLimit) {limitDesc = '人数上限MAX=' + timeSet.limit;} elselimitDesc = '人数不限制NO';this._meetLog(meet, `------------------------------`);this._meetLog(meet, `#预约时段控制,预约日期=<${daySet.day}>`, `预约时段=[${timeSet.start}-${timeSet.end}],状态=${statusDesc}, ${limitDesc} 当前预约成功人数=${timeSet.stat.succCnt}`);if (timeSet.status == 0) this.AppError('该时段预约已经关闭,请选择其他');// 时段总人数限制if (timeSet.isLimit) {if (timeSet.stat.succCnt >= timeSet.limit) {this.AppError('该时段预约人员已满,请选择其他');}let maxCnt = timeSet.limit - timeSet.stat.succCnt;if (maxCnt < meetPeopleCnt) {this.AppError('本时段最多还可以预约' + (maxCnt) + '人,您当前提交了' + meetPeopleCnt + '人,请调整后再提交');}}}/** 报名规则校验 */async checkMeetRules(userId, meetId, timeMark, formsList = null) {// 预约时段是否存在let meetWhere = {_id: meetId};let day = this.getDayByTimeMark(timeMark);let meet = await this.getMeetOneDay(meetId, day, meetWhere);if (!meet) {this.AppError('预约时段选择错误,请重新选择');}// 预约时段人数和状态控制校验let meetPeopleCnt = formsList ? formsList.length : 1;await this.checkMeetTimeControll(meet, timeMark, meetPeopleCnt);// 截止规则  await this.checkMeetEndSet(meet, timeMark);// 针对用户的次数限制await this.checkMeetLimitSet(userId, meet, timeMark, meetPeopleCnt);}// 预约次数限制校验async checkMeetLimitSet(userId, meet, timeMark, nowCnt) {if (!meet) this.AppError('预约次数规则错误, 预约项目不存在');let meetId = meet._id;let daySet = this.getDaySetByTimeMark(meet, timeMark); // 当天设置let timeSet = this.getTimeSetByTimeMark(meet, timeMark); // 预约时段设置this._meetLog(meet, `------------------------------`);this._meetLog(meet, `#预约次数规则,预约日期=<${daySet.day}>`, `预约时段=[${timeSet.start}~${timeSet.end}]`);let where = {JOIN_MEET_ID: meetId,JOIN_MEET_TIME_MARK: timeMark,JOIN_USER_ID: userId,JOIN_STATUS: JoinModel.STATUS.SUCC}let cnt = await JoinModel.count(where);let maxCnt = projectConfig.MEET_MAX_JOIN_CNT;this._meetLog(meet, `预约次数规则,mode=本时段可预约${maxCnt}次`, `当前已预约=${cnt}次`);if (cnt >= maxCnt)this.AppError(`您本时段已经预约,不能继续预约`);}// 预约截止设置校验async checkMeetEndSet(meet, timeMark) {if (!meet) this.AppError('预约截止规则错误, 预约项目不存在');this._meetLog(meet, `------------------------------`);let daySet = this.getDaySetByTimeMark(meet, timeMark); // 当天设置let timeSet = this.getTimeSetByTimeMark(meet, timeMark); // 预约时段设置this._meetLog(meet, `#预约截止规则,预约日期=<${daySet.day}>`, `预约时段=[${timeSet.start}-${timeSet.end}]`);let nowTime = timeUtil.time('Y-M-D h:m:s');/*let startTime = daySet.day + ' ' + timeSet.start + ':00';this._meetLog(meet, `预约开始规则,mode=<时段过期判定>`, `预约开始时段=${startTime},当前时段=${nowTime}`);if (nowTime > startTime) {this.AppError('该时段已开始,无法预约,请选择其他');}*/let endTime = daySet.day + ' ' + timeSet.end + ':59';this._meetLog(meet, `预约开始规则,mode=<时段过期判定>`, `预约结束时段=${endTime},当前时段=${nowTime}`);if (nowTime > endTime) {this.AppError('该时段已结束,无法预约,请选择其他');}}/**  预约详情 */async viewMeet(meetId) {let fields = '*';let where = {_id: meetId,MEET_STATUS: ['in', [MeetModel.STATUS.COMM, MeetModel.STATUS.OVER]]}let meet = await MeetModel.getOne(where, fields);if (!meet) return null;let getDaysSet = [];meet.MEET_DAYS_SET = await this.getDaysSet(meetId, timeUtil.time('Y-M-D')); //今天及以后let daysSet = meet.MEET_DAYS_SET;let now = timeUtil.time('Y-M-D');for (let k = 0; k < daysSet.length; k++) {let dayNode = daysSet[k];if (dayNode.day < now) continue; // 排除过期let getTimes = [];for (let j in dayNode.times) {let timeNode = dayNode.times[j];// 排除状态关闭的时段if (timeNode.status != 1) continue;// 判断数量是否已满if (timeNode.isLimit && timeNode.stat.succCnt >= timeNode.limit)timeNode.error = '预约已满';// 截止规则if (!timeNode.error) {try {await this.checkMeetEndSet(meet, timeNode.mark);} catch (ex) {if (ex.name == 'AppError')timeNode.error = '预约结束';elsethrow ex;}}getTimes.push(timeNode);}dayNode.times = getTimes;getDaysSet.push(dayNode);}// 只返回需要的字段let ret = {};ret.MEET_DAYS_SET = getDaysSet;ret.MEET_QR = meet.MEET_QR;ret.MEET_TITLE = meet.MEET_TITLE;ret.MEET_CATE_NAME = meet.MEET_CATE_NAME;ret.MEET_OBJ = meet.MEET_OBJ;return ret;}/**  预约前获取关键信息 */async detailForJoin(userId, meetId, timeMark) {let fields = 'MEET_DAYS_SET,MEET_JOIN_FORMS, MEET_TITLE';let where = {_id: meetId,MEET_STATUS: ['in', [MeetModel.STATUS.COMM, MeetModel.STATUS.OVER]]}let day = this.getDayByTimeMark(timeMark);let meet = await this.getMeetOneDay(meetId, day, where, fields);if (!meet) return null;let dayDesc = timeUtil.fmtDateCHN(this.getDaySetByTimeMark(meet, timeMark).day);let timeSet = this.getTimeSetByTimeMark(meet, timeMark);let timeDesc = timeSet.start + '~' + timeSet.end;meet.dayDesc = dayDesc + ' ' + timeDesc;// 取出本人最近一次本时段填写表单let whereMy = {JOIN_USER_ID: userId,}let orderByMy = {JOIN_ADD_TIME: 'desc'}let joinMy = await JoinModel.getOne(whereMy, 'JOIN_FORMS', orderByMy);if (joinMy)meet.myForms = joinMy.JOIN_FORMS;elsemeet.myForms = [];return meet;}/** 按天获取预约项目 */async getMeetListByDay(day) {let where = {'meet.MEET_STATUS': ['in', [MeetModel.STATUS.COMM, MeetModel.STATUS.OVER]],'day': day,};let orderBy = {'MEET_ORDER': 'asc','MEET_ADD_TIME': 'desc'};let fields = 'meet.MEET_ORDER,meet.MEET_ADD_TIME,meet.MEET_TITLE,meet.MEET_DAYS_SET,meet.MEET_OBJ.cover, DAY_MEET_ID, day, times';let joinParams = {from: MeetModel.CL,localField: 'DAY_MEET_ID',foreignField: '_id',as: 'meet',};let list = await DayModel.getListJoin(joinParams, where, fields, orderBy, 1, 100, false);list = list.list;let retList = [];for (let k = 0; k < list.length; k++) {let usefulTimes = [];for (let j in list[k].times) {if (list[k].times[j].status != 1) continue;usefulTimes.push(list[k].times[j]);}if (usefulTimes.length == 0) continue;let node = {};node.timeDesc = usefulTimes.length > 1 ? usefulTimes.length + '个时段' : usefulTimes[0].start;node.title = list[k].meet.MEET_TITLE;node.pic = list[k].meet.MEET_OBJ.cover;node._id = list[k].DAY_MEET_ID;retList.push(node);}return retList;}/** 获取从某天开始可预约的日期 */async getHasDaysFromDay(day) {let where = {day: ['>=', day],};let fields = 'times,day';let list = await DayModel.getAllBig(where, fields);let retList = [];for (let k = 0; k < list.length; k++) {for (let n in list[k].times) {if (list[k].times[n].status == 1) {retList.push(list[k].day);break;}}}return retList;}/** 取得预约分页列表 */async getMeetList({search, // 搜索条件sortType, // 搜索菜单sortVal, // 搜索菜单orderBy, // 排序 cateId, //分类查询条件page,size,isTotal = true,oldTotal}) {orderBy = orderBy || {'MEET_ORDER': 'asc','MEET_ADD_TIME': 'desc'};let fields = 'MEET_TITLE,MEET_OBJ,MEET_DAYS,MEET_CATE_NAME,MEET_CATE_ID';let where = {};where.and = {_pid: this.getProjectId() //复杂的查询在此处标注PID};if (cateId && cateId !== '0') where.and.MEET_CATE_ID = cateId;where.and.MEET_STATUS = ['in', [MeetModel.STATUS.COMM, MeetModel.STATUS.OVER]]; // 状态  if (util.isDefined(search) && search) {where.or = [{ MEET_TITLE: ['like', search] },];} else if (sortType && util.isDefined(sortVal)) {// 搜索菜单switch (sortType) {case 'sort': {orderBy = this.fmtOrderBySort(sortVal, 'NEWS_ADD_TIME');break;}case 'cateId': {if (sortVal) where.and.MEET_CATE_ID = String(sortVal);break;}}}let result = await MeetModel.getList(where, fields, orderBy, page, size, isTotal, oldTotal);return result;}/** 取消我的预约 只有成功可以取消 */async cancelMyJoin(userId, joinId) {let where = {JOIN_USER_ID: userId,_id: joinId,JOIN_IS_CHECKIN: 0, // 核销不能取消JOIN_STATUS: JoinModel.STATUS.SUCC};let join = await JoinModel.getOne(where);if (!join) {this.AppError('未找到可取消的预约记录');}// 取消规则判定let whereMeet = {_id: join.JOIN_MEET_ID,MEET_STATUS: ['in', [MeetModel.STATUS.COMM, MeetModel.STATUS.OVER]]}let meet = await this.getMeetOneDay(join.JOIN_MEET_ID, join.JOIN_MEET_DAY, whereMeet);if (!meet) this.AppError('预约项目不存在或者已关闭');let daySet = this.getDaySetByTimeMark(meet, join.JOIN_MEET_TIME_MARK);let timeSet = this.getTimeSetByTimeMark(meet, join.JOIN_MEET_TIME_MARK);if (!timeSet) this.AppError('被取消的时段不存在');if (meet.MEET_CANCEL_SET == 0)this.AppError('该预约不能取消');let startT = daySet.day + ' ' + timeSet.start + ':00';let startTime = timeUtil.time2Timestamp(startT);let now = timeUtil.time();if (meet.MEET_CANCEL_SET == 2 && now > startTime)this.AppError('该预约时段已经开始,无法取消');// TODO 已过期不能取消await JoinModel.del(where);// 统计this.statJoinCnt(join.JOIN_MEET_ID, join.JOIN_MEET_TIME_MARK);}/** 取得我的预约详情 */async getMyJoinDetail(userId, joinId) {let fields = 'JOIN_COMPLETE_END_TIME,JOIN_IS_CHECKIN,JOIN_CHECKIN_TIME,JOIN_REASON,JOIN_MEET_ID,JOIN_MEET_TITLE,JOIN_MEET_DAY,JOIN_MEET_TIME_START,JOIN_MEET_TIME_END,JOIN_STATUS,JOIN_ADD_TIME,JOIN_CODE,JOIN_FORMS';let where = {_id: joinId,JOIN_USER_ID: userId};return await JoinModel.getOne(where, fields);}/** 取得我的预约分页列表 */async getMyJoinList(userId, {search, // 搜索条件sortType, // 搜索菜单sortVal, // 搜索菜单orderBy, // 排序 page,size,isTotal = true,oldTotal}) {orderBy = orderBy || {//	'JOIN_MEET_DAY': 'desc',//	'JOIN_MEET_TIME_START': 'desc','JOIN_ADD_TIME': 'desc'};let fields = 'JOIN_COMPLETE_END_TIME,JOIN_IS_CHECKIN,JOIN_REASON,JOIN_MEET_ID,JOIN_MEET_TITLE,JOIN_MEET_DAY,JOIN_MEET_TIME_START,JOIN_MEET_TIME_END,JOIN_STATUS,JOIN_ADD_TIME,JOIN_OBJ';let where = {JOIN_USER_ID: userId};//where.MEET_STATUS = ['in', [MeetModel.STATUS.COMM, MeetModel.STATUS.OVER]]; // 状态  if (util.isDefined(search) && search) {where['JOIN_MEET_TITLE'] = {$regex: '.*' + search,$options: 'i'};} else if (sortType) {// 搜索菜单switch (sortType) {case 'cateId': {if (sortVal) where.JOIN_MEET_CATE_ID = String(sortVal);break;}case 'all': { //所有 break;}case 'use': { //可用未过期where.JOIN_STATUS = JoinModel.STATUS.SUCC;where.JOIN_COMPLETE_END_TIME = ['>=', timeUtil.time('Y-M-D h:m')];break;}case 'check': { //已核销where.JOIN_STATUS = JoinModel.STATUS.SUCC;where.JOIN_IS_CHECKIN = 1;break;}case 'timeout': { //已过期未核销where.JOIN_STATUS = JoinModel.STATUS.SUCC;where.JOIN_IS_CHECKIN = 0;where.JOIN_COMPLETE_END_TIME = ['<', timeUtil.time('Y-M-D h:m')];break;}case 'succ': { //预约成功where.JOIN_STATUS = JoinModel.STATUS.SUCC;//where.JOIN_MEET_DAY = ['>=', timeUtil.time('Y-M-D h:m')];//where.JOIN_MEET_TIME_START = ['>=', timeUtil.time('h:m')];break;}case 'cancel': { //已取消where.JOIN_STATUS = ['in', [JoinModel.STATUS.CANCEL, JoinModel.STATUS.ADMIN_CANCEL]];break;}}}let result = await JoinModel.getList(where, fields, orderBy, page, size, isTotal, oldTotal);return result;}/** 取得我的某日预约列表 */async getMyJoinSomeday(userId, day) {let fields = 'JOIN_IS_CHECKIN,JOIN_MEET_ID,JOIN_MEET_TITLE,JOIN_MEET_DAY,JOIN_MEET_TIME_START,JOIN_MEET_TIME_END,JOIN_STATUS,JOIN_ADD_TIME';let where = {JOIN_USER_ID: userId,JOIN_MEET_DAY: day};//where.MEET_STATUS = ['in', [MeetModel.STATUS.COMM, MeetModel.STATUS.OVER]]; // 状态  let orderBy = {'JOIN_MEET_TIME_START': 'asc','JOIN_ADD_TIME': 'desc'}return await JoinModel.getAll(where, fields, orderBy);}
}

UI设计

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

老师端设计

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

管理端

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

git代码下载

git下载

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

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

相关文章

记录第一次使用air热更新golang项目

下载 go install github.com/cosmtrek/airlatest 下载时提示&#xff1a; module declares its path as: github.com/air-verse/air but was required as: github.com/cosmtrek/air 此时&#xff0c;需要在go.mod中加上这么一句&#xff1a; replace github.com/cosmtrek/air &…

qt QGridLayout 简单实验1

1.概要 2.实验 2.1 实验1 简单实验跨行 2.1.1 代码 #ifndef WIDGET_H #define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr);~W…

STM32 - 内存分区与OTA

最近搞MCU&#xff0c;发现它与SOC之间存在诸多差异&#xff0c;不能沿用SOC上一些技术理论。本文以STM L4为例&#xff0c;总结了一些STM32 小白入门指南。 标题MCU没有DDR&#xff1f; 是的。MCU并没有DDR&#xff0c;而是让代码存储在nor flash上&#xff0c;临时变量和栈…

yolov5实例分割跑通以及C#读取yolov5_Seg实例分割转换onnx进行检测部署

一、首先需要训练yolov5_seg的模型&#xff0c;可以去网上学习&#xff0c;或者你直接用我的&#xff0c; 训练环境和yolov5—7.0的环境一样&#xff0c;你可以直接拷过来用。 yolov5_seg算法 链接&#xff1a;https://pan.baidu.com/s/1m-3lFWRHwg5t8MmIOKm4FA 提取码&…

【MySQL】1.初识MySQL

初识MySQL 一.MySQL 安装1.卸载已有的 MySQL2.获取官方 yum 源3.安装 MySQL4.登录 MySQL5.配置 my.cnf 二.MySQL 数据库基础1.MySQL 是什么&#xff1f;2.服务器&#xff0c;数据库和表3.mysqld 的层状结构4.SQL 语句分类 一.MySQL 安装 1.卸载已有的 MySQL //查询是否有相关…

《Windows API每日一练》8.3 scrollbar控件

在第三章SYSMETS2.C实例中&#xff0c;我们是通过CreateWindow函数创建窗口的参数窗口样式中添加垂直或水平滚动条。本节我们将讲述作为子窗口控件的滚动条。 本节必须掌握的知识点&#xff1a; 滚动条类 滚动条控件和着色 8.3.1 滚动条类 ■窗口滚动条与滚动条控件的异同 …

在Linux环境下搭建Redis服务结合内网穿透实现通过GUI工具远程管理数据库

文章目录 前言1. 安装Docker步骤2. 使用docker拉取redis镜像3. 启动redis容器4. 本地连接测试4.1 安装redis图形化界面工具4.2 使用RDM连接测试 5. 公网远程访问本地redis5.1 内网穿透工具安装5.2 创建远程连接公网地址5.3 使用固定TCP地址远程访问 前言 本文主要介绍如何在Li…

mysql 9 新特新

mysql9新特性 新特性Audit Log NotesC API NotesCharacter Set SupportCompilation NotesComponent NotesConfiguration NotesData Dictionary NotesData Type NotesDeprecation and Removal NotesEvent Scheduler NotesJavaScript ProgramsOptimizer NotesPerformance Schema …

Spring中的事件监听器使用学习

一、什么是Spring中的事件监听机制&#xff1f; Spring框架中的事件监听机制是一种设计模式&#xff0c;它允许你定义和触发事件&#xff0c;同时允许其他组件监听这些事件并在事件发生时作出响应。这种机制基于观察者模式&#xff0c;提供了一种松耦合的方式来实现组件间的通信…

CTF实战:从入门到提升

CTF实战&#xff1a;从入门到提升 &#x1f680;前言 没有网络安全就没有国家安全&#xff0c;网络安全不仅关系到国家整体信息安全&#xff0c;也关系到民生安全。近年来&#xff0c;随着全国各行各业信息化的发展&#xff0c;网络与信息安全得到了进一步重视&#xff0c;越…

XAML 框架横向对比

多年来&#xff0c;基于 XAML 的 UI 框架有了很大的发展。下面的图表很好地证明了这个观点。XAML UI 框架的三大巨头&#xff1a;Avalonia UI、Uno Platform 和 .NET MAUI 都支持跨平台的应用。事实上&#xff0c;除了 Avalonia UI&#xff0c;对跨平台 XAML 的需求是它们发展的…

【深度学习】图形模型基础(5):线性回归模型第四部分:预测与贝叶斯推断

1.引言 贝叶斯推断超越了传统估计方法&#xff0c;它包含三个关键步骤&#xff1a;结合数据和模型形成后验分布&#xff0c;通过模拟传播不确定性&#xff0c;以及利用先验分布整合额外信息。本文将通过实际案例阐释这些步骤&#xff0c;展示它们在预测和推断中的挑战和应用。…

Unity 使用AVProMovieCapture实现Game视图屏幕录制

内容将会持续更新&#xff0c;有错误的地方欢迎指正&#xff0c;谢谢! Unity 使用AVProMovieCapture实现Game视图屏幕录制 TechX 坚持将创新的科技带给世界&#xff01; 拥有更好的学习体验 —— 不断努力&#xff0c;不断进步&#xff0c;不断探索 TechX —— 心探索、心…

【云计算】公有云、私有云、混合云、社区云、多云

公有云、私有云、混合云、社区云、多云 1.云计算的形态1.1 公有云1.2 私有云1.3 混合云1.4 社区云1.5 多云1.5.1 多云和混合云之间的关系1.5.2 多云的用途1.5.3 影子 IT 和多云1.5.4 优缺点 2.不同云形态的对比 1.云计算的形态 张三⾃⼰在家做饭吃&#xff0c;这是 私有云&…

【扩散模型】LCM LoRA:一个通用的Stable Diffusion加速模块

潜在一致性模型&#xff1a;[2310.04378] Latent Consistency Models: Synthesizing High-Resolution Images with Few-Step Inference (arxiv.org) 原文&#xff1a;Paper page - Latent Consistency Models: Synthesizing High-Resolution Images with Few-Step Inference (…

ELK优化之Filebeat部署

目录 1.安装配置Nginx 2.安装 Filebeat 3.设置 filebeat 的主配置文件 4.修改Logstash配置 5.启动配置 6.kibana验证 主机名ip地址主要软件es01192.168.9.114ElasticSearches02192.168.9.115ElasticSearches03192.168.9.116ElasticSearch、Kibananginx01192.168.9.113ng…

Redis---9---集群(cluster)

将新增的6387节点&#xff08;空槽号&#xff09;作为master节点加入原集群 Redis—9—集群&#xff08;cluster&#xff09; 是什么 定义 ​ 由于数据量过大&#xff0c;单个Master复制集难以承担&#xff0c;因此需要对多个复制集进行集群&#xff0c;形成水平扩展每个复…

5个实用的文章生成器,高效输出优质文章

在自媒体时代&#xff0c;优质内容的持续输出是吸引读者、提升影响力的关键。然而&#xff0c;对于许多自媒体创作者来说&#xff0c;频繁的创作难免会遭遇灵感枯竭、创作不出文章的困扰。此时&#xff0c;文章生成器便成为了得力的助手。文章生成器的优势能够快速自动生成高质…

代码随想录算法训练营第13天|二叉树的递归遍历、二叉树的迭代遍历、二叉树的统一迭代法、102.二叉树的层序遍历

打卡Day13 1.理论基础2.二叉树的递归遍历3.二叉树的迭代遍历3.二叉树的统一迭代法4.102.二叉树的层序遍历扩展107. 二叉树的层序遍历 II199.二叉树的右视图637.二叉树的层平均值429.N叉树的层序遍历515.在每个树行中找最大值116.填充每个节点的下一个右侧节点指针117. 填充每个…

如何保证接口幂等性

如何保证接口幂等性 1、幂等性是什么&#xff1f; 接口幂等性是指用户对于同一操作发起的一次请求或者多次请求的结果是一致的&#xff0c;不会因为多次点击而产生了不同的结果。 2、使用幂等性的场景有哪些&#xff1f; 页面点击保存按钮时&#xff0c;不小心快速点了两次…