diff --git a/src/pages/salon/index.tsx b/src/pages/salon/index.tsx index 6e9f161..1ed4430 100644 --- a/src/pages/salon/index.tsx +++ b/src/pages/salon/index.tsx @@ -1,68 +1,56 @@ -// @ts-nocheck -import { Component } from "react"; -import { View, Text, Image, Button, Picker } from "@tarojs/components"; +import { View, Text, Image, Picker } from "@tarojs/components"; import "./index.scss"; import { AtButton, AtInput, - AtTabBar, AtForm, AtMessage, AtList, AtListItem, - AtTag, AtTextarea, } from "taro-ui"; -import React, { useCallback, useEffect, useState } from "react"; -import { AtGrid } from "taro-ui"; -import { Swiper, SwiperItem } from "@tarojs/components"; -import { AtCard } from "taro-ui"; +import React, { useEffect, useState } from "react"; import Taro from "@tarojs/taro"; + import loft from "../../images/loft.png"; -import nomadvloglife from "../../images/nomadvloglife.png"; - -import { - AtModal, - AtModalHeader, - AtModalContent, - AtModalAction, - AtAvatar, - AtAccordion, -} from "taro-ui"; - import qrcode from "../../images/qrcode.png"; import joinGroup from "../../images/joinGroup.png"; -const PB_URL = 'https://pocketbase.hackrobot.cn'; -const COLLECTION = 'solan'; // 你建立的表名 -const PAY_API_URL = 'https://api.hackrobot.cn/payh5'; // 你的支付接口地址(根据实际调整) +const PB_URL = "https://pocketbase.hackrobot.cn"; +const COLLECTION = "solan"; +const PAY_API_URL = "https://api.hackrobot.cn/payh5"; +const SUBMIT_APPLICATION_URL = + "https://api.hackrobot.cn/submit_meetup_application"; const Salon = () => { const [meetupQR, setmeetupQR] = useState(false); const [isWeChat, setisWeChat] = useState(false); useEffect(() => { - isWeChatFun(); - checkIfJoined(); - checkPendingAndPaid(); + const init = async () => { + isWeChatFun(); + checkIfJoined(); + + const userId = getOrCreateUserId(); + const fullyPaid = await checkIfFullyPaid(userId); + + if (fullyPaid) { + Taro.setStorageSync("salonJoined", true); + setmeetupQR(true); + } + }; + init(); }, []); - // 检查是否已加入(本地标记) const checkIfJoined = () => { - if (Taro.getStorageSync('salonJoined')) { + if (Taro.getStorageSync("salonJoined")) { setmeetupQR(true); } }; - const handleClick = (value) => { - Taro.navigateTo({ - url: "/pages/index/index", - }); - }; - const isWeChatFun = () => { - var ua = navigator.userAgent.toLowerCase(); - if (ua.indexOf("micromessenger") != -1) { + const ua = navigator.userAgent.toLowerCase(); + if (ua.indexOf("micromessenger") !== -1) { setisWeChat(true); return true; } else { @@ -71,25 +59,22 @@ const Salon = () => { } }; - // 生成或获取 userId(无下划线,干净格式) const getOrCreateUserId = () => { - let userId = Taro.getStorageSync('userId'); + let userId = Taro.getStorageSync("userId"); if (!userId) { userId = `user${Date.now()}`; - Taro.setStorageSync('userId', userId); + Taro.setStorageSync("userId", userId); } return userId; }; - // 检查是否已支付(查询 payments 表) - const checkIfPaid = async (userId) => { + const checkIfFullyPaid = (userId) => { return new Promise((resolve) => { Taro.request({ - url: `${PB_URL}/api/collections/payments/records`, - method: 'GET', + url: `${PB_URL}/api/collections/${COLLECTION}/records`, + method: "GET", data: { - filter: `(user_id="${userId}" && type="meetup")`, - sort: '-created', + filter: `(user_id="${userId}" && amount > 0 && type="meetup")`, perPage: 1, }, success: (res) => { @@ -100,210 +85,158 @@ const Salon = () => { }); }; - // 支付函数(XorPay H5) - const payh5 = (type, total_fee = 9900) => { // 99元 + const payh5 = (type, total_fee = 8800) => { const userId = getOrCreateUserId(); Taro.request({ url: PAY_API_URL, - method: 'POST', + method: "POST", data: { total_fee, type, user_id: userId, - // return_url: window.location.href, // 如果后端支持,取消注释并在后端加上, 支付成功自动返回 }, header: { - 'content-type': 'application/json', + "content-type": "application/json", }, success: (res) => { - if (res.data?.status === 'ok' && res.data?.xorpay_params) { + if (res.data?.status === "ok" && res.data?.xorpay_params) { const params = res.data.xorpay_params; - const form = document.createElement('form'); - form.method = 'POST'; + const form = document.createElement("form"); + form.method = "POST"; form.action = res.data.xorpay_url; - form.style.display = 'none'; + form.style.display = "none"; for (const key in params) { - const input = document.createElement('input'); - input.type = 'hidden'; + const input = document.createElement("input"); + input.type = "hidden"; input.name = key; input.value = params[key]; form.appendChild(input); } - // 如果你希望支付成功自动返回,取消注释以下(需后端支持 return_url) - // const returnInput = document.createElement('input'); - // returnInput.type = 'hidden'; - // returnInput.name = 'return_url'; - // returnInput.value = window.location.href; - // form.appendChild(returnInput); - document.body.appendChild(form); form.submit(); } else { - Taro.showToast({ title: '支付发起失败', icon: 'none' }); + Taro.showToast({ title: "支付发起失败", icon: "none" }); } }, fail: () => { - Taro.showToast({ title: '网络错误', icon: 'none' }); + Taro.showToast({ title: "网络错误", icon: "none" }); }, }); }; - // 表单状态统一管理 const [form, setForm] = useState({ - nickname: '', - occupation: '', - reason: '', - wechatId: '', - gender: '', - education: '', - gradYear: '', - phone: '', + nickname: "", + occupation: "", + reason: "", + wechatId: "", + gender: "", + education: "", + gradYear: "", + phone: "", }); - // 性别下拉选项(保持原样,实现隐形限制) - const genderOptions = ['男', '女']; + const genderOptions = ["男", "女"]; const [genderIndex, setGenderIndex] = useState(null); - // 学历下拉选项(保持原样) - const educationOptions = ['高中及以下', '大专', '本科', '硕士']; + const educationOptions = ["高中及以下", "大专", "本科", "硕士"]; const [educationIndex, setEducationIndex] = useState(null); - // 毕业年份下拉选项 const currentYear = new Date().getFullYear(); const yearOptions = []; for (let i = 0; i <= 60; i++) { yearOptions.push((currentYear - i).toString()); } - const [gradYearIndex, setGradYearIndex] = useState(0); + const [gradYearIndex, setGradYearIndex] = useState(null); - // 通用字段更新函数 const updateField = (field) => (value) => { setForm((prev) => ({ ...prev, [field]: value })); }; - // 性别选择变更(保持原逻辑,实现隐形性别限制) const handleGenderChange = (e) => { const idx = e.detail.value; setGenderIndex(idx); - updateField('gender')(idx === 0 ? '' : genderOptions[idx]); + updateField("gender")(genderOptions[idx]); }; - // 学历选择变更 const handleEducationChange = (e) => { const idx = e.detail.value; setEducationIndex(idx); - updateField('education')(idx === 0 ? '' : educationOptions[idx]); + updateField("education")(educationOptions[idx]); }; - // 毕业年份选择变更 const handleGradYearChange = (e) => { - const idx = e.detail.value; setGradYearIndex(idx); - updateField('gradYear')(idx === 0 ? '' : yearOptions[idx]); + updateField("gradYear")(yearOptions[idx]); }; - // 提交申请到 PocketBase - const submitApplication = (submitData) => { - const uploadUrl = `${PB_URL}/api/collections/${COLLECTION}/records`; - - Taro.request({ - url: uploadUrl, - method: 'POST', - header: { 'Content-Type': 'application/json' }, - data: { - nickname: submitData.nickname, - occupation: submitData.occupation, - reason: submitData.reason, - wechatId: submitData.wechatId, - gender: submitData.gender, - education: submitData.education, - gradYear: submitData.gradYear, - phone: submitData.phone, - calculated_age: submitData.calculatedAge, - user_id: submitData.userId || getOrCreateUserId(), - }, - success: (res) => { - if (res.statusCode === 200 || res.statusCode === 201) { - Taro.showToast({ title: '申请提交成功,欢迎加入!', icon: 'success' }); - Taro.setStorageSync('salonJoined', true); - setmeetupQR(true); - localStorage.removeItem('pendingSalonApplication'); - } else { - Taro.showToast({ title: '提交失败', icon: 'none' }); - } - }, - fail: () => { - Taro.showToast({ title: '提交失败,请检查网络', icon: 'none' }); - }, + const submitApplicationFirst = (submitData) => { + return new Promise((resolve, reject) => { + Taro.request({ + url: SUBMIT_APPLICATION_URL, + method: "POST", + header: { "Content-Type": "application/json" }, + data: submitData, + success: (res) => { + if (res.statusCode === 200 && res.data?.status === "ok") { + resolve(true); + } else { + Taro.showToast({ title: "申请提交失败", icon: "none" }); + reject(); + } + }, + fail: () => { + Taro.showToast({ title: "网络错误,请重试", icon: "none" }); + reject(); + }, + }); }); }; - // 检查本地是否有 pending 申请且已支付 → 自动提交 - const checkPendingAndPaid = async () => { - const pending = localStorage.getItem('pendingSalonApplication'); - if (!pending) return; - - const pendingData = JSON.parse(pending); - const userId = getOrCreateUserId(); - - if (pendingData.userId !== userId) return; - - const paid = await checkIfPaid(userId); - if (paid) { - submitApplication({ - ...pendingData.form, - calculatedAge: pendingData.calculatedAge, - userId, - }); - } - }; - const handleSubmit = async () => { - // 原有必填校验(包含性别隐形限制) - if ( - !form.nickname || - !form.occupation || - !form.reason || - !form.wechatId || - !form.gender - ) { + let missing = []; + + if (!form.nickname) missing.push("昵称"); + if (!form.occupation) missing.push("职业/专业"); + if (!form.reason) missing.push("自我介绍"); + if (!form.wechatId) missing.push("微信号"); + if (!form.gender) missing.push("性别"); + if (!form.education) missing.push("学历"); + if (!form.gradYear) missing.push("毕业时间"); + if (!form.phone) missing.push("手机号"); // 手机号必填 + + if (missing.length > 0) { Taro.atMessage({ - message: '请填写所有必填项', - type: 'warning', + message: `请填写:${missing.join("、")}`, + type: "warning", }); return; } - // 隐形校验学历和毕业年份(必须有效) - if ( - !form.education || - !form.gradYear || - form.gradYear === '请选择毕业年份' - ) { + // 手机号正则校验(必填,必须11位有效手机号) + if (!/^1[3-9]\d{9}$/.test(form.phone)) { Taro.atMessage({ - message: '请填写所有必填项', - type: 'warning', + message: "手机号格式错误,请填写11位有效手机号", + type: "warning", }); return; } - // 计算估算年龄 const gradAgeMap = { - '高中及以下': 18, - '大专': 21, - '本科': 22, - '硕士': 25, + 高中及以下: 18, + 大专: 21, + 本科: 22, + 硕士: 25, }; const baseAge = gradAgeMap[form.education] || 22; const gradYearNum = parseInt(form.gradYear, 10); - + if (isNaN(gradYearNum)) { Taro.atMessage({ - message: '请填写所有必填项', - type: 'warning', + message: "毕业年份格式错误", + type: "warning", }); return; } @@ -312,147 +245,257 @@ const Salon = () => { const userId = getOrCreateUserId(); - // 保存 pending 申请(用于支付后自动提交) - localStorage.setItem('pendingSalonApplication', JSON.stringify({ - form, - calculatedAge, - userId, - })); + const submitData = { + ...form, + calculated_age: calculatedAge, + user_id: userId, + }; - // 检查是否已支付 - const paid = await checkIfPaid(userId); - if (paid) { - // 已支付,直接提交 - submitApplication({ ...form, calculatedAge, userId }); - } else { - // 未支付,发起支付(99元,类型 meetup) - payh5('meetup', 9900); - Taro.showToast({ title: '正在跳转支付,请完成支付后返回', icon: 'loading', duration: 3000 }); + try { + await submitApplicationFirst(submitData); + + Taro.showToast({ + title: "申请已提交,正在跳转支付(88元场地管理费)", + icon: "loading", + duration: 3000, + }); + + payh5("meetup", 8800); + } catch { + // 提交失败已提示 } }; - // 如果已加入(支付+提交成功),显示成功页面 if (meetupQR) { return ( - - - - 欢迎加入数字游民社区! + + + + + 🎉 欢迎加入数字游民社区! + - + {isWeChat ? ( - + ) : ( - 请在微信中打开本页面以查看社群二维码 - + + 🔴 请在微信中打开本页面以查看社群二维码 + + )} + + 💡 入群后请遵守社区规则,共同维护良好氛围~ + ); } - // 默认显示表单 return ( - - - + + + + + + 🌍 数字游民社区报名 + +
+ + 💼 结识志同道合的伙伴 +
+ 📍 线下聚会 + 线上分享 +
+ 🤝 互助成长,资源共享 +
+
- + - {/* 性别下拉(保持原样) */} - + - - - 自我介绍 + + + 📝 自我介绍 - {/* 学历下拉 */} - + - {/* 毕业年份下拉 */} - + - - 提交申请 - + + + 提交申请 + + + + 🔍 提交后将进行审核 +
+ 💰 通过审核需支付88元场地管理费 +
+ ❤️ 组织者纯公益,不赚钱,所有费用用于场地和活动 +
+
+
- - - {/* 支付后申请将自动提交,支付成功请返回本页面(或刷新) */} -
); }; -export default Salon; \ No newline at end of file +export default Salon;