register.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. import { enroll,smsSend } from '../../api/other';
  2. import { FETCH_AND_FORMAT_USER_INFO } from '../../utils/util.js'
  3. import { uploadImage } from '../../utils/upload.js';
  4. import {BASE_URL} from '../../utils/request';
  5. const app = getApp();
  6. Page({
  7. data: {
  8. formData: {
  9. phone: '',
  10. captcha: '',
  11. nickname: '',
  12. gender: '', // '女' 或 '男'
  13. race_number: '', // 身份证号
  14. // competition_no: '', // 比赛ID
  15. competition_image: '' // 上传的图片路径
  16. },
  17. phoneError: '',
  18. raceNumberError:'',
  19. genders: ['女', '男'],
  20. showPicker: false,
  21. fileList: [],
  22. checked: false,
  23. showRegistrationSuccess: false,
  24. canSubmit: false, // 按钮是否可点击
  25. showAgreementModal:false,
  26. agreementContent:'',
  27. agreementTitle:'',
  28. codeText: '获取验证码',
  29. codeDisabled: false,
  30. timer: null,
  31. countdown: 60,
  32. couponInfo:{},
  33. filePath: '', // 上传成功的文件路径
  34. fileType: '', // image / pdf
  35. baseUrl:BASE_URL
  36. },
  37. onShowPicker() {
  38. this.setData({ showPicker: true });
  39. },
  40. onCancel() {
  41. this.setData({ showPicker: false });
  42. },
  43. // 性别确定
  44. onConfirm(event) {
  45. const { value } = event.detail;
  46. this.setData({
  47. formData: {
  48. ...this.data.formData,
  49. gender: value
  50. },
  51. showPicker: false
  52. }, () => this.checkFormValid());
  53. },
  54. // 点击上传区域
  55. chooseFile() {
  56. wx.showActionSheet({
  57. itemList: ['图片', 'PDF'],
  58. success: res => {
  59. if (res.tapIndex === 0) {
  60. this.chooseImage();
  61. } else {
  62. this.choosePdf();
  63. }
  64. }
  65. });
  66. },
  67. // 选择图片
  68. chooseImage() {
  69. wx.chooseImage({
  70. count: 1,
  71. sizeType: ['original', 'compressed'],
  72. sourceType: ['album', 'camera'],
  73. success: res => {
  74. const path = res.tempFilePaths[0];
  75. this.uploadFile(path, 'image');
  76. }
  77. });
  78. },
  79. // 选择 PDF
  80. choosePdf() {
  81. wx.chooseMessageFile({
  82. count: 1,
  83. type: 'file',
  84. success: res => {
  85. const file = res.tempFiles[0];
  86. if (file.name.endsWith('.pdf')) {
  87. this.uploadFile(file.path, 'pdf');
  88. } else {
  89. wx.showToast({ title: '请选择 PDF 文件', icon: 'none' });
  90. }
  91. }
  92. });
  93. },
  94. // 上传文件
  95. async uploadFile(path, type) {
  96. if (!path) {
  97. wx.showToast({ title: '文件路径错误', icon: 'none' });
  98. return;
  99. }
  100. try {
  101. const res = await uploadImage(path);
  102. console.log('上传成功:', res);
  103. this.setData({
  104. filePath: res.url,
  105. fileType: type,
  106. "formData.competition_image": res.path
  107. });
  108. } catch (err) {
  109. console.error('上传失败:', err);
  110. }
  111. },
  112. // 删除文件
  113. removeFile() {
  114. this.setData({
  115. filePath: '',
  116. fileType: '',
  117. "formData.competition_image": ''
  118. });
  119. },
  120. // 输入框数据绑定
  121. onInput(e) {
  122. console.log(e)
  123. const field = e.currentTarget.dataset.field;
  124. const value = e.detail;
  125. console.log(value)
  126. // 手机号单独做校验
  127. if (field === 'phone') {
  128. const regPhone = /^1[3-9]\d{9}$/;
  129. if (value && !regPhone.test(value)) {
  130. this.setData({ phoneError: '手机号格式不正确' });
  131. }else{
  132. this.setData({ phoneError: '' });
  133. }
  134. }
  135. if (field === 'race_number') {
  136. const regIdCard = /^\d{18}$/;
  137. if (value && !regIdCard.test(value)) {
  138. this.setData({ raceNumberError: '身份证号格式不正确' });
  139. }else{
  140. this.setData({ raceNumberError: '' });
  141. }
  142. }
  143. this.setData({
  144. formData: { ...this.data.formData, [field]: value }
  145. }, () => this.checkFormValid());
  146. },
  147. // 勾选协议
  148. onCheckbox(event) {
  149. this.setData({ checked: event.detail }, () => this.checkFormValid());
  150. },
  151. // 校验表单是否可提交
  152. checkFormValid() {
  153. const { phone, captcha, nickname, gender, race_number } = this.data.formData;
  154. const valid = phone && captcha && nickname && gender && race_number && this.data.checked;
  155. this.setData({ canSubmit: valid });
  156. },
  157. // 获取验证码
  158. async getCode() {
  159. if(this.data.codeDisabled) return;
  160. const phone = this.data.formData.phone;
  161. if (!phone) {
  162. wx.showToast({
  163. title: '请输入手机号',
  164. icon: 'none'
  165. });
  166. return;
  167. }
  168. if (!/^1[3-9]\d{9}$/.test(phone)) {
  169. wx.showToast({
  170. title: '手机号格式不正确',
  171. icon: 'none'
  172. });
  173. return;
  174. }
  175. // 禁用按钮
  176. this.setData({ codeDisabled: true });
  177. const res = await smsSend({phone:this.data.formData.phone});
  178. if (res.code == 200) {
  179. wx.showToast({ title: '验证码已发送', icon: 'none' });
  180. this.startCountdown();
  181. } else {
  182. wx.showToast({ title: res.message || '发送失败', icon: 'none' });
  183. this.setData({ codeDisabled: false });
  184. }
  185. },
  186. // 提交报名
  187. async onSubmit() {
  188. if (!this.data.canSubmit) return;
  189. const payload = {
  190. ...this.data.formData,
  191. gender: this.data.formData.gender === '女' ? 0 : 1
  192. };
  193. const res = await enroll(payload);
  194. if (res.code === 200) {
  195. // 优惠券信息
  196. this.setData({
  197. couponInfo:res.data[0]
  198. })
  199. this.setData({ showRegistrationSuccess: true });
  200. app.globalData.userInfo = await FETCH_AND_FORMAT_USER_INFO();
  201. } else {
  202. wx.showToast({ title: res.message || '报名失败', icon: 'none', duration: 2000 });
  203. }
  204. },
  205. // 点击协议文字显示弹窗
  206. showAgreement(e) {
  207. const type = e.currentTarget.dataset.type;
  208. const dataInfo = app.globalData.programConfig;
  209. this.setData({
  210. showAgreementModal: true,
  211. agreementContent: type == 'rules'?dataInfo.rules : type == 'liability'?dataInfo.disclaimer : dataInfo.privacy_policy,
  212. agreementTitle:type == 'rules'?'活动规则': type == 'liability'?'免责协议' : '隐私政策'
  213. });
  214. },
  215. closeAgreementModal() {
  216. this.setData({ showAgreementModal: false });
  217. },
  218. onReceive() {
  219. this.setData({ showRegistrationSuccess: false });
  220. wx.navigateBack({ delta: 1 });
  221. },
  222. //预览图片
  223. previewImage(e){
  224. const current = e.currentTarget.dataset.src;
  225. wx.previewImage({
  226. current,
  227. urls: [current]
  228. });
  229. },
  230. startCountdown() {
  231. let countdown = this.data.countdown;
  232. this.setData({ codeText: `${countdown}s` });
  233. if (this.data.timer) clearInterval(this.data.timer);
  234. this.data.timer = setInterval(() => {
  235. countdown -= 1;
  236. if (countdown <= 0) {
  237. clearInterval(this.data.timer);
  238. this.setData({ codeText: '获取验证码', codeDisabled: false, countdown: 60 });
  239. } else {
  240. this.setData({ codeText: `${countdown}s`, countdown });
  241. }
  242. }, 1000);
  243. },
  244. onUnload() {
  245. if (this.data.timer) clearInterval(this.data.timer);
  246. }
  247. });