当前位置: 首页 > news >正文

什么职位做网站雅奇小蘑菇做网站好不好用

什么职位做网站,雅奇小蘑菇做网站好不好用,企业代码查询入口,分销系统怎么做背景调研 培训老师预约小程序#xff1a; 教师和学生可以更便捷地安排课程#xff0c;并提升教学质量和学习效果#xff0c;使之成为管理和提升教学效果的强大工具。培训老师可以在小程序上设置自己的可预约时间#xff0c;学员可以根据老师的日程安排选择合适的时间进行预…背景调研 培训老师预约小程序 教师和学生可以更便捷地安排课程并提升教学质量和学习效果使之成为管理和提升教学效果的强大工具。培训老师可以在小程序上设置自己的可预约时间学员可以根据老师的日程安排选择合适的时间进行预约。这样可以提高预约的效率减少沟通成本方便双方的安排 功能规划 首页展示展示最新的公告通知、老师推荐等内容吸引用户关注。 老师列表列出所有开课的老师信息包括老师的个人简介、星级等方便用户选择合适的老师。 预约功能用户可以根据自己的需求选择老师并进行预约。 预约管理用户可以查看自己的预约记录包括已完成的预约和待核销的预约也可以取消预约。 后台端可以添加和设定老师的基本信息账号登陆密码等。 老师端可以编辑自己的个人资料头像简介标签集等设定预约时段排期可预约时段各时段人数限定 在现场核销用户的预约码。 顾客端选择自己需要的老师和时段下单预约预约成功后出示预约码给老师或者工作人员核销。 概要设计 数据库设计 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|default1|comment取消设置 0不允,1允许,2仅开始前可取消,MEET_STATUS: int|true|default1|comment状态 0未启用,1使用中,9停止预约,10已关闭,MEET_ORDER: int|true|default9999,MEET_VOUCH: int|true|default0,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|default0|comment当前登录token time,MEET_MINI_OPENID: string|false|comment小程序openid,MEET_LOGIN_CNT: int|true|default0|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|default1|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|default0|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(预约时段设置错误daytime);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.w-s-a.com/news/494622/

相关文章:

  • 合肥网站建设团队简述网站内容管理流程
  • 网站广告是内容营销吗wordpress增加背景图片
  • 网站建设技术jsp课程设计响应式布局网站开发
  • 东莞网站排名优化seo套路网站怎么做的
  • 我做网站网络建站一般多少钱
  • 如何快速提升网站关键词排名房地产网站开发毕业设计
  • 做网站 提交源码 论坛sem分析是什么意思
  • 网站建设与部署阿里云大学百度付费推广有几种方式
  • 作品集怎么做网站个人简历模板免费下
  • 工业网站素材重庆关键词自动排名
  • 拖拽式网站建设费用微网站怎么做的好名字
  • 长沙电信网站备案谷歌推广怎么做最有效
  • 网站建设与管理总结报告华为开发者联盟
  • 门诊部网站建设天空建筑网站
  • 扬州市城乡建设网站高端品牌鞋子有哪些牌子
  • 杭州网站建设招聘网长沙网络销售公司
  • 网站制作一年多少钱免费做电子章网站
  • 信誉好的营销网站建设徐州市铜山新区建设局网站
  • 建行网站关于我们山西seo和网络推广
  • 1m带宽做网站怎么样深圳网站建设制作开发公司
  • 网站建设 服务内容 费用郴州网站建设公司哪里有
  • 网站关键词重要性育才网站建设
  • 网络安全形势下怎么建设学校网站wordpress最新主题下载
  • 自己建设网站需要什么条件.gs域名做网站怎么样
  • 网上做公益的网站推广手机卡返佣平台
  • 网站是公司域名是个人可以南京建设银行官方网站
  • 做互联网网站的会抓百度网盟推广 网站
  • 商务网站开发设计结论微信报名小程序怎么制作
  • 网站建设销售简历wordpress七比2
  • 制作网站报价工程项目查询哪个网站