从 0 到 1:学员课时预约与扣课小程序开发笔记
 作者:CC同学
- 2023-03-27  广东
- 本文字数:2687 字 - 阅读完需:约 9 分钟 
开发背景
- 机构:各类音体美,数理化培训机构需要进行课时管理、课时统计、课时计算、课时记录、上课预约登记, 
- 学员:需要实时查看自己的课程消耗情况,使用记录。 
- 管理者:需要随时查看,增减学员的课程数量 
功能规划
 
 技术选型
- 使用微信小程序平台进行开发。 
- 使用腾讯专门的小程序云开发技术,云资源包含云函数,数据库,带宽,存储空间,定时器等,资源配额价格低廉,无需域名和服务器即可搭建。 
- 小程序本身的即用即走,适合小工具的使用场景,也适合快速开发迭代。 
- 云开发技术采用腾讯内部链路,没有被黑客攻击的风险,不会 DDOS 攻击,节省防火墙费用,安全性高且免维护。 
- 资源承载力可根据业务发展需要随时弹性扩展 
数据库设计
LessonLogModel.DB_STRUCTURE = {	_pid: 'string|true',	LESSON_LOG_ID: 'string|true',
	LESSON_LOG_USER_ID: 'string|true|comment=用户ID',
	LESSON_LOG_MEET_ID: 'string|false|comment=预约项目PK',
	LESSON_LOG_DESC: 'string|false|comment=备注',
	LESSON_LOG_TYPE: 'int|true|default=1|comment=类型 0=用户约课-,1=用户取消预约+,10=后台增加课时+,11=后台减少课时-,12=后台取消预约+,13=后台恢复+',
	LESSON_LOG_EDIT_ADMIN_ID: 'string|false|comment=最近修改的管理员ID',	LESSON_LOG_EDIT_ADMIN_NAME: 'string|false|comment=最近修改的管理员名',	LESSON_LOG_EDIT_ADMIN_TIME: 'int|true|default=0|comment=管理员最近修改的时间',
	LESSON_LOG_CHANGE_CNT: 'int|true|default=0|comment=当变动课时数(可正负)',	LESSON_LOG_LAST_CNT: 'int|true|default=0|comment=变动前次数',	LESSON_LOG_NOW_CNT: 'int|true|default=0|comment=当前次数', 
	LESSON_LOG_ADD_TIME: 'int|true',	LESSON_LOG_ADD_IP: 'string|false',
	LESSON_LOG_EDIT_TIME: 'int|true',	LESSON_LOG_EDIT_IP: 'string|false',}
// 字段前缀LessonLogModel.FIELD_PREFIX = "LESSON_LOG_";
/** * 类型 0=初始赠送,1=学员约课,2=学员取消预约,10=后台增加课时,11=后台减少课时,12=后台取消预约,13=后台恢复 */LessonLogModel.TYPE = {	INIT: 0,	USER_APPT: 1,	USER_CANCEL: 2,	ADMIN_ADD: 10,	ADMIN_REDUCE: 11,	ADMIN_CANCEL: 12,	ADMIN_RECOVER: 13};
LessonLogModel.TYPE_DESC = {	INIT: '初始赠送',	USER_APPT: '学员约课',	USER_CANCEL: '学员取消预约',	ADMIN_ADD: '后台增加课时',	ADMIN_REDUCE: '后台减少课时',	ADMIN_CANCEL: '后台取消预约',	ADMIN_RECOVER: '后台恢复预约'};
JoinModel.DB_STRUCTURE = {	_pid: 'string|true',	JOIN_ID: 'string|true',
	JOIN_EDIT_ADMIN_ID: 'string|false|comment=最近修改的管理员ID',	JOIN_EDIT_ADMIN_NAME: 'string|false|comment=最近修改的管理员名',	JOIN_EDIT_ADMIN_TIME: 'int|true|default=0|comment=管理员最近修改的时间',	JOIN_EDIT_ADMIN_STATUS: 'int|false|comment=最近管理员修改为的状态 ',
	JOIN_IS_ADMIN: 'int|true|default=0|comment=是否管理员添加 0/1',
	JOIN_CODE: 'string|true|comment=核验码15位',	JOIN_IS_CHECKIN: 'int|true|default=0|comment=是否核销 0/1 ',	JOIN_CHECKIN_TIME: 'int|true|default=0',
	JOIN_USER_ID: 'string|true|comment=用户ID',	JOIN_MEET_ID: 'string|true|comment=预约PK',	JOIN_MEET_CATE_ID: 'string|true',	JOIN_MEET_CATE_NAME: 'string|true',	JOIN_MEET_TITLE: 'string|true|comment=项目',	JOIN_MEET_DAY: 'string|true|comment=日期',	JOIN_MEET_TIME_START: 'string|true|comment=时段开始',	JOIN_MEET_TIME_END: 'string|true|comment=时段结束',	JOIN_MEET_TIME_MARK: 'string|true|comment=时段标识',
	JOIN_COMPLETE_END_TIME: 'string|false|comment=完整结束时间',
	JOIN_START_TIME: 'int|true|comment=开始时间戳',
	JOIN_FORMS: 'array|true|default=[]|comment=表单',	/* title:	   mark:	   type:	   val:	*/	JOIN_OBJ: 'object|true|default={}',
	JOIN_STATUS: 'int|true|default=1|comment=状态 1=预约成功,10=已取消, 99=系统取消',
	JOIN_REASON: 'string|false|comment=审核拒绝或者取消理由',
	JOIN_ADD_TIME: 'int|true',	JOIN_EDIT_TIME: 'int|true',	JOIN_ADD_IP: 'string|false',	JOIN_EDIT_IP: 'string|false',};
