开发背景
机构:各类音体美,数理化培训机构须要进行课时治理、课时统计、课时计算、课时记录、上课预约注销,
学员:须要实时查看本人的课程耗费状况,应用记录。
管理者:须要随时查看,增减学员的课程数量
性能布局
技术选型
- 应用微信小程序平台进行开发。
- 应用腾讯专门的小程序云开发技术,云资源蕴含云函数,数据库,带宽,存储空间,定时器等,资源配额价格低廉,无需域名和服务器即可搭建。
- 小程序自身的即用即走,适宜小工具的应用场景,也适宜疾速开发迭代。
- 云开发技术采纳腾讯外部链路,没有被黑客攻击的危险,不会 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源码
git源码下载