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.

1049 lines
22 KiB

4 weeks ago
4 weeks ago
1 month ago
1 month ago
  1. <template>
  2. <view class="login-registration-container">
  3. <!-- 自定义导航栏 -->
  4. <view
  5. class="custom-navbar"
  6. :style="{ paddingTop: safeAreaInsets?.top + 'px' }"
  7. >
  8. <!-- <view class="nav-left">
  9. <text class="back-btn" @click="goToIndex"></text>
  10. </view> -->
  11. <view class="nav-right">
  12. <image
  13. class="icons"
  14. src="../../../static/icons/Headset.png"
  15. alt="联系客服"
  16. />
  17. <image
  18. class="icons"
  19. @click="goToIndex"
  20. src="../../../static/icons/Frame.png"
  21. alt="返回首页"
  22. />
  23. </view>
  24. </view>
  25. <!-- Logo -->
  26. <!-- <image class="logo" src="/static/logo.png" mode="aspectFit"></image> -->
  27. <!-- 欢迎语 -->
  28. <text class="welcome-text">欢迎来到DeepChart</text>
  29. <!-- 邮箱/手机号切换 -->
  30. <view class="switch-container">
  31. <text
  32. class="switch-item"
  33. :class="{ active: switchType === 'Email' }"
  34. @click="switchEmail"
  35. >邮箱</text
  36. >
  37. <text
  38. class="switch-item"
  39. :class="{ active: switchType === 'Phone' }"
  40. @click="switchPhone"
  41. >手机号</text
  42. >
  43. </view>
  44. <!-- 输入框 -->
  45. <view class="input-container">
  46. <view v-if="switchType === 'Email'">
  47. <!-- 修改邮箱输入框容器将图标包含在内 -->
  48. <view class="input-with-icon">
  49. <image
  50. class="input-icon"
  51. src="../../../static/icons/Mail.png"
  52. alt=""
  53. />
  54. <input
  55. class="input-field"
  56. type="text"
  57. placeholder="请输入邮箱"
  58. v-model="email"
  59. />
  60. <view>
  61. <button
  62. class="send-code-btn-email"
  63. :disabled="isCodeBtnDisabled"
  64. :class="{ 'send-code-btn-disabled': isCodeBtnDisabled }"
  65. @click="sendCode"
  66. >
  67. <text
  68. class="send-code-text"
  69. :class="{ 'send-code-btn-disabled-text': isCodeBtnDisabled }"
  70. >{{ codeBtnText }}</text
  71. >
  72. </button>
  73. </view>
  74. </view>
  75. <view class="input-with-icon">
  76. <image
  77. class="input-icon"
  78. src="../../../static/icons/Text-recognition.png"
  79. alt=""
  80. />
  81. <input
  82. class="input-field"
  83. type="text"
  84. placeholder="请输入验证码"
  85. v-model="verifyCode"
  86. />
  87. </view>
  88. </view>
  89. <view v-if="switchType === 'Phone'" class="phone-input-container">
  90. <view class="country-code-selector" @click="showCountryPicker">
  91. <image
  92. class="country-flag-img"
  93. src="../../../static/icons/Iphone.png"
  94. mode="aspectFit"
  95. ></image>
  96. <text class="country-code">{{ selectedCountry.code }}</text>
  97. <!-- <text class="arrow-down"></text> -->
  98. </view>
  99. <input
  100. class="input-field phone-input"
  101. type="number"
  102. placeholder="输入手机号"
  103. v-model="phone"
  104. @input="onPhoneInput"
  105. />
  106. <view>
  107. <button
  108. class="send-code-btn"
  109. :disabled="isCodeBtnDisabled"
  110. :class="{ 'send-code-btn-disabled': isCodeBtnDisabled }"
  111. @click="sendCode"
  112. >
  113. <text
  114. class="send-code-text"
  115. :class="{ 'send-code-btn-disabled-text': isCodeBtnDisabled }"
  116. >{{ codeBtnText }}</text
  117. >
  118. </button>
  119. </view>
  120. </view>
  121. <view v-if="switchType === 'Phone'" class="input-with-icon">
  122. <image
  123. class="input-icon"
  124. src="../../../static/icons/Text-recognition.png"
  125. alt=""
  126. />
  127. <input
  128. class="input-field"
  129. type="text"
  130. placeholder="请输入验证码"
  131. v-model="verifyCode"
  132. />
  133. </view>
  134. </view>
  135. <!-- 用户协议 -->
  136. <view @click="changeCheckbox" class="agreement-container-one">
  137. <image class="checkbox" :src="checkboxUrl"></image>
  138. <text class="agreement-text-one"
  139. >接受 <text class="link" @click="openAgreement">用户协议</text>
  140. <text class="link" @click="openPrivacy">隐私政策</text></text
  141. >
  142. </view>
  143. <!-- 注册按钮 -->
  144. <button class="register-btn" @click="register">
  145. <text v-if="!isLoading">注册</text>
  146. <image
  147. v-else
  148. class="icons-rotation"
  149. src="../../../static/icons/loading.png"
  150. ></image>
  151. </button>
  152. <!-- 或者 -->
  153. <text class="or-text" @click="goToLogin"
  154. >已有账号
  155. <text class="link">登录</text>
  156. </text>
  157. <!-- 同意弹窗 -->
  158. <uniPopup ref="agreementPopup" type="dialog">
  159. <view class="popup-content">
  160. <text class="popup-message"
  161. >请阅读并同意<text @click="openAgreement" class="popup-message-link"
  162. >服务协议</text
  163. ><text @click="openPrivacy" class="popup-message-link"
  164. >隐私权限</text
  165. >
  166. </text>
  167. <view class="button-group">
  168. <button class="cancel-button" @click="handleCancel">
  169. <text class="cancel-text">取消</text>
  170. </button>
  171. <button class="agree-button" @click="handleAgree">
  172. <text class="agree-text">同意</text>
  173. </button>
  174. </view>
  175. </view>
  176. </uniPopup>
  177. <footerBar class="static-footer" :type="type"></footerBar>
  178. </view>
  179. </template>
  180. <script setup>
  181. import { ref } from "vue";
  182. // 导入完整的国家列表
  183. import countryList from "../login/list";
  184. import footerBar from "../../../components/footerBar";
  185. import uniPopup from "../../../uni_modules/uni-popup/components/uni-popup/uni-popup.vue";
  186. import { verificationPhone, verificationEmail } from "../login/verification";
  187. import {
  188. registerApi,
  189. SendEmailCodeApi,
  190. SendPhoneCodeApi,
  191. } from "../../../api/start/login";
  192. const type = ref("member");
  193. const email = ref("");
  194. const password = ref("");
  195. const phone = ref("");
  196. const country = ref("+86");
  197. const agreed = ref(false);
  198. const switchType = ref("Phone"); // 默认是邮箱注册
  199. const { safeAreaInsets } = uni.getSystemInfoSync();
  200. const codeBtnText = ref("获取验证码");
  201. const isCodeBtnDisabled = ref(false); // 添加验证码按钮禁用状态
  202. const checkboxUrl = ref("../../../static/icons/Check-one-false.png");
  203. const verifyCode = ref("");
  204. const account = ref("");
  205. const isLoading = ref(false);
  206. // 使用从list.js导入的完整国家列表数据
  207. const countries = ref(
  208. countryList.list.map((item) => ({
  209. name: item.name,
  210. code: `+${item.tel}`,
  211. flag: item.flag,
  212. short: item.short,
  213. en: item.en,
  214. }))
  215. );
  216. // 默认选中的国家(中国)
  217. const selectedCountry = ref(
  218. countries.value.find((country) => country.short === "CN") ||
  219. countries.value[0]
  220. );
  221. // 显示国家选择器
  222. function showCountryPicker() {
  223. uni.showActionSheet({
  224. itemList: countries.value.map(
  225. (country) => `${country.name} ${country.code}`
  226. ),
  227. success: function (res) {
  228. selectedCountry.value = countries.value[res.tapIndex];
  229. },
  230. });
  231. }
  232. function goToIndex() {
  233. // 返回上一页
  234. uni.navigateTo({
  235. url: "/pages/start/index/index",
  236. });
  237. }
  238. function switchEmail() {
  239. // 切换到邮箱注册
  240. switchType.value = "Email";
  241. verifyCode.value = "";
  242. }
  243. function switchPhone() {
  244. // 切换到手机注册
  245. switchType.value = "Phone";
  246. verifyCode.value = "";
  247. }
  248. // 注册
  249. async function register() {
  250. if (!basicVerification()) {
  251. return;
  252. }
  253. const account = changeAccount();
  254. const registerType = changeLoginType();
  255. isLoading.value = true;
  256. const res = await registerApi({
  257. registerType: registerType,
  258. account: account,
  259. verifyCode: verifyCode.value,
  260. agree: agreed.value,
  261. });
  262. isLoading.value = false;
  263. const message = res.message;
  264. if (res.code === 200) {
  265. // 登录成功
  266. uni.showToast({
  267. title: "注册成功",
  268. icon: "success",
  269. });
  270. const userStore = useUserStore();
  271. userStore.setUserInfo(res.data);
  272. console.log("userInfo为", userStore.userInfo);
  273. // 跳转到首页
  274. uni.redirectTo({
  275. url: "/pages/home/home",
  276. });
  277. } else {
  278. // 登录失败
  279. uni.showToast({
  280. title: message,
  281. icon: "none",
  282. });
  283. }
  284. }
  285. // 请求账户
  286. function changeAccount() {
  287. if (switchType.value === "User") {
  288. account.value = deepChartID.value;
  289. }
  290. if (switchType.value === "Phone") {
  291. account.value = `${country.value}${phone.value}`;
  292. }
  293. if (switchType.value === "Email") {
  294. account.value = email.value;
  295. }
  296. return account.value;
  297. }
  298. // 改变请求时的type
  299. function changeLoginType() {
  300. if (switchType.value === "User") {
  301. return "DCCODE";
  302. }
  303. if (switchType.value === "Phone") {
  304. return "PHONE";
  305. }
  306. if (switchType.value === "Email") {
  307. return "EMAIL";
  308. }
  309. }
  310. // 基础验证
  311. function basicVerification() {
  312. if (switchType.value === "User") {
  313. if (!deepChartID.value) {
  314. uni.showToast({
  315. title: "请输入用户名",
  316. icon: "none",
  317. });
  318. return false;
  319. }
  320. if (!password.value) {
  321. uni.showToast({
  322. title: "请输入密码",
  323. icon: "none",
  324. });
  325. return false;
  326. }
  327. }
  328. if (switchType.value === "Phone") {
  329. // 登录逻辑
  330. if (!phone.value) {
  331. uni.showToast({
  332. title: "请输入手机号码",
  333. icon: "none",
  334. });
  335. return false;
  336. }
  337. const phoneAll = `${country.value}${phone.value}`;
  338. console.log("完整手机号" + phoneAll);
  339. if (!validatePhoneNumber(country.value, phone.value)) {
  340. return false;
  341. }
  342. if (!verifyCode.value) {
  343. uni.showToast({
  344. title: "请输入验证码",
  345. icon: "none",
  346. });
  347. return false;
  348. }
  349. }
  350. if (switchType.value === "Email") {
  351. // 登录逻辑
  352. if (!email.value) {
  353. uni.showToast({
  354. title: "请输入邮箱地址",
  355. icon: "none",
  356. });
  357. return false;
  358. }
  359. const bool = verificationEmail(email.value);
  360. console.log("验证是否成功", bool);
  361. // 检查格式是否正确
  362. if (!bool) {
  363. uni.showToast({
  364. title: "邮箱格式不正确",
  365. icon: "none",
  366. });
  367. return false;
  368. }
  369. if (!verifyCode.value) {
  370. uni.showToast({
  371. title: "请输入验证码",
  372. icon: "none",
  373. });
  374. return false;
  375. }
  376. }
  377. if (!agreed.value) {
  378. // 显示同意弹窗
  379. agreementPopup.value.open();
  380. return;
  381. }
  382. return true;
  383. }
  384. // 验证码验证
  385. function VerCodeVerfifcation() {
  386. if (switchType.value === "Phone") {
  387. if (!phone.value) {
  388. uni.showToast({
  389. title: "请输入手机号",
  390. icon: "none",
  391. });
  392. return false;
  393. }
  394. const bool = verificationPhone(country.value, phone.value);
  395. console.log("验证是否成功", bool);
  396. // 检查格式是否正确
  397. if (!bool) {
  398. uni.showToast({
  399. title: "手机号格式不正确",
  400. icon: "none",
  401. });
  402. return false;
  403. }
  404. }
  405. if (switchType.value === "Email") {
  406. if (!email.value) {
  407. uni.showToast({
  408. title: "请输入邮箱地址",
  409. icon: "none",
  410. });
  411. return false;
  412. }
  413. const bool = verificationEmail(email.value);
  414. console.log("验证是否成功", bool);
  415. // 检查格式是否正确
  416. if (!bool) {
  417. uni.showToast({
  418. title: "邮箱格式不正确",
  419. icon: "none",
  420. });
  421. return false;
  422. }
  423. }
  424. return true;
  425. }
  426. function goToLogin() {
  427. // 跳转到登录页
  428. uni.navigateTo({
  429. url: "/pages/start/login/login",
  430. });
  431. }
  432. function onPhoneInput(e) {
  433. // 确保只允许输入数字
  434. const value = e.detail.value;
  435. // 使用 isNaN 检查是否为有效数字
  436. if (isNaN(value)) {
  437. phone.value = "";
  438. } else {
  439. phone.value = value;
  440. }
  441. }
  442. async function sendCode() {
  443. if (!VerCodeVerfifcation()) {
  444. return;
  445. }
  446. // 如果按钮已禁用,则不执行后续逻辑
  447. if (isCodeBtnDisabled.value) return;
  448. console.log("发送验证码");
  449. if (switchType.value === "Phone") {
  450. // 发送验证码
  451. const phoneAll = `${country.value}${phone.value}`;
  452. const res = await SendPhoneCodeApi({
  453. phone: phoneAll,
  454. });
  455. console.log("手机验证码:", res.message);
  456. if (!res) {
  457. uni.showToast({
  458. title: "请求失败",
  459. icon: "none",
  460. });
  461. }
  462. }
  463. if (switchType.value === "Email") {
  464. // 发送验证码
  465. const res = await SendEmailCodeApi({
  466. email: email.value,
  467. });
  468. console.log("邮箱验证码:", res.message);
  469. if (!res) {
  470. uni.showToast({
  471. title: "请求失败",
  472. icon: "none",
  473. });
  474. }
  475. }
  476. // 设置按钮为禁用状态
  477. isCodeBtnDisabled.value = true;
  478. codeBtnText.value = "重新发送";
  479. let time = 6;
  480. const timer = setInterval(() => {
  481. time--;
  482. codeBtnText.value = "重新发送 " + time + "s";
  483. if (time <= 0) {
  484. clearInterval(timer);
  485. codeBtnText.value = "重新发送";
  486. // 倒计时结束后启用按钮
  487. isCodeBtnDisabled.value = false;
  488. }
  489. }, 1000);
  490. return;
  491. }
  492. function openAgreement() {
  493. // 打开用户协议
  494. console.log("打开用户协议");
  495. uni.navigateTo({
  496. url: "/pages/start/agreement/agreement",
  497. });
  498. }
  499. function openPrivacy() {
  500. // 打开隐私政策
  501. console.log("打开隐私政策");
  502. uni.navigateTo({
  503. url: "/pages/start/privacy/privacy",
  504. });
  505. }
  506. function changeCheckbox() {
  507. agreed.value = !agreed.value;
  508. checkboxUrl.value = agreed.value
  509. ? "../../../static/icons/Check-one-true.png"
  510. : "../../../static/icons/Check-one-false.png";
  511. }
  512. // 验证手机号是否正确
  513. function validatePhoneNumber(countryCode, phoneNumber) {
  514. // 检查是否为空
  515. if (!phoneNumber || phoneNumber.trim() === "") {
  516. uni.showToast({
  517. title: "手机号不能为空",
  518. icon: "none",
  519. });
  520. return false;
  521. }
  522. const bool = verificationPhone(countryCode, phoneNumber);
  523. console.log("验证是否成功", bool);
  524. // 检查格式是否正确
  525. if (!bool) {
  526. uni.showToast({
  527. title: "手机号格式不正确",
  528. icon: "none",
  529. });
  530. return false;
  531. }
  532. // 去掉+号后检查长度(手机号通常在7到15位之间)
  533. const cleanNumber = phoneNumber.replace(/^\+/, "");
  534. if (cleanNumber.length < 7 || cleanNumber.length > 15) {
  535. uni.showToast({
  536. title: "手机号长度不正确",
  537. icon: "none",
  538. });
  539. return false;
  540. }
  541. return true;
  542. }
  543. // 添加弹窗引用
  544. const agreementPopup = ref(null);
  545. // 处理同意按钮点击
  546. function handleAgree() {
  547. // 关闭弹窗
  548. agreementPopup.value.close();
  549. // 设置为已同意
  550. agreed.value = true;
  551. checkboxUrl.value = "../../../static/icons/Check-one-true.png";
  552. // 继续登录流程
  553. }
  554. // 处理同意按钮点击
  555. function handleCancel() {
  556. // 关闭弹窗
  557. agreementPopup.value.close();
  558. }
  559. </script>
  560. <style scoped>
  561. .login-registration-container {
  562. display: flex;
  563. flex-direction: column;
  564. align-items: center;
  565. justify-content: center;
  566. padding: 0 70rpx;
  567. height: 100vh;
  568. background-color: #ffffff;
  569. }
  570. /* 自定义导航栏样式 */
  571. .custom-navbar {
  572. position: absolute;
  573. top: 0;
  574. left: 0;
  575. /* z-index: 999; */
  576. width: 90%;
  577. height: 80rpx;
  578. display: flex;
  579. justify-content: space-between;
  580. align-items: center;
  581. padding: 10rpx 40rpx;
  582. margin-bottom: 20rpx;
  583. }
  584. .nav-left,
  585. .nav-right {
  586. flex: 1;
  587. }
  588. .nav-right {
  589. display: flex;
  590. justify-content: flex-end;
  591. }
  592. .icons {
  593. margin: 20rpx;
  594. width: 40rpx;
  595. height: 40rpx;
  596. /* margin-right: 10rpx; */
  597. }
  598. .icons-rotation {
  599. margin: 20rpx;
  600. width: 40rpx;
  601. height: 40rpx;
  602. /* margin-right: 10rpx; */
  603. animation: rotation 2s linear infinite;
  604. }
  605. @keyframes rotation {
  606. from {
  607. transform: rotate(0deg);
  608. }
  609. to {
  610. transform: rotate(360deg);
  611. }
  612. }
  613. .back-btn,
  614. .headphone-btn {
  615. font-size: 36rpx;
  616. font-weight: bold;
  617. color: #333333;
  618. padding: 10rpx;
  619. }
  620. .logo {
  621. width: 120rpx;
  622. height: 120rpx;
  623. margin-bottom: 60rpx;
  624. border-radius: 20%;
  625. }
  626. .welcome-text {
  627. font-size: 48rpx;
  628. font-weight: bold;
  629. color: #333333;
  630. margin-bottom: 60rpx;
  631. /* text-align: left; */
  632. /* align-self: flex-start; */
  633. }
  634. .switch-container {
  635. display: flex;
  636. margin-bottom: 40rpx;
  637. align-self: flex-start;
  638. }
  639. .switch-item {
  640. font-size: 28rpx;
  641. color: #999999;
  642. padding: 10rpx 20rpx;
  643. position: relative;
  644. }
  645. .switch-item::after {
  646. content: "";
  647. position: absolute;
  648. bottom: 0;
  649. left: 50%;
  650. transform: translateX(-50%);
  651. width: 60%;
  652. /* 控制边框宽度 */
  653. height: 2rpx;
  654. background-color: transparent;
  655. }
  656. .switch-item.active {
  657. color: #333333;
  658. font-weight: 700;
  659. }
  660. .switch-item.active::after {
  661. content: "";
  662. position: absolute;
  663. top: 60rpx;
  664. bottom: 0;
  665. left: 50%;
  666. transform: translateX(-50%);
  667. width: 30%;
  668. /* 控制边框宽度 */
  669. height: 7rpx;
  670. background-color: #333333;
  671. }
  672. .input-container {
  673. width: 100%;
  674. }
  675. /* 添加图标输入框样式 */
  676. .input-with-icon {
  677. display: flex;
  678. align-items: center;
  679. width: 100%;
  680. height: 80rpx;
  681. border-bottom: 2rpx solid #e5e5e5;
  682. margin-bottom: 20rpx;
  683. }
  684. .input-icon {
  685. width: 40rpx;
  686. height: 40rpx;
  687. margin: 0 20rpx;
  688. }
  689. .input-field {
  690. flex: 1;
  691. height: 80rpx;
  692. padding: 15rpx 0;
  693. font-size: 28rpx;
  694. color: #333333;
  695. border: none;
  696. background-color: transparent;
  697. }
  698. .phone-input-container {
  699. display: flex;
  700. align-items: center;
  701. width: 95.8%;
  702. height: 80rpx;
  703. /* border-radius: 20rpx; */
  704. /* border: 2rpx solid #e5e5e5; */
  705. /* background-color: #f5f5f5; */
  706. padding: 0 10rpx;
  707. border-bottom: 2rpx solid #e5e5e5;
  708. margin-bottom: 20rpx;
  709. }
  710. .country-code-selector {
  711. display: flex;
  712. align-items: center;
  713. padding: 0 10rpx;
  714. padding-bottom: 1rpx;
  715. height: 100%;
  716. /* border-right: 2rpx solid #e5e5e5; */
  717. /* background-color: #f5f5f5; */
  718. border-radius: 20rpx 0 0 20rpx;
  719. }
  720. .country-code {
  721. font-size: 28rpx;
  722. color: #333333;
  723. margin-right: 10rpx;
  724. }
  725. .country-flag-img {
  726. width: 40rpx;
  727. height: 40rpx;
  728. margin-right: 10rpx;
  729. }
  730. .arrow-down {
  731. font-size: 20rpx;
  732. color: #999999;
  733. }
  734. .phone-input {
  735. flex: 1;
  736. width: auto;
  737. height: 100%;
  738. border: none;
  739. background-color: transparent;
  740. padding: 0 0rpx;
  741. }
  742. .send-code-btn {
  743. width: 200rpx;
  744. height: 60rpx;
  745. display: inline-flex;
  746. padding: 0rpx 10rpx;
  747. justify-content: center;
  748. align-items: center;
  749. gap: 10px;
  750. border-radius: 4px;
  751. background: #000;
  752. }
  753. .send-code-btn-email {
  754. width: 200rpx;
  755. height: 60rpx;
  756. display: inline-flex;
  757. padding: 0rpx 10rpx;
  758. justify-content: center;
  759. align-items: center;
  760. gap: 10px;
  761. border-radius: 4px;
  762. background: #000;
  763. margin-right: 15rpx;
  764. }
  765. .send-code-btn-disabled {
  766. background: #e6e6e6;
  767. /* 禁用状态下的灰色背景 */
  768. }
  769. .send-code-btn-disabled-text {
  770. color: #999999 !important;
  771. }
  772. .send-code-text {
  773. color: #fff;
  774. font-size: 28rpx;
  775. }
  776. .agreement-container-one {
  777. display: flex;
  778. align-items: center;
  779. align-self: flex-start;
  780. margin-bottom: 80rpx;
  781. }
  782. .agreement-container {
  783. display: flex;
  784. align-items: center;
  785. margin-bottom: 40rpx;
  786. margin-top: -75.5rpx;
  787. align-self: flex-start;
  788. }
  789. .checkbox {
  790. width: 30rpx;
  791. height: 30rpx;
  792. margin-left: 20rpx;
  793. /* flex: content; */
  794. }
  795. .agreement-text-one {
  796. font-size: 22rpx;
  797. color: #666666;
  798. text-align: center;
  799. margin-left: 10rpx;
  800. }
  801. .agreement-text {
  802. margin-left: 20rpx;
  803. font-size: 24rpx;
  804. color: #666666;
  805. }
  806. .link {
  807. color: #333333;
  808. font-weight: bold;
  809. text-decoration: underline;
  810. }
  811. .register-btn {
  812. width: 100%;
  813. height: 80rpx;
  814. background-color: #000000;
  815. color: white;
  816. font-size: 32rpx;
  817. font-weight: bold;
  818. border-radius: 40rpx;
  819. margin-bottom: 40rpx;
  820. }
  821. .or-text {
  822. flex-direction: column;
  823. font-size: 24rpx;
  824. color: #999999;
  825. margin-top: 330rpx;
  826. margin-bottom: -22rpx;
  827. }
  828. .third-party-login {
  829. width: 100%;
  830. margin-bottom: 60rpx;
  831. }
  832. .third-party-text {
  833. color: #ffffff;
  834. font-weight: bold;
  835. white-space: pre;
  836. }
  837. .third-party-btn {
  838. width: 100%;
  839. height: 80rpx;
  840. background-color: rgb(0, 0, 0);
  841. border: 2rpx solid #e5e5e5;
  842. border-radius: 40rpx;
  843. display: flex;
  844. align-items: center;
  845. justify-content: center;
  846. margin-bottom: 20rpx;
  847. font-size: 28rpx;
  848. color: #333333;
  849. }
  850. .google-icon,
  851. .apple-icon {
  852. width: 60rpx;
  853. height: 60rpx;
  854. margin-right: 20rpx;
  855. }
  856. .existing-account {
  857. display: flex;
  858. align-items: center;
  859. }
  860. .account-text {
  861. font-size: 24rpx;
  862. color: #666666;
  863. }
  864. .login-link {
  865. font-size: 24rpx;
  866. font-weight: bold;
  867. color: #333333;
  868. margin-left: 10rpx;
  869. text-decoration: underline;
  870. }
  871. .static-footer {
  872. position: fixed;
  873. bottom: 0;
  874. }
  875. /* 弹窗样式 */
  876. .popup-content {
  877. background-color: #ffffff;
  878. padding: 40rpx;
  879. text-align: center;
  880. border-radius: 10rpx;
  881. width: 550rpx;
  882. }
  883. .popup-message {
  884. font-size: 28rpx;
  885. color: #000000;
  886. margin-bottom: 60rpx;
  887. margin-top: 20rpx;
  888. text-align: center; /* 水平居中 */
  889. display: flex; /* 使用flex布局 */
  890. justify-content: center; /* 水平居中 */
  891. align-items: center; /* 垂直居中 */
  892. font-weight: 300;
  893. }
  894. .popup-message-link {
  895. font-weight: 700;
  896. }
  897. .button-group {
  898. display: flex;
  899. justify-content: space-around;
  900. }
  901. .agree-button {
  902. width: 160rpx;
  903. height: 56rpx;
  904. background-color: #000000;
  905. border-radius: 40rpx;
  906. display: flex; /* 添加flex布局 */
  907. align-items: center; /* 垂直居中 */
  908. justify-content: center; /* 水平居中 */
  909. }
  910. .agree-text {
  911. color: #ffffff;
  912. font-size: 34rpx;
  913. /* 添加垂直居中相关样式 */
  914. display: flex;
  915. align-items: center;
  916. justify-content: center;
  917. line-height: 1; /* 确保文字垂直居中 */
  918. }
  919. .cancel-button {
  920. width: 160rpx;
  921. height: 56rpx;
  922. background-color: #e5e5e5;
  923. border-radius: 40rpx;
  924. display: flex; /* 添加flex布局 */
  925. align-items: center; /* 垂直居中 */
  926. justify-content: center; /* 水平居中 */
  927. }
  928. .cancel-text {
  929. color: #333333;
  930. font-size: 34rpx;
  931. /* 添加垂直居中相关样式 */
  932. display: flex;
  933. align-items: center;
  934. justify-content: center;
  935. line-height: 1; /* 确保文字垂直居中 */
  936. }
  937. </style>