从0到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下载
相关文章:

从0到1:培训老师预约小程序开发笔记二
背景调研 培训老师预约小程序: 教师和学生可以更便捷地安排课程,并提升教学质量和学习效果,使之成为管理和提升教学效果的强大工具。培训老师可以在小程序上设置自己的可预约时间,学员可以根据老师的日程安排选择合适的时间进行预…...

【FFmpeg】av_read_frame函数
目录 1.av_read_frame1.2 从pkt buffer中读取帧(avpriv_packet_list_get)1.3 从流当中读取帧(read_frame_internal)1.3.1 读取帧(ff_read_packet)1.3.2 解析packet(parse_packet)1.3…...

女生学计算机好不好?感觉计算机分有点高……?
众所周知,在国内的高校里,计算机专业的女生是非常少的,很多小班30人左右,但是每个班女生人数只有个位数。这就给很多人一个感觉,是不是女生天生就不适合学这个东西呢?女生是不是也应该放弃呢?当…...
windows10/11 如何开启卓越性能模式
在Windows 10和Windows 11中,可以通过以下步骤启用“卓越性能”模式。请注意,卓越性能模式仅在Windows 10 Pro for Workstations和Windows 10 Enterprise版本中可用。 使用命令提示符启用卓越性能模式 打开命令提示符: 按Win X键࿰…...
JSP WEB开发(二) JavaBean
目录 JavaBean JavaBean特征 JavaBean的标签 JavaBean 的范围 标签 JavaBean JavaBean 是一种符合某些命名和设计规范的 Java 类,它是一种可重用组件技术,主要用于封装数据,执行负责的计算任务,封装事务逻辑等。JavaBean 的实…...

G2.【C语言】EasyX绘制颜色窗口
1.窗口 窗口:宽度*高度(单位都是像素) #include <stdio.h> #include <easyx.h> int main() {initgraph(640, 480);getchar();return 0; } 640是宽,480是高 2.操作窗口的三个按钮 #include <stdio.h> #incl…...

异构计算技术与DTK异构开发套件
异构计算技术与DTK异构开发套件 费林分类法:SISD SIMD MISD MIMD 指令流I和数据流D MIMD不同存储结构: UMA均匀存储访问模型NUMA非均匀存储访问模型Cluster集群 现在以Cluster为主 DTK异构开发套件 生态结构 异构并行编程模型是什么 HIPÿ…...

数据结构之“栈”(全方位认识)
🌹个人主页🌹:喜欢草莓熊的bear 🌹专栏🌹:数据结构 前言 栈是一种数据结构,具有" 后进先出 "的特点 或者也可见说是 ” 先进后出 “。大家一起加油吧冲冲冲!! …...

vue项目打包部署后 浏览器自动清除缓存问题(解决方法)
vue打包部署后 浏览器缓存问题,导致控制台报错ChunkLoadError: Loading chunk failed的解决方案 一、报错如下: 每次build打包部署到服务器上时,偶尔会出现前端资源文件不能及时更新到最新,浏览器存在缓存问题,这时在…...

解决vscode配置C++编译带有中文名称报错问题
在新电脑上安装vscode运行带有中文路径和中文名称的C代码时遇到报错 根据别人的教程将laugh.json文件中"program": "${fileDirname}\\${fileBasenameNoExtension}.exe",改成了"program": "${fileDirname}\\output\\test.exe",&#x…...
A61 STM32_HAL库函数 之 TIM扩展驱动 -- C -- 所有函数的介绍及使用
A61 STM32_HAL库函数 之 TIM扩展驱动 -- C -- 所有函数的介绍及使用 1 该驱动函数预览1.24 HAL_TIMEx_OnePulseN_Stop1.25 HAL_TIMEx_OnePulseN_Start_IT1.26 HAL_TIMEx_OnePulseN_Stop_IT1.27 HAL_TIMEx_ConfigCommutationEvent1.28 HAL_TIMEx_ConfigCommutationEvent_IT1.29 …...

