预约小程序------多选的修改
- 预约小程序模版的来源:yunzizyy/ZixiAppt:
- 在这个小程序上做了较多的修改(补充了丢失的代码、二维码签到、惩罚封禁机制、多选时间段和设置日期),其中有一个涉及到了时间段选择中的多选功能的添加,分享给大家。
- 部署这个小程序还遇到了隐私协议的问题,随便也解决了。
- 不过后面个人开发版无法带后台管理系统,有点尴尬,只能将它放在体验版里(ps:明明之前还通过审核了,后面还是不行)。
- 因为小程序在使用中,就不公开具体源码了(大佬求放过)。
1.在点击选择时间段界面
-
天数改为15天
-
点击时间段实现多选(变色前先检查能否预约、预约人数是否已满)
js
//miniprogram\behavior\meet_detail_bh.js
//原本从meet中获取时间段
let time = this.data.meet.MEET_DAYS_SET[dayIdx].times[timeIdx];
//在通过meetid和时间段的mark定位到预约的时间段
let meetId = this.data.id;
let timeMark = time.mark;
//bindCommitTimeTap函数中用过数组的方式存储多个timeMark实现多个存储
2.在座位选择界面
-
根据上个界面传入的参数(变成字符串类型),在detailForJoin函数中对timeMark转换为timeMarks(数组类型)
-
在默认detailForJoin函数中
原本的参数
后面的参数
-
list:list的生成需要用到的参数有:timeMark
let whereAll = { JOIN_MEET_ID: meetId, JOIN_MEET_TIME_MARK: timeMark, JOIN_STATUS: JoinModel.STATUS.SUCC }
因此需要循环遍历timeMarks,获取多个list
-
dayDesc:dayDesc的生成需要用到的参数有:meet, timeMark。但是meet不同循环遍历获得
jslet dayDesc = timeUtil.fmtDateCHN(this.getDaySetByTimeMark(meet, timeMark).day); let timeSet = this.getTimeSetByTimeMark(meet, timeMark); let timeDesc = timeSet.start + '~' + timeSet.end; meet.dayDesc = dayDesc + ' ' + timeDesc;
-
meet.MEET_DAYS_SET :主要是自习室的某天下所有时间段的详细信息,仅是为了获得limit和isLimit两个参数,感觉可以不用遍历。而且这个参数在前端页面好像也没用。
meet.MEET_DAYS_SET = await this.getDaysSet(meetId, day, day); let times = meet.MEET_DAYS_SET[0].times let matchedTime = times.find(time => time.mark === timeMark); if (matchedTime) { var limit = matchedTime.limit; var isLimit = matchedTime.isLimit; } else { console.log("未找到匹配的 timeMark"); }
成功返回数据。(MEET_DAYS_SET无法使用,因为只保留的最后一天的数据,后续使用需要修改代码)
-
-
更改时间段显示页面为下拉框------方便显示更多的时间段
将更改时间段改为标题处:data-type="back",代表返回是上一个界面,一定要带上,否则仅带bindtap="url"是不行的。
另外data-type="back",将会将type='back'这个参数传入元素的e.currentTarget.dataset.type变量中
html<view class="form-group" bindtap="url" data-type="back">
下拉框设置参考个人信息的学院设置,把select功能去掉即可
php+HTML<view class="form-group"> <view class="title">*学院</view> <cmpt-picker class="selected-school" sourceData="{{schoolList}}" bind:select="schoolPickerChange" data-type="picker" data-item="formschool" model:value="{{formschool}}" item="{{formschool}}"> </cmpt-picker> </view>
html<view class="form-group"> <view class="title text-cut" style="padding-right:0"> <text class="icon-calendar margin-right-xxs"></text> <text style="margin-left: 10px;">所有日期:</text> </view> <cmpt-picker style="font-weight: bold;margin-right: 10px;" sourceData="{{meet.dayDesc}}" bind:select="" data-type="picker" data-item="dayDesc" model:value="{{meet.dayDesc[0]}}" item="{{meet.dayDesc[0]}}"> </cmpt-picker> </view>
3.批量预约
-
将传入的timamark变为数组再批量插入预约
await DayModel.insertBatch(days); // "cmpt-calendar": "../../../../../miniprogram/cmpts/public/calendar/calendar_comm/calendar_comm_cmpt" // "cmpt-calendar": "../../../../../cmpts/public/calendar/calendar_comm/calendar_comm_cmpt"
bug:预约成功后在我的预约中显示的是两个相同的预约记录(时间相同)
解决
-
发现了在插入之前,data的JOIN_MEET_TIME_MARK是一样的,根本没变过
-
node在前面进行了定义,应该在循环内部定义
-
下面代码放入循环内部
jslet node = { JOIN_USER_ID: userId, JOIN_MEET_ID: meetId, JOIN_STUDENT_ID: user.USER_STUDENT_ID, JOIN_CHOOSE_SEAT: chooseSeat, JOIN_FORMS: forms, JOIN_STATUS: JoinModel.STATUS.SUCC, JOIN_CODE: dataUtil.genRandomIntString(15), JOIN_Handled: false };
-
4.返回数据的处理
-
返回数据中data含有多个预约node数据
jstry { await cloudHelper.callCloudSumbit('meet/join', params, opts).then(res => { if (res.data) { let joindata = res.data console.log('joindata', joindata) let opts = { hint: false } cloudHelper.callCloudSumbit('meet/join_notice', joindata, opts) let content = '预约成功!' wx.showModal({ title: '温馨提示', showCancel: false, content, success() { let ck = () => { wx.reLaunch({ url: pageHelper.fmtURLByPID('/pages/my/join_detail/my_join_detail?flag=home&id='), }) } ck(); } }) } }) } catch (err) { console.log(err); // 重新渲染数据 this._loadDetail(); };
-
用res接收返回的数据,发送到模版中并且跳转到相应的界面(将跳转到我的预约中,而不是专门某个预)
jswx.reLaunch({ url: pageHelper.fmtURLByPID('/pages/my/join_detail/my_join_detail?flag=home'), }) wx.reLaunch({ url: pageHelper.fmtURLByPID('/pages/my/join/my_join'), })
-
预约模版中,利用joindata中的data数据进行模版渲染(后续可能需要修改一下字段,日期这边尽量改成字段或者数组)
jscloudHelper.callCloudSumbit('meet/join_notice', joindata, opts) const cloud = CLOUD.getCloud() let input = this._request; console.log('joinNotice传参input',input) try { const result = await cloud.openapi.subscribeMessage.send({ touser:input.data[0].JOIN_USER_ID, //要推送给那个用户 page: input.url, //要跳转到那个小程序页面 data: {//推送的内容 number20: { value: input.data[0].JOIN_STUDENT_ID }, date3: { value: input.data[0].JOIN_MEET_DAY }, thing46: { value: input.data[0].JOIN_CHOOSE_SEAT }, phrase14: { value: '预约成功' }, thing8: { value: '预约须提前两小时取消!' }, }, templateId: '8EquXUUczt7ZFvSL-Qst_vVkRkeJqcUQKia6a6X6j1Y' //模板id })
5.多选时,取消时间段不需要进行before_join校验
//变色时通过一个selected属性来确定的
timesArray[j].selected = false;
//因此后面改变时,需要判断点击后是否为false就好了
6.修改了一下选项框的css样式
7.调整
-
模版消息中,当日期是多个时,在日期后加~符号或者...
value: input.data[0].JOIN_MEET_DAY+'~'+input.data[input.data.length - 1].JOIN_MEET_DAY
-
放出日期中设置放15天给学生进行预约(完成)
-
设置三个自习室进行预约,座位数分别是20、28、25
8.配置云函数的新版本进行灰度测试
云函数的新版本:注意,创建新版本后,原来的版本会被冻结为版本1,latest版本在更新云函数之前和版本1一致,但是后面更新云函数后会导致latest版本更新
云函数和体验版的关系:体验版和正式版分别有一整套源码,但是他们调用的云函数都是一样的(所以要对云函数进行流量分配,如果是正式版调用的应该是之前的版本1的云函数,而如果是体验版调用的是latest版本云函数)
9.上传体验版本
上传完体验版本后,还要记得更新云函数。上传版本主要是对除了云函数外的修改进行提交,仅上传体验版本是无法实现对云函数的更改的!!!
10.审核中的要求
个人信息收集
-
去除进入小程序就要注册的限制,改成进行预约时要进行限制(注释掉app.js的校验代码)
js// 去除进入小程序就要注册的限制 /* let opts = { title: 'bar' } this.globalData.userNotExist = true; // 保证异步操作完成后再设置 globalData return cloudHelper.callCloudData('passport/my_detail', {}, opts) .then(user => { if (!user) { this.globalData.userNotExist = true; return pageHelper.showModal('首次使用小程序必须先注册'); }else{ this.globalData.userNotExist =false; } }) .catch(error => { console.error('Error calling cloud function:', error); }) */ // 如果用户不存在 // 去除进入小程序就要注册的限制 /* if (this.globalData.userNotExist) { wx.switchTab({ url: 'projects/A00/my/index/my_index' }); } */
-
在预约时再进行校验beforejoin(已完成),未注册的跳转到注册界面(或者修改信息界面)
jsif (res.data.result === 1500) { pageHelper.showModal(res.data.msg, '温馨提示', function(res) { wx.reLaunch({ url: pageHelper.fmtURLByPID('/pages/my/edit/my_edit'), }); });
-
每次跳转到修改个人信息界面时,都要弹出隐私协议,引导用户同意,不同意则回到主页面
-
下载隐私界面弹窗组件并引入
html<privacy-popup bind:agree="agree" bind:disagree="disagree"></privacy-popup>
-
同意才允许点击,否则点击按钮报错(否则人家都提交了)
-
不同意则回到主页面(跳转)
-