与牧同行-小程序用户端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

316 lines
6.3 KiB

  1. // pages/real-name-auth/real-name-auth.js
  2. Page({
  3. data: {
  4. // 表单数据
  5. name: '',
  6. phone: '',
  7. smsCode: '',
  8. // 焦点状态
  9. nameFocus: false,
  10. phoneFocus: false,
  11. codeFocus: false,
  12. // 错误提示
  13. nameError: '',
  14. phoneError: '',
  15. smsCodeError: '',
  16. // 验证码相关
  17. canSendCode: false,
  18. countdown: 0,
  19. countdownTimer: null,
  20. // 协议状态
  21. agreed: false,
  22. // 提交状态
  23. canSubmit: false,
  24. isSubmitting: false,
  25. // 弹窗
  26. showSuccessModal: false
  27. },
  28. onLoad() {
  29. this.checkForm();
  30. },
  31. onUnload() {
  32. // 清除定时器
  33. if (this.data.countdownTimer) {
  34. clearInterval(this.data.countdownTimer);
  35. }
  36. },
  37. // 姓名输入处理
  38. onNameInput(e) {
  39. const name = e.detail.value.trim();
  40. let nameError = '';
  41. if (name && !/^[\u4e00-\u9fa5]{2,10}$/.test(name)) {
  42. nameError = '姓名应为2-10个汉字';
  43. }
  44. this.setData({
  45. name: name,
  46. nameError: nameError
  47. }, () => {
  48. this.checkForm();
  49. this.checkCanSendCode();
  50. });
  51. },
  52. onNameFocus() {
  53. this.setData({ nameFocus: true });
  54. },
  55. onNameBlur() {
  56. this.setData({ nameFocus: false });
  57. },
  58. // 手机号输入处理
  59. onPhoneInput(e) {
  60. const phone = e.detail.value.trim();
  61. let phoneError = '';
  62. if (phone && !/^1[3-9]\d{9}$/.test(phone)) {
  63. phoneError = '请输入正确的手机号码';
  64. }
  65. this.setData({
  66. phone: phone,
  67. phoneError: phoneError
  68. }, () => {
  69. this.checkForm();
  70. this.checkCanSendCode();
  71. });
  72. },
  73. onPhoneFocus() {
  74. this.setData({ phoneFocus: true });
  75. },
  76. onPhoneBlur() {
  77. this.setData({ phoneFocus: false });
  78. },
  79. // 验证码输入处理
  80. onSmsCodeInput(e) {
  81. const smsCode = e.detail.value.trim();
  82. let smsCodeError = '';
  83. if (smsCode && !/^\d{6}$/.test(smsCode)) {
  84. smsCodeError = '请输入6位数字验证码';
  85. }
  86. this.setData({
  87. smsCode: smsCode,
  88. smsCodeError: smsCodeError
  89. }, () => {
  90. this.checkForm();
  91. });
  92. },
  93. onCodeFocus() {
  94. this.setData({ codeFocus: true });
  95. },
  96. onCodeBlur() {
  97. this.setData({ codeFocus: false });
  98. },
  99. // 检查是否可以发送验证码
  100. checkCanSendCode() {
  101. const { name, phone, nameError, phoneError } = this.data;
  102. const canSendCode = name && phone && !nameError && !phoneError;
  103. this.setData({ canSendCode });
  104. },
  105. // 发送验证码
  106. async sendSmsCode() {
  107. const { name, phone, countdown } = this.data;
  108. if (countdown > 0) return;
  109. // 验证手机号格式
  110. if (!/^1[3-9]\d{9}$/.test(phone)) {
  111. this.setData({ phoneError: '请输入正确的手机号码' });
  112. return;
  113. }
  114. // 显示加载
  115. wx.showLoading({
  116. title: '发送中...',
  117. mask: true
  118. });
  119. try {
  120. // 模拟发送验证码请求
  121. await new Promise(resolve => setTimeout(resolve, 1500));
  122. wx.hideLoading();
  123. // 发送成功
  124. wx.showToast({
  125. title: '验证码已发送',
  126. icon: 'success',
  127. duration: 2000
  128. });
  129. // 开始倒计时
  130. this.startCountdown();
  131. } catch (error) {
  132. wx.hideLoading();
  133. wx.showToast({
  134. title: '发送失败,请重试',
  135. icon: 'error',
  136. duration: 2000
  137. });
  138. }
  139. },
  140. // 开始倒计时
  141. startCountdown() {
  142. this.setData({ countdown: 60 });
  143. const timer = setInterval(() => {
  144. let { countdown } = this.data;
  145. countdown--;
  146. if (countdown <= 0) {
  147. clearInterval(timer);
  148. this.setData({
  149. countdown: 0,
  150. countdownTimer: null
  151. });
  152. } else {
  153. this.setData({
  154. countdown: countdown,
  155. countdownTimer: timer
  156. });
  157. }
  158. }, 1000);
  159. },
  160. // 协议处理
  161. toggleAgreement() {
  162. this.setData({
  163. agreed: !this.data.agreed
  164. }, () => {
  165. this.checkForm();
  166. });
  167. },
  168. viewAgreement() {
  169. wx.navigateTo({
  170. url: '/pages/web-view/web-view?url=' + encodeURIComponent('https://your-domain.com/agreement')
  171. });
  172. },
  173. viewPrivacy() {
  174. wx.navigateTo({
  175. url: '/pages/web-view/web-view?url=' + encodeURIComponent('https://your-domain.com/privacy')
  176. });
  177. },
  178. // 检查表单
  179. checkForm() {
  180. const {
  181. name,
  182. phone,
  183. smsCode,
  184. nameError,
  185. phoneError,
  186. smsCodeError,
  187. agreed
  188. } = this.data;
  189. const isValid = name &&
  190. phone &&
  191. smsCode &&
  192. !nameError &&
  193. !phoneError &&
  194. !smsCodeError &&
  195. agreed;
  196. this.setData({
  197. canSubmit: isValid
  198. });
  199. },
  200. // 提交认证
  201. async submitAuth() {
  202. if (!this.data.canSubmit || this.data.isSubmitting) return;
  203. this.setData({ isSubmitting: true });
  204. // 验证数据
  205. const { name, phone, smsCode } = this.data;
  206. // 最终验证
  207. if (!/^[\u4e00-\u9fa5]{2,10}$/.test(name)) {
  208. this.setData({
  209. nameError: '姓名应为2-10个汉字',
  210. isSubmitting: false
  211. });
  212. return;
  213. }
  214. if (!/^1[3-9]\d{9}$/.test(phone)) {
  215. this.setData({
  216. phoneError: '请输入正确的手机号码',
  217. isSubmitting: false
  218. });
  219. return;
  220. }
  221. if (!/^\d{6}$/.test(smsCode)) {
  222. this.setData({
  223. smsCodeError: '请输入6位数字验证码',
  224. isSubmitting: false
  225. });
  226. return;
  227. }
  228. try {
  229. // 模拟API请求
  230. await new Promise(resolve => setTimeout(resolve, 2000));
  231. // 提交成功
  232. this.setData({
  233. isSubmitting: false,
  234. showSuccessModal: true
  235. });
  236. // 保存认证信息到本地
  237. wx.setStorageSync('realNameAuth', {
  238. name: name,
  239. phone: phone,
  240. certified: true,
  241. certifiedTime: new Date().getTime()
  242. });
  243. } catch (error) {
  244. this.setData({ isSubmitting: false });
  245. wx.showToast({
  246. title: '认证失败,请重试',
  247. icon: 'error',
  248. duration: 2000
  249. });
  250. }
  251. },
  252. // 成功弹窗处理
  253. closeSuccessModal() {
  254. this.setData({ showSuccessModal: false });
  255. },
  256. // 前往首页
  257. goToHome() {
  258. this.closeSuccessModal();
  259. wx.switchTab({
  260. url: '/pages/index/index'
  261. });
  262. }
  263. });