招生报名缴费小程序开发笔记(上)

前期调研

  • 1.数字化趋势: 随着社会的数字化转型,越来越多的教育机构倾向于采用数字工具来简化和优化他们的招生和报名过程。招生报名缴费小程序是应对这一趋势的一种解决方案,可以提供高效、方便、快速的在线招生渠道。
  • 2.用户需求: 学生和家长希望能够通过手机或电脑完成入学申请和缴费,而不必亲自前往学校或教育机构,填写纸质表格,或排队等候。这种便捷性对于吸引更多申请者和提高报名率非常重要。
  • 3.减少错误和欺诈: 使用在线报名和缴费系统可以减少手动处理和数据输入错误的风险。此外,数字支付方法可以提高资金管理的透明度,减少现金管理问题和欺诈风险。
  • 4.提高效率: 传统的报名流程通常需要大量的人力资源和时间,而自动化的招生报名缴费小程序可以大大提高效率,减少了繁琐的手工工作。
  • 5.竞争优势: 对于教育机构而言,提供一种现代化、便捷的招生报名流程可以成为他们在竞争激烈的市场中脱颖而出的重要优势。
  • 6.数据分析和管理: 数字化报名系统可以生成大量数据,使教育机构能够更好地了解他们的申请者,优化招生流程,并进行更精确的市场营销。

综上所述,招生报名缴费小程序的开发背景是满足数字化趋势、提供用户需求、提高效率、降低错误和欺诈风险,并在教育市场中获得竞争优势。这种小程序为学校、大学和培训机构提供了一个现代化、便捷的方式来管理招生流程,同时也为申请者提供更好的用户体验。

功能设计

招生报名缴费小程序是一个用于学校、大学、培训机构或其他教育机构的应用程序,旨在帮助学生完成入学申请和支付报名费用。以下是招生报名缴费小程序可能包括的功能和组成部分:

  • 1.用户注册与登录: 学生和家长需要能够创建个人账户并登录,以便访问相关功能。
  • 2.招生信息浏览: 提供学校或机构的招生信息,包括不同课程、入学要求、截止日期等。
  • 3.在线报名表格: 学生可以填写入学申请表格,包括个人信息、学历背景、联系信息等。
  • 4.文件上传: 允许学生上传必要的文件,如身份证、学历证明、推荐信等。
  • 5.报名费计算: 根据所选课程和选项自动计算报名费用,并显示给用户。
  • 6.在线支付: 提供各种支付选项,如信用卡、支付宝、微信支付等,以便用户能够方便地支付报名费用。
  • 7.报名进度追踪: 学生可以查看他们的报名进度,了解是否需要提供额外的信息,审核状态等。
  • 8.通知和提醒: 发送通知和提醒,以提醒学生关于重要的报名截止日期、文件提交等事项。
  • 9.电子收据和确认信: 学生完成缴费后,能够获得电子收据和入学确认信。
    招生报名缴费小程序的设计和开发需要充分考虑用户友好性、安全性和数据保护,以确保顺畅的用户体验和数据的安全性。这样的小程序可以极大地简化招生报名过程,提高效率,同时提供更好的用户体验。
    在这里插入图片描述

数据库设计