使用瀚高数据库开发管理工具进行数据的备份与恢复---国产瀚高数据库工作笔记008
使用瀚高数据库,备份 恢复数据 然后找到对应的目录 其实就是hgdbdeveloper,瀚高的数据库开发管理工具 对应的包中有个dbclient 这个目录,选中这个目录以后,就可以了,然后 在对应的数据库,比如 data_middle 中,选中 某个模式,比如bigdata_huiju 然后右键进行,点击 恢复,然…...
css 选择器汇总
目录 所有选择器伪类选择器 所有选择器 选择器用法id选择器#myid类选择器.myclassname标签选择器div,h1,p相邻选择器h1p子选择器ul > li后代选择器li a通配符选择器*属性选择器a[rel“external”]伪类选择器a:hover, li:nth-child 伪类选择器 在CSS3中新增了一个结构伪类选…...
My Greedy Algorithm(贪心算法)之路(一)
引子:我们之前,其实也遇到过贪心算法,0,1背包就是一个典型的贪心算法问题,那今天我就来开始my-Greedy Algorithm的道路。 什么是贪心算法? 我愿称贪心算法为贪婪鼠目寸光,贪心算法(Greedy Alg…...

Win11 Python3.10 安装pytorch3d
0,背景 Python3.10、cuda 11.7、pytorch 2.0.1 阅读【深度学习】【三维重建】windows10环境配置PyTorch3d详细教程-CSDN博客 1,解决方法 本来想尝试,结果发现CUB安装配置对照表里没有cuda 11.7对应的版本,不敢轻举妄动&#x…...
kotlin 中 string array 怎么表示
在 Kotlin 中,字符串数组可以使用 Array<String> 类型表示。你可以通过多种方式来创建和初始化字符串数组。以下是几种常见的方法: 使用 arrayOf 函数: val stringArray arrayOf("Hello", "World", "Kotli…...

ffmpeg使用bmp编码器把bgr24编码为bmp图像
version #define LIBAVCODEC_VERSION_MAJOR 60 #define LIBAVCODEC_VERSION_MINOR 15 #define LIBAVCODEC_VERSION_MICRO 100 note 不使用AVOutputFormat code void CFfmpegOps::EncodeBGR24ToBMP(const char* infile, const char* width_str, const char* height_str…...

基于YOLOv10+YOLOP+PYQT的可视化系统,实现多类别目标检测+可行驶区域分割+车道线分割【附代码】
文章目录 前言视频效果必要环境一、代码结构1、 训练参数解析2、 核心代码解析1.初始化Detector类2. torch.no_grad()3. 复制输入图像并初始化计数器4. 调用YOLOv10模型进行目标检测5. 提取检测结果信息6. 遍历检测结果并在图像上绘制边界框和标签7. 准备输入图像以适应End-to-…...

计算机网络之令牌总线
上文内容:什么是以太网 1.令牌总线工作原理 在总线的基础上,通过在网络结点之间有序地传递令牌来分配各结点对共享型总线的访问权利,形成闭合的逻辑环路。 完全采用半双工的操作方式,只有获得令牌的结点才能发送信息ÿ…...

策略模式的应用
前言 系统有一个需求就是采购员审批注册供应商的信息时,会生成一个供应商的账号,此时需要发送供应商的账号信息(账号、密码)到注册填写的邮箱中,通知供应商账号信息,当时很快就写好了一个工具类࿰…...

CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...

自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...

LLMs 系列实操科普(1)
写在前面: 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容,原视频时长 ~130 分钟,以实操演示主流的一些 LLMs 的使用,由于涉及到实操,实际上并不适合以文字整理,但还是决定尽量整理一份笔…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...
jmeter聚合报告中参数详解
sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...

图解JavaScript原型:原型链及其分析 | JavaScript图解
忽略该图的细节(如内存地址值没有用二进制) 以下是对该图进一步的理解和总结 1. JS 对象概念的辨析 对象是什么:保存在堆中一块区域,同时在栈中有一块区域保存其在堆中的地址(也就是我们通常说的该变量指向谁&…...
二维FDTD算法仿真
二维FDTD算法仿真,并带完全匹配层,输入波形为高斯波、平面波 FDTD_二维/FDTD.zip , 6075 FDTD_二维/FDTD_31.m , 1029 FDTD_二维/FDTD_32.m , 2806 FDTD_二维/FDTD_33.m , 3782 FDTD_二维/FDTD_34.m , 4182 FDTD_二维/FDTD_35.m , 4793...