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.

1009 lines
22 KiB

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