ActivityModel.DB_STRUCTURE = {_pid: 'string|true',ACTIVITY_ID: 'string|true',ACTIVITY_TITLE: 'string|true|comment=标题',ACTIVITY_STATUS: 'int|true|default=1|comment=状态 0=未启用,1=使用中',ACTIVITY_CATE_ID: 'string|true|default=0|comment=分类',ACTIVITY_CATE_NAME: 'string|false|comment=分类冗余',ACTIVITY_CANCEL_SET: 'int|true|default=1|comment=取消设置 0=不允,1=允许,2=仅截止前可取消',ACTIVITY_CHECK_SET: 'int|true|default=0|comment=审核 0=不需要审核,1=需要审核', ACTIVITY_MAX_CNT: 'int|true|default=20|comment=人数上限 0=不限',ACTIVITY_START: 'int|false|comment=开始时间戳',ACTIVITY_END: 'int|false|comment=截止时间戳',ACTIVITY_START_DAY: 'string|false|comment=开始时间',ACTIVITY_END_DAY: 'string|false|comment=截止时间', ACTIVITY_START_MONTH: 'string|false|comment=开始月份',ACTIVITY_END_MONTH: 'string|false|comment=截止月份',ACTIVITY_ORDER: 'int|true|default=9999',ACTIVITY_VOUCH: 'int|true|default=0',ACTIVITY_FORMS: 'array|true|default=[]',ACTIVITY_OBJ: 'object|true|default={}',ACTIVITY_JOIN_FORMS: 'array|true|default=[]', ACTIVITY_QR: 'string|false',ACTIVITY_VIEW_CNT: 'int|true|default=0',ACTIVITY_COMMENT_CNT: 'int|true|default=0',ACTIVITY_METHOD: 'int|true|default=0|comment=支付方式 0=线下,1=线上',ACTIVITY_FEE: 'int|false|comment=支付金额 分',ACTIVITY_JOIN_CNT: 'int|true|default=0',ACTIVITY_PAY_CNT: 'int|true|default=0|comment=支付数',ACTIVITY_PAY_FEE: 'int|true|default=0|comment=支付额', ACTIVITY_ADD_TIME: 'int|true',ACTIVITY_EDIT_TIME: 'int|true',ACTIVITY_ADD_IP: 'string|false',ACTIVITY_EDIT_IP: 'string|false',
};// 字段前缀
ActivityModel.FIELD_PREFIX = "ACTIVITY_";/*** 状态 0=未启用,1=使用中 */
ActivityModel.STATUS = {UNUSE: 0,COMM: 1
};ActivityJoinModel.DB_STRUCTURE = {_pid: 'string|true',ACTIVITY_JOIN_ID: 'string|true',ACTIVITY_JOIN_ACTIVITY_ID: 'string|true|comment=报名PK',ACTIVITY_JOIN_IS_ADMIN: 'int|true|default=0|comment=是否管理员添加 0/1',ACTIVITY_JOIN_CANCEL_TIME: 'int|true|default=0|comment=取消时间',ACTIVITY_JOIN_USER_ID: 'string|true|comment=用户ID',ACTIVITY_JOIN_FORMS: 'array|true|default=[]|comment=表单',ACTIVITY_JOIN_OBJ: 'object|true|default={}',ACTIVITY_JOIN_STATUS: 'int|true|default=1|comment=状态  0=待审核 1=报名成功, 98=自己取消,99=审核未过/取消',ACTIVITY_JOIN_REASON: 'string|false|comment=审核拒绝或者取消理由',ACTIVITY_JOIN_FEE: 'int|true|default=0|comment=需支付费用 分',ACTIVITY_JOIN_PAY_TRADE_NO: 'string|false|comment=商家订单号 32位',ACTIVITY_JOIN_PAY_STATUS: 'int|true|default=0|comment=支付状态 0=未支付 1=已支付 8=已退款 99=无需支付',ACTIVITY_JOIN_PAY_FEE: 'int|true|default=0|comment=已支付费用 分',ACTIVITY_JOIN_PAY_TIME: 'int|true|default=0|comment=支付时间',ACTIVITY_JOIN_ADD_TIME: 'int|true',ACTIVITY_JOIN_EDIT_TIME: 'int|true',ACTIVITY_JOIN_ADD_IP: 'string|false',ACTIVITY_JOIN_EDIT_IP: 'string|false',
};// 字段前缀
ActivityJoinModel.FIELD_PREFIX = "ACTIVITY_JOIN_";/*** 状态 0=待审核 1=报名成功, 99=审核未过*/
ActivityJoinModel.STATUS = {WAIT: 0,SUCC: 1,CANCEL: 98,ADMIN_CANCEL: 99
};ActivityJoinModel.STATUS_DESC = {WAIT: '待审核',SUCC: '成功',CANCEL: '取消',ADMIN_CANCEL: '审核未过'
};

代码核心

