register.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. import { enroll,smsSend } from '../../api/other';
  2. const app = getApp();
  3. Page({
  4. data: {
  5. formData: {
  6. phone: '',
  7. captcha: '',
  8. nickname: '',
  9. gender: '', // '女' 或 '男'
  10. race_number: '', // 身份证号
  11. // competition_no: '', // 比赛ID
  12. competition_image: '' // 上传的图片路径
  13. },
  14. phoneError: '',
  15. genders: ['女', '男'],
  16. showPicker: false,
  17. pickerValue: '',
  18. fileList: [],
  19. checked: false,
  20. showRegistrationSuccess: false,
  21. canSubmit: false, // 按钮是否可点击
  22. showAgreementModal:false,
  23. agreementContent:'',
  24. agreementTitle:'',
  25. codeText: '获取验证码',
  26. codeDisabled: false,
  27. timer: null,
  28. countdown: 60
  29. },
  30. onShowPicker() {
  31. this.setData({ showPicker: true });
  32. },
  33. onCancel() {
  34. this.setData({ showPicker: false });
  35. },
  36. onPickerChange(event) {
  37. const { value } = event.detail;
  38. this.setData({ pickerValue: value });
  39. },
  40. // 性别确定
  41. onConfirm() {
  42. this.setData({
  43. formData: {
  44. ...this.data.formData,
  45. gender: this.data.pickerValue
  46. },
  47. showPicker: false
  48. }, () => this.checkFormValid());
  49. },
  50. // 上传文件
  51. afterRead(event) {
  52. const { file } = event.detail;
  53. wx.uploadFile({
  54. url: 'https://example.weixin.qq.com/upload', // 替换成真实接口
  55. filePath: file.url,
  56. name: 'file',
  57. formData: { user: 'test' },
  58. success: (res) => {
  59. const { fileList } = this.data;
  60. const path = res.data; // 假设返回路径
  61. fileList.push({ ...file, url: path });
  62. this.setData({
  63. fileList,
  64. formData: { ...this.data.formData, competition_image: path }
  65. });
  66. }
  67. });
  68. },
  69. // 输入框数据绑定
  70. onInput(e) {
  71. const field = e.currentTarget.dataset.field;
  72. const value = e.detail;
  73. // 手机号单独做校验
  74. if (field === 'phone') {
  75. const regPhone = /^1[3-9]\d{9}$/;
  76. if (value && !regPhone.test(value)) {
  77. this.setData({ phoneError: '手机号格式不正确' });
  78. }else{
  79. this.setData({ phoneError: '' });
  80. }
  81. }
  82. this.setData({
  83. formData: { ...this.data.formData, [field]: value }
  84. }, () => this.checkFormValid());
  85. },
  86. // 勾选协议
  87. onCheckbox(event) {
  88. this.setData({ checked: event.detail }, () => this.checkFormValid());
  89. },
  90. // 校验表单是否可提交
  91. checkFormValid() {
  92. const { phone, captcha, nickname, gender, race_number } = this.data.formData;
  93. const valid = phone && captcha && nickname && gender && race_number && this.data.checked;
  94. this.setData({ canSubmit: valid });
  95. },
  96. // 获取验证码
  97. async getCode() {
  98. if(this.data.codeDisabled) return;
  99. const phone = this.data.formData.phone;
  100. if (!phone) {
  101. wx.showToast({
  102. title: '请输入手机号',
  103. icon: 'none'
  104. });
  105. return;
  106. }
  107. if (!/^1[3-9]\d{9}$/.test(phone)) {
  108. wx.showToast({
  109. title: '手机号格式不正确',
  110. icon: 'none'
  111. });
  112. return;
  113. }
  114. // 禁用按钮
  115. this.setData({ codeDisabled: true });
  116. // 发送验证码请求给后台
  117. const res = await smsSend({phone:this.data.formData.phone});
  118. if (res.code == 200) {
  119. wx.showToast({ title: '验证码已发送', icon: 'none' });
  120. this.startCountdown();
  121. } else {
  122. wx.showToast({ title: res.message || '发送失败', icon: 'none' });
  123. this.setData({ codeDisabled: false });
  124. }
  125. },
  126. // 提交报名
  127. async onSubmit() {
  128. if (!this.data.canSubmit) return;
  129. const payload = {
  130. ...this.data.formData,
  131. gender: this.data.formData.gender === '女' ? 0 : 1
  132. };
  133. const res = await enroll(payload);
  134. if (res.code === 200) {
  135. wx.showToast({ title: res.data, icon: 'none', duration: 2000 });
  136. this.setData({ showRegistrationSuccess: true });
  137. } else {
  138. wx.showToast({ title: res.message || '报名失败', icon: 'none', duration: 2000 });
  139. }
  140. },
  141. // 点击协议文字显示弹窗
  142. showAgreement(e) {
  143. const type = e.currentTarget.dataset.type;
  144. const dataInfo = app.globalData.programConfig.marathon_event;
  145. this.setData({
  146. showAgreementModal: true,
  147. agreementContent: type == 'rules'?dataInfo.rules : type == 'liability'?dataInfo.disclaimer : dataInfo.privacy_policy,
  148. agreementTitle:type == 'rules'?'活动规则': type == 'liability'?'免责协议' : '隐私政策'
  149. });
  150. },
  151. closeAgreementModal() {
  152. this.setData({ showAgreementModal: false });
  153. },
  154. onReceive() {
  155. this.setData({ showRegistrationSuccess: false });
  156. wx.navigateBack({ delta: 1 });
  157. },
  158. startCountdown() {
  159. let countdown = this.data.countdown;
  160. this.setData({ codeText: `${countdown}s` });
  161. if (this.data.timer) clearInterval(this.data.timer);
  162. this.data.timer = setInterval(() => {
  163. countdown -= 1;
  164. if (countdown <= 0) {
  165. clearInterval(this.data.timer);
  166. this.setData({ codeText: '获取验证码', codeDisabled: false, countdown: 60 });
  167. } else {
  168. this.setData({ codeText: `${countdown}s`, countdown });
  169. }
  170. }, 1000);
  171. },
  172. onUnload() {
  173. if (this.data.timer) clearInterval(this.data.timer);
  174. }
  175. });