复制代码
 关键代码实现
// 用户预约逻辑	async join(userId, meetId, timeMark, formsList) {		// 预约时段是否存在		let meetWhere = {			_id: meetId		};		let day = this.getDayByTimeMark(timeMark);		let meet = await this.getMeetOneDay(meetId, day, meetWhere);
		if (!meet) {			this.AppError('预约时段选择错误1,请重新选择');		}
		let daySet = this.getDaySetByTimeMark(meet, timeMark);		if (!daySet)			this.AppError('预约时段选择错误2,请重新选择');
		let timeSet = this.getTimeSetByTimeMark(meet, timeMark);		if (!timeSet)			this.AppError('预约时段选择错误3,请重新选择');
		// 规则校验		await this.checkMeetRules(userId, meetId, timeMark, formsList);
		let data = {};
		data.JOIN_USER_ID = userId;		data.JOIN_MEET_ID = meetId;		data.JOIN_MEET_CATE_ID = meet.MEET_CATE_ID;		data.JOIN_MEET_CATE_NAME = meet.MEET_CATE_NAME;		data.JOIN_MEET_TITLE = meet.MEET_TITLE;		data.JOIN_MEET_DAY = daySet.day;		data.JOIN_MEET_TIME_START = timeSet.start;		data.JOIN_MEET_TIME_END = timeSet.end;		data.JOIN_MEET_TIME_MARK = timeMark;		data.JOIN_START_TIME = timeUtil.time2Timestamp(daySet.day + ' ' + timeSet.start + ':00');		data.JOIN_STATUS = JoinModel.STATUS.SUCC;		data.JOIN_COMPLETE_END_TIME = daySet.day + ' ' + timeSet.end;
		// 入库		for (let k = 0; k < formsList.length; k++) {			let forms = formsList[k];			data.JOIN_FORMS = forms;			data.JOIN_OBJ = dataUtil.dbForms2Obj(forms);			data.JOIN_CODE = dataUtil.genRandomIntString(15);			await JoinModel.insert(data);		}
		// 统计		await this.statJoinCnt(meetId, timeMark);
		// 课时统计		await this.editUserMeetLesson(null, userId, -1, LessonLogModel.TYPE.USER_APPT, meetId, '《' + meet.MEET_TITLE + '》')
		return {			result: 'ok',		}	}
复制代码
 前端 UI 设计
 
  
  
  
  
 老师端
 
  
  
 后台管理端
 
  
  
  
 git 源码
https://gitee.com/soft-m/ChildrenPalace?_from=gitee_search
划线
评论
复制
发布于: 刚刚阅读数: 6

CC同学
关注
CC同学的小程序开发笔记 2021-06-13 加入
大鹅厂的小小程序媛,vx: cclinux0730










 
    
评论