async minuteJob() {console.log('### minuteJob >>>>>');// 未支付的成功订单取消  let time = this._timestamp - 6 * 60 * 1000;console.log('###### Begin>>> 未支付订单6分钟后取消, time<=' + time + ', ' + timeUtil.timestamp2Time(time));let where = {ACTIVITY_JOIN_STATUS: ['in', [ActivityJoinModel.STATUS.WAIT, ActivityJoinModel.STATUS.SUCC]],ACTIVITY_JOIN_PAY_STATUS: 0,ACTIVITY_JOIN_ADD_TIME: ['<=', time],}let rows = await ActivityJoinModel.getAll(where, '*', {}, 3000, false);console.log('未支付订单6分钟后取消, count=', rows.length);for (let k in rows) {let activityJoin = rows[k];let tradeNo = activityJoin.ACTIVITY_JOIN_PAY_TRADE_NO;if (!await this.fixActivityJoinPay(tradeNo, activityJoin.ACTIVITY_JOIN_ACTIVITY_ID)) {console.log('该报名记录未支付,已取消并删除!', activityJoin);}}console.log('###### END. 未支付订单6分钟后取消');}// 获取当前报名状态getJoinStatusDesc(activity) {let timestamp = this._timestamp;if (activity.ACTIVITY_STATUS == 0)return '报名停止';else if (activity.ACTIVITY_START > timestamp)return '报名未开始';else if (activity.ACTIVITY_END <= timestamp)return '报名截止';else if (activity.ACTIVITY_MAX_CNT > 0&& activity.ACTIVITY_JOIN_CNT >= activity.ACTIVITY_MAX_CNT)return '报名已满';elsereturn '报名中';}/** 浏览信息 */async viewActivity(userId, id) {await this.fixUserActivityJoinPayRecord(userId);let fields = '*';let where = {_id: id,ACTIVITY_STATUS: ActivityModel.STATUS.COMM}let activity = await ActivityModel.getOne(where, fields);if (!activity) return null;ActivityModel.inc(id, 'ACTIVITY_VIEW_CNT', 1);// 判断是否有报名let whereJoin = {ACTIVITY_JOIN_USER_ID: userId,ACTIVITY_JOIN_ACTIVITY_ID: id,ACTIVITY_JOIN_STATUS: ['in', [ActivityJoinModel.STATUS.WAIT, ActivityJoinModel.STATUS.SUCC]]}let activityJoin = await ActivityJoinModel.getOne(whereJoin);if (activityJoin) {activity.myActivityJoinId = activityJoin._id;activity.myActivityJoinTag = (activityJoin.ACTIVITY_JOIN_STATUS == ActivityJoinModel.STATUS.WAIT) ? '待审核' : '已报名';if (activity.myActivityJoinTag == '已报名' && activityJoin.ACTIVITY_JOIN_PAY_STATUS == 1) {activity.myActivityJoinTag = '已报名缴费';}}else {activity.myActivityJoinId = '';activity.myActivityJoinTag = '';}return activity;}/** 取得分页列表 */async getActivityList({cateId, //分类查询条件search, // 搜索条件sortType, // 搜索菜单sortVal, // 搜索菜单orderBy, // 排序 page,size,isTotal = true,oldTotal}) {orderBy = orderBy || {'ACTIVITY_ORDER': 'asc','ACTIVITY_ADD_TIME': 'desc'};let fields = 'ACTIVITY_START_MONTH,ACTIVITY_END_MONTH,ACTIVITY_START_DAY,ACTIVITY_END_DAY,ACTIVITY_JOIN_CNT,ACTIVITY_OBJ,ACTIVITY_VIEW_CNT,ACTIVITY_TITLE,ACTIVITY_MAX_CNT,ACTIVITY_START,ACTIVITY_END,ACTIVITY_ORDER,ACTIVITY_STATUS,ACTIVITY_CATE_NAME,ACTIVITY_OBJ';let where = {};where.and = {_pid: this.getProjectId() //复杂的查询在此处标注PID};if (cateId && cateId !== '0') where.and.ACTIVITY_CATE_ID = cateId;where.and.ACTIVITY_STATUS = ActivityModel.STATUS.COMM; // 状态  if (util.isDefined(search) && search) {where.or = [{ACTIVITY_TITLE: ['like', search]},];} else if (sortType && util.isDefined(sortVal)) {// 搜索菜单switch (sortType) {case 'cateId': {if (sortVal) where.and.ACTIVITY_CATE_ID = String(sortVal);break;}case 'sort': {// 排序orderBy = this.fmtOrderBySort(sortVal, 'ACTIVITY_ADD_TIME');break;}case 'today': { //今天let time = timeUtil.time('Y-M-D');where.and.ACTIVITY_START_DAY = ['<=', time];where.and.ACTIVITY_END_DAY = ['>=', time];break;}case 'tomorrow': { //明日let time = timeUtil.time('Y-M-D', 86400);where.and.ACTIVITY_START_DAY = ['<=', time];where.and.ACTIVITY_END_DAY = ['>=', time];break;}case 'month': { //本月let month = timeUtil.time('Y-M');where.and.ACTIVITY_START_MONTH = ['<=', month];where.and.ACTIVITY_END_MONTH = ['>=', month];break;}}}return await ActivityModel.getList(where, fields, orderBy, page, size, isTotal, oldTotal);}/** 取得我的报名分页列表 */async getMyActivityJoinList(userId, {search, // 搜索条件sortType, // 搜索菜单sortVal, // 搜索菜单orderBy, // 排序 page,size,isTotal = true,oldTotal}) {await this.fixUserActivityJoinPayRecord(userId);orderBy = orderBy || {'ACTIVITY_JOIN_ADD_TIME': 'desc'};let fields = 'ACTIVITY_JOIN_PAY_STATUS,ACTIVITY_JOIN_REASON,ACTIVITY_JOIN_ACTIVITY_ID,ACTIVITY_JOIN_STATUS,ACTIVITY_JOIN_ADD_TIME,activity.ACTIVITY_END,activity.ACTIVITY_START,activity.ACTIVITY_TITLE';let where = {ACTIVITY_JOIN_USER_ID: userId};if (util.isDefined(search) && search) {where['activity.ACTIVITY_TITLE'] = {$regex: '.*' + search,$options: 'i'};} else if (sortType) {// 搜索菜单switch (sortType) {case 'timedesc': { //按时间倒序orderBy = {'activity.ACTIVITY_START': 'desc','ACTIVITY_JOIN_ADD_TIME': 'desc'};break;}case 'timeasc': { //按时间正序orderBy = {'activity.ACTIVITY_START': 'asc','ACTIVITY_JOIN_ADD_TIME': 'asc'};break;}case 'succ': {where.ACTIVITY_JOIN_STATUS = ActivityJoinModel.STATUS.SUCC;break;}case 'wait': {where.ACTIVITY_JOIN_STATUS = ActivityJoinModel.STATUS.WAIT;break;}case 'usercancel': {where.ACTIVITY_JOIN_STATUS = ActivityJoinModel.STATUS.CANCEL;break;}case 'cancel': {where.ACTIVITY_JOIN_STATUS = ActivityJoinModel.STATUS.ADMIN_CANCEL;break;}}}let joinParams = {from: ActivityModel.CL,localField: 'ACTIVITY_JOIN_ACTIVITY_ID',foreignField: '_id',as: 'activity',};let result = await ActivityJoinModel.getListJoin(joinParams, where, fields, orderBy, page, size, isTotal, oldTotal);return result;}/** 取得我的报名详情 */async getMyActivityJoinDetail(userId, activityJoinId) {let fields = '*';let where = {_id: activityJoinId,ACTIVITY_JOIN_USER_ID: userId};let activityJoin = await ActivityJoinModel.getOne(where, fields);if (activityJoin) {activityJoin.activity = await ActivityModel.getOne(activityJoin.ACTIVITY_JOIN_ACTIVITY_ID, 'ACTIVITY_TITLE,ACTIVITY_START,ACTIVITY_END');}return activityJoin;}// 修正某用户所有未支付的成功订单状态,无须支付的不用处理async fixUserActivityJoinPayRecord(userId) {let where = {ACTIVITY_JOIN_USER_ID: userId,ACTIVITY_JOIN_PAY_STATUS: 0,ACTIVITY_JOIN_STATUS: ['in', [ActivityJoinModel.STATUS.WAIT, ActivityJoinModel.STATUS.SUCC]],}let list = await ActivityJoinModel.getAll(where);for (let k = 0; k < list.length; k++) {await this.fixActivityJoinPay(list[k].ACTIVITY_JOIN_PAY_TRADE_NO, list[k].ACTIVITY_JOIN_ACTIVITY_ID);}}// 修正某订单状态 (仅需支付订单)async fixActivityJoinPay(tradeNo, activityId) {if (!tradeNo) {// 无支付号空单 删除await ActivityJoinModel.del({ ACTIVITY_JOIN_PAY_TRADE_NO: tradeNo });// 重新统计this.statActivityJoin(activityId);return false;}let payService = new PayService();if (!await payService.fixPayResult(tradeNo)) {// 关闭未支付单payService.closePay(tradeNo);// 未支付 await ActivityJoinModel.del({ ACTIVITY_JOIN_PAY_TRADE_NO: tradeNo });// 重新统计this.statActivityJoin(activityId);return false;}// 已支付let pay = await PayModel.getOne({ PAY_TRADE_NO: tradeNo });if (!pay) this.AppError('支付流水异常,请核查');// 更新支付信息let data = {ACTIVITY_JOIN_PAY_STATUS: 1,ACTIVITY_JOIN_PAY_TRADE_NO: tradeNo,ACTIVITY_JOIN_PAY_FEE: pay.PAY_TOTAL_FEE,ACTIVITY_JOIN_PAY_TIME: pay.PAY_END_TIME,}await ActivityJoinModel.edit({ ACTIVITY_JOIN_PAY_TRADE_NO: tradeNo }, data);// 重新统计this.statActivityJoin(activityId);return true;}//################## 报名 // 报名 async prepay(userId, activityId, forms) {this.AppError('[招生报名缴费]该功能暂不开放,如有需要请加作者微信:cclinux0730');}async statActivityJoin(activityId) {// 报名数let where = {ACTIVITY_JOIN_ACTIVITY_ID: activityId,ACTIVITY_JOIN_STATUS: ['in', [ActivityJoinModel.STATUS.WAIT, ActivityJoinModel.STATUS.SUCC]]}let cnt = await ActivityJoinModel.count(where);// 已支付记录let wherePayCnt = {ACTIVITY_JOIN_ACTIVITY_ID: activityId,ACTIVITY_JOIN_PAY_STATUS: 1,ACTIVITY_JOIN_STATUS: ['in', [ActivityJoinModel.STATUS.WAIT, ActivityJoinModel.STATUS.SUCC]]}let payCnt = await ActivityJoinModel.count(wherePayCnt);// 已支付金额let wherePayFee = {ACTIVITY_JOIN_ACTIVITY_ID: activityId,ACTIVITY_JOIN_PAY_STATUS: 1,ACTIVITY_JOIN_STATUS: ['in', [ActivityJoinModel.STATUS.WAIT, ActivityJoinModel.STATUS.SUCC]]}let payFee = await ActivityJoinModel.sum(wherePayFee, 'ACTIVITY_JOIN_PAY_FEE');let data = {ACTIVITY_JOIN_CNT: cnt,ACTIVITY_PAY_CNT: payCnt,ACTIVITY_PAY_FEE: payFee,}await ActivityModel.edit(activityId, data);}/**  报名前获取关键信息 */async detailForActivityJoin(userId, activityId) {await this.fixUserActivityJoinPayRecord(userId);let fields = 'ACTIVITY_JOIN_FORMS, ACTIVITY_TITLE, ACTIVITY_FEE, ACTIVITY_METHOD';let where = {_id: activityId,ACTIVITY_STATUS: ActivityModel.STATUS.COMM}let activity = await ActivityModel.getOne(where, fields);if (!activity)this.AppError('该报名不存在');let whereMy = {ACTIVITY_JOIN_USER_ID: userId,}let orderByMy = {ACTIVITY_JOIN_ADD_TIME: 'desc'}//***取得本人所有记录let joinList = await ActivityJoinModel.getAll(whereMy, 'ACTIVITY_JOIN_OBJ,ACTIVITY_JOIN_FORMS', orderByMy);let addressList = [];let addressList2 = [];for (let k = 0; k < joinList.length; k++) {let exist = false;for (let j = 0; j < addressList.length; j++) {if (addressList[j].name === joinList[k].ACTIVITY_JOIN_OBJ.name) {exist = true;break;}}if (!exist) {addressList.push(joinList[k].ACTIVITY_JOIN_OBJ);addressList2.push(joinList[k].ACTIVITY_JOIN_FORMS);}}// 取出本人最近一次的填写表单let joinMy = await ActivityJoinModel.getOne(whereMy, 'ACTIVITY_JOIN_FORMS', orderByMy);joinMy = null;let myForms = joinMy ? joinMy.ACTIVITY_JOIN_FORMS : [];activity.myForms = myForms;activity.addressList = addressList;activity.addressList2 = addressList2;activity.ACTIVITY_FEE = Number(dataUtil.fmtMoney(activity.ACTIVITY_FEE / 100));return activity;}/** 取消我的报名 只有成功和待审核可以取消   */async cancelMyActivityJoin(userId, activityJoinId) {let where = {_id: activityJoinId,ACTIVITY_JOIN_USER_ID: userId,ACTIVITY_JOIN_STATUS: ['in', [ActivityJoinModel.STATUS.WAIT, ActivityJoinModel.STATUS.SUCC]] //只有成功和待审核可以取消};let activityJoin = await ActivityJoinModel.getOne(where);if (!activityJoin) {this.AppError('未找到可取消的报名记录');}let activity = await ActivityModel.getOne(activityJoin.ACTIVITY_JOIN_ACTIVITY_ID);if (!activity)this.AppError('该报名不存在');if (activity.ACTIVITY_CANCEL_SET == 0)this.AppError('该报名不能取消报名');if (activity.ACTIVITY_CANCEL_SET == 2 && activity.ACTIVITY_END < this._timestamp)this.AppError('该报名已经截止,无法取消');if (activityJoin.ACTIVITY_JOIN_PAY_STATUS == 99) {// 无须支付// 更新记录 let data = {ACTIVITY_JOIN_STATUS: ActivityJoinModel.STATUS.CANCEL,ACTIVITY_JOIN_CANCEL_TIME: this._timestamp,}await ActivityJoinModel.edit(activityJoinId, data);}else {let tradeNo = activityJoin.ACTIVITY_JOIN_PAY_TRADE_NO;if (!await this.fixActivityJoinPay(tradeNo, activityJoin.ACTIVITY_JOIN_ACTIVITY_ID)) {this.AppError('该报名记录未支付,已取消并删除!');}let payService = new PayService();await payService.refundPay(tradeNo, '用户取消报名');// 更新记录 let data = {ACTIVITY_JOIN_STATUS: ActivityJoinModel.STATUS.CANCEL,ACTIVITY_JOIN_CANCEL_TIME: this._timestamp,ACTIVITY_JOIN_PAY_STATUS: 8,}await ActivityJoinModel.edit(activityJoinId, data);}// 统计await this.statActivityJoin(activityJoin.ACTIVITY_JOIN_ACTIVITY_ID);}/** 按天获取报名项目 */async getActivityListByDay(day) {let where = {ACTIVITY_START_DAY: ['<=', day],ACTIVITY_END_DAY: ['>=', day]};let orderBy = {'ACTIVITY_ORDER': 'asc','ACTIVITY_ADD_TIME': 'desc'};let fields = 'ACTIVITY_TITLE,ACTIVITY_START,ACTIVITY_OBJ.cover';let list = await ActivityModel.getAll(where, fields, orderBy);let retList = [];for (let k = 0; k < list.length; k++) {let node = {};node.timeDesc = timeUtil.timestamp2Time(list[k].ACTIVITY_START, 'h:m');node.title = list[k].ACTIVITY_TITLE;node.pic = list[k].ACTIVITY_OBJ.cover[0];node._id = list[k]._id;retList.push(node);}return retList;}/*** 获取从某天开始可报名的日期* @param {*} fromDay  日期 Y-M-D*/async getActivityHasDaysFromDay(fromDay) {let where = {ACTIVITY_STATUS: 1,//ACTIVITY_START_DAY: ['<=', fromDay],ACTIVITY_END_DAY: ['>=', fromDay]};let fields = 'ACTIVITY_START_DAY,ACTIVITY_END_DAY';let list = await ActivityModel.getAllBig(where, fields);if (list.length == 0) return;let min = await ActivityModel.min(where, 'ACTIVITY_START_DAY');let max = await ActivityModel.max(where, 'ACTIVITY_END_DAY');let minTimestamp = timeUtil.time2Timestamp(min);let maxTimestamp = timeUtil.time2Timestamp(max);let retList = [];for (let n = minTimestamp; n <= maxTimestamp; n += 86400 * 1000) {let day = timeUtil.timestamp2Time(n, 'Y-M-D');if (day < fromDay) continue;for (let k = 0; k < list.length; k++) {if (day >= list[k].ACTIVITY_START_DAY && day <= list[k].ACTIVITY_END_DAY) {if (!retList.includes(day)) retList.push(day);break;}}}return retList;}

管理系统

在这里插入图片描述

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

用户系统设计

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

代码下载git

下载地址

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

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

相关文章

Jtti:Apache服务的反向代理及负载均衡怎么配置

配置Apache服务的反向代理和负载均衡可以帮助您分散负载并提高应用程序的可用性和性能。下面是一些通用的步骤&#xff0c;以配置Apache反向代理和负载均衡。 1. 安装和配置Apache&#xff1a; 确保您已经安装了Apache HTTP服务器。通常&#xff0c;Apache的配置文件位于/etc…

VSCode-C/C++环境配置

0.下载VSCode VSCode官网 Visual Studio Code - Code Editing. Redefined 1.安装VSCode 2.编译器下载与配置 2.1下载编译器安装包 编译器的安装包分为两种一种是在线的一种是离线的,其区别的特点如下 在线安装&#xff08;只是个下载器&#xff0c;打开后还要下载各种东西…

RocketMQ生产者消息发送出去了,消费者一直接收不到怎么办?(Rocket MQ订阅关系一致性)

问题: 使用RocketMQ消息队列&#xff0c;生产者将数据发送出去了&#xff0c;但是生产者一致没接收到&#xff08;或者是间隔好几分钟&#xff0c;突然接收到一条数据&#xff09;怎么办&#xff1f;并且通过rocket web控制台查看消息的状态为NOT_ONELINE或者NOT_CONSUME&#…

韦东山D1S板子——利用xfel工具初始化内置64MB内存,并直接下载程序到内存运行

1、前言 &#xff08;1&#xff09;最近使用韦东山老师的D1S板子学习RISC-V架构知识&#xff0c;我是结合《RISC-V体系结构编程与实践》这本书的进行学习&#xff0c;其中韦东山老师对书中的代码做了部分移植&#xff0c;到MMU模块就没有在移植书中代码&#xff1b; &#xff0…

java毕业设计基于springboot+vue高校本科学生综评系统

项目介绍 本系统是利用Spring Boot框架而设计的一款结合用户的实际情况而设计的平台&#xff0c;利用VUE技术来将可供学生和管理员来使用的所有界面来显示出来&#xff0c;利用Java语言技术来编程实现用户和管理员所执行的各类操作业务逻辑&#xff0c;以MySQL数据库来存取系统…

把Qt6.2.4内置的标签打印了一遍

2023年10月31日&#xff0c;周二晚上 #include <QGridLayout> #include <QPushButton> #include <QLabel> #include <QApplication> #include <QStyle>int main(int argc, char *argv[]) {QApplication a(argc, argv);QWidget widget;widget.set…

Python 数学函数和 math 模块指南

Python 提供了一组内置的数学函数&#xff0c;包括一个广泛的数学模块&#xff0c;可以让您对数字执行数学任务。 内置数学函数。min() 和 max() 函数可用于在可迭代对象中查找最低或最高值&#xff1a; 示例&#xff1a;查找可迭代对象中的最低或最高值&#xff1a; x min…

Webpack常见的插件和模式

文章目录 一、认识插件Plugin1.认识Plugin 二、CleanWebpackPlugin三、HtmlWebpackPlugin1.生成index.html分析2.自定义HTML模板3.自定义模板数据填充 四、DefinePlugin1.DefinePlugin的介绍2.DefinePlugin的使用 五、Mode配置 一、认识插件Plugin 1.认识Plugin Webpack的另一…

MySQL主从复制原理

1、MySQL主从复制的三个步骤及其原理图 slave会从master读取binlog来进行数据同步 MySQL复制过程分成三步&#xff1a; 1、master将改变记录到二进制日志&#xff08;binary log&#xff09;。这些记录过程叫做二进制日志事件&#xff0c;binary log events。 2、slave将ma…

AcWing 第127场周赛 构造矩阵

构造题目&#xff0c;考虑去除掉最后一行最后一列先进行考虑&#xff0c;假设除了最后一行和最后一列都已经排好了&#xff08;你可以随便排&#xff09;&#xff0c;那么分析知最后一个数字由限制以外其他都已经确定了&#xff0c;无解的情况是k为-1 并且n&#xff0c;m的奇偶…

【多线程面试题十七】、如果不使用synchronized和Lock,如何保证线程安全?

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a;如果不使用synchronized…

【Linux】虚拟机部署与发布J2EE项目(Linux版本)

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《微信小程序开发实战》。&#x1f3af;&#x1f3a…

零资源的大语言模型幻觉预防

零资源的大语言模型幻觉预防 摘要1 引言2 相关工作2.1 幻觉检测和纠正方法2.2 幻觉检测数据集 3 方法论3.1 概念提取3.2 概念猜测3.2.1 概念解释3.2.2 概念推理 3.3 聚合3.3.1 概念频率分数3.3.2 加权聚合 4 实验5 总结 摘要 大语言模型&#xff08;LLMs&#xff09;在各个领域…

FedGNN: Federated Graph Neural Network for Privacy-Preserving Recommendation

FedGNN&#xff1a;用于隐私保护推荐的联邦图神经网络 参考笔记 ICML-21-workshop 本文的主要创新工作 在具有局部差分隐私的模型训练中保护模型梯度&#xff0c;并提出一种伪交互项目采样技术来保护用户与之交互的项目。提出了一种保护隐私的用户-项目图扩展方法&#xff0…

Go学习第十七章——Gin中间件与路由

Go web框架——Gin中间件与路由 1 单独注册中间件1.1 入门案例1.2 多个中间件1.3 中间件拦截响应1.4 中间件放行 2 全局注册中间件3 自定义参数传递4 路由分组4.1 入门案例4.2 路由分组注册中间件4.3 综合使用 5 使用内置的中间件6 中间件案例权限验证耗时统计 1 单独注册中间件…

【c++|opencv】一、基础操作---3.访问图像元素

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 访问图像元素 1. 访问图像像素 1.1 访问某像素 //灰度图像&#xff1a; image.at<uchar>(j, i) //j为行数&#xff0c;i为列数 //BGR彩色图像 i…

思维训练第三课 反意疑问句

系列文章目录 文章目录 系列文章目录前言一、什么是反意疑问句二、反意疑问句的回答&#x1f49a;主系表/主谓宾&#xff08;肯定&#xff09;&#xff0c;否定提问1、一般现在时2、一般过去时3、一般将来时4、现在完成时 &#x1f49b; 主谓宾1、一般现在2、一般过去3、一般将…

大数据可视化BI分析工具Apache Superset实现公网远程访问

大数据可视化BI分析工具Apache Superset实现公网远程访问 文章目录 大数据可视化BI分析工具Apache Superset实现公网远程访问前言1. 使用Docker部署Apache Superset1.1 第一步安装docker 、docker compose1.2 克隆superset代码到本地并使用docker compose启动 2. 安装cpolar内网…

【mfc/VS2022】计图实验:绘图工具设计知识笔记3

实现类对串行化的支持 如果要用CArchive类保存对象的话&#xff0c;那么这个对象的类必须支持串行化。一个可串行化的类通常有一个Serialize成员函数。要想使一个类可串行化&#xff0c;要经历以下5个步骤&#xff1a; 1、从CObject派生类 2、重写Serialize成员函数 3、使用DE…

java基础 集合2

前9点&#xff0c;在另一篇作品中&#xff0c;可以从集合1开始观看 9.List遍历方式&#xff1a; 10.Arraylist底层原理&#xff1a; 11.Linklist底层原理&#xff1a; 1.LinkedList做队列和栈&#xff1a; package day01;import java.util.ArrayList; import java.util.I…