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.

1181 lines
25 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="verifyCode"
  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="verifyCode"
  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="Login">登录</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-message"
  218. >请阅读并同意<text @click="openAgreement" class="popup-message-link"
  219. >服务协议</text
  220. ><text @click="openPrivacy" class="popup-message-link"
  221. >隐私权限</text
  222. >
  223. </text>
  224. <view class="button-group">
  225. <button class="cancel-button" @click="handleCancel">
  226. <text class="cancel-text">取消</text>
  227. </button>
  228. <button class="agree-button" @click="handleAgree">
  229. <text class="agree-text">同意</text>
  230. </button>
  231. </view>
  232. </view>
  233. </uniPopup>
  234. <footerBar class="static-footer" :type="type"></footerBar>
  235. </view>
  236. </template>
  237. <script setup>
  238. import { ref } from "vue";
  239. // 导入完整的国家列表
  240. import countryList from "./list.js";
  241. import footerBar from "../../../components/footerBar-cn";
  242. import uniPopupDialogVue from "../../../uni_modules/uni-popup/components/uni-popup-dialog/uni-popup-dialog.vue";
  243. import uniPopup from "../../../uni_modules/uni-popup/components/uni-popup/uni-popup.vue";
  244. import { verificationPhone, verificationEmail } from "../login/verification";
  245. import {
  246. LoginApi,
  247. SendEmailCodeApi,
  248. SendPhoneCodeApi,
  249. } from "../../../api/start/login";
  250. import { useUserStore } from "../../../stores/modules/userInfo";
  251. const deepChartID = ref("");
  252. const type = ref("member");
  253. const email = ref("");
  254. const password = ref("");
  255. const country = ref("+86");
  256. const phone = ref("");
  257. const agreed = ref(false);
  258. const switchType = ref("User"); // 默认是邮箱注册
  259. const { safeAreaInsets } = uni.getSystemInfoSync();
  260. const codeBtnText = ref("获取验证码");
  261. const isCodeBtnDisabled = ref(false); // 添加验证码按钮禁用状态
  262. const checkboxUrl = ref("../../../static/icons/Check-one-false.png");
  263. const verifyCode = ref("");
  264. const account = ref("");
  265. // 使用从list.js导入的完整国家列表数据
  266. const countries = ref(
  267. countryList.list.map((item) => ({
  268. name: item.name,
  269. code: `+${item.tel}`,
  270. flag: item.flag,
  271. short: item.short,
  272. en: item.en,
  273. }))
  274. );
  275. // 默认选中的国家(中国)
  276. const selectedCountry = ref(
  277. countries.value.find((country) => country.short === "CN") ||
  278. countries.value[0]
  279. );
  280. // 显示国家选择器
  281. function showCountryPicker() {
  282. uni.showActionSheet({
  283. itemList: countries.value.map(
  284. (country) => `${country.name} ${country.code}`
  285. ),
  286. success: function (res) {
  287. selectedCountry.value = countries.value[res.tapIndex];
  288. country.value = selectedCountry.value.code;
  289. },
  290. });
  291. }
  292. function goToIndex() {
  293. // 返回上一页
  294. uni.navigateTo({
  295. url: "/pages/start/index/index",
  296. });
  297. }
  298. function switchUser() {
  299. // 切换到手机注册
  300. switchType.value = "User";
  301. password.value = "";
  302. verifyCode.value = "";
  303. }
  304. function switchEmail() {
  305. // 切换到邮箱注册
  306. switchType.value = "Email";
  307. password.value = "";
  308. verifyCode.value = "";
  309. }
  310. function switchPhone() {
  311. // 切换到手机注册
  312. switchType.value = "Phone";
  313. password.value = "";
  314. verifyCode.value = "";
  315. }
  316. // 登录
  317. async function Login() {
  318. if (!basicVerification()) {
  319. return;
  320. }
  321. const account = changeAccount();
  322. const loginType = changeLoginType();
  323. const res = await LoginApi({
  324. loginType: loginType,
  325. account: account,
  326. verifyCode: verifyCode.value,
  327. password: password.value,
  328. useCode: verifyCode.value ? true : false,
  329. idToken: "",
  330. });
  331. // const res = await uni.request({
  332. // url: 'https://hwjb.homilychart.com/testApi/UserLogin/login',
  333. // data: {},
  334. // header: {
  335. // Accept: 'application/json',
  336. // 'Content-Type': 'application/json' },
  337. // method: 'POST',
  338. // sslVerify: true,
  339. // success: ({ data, statusCode, header }) => {
  340. // console.log(data);
  341. // console.log(statusCode);
  342. // console.log(header);
  343. // },
  344. // fail: (error) => {
  345. // console.log("error是",error);
  346. // }
  347. // })
  348. const message = res.message;
  349. if (res.code === 200) {
  350. // 登录成功
  351. uni.showToast({
  352. title: "登录成功",
  353. icon: "success",
  354. });
  355. const userStore = useUserStore();
  356. userStore.setUserInfo(res.data);
  357. console.log("userInfo为", userStore.userInfo);
  358. // 跳转到首页
  359. uni.switchTab({
  360. url: "/pages/start/index/index",
  361. });
  362. } else {
  363. // 登录失败
  364. uni.showToast({
  365. title: message,
  366. icon: "none",
  367. });
  368. }
  369. }
  370. // 基础验证
  371. function basicVerification() {
  372. if (switchType.value === "User") {
  373. if (!deepChartID.value) {
  374. uni.showToast({
  375. title: "请输入用户名",
  376. icon: "none",
  377. });
  378. return false;
  379. }
  380. if (!password.value) {
  381. uni.showToast({
  382. title: "请输入密码",
  383. icon: "none",
  384. });
  385. return false;
  386. }
  387. }
  388. if (switchType.value === "Phone") {
  389. // 登录逻辑
  390. if (!phone.value) {
  391. uni.showToast({
  392. title: "请输入手机号码",
  393. icon: "none",
  394. });
  395. return false;
  396. }
  397. const phoneAll = `${country.value}${phone.value}`;
  398. console.log("完整手机号" + phoneAll);
  399. if (!validatePhoneNumber(country.value, phone.value)) {
  400. return false;
  401. }
  402. if (!verifyCode.value) {
  403. uni.showToast({
  404. title: "请输入验证码",
  405. icon: "none",
  406. });
  407. return false;
  408. }
  409. }
  410. if (switchType.value === "Email") {
  411. // 登录逻辑
  412. if (!email.value) {
  413. uni.showToast({
  414. title: "请输入邮箱地址",
  415. icon: "none",
  416. });
  417. return false;
  418. }
  419. const bool = verificationEmail(email.value);
  420. console.log("验证是否成功", bool);
  421. // 检查格式是否正确
  422. if (!bool) {
  423. uni.showToast({
  424. title: "邮箱格式不正确",
  425. icon: "none",
  426. });
  427. return false;
  428. }
  429. if (!verifyCode.value) {
  430. uni.showToast({
  431. title: "请输入验证码",
  432. icon: "none",
  433. });
  434. return false;
  435. }
  436. }
  437. if (!agreed.value) {
  438. // 显示同意弹窗
  439. agreementPopup.value.open();
  440. return;
  441. }
  442. return true;
  443. }
  444. // 注册码码验证
  445. function VerCodeVerfifcation() {
  446. if (switchType.value === "Phone") {
  447. if (!phone.value) {
  448. uni.showToast({
  449. title: "请输入手机号",
  450. icon: "none",
  451. });
  452. return false;
  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 false;
  463. }
  464. }
  465. if (switchType.value === "Email") {
  466. if (!email.value) {
  467. uni.showToast({
  468. title: "请输入邮箱地址",
  469. icon: "none",
  470. });
  471. return false;
  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 false;
  482. }
  483. }
  484. return true;
  485. }
  486. // 请求账户
  487. function changeAccount() {
  488. if (switchType.value === "User") {
  489. account.value = deepChartID.value;
  490. }
  491. if (switchType.value === "Phone") {
  492. account.value = `${country.value}${phone.value}`;
  493. }
  494. if (switchType.value === "Email") {
  495. account.value = email.value;
  496. }
  497. return account.value;
  498. }
  499. // 改变请求时的type
  500. function changeLoginType() {
  501. if (switchType.value === "User") {
  502. return "DCCODE";
  503. }
  504. if (switchType.value === "Phone") {
  505. return "PHONE";
  506. }
  507. if (switchType.value === "Email") {
  508. return "EMAIL";
  509. }
  510. }
  511. // 添加弹窗引用
  512. const agreementPopup = ref(null);
  513. // 处理同意按钮点击
  514. function handleAgree() {
  515. // 关闭弹窗
  516. agreementPopup.value.close();
  517. // 设置为已同意
  518. agreed.value = true;
  519. checkboxUrl.value = "../../../static/icons/Check-one-true.png";
  520. // 继续登录流程
  521. }
  522. // 处理同意按钮点击
  523. function handleCancel() {
  524. // 关闭弹窗
  525. agreementPopup.value.close();
  526. }
  527. // 苹果登录
  528. function loginWithApple() {
  529. // Apple登录逻辑
  530. console.log("通过Apple登录");
  531. uni.login({
  532. provider: "apple",
  533. success: function (loginRes) {
  534. // 登录成功
  535. uni.getUserInfo({
  536. provider: "apple",
  537. success: function (info) {
  538. console.log(info);
  539. },
  540. });
  541. },
  542. fail: function (err) {
  543. // 登录授权失败
  544. // err.code错误码参考`授权失败错误码(code)说明`
  545. console.log(err);
  546. },
  547. });
  548. }
  549. // 谷歌登录
  550. function loginWithGoogle() {
  551. // Google登录逻辑
  552. console.log("通过Google登录");
  553. uni.login({
  554. provider: "google",
  555. success: function (loginRes) {
  556. // 登录成功
  557. uni.getUserInfo({
  558. provider: "google",
  559. success: function (info) {
  560. console.log(info);
  561. },
  562. });
  563. },
  564. fail: function (err) {
  565. // 登录授权失败
  566. // err.code是错误码
  567. console.log(err);
  568. },
  569. });
  570. }
  571. function goToRegistration() {
  572. // 跳转到登录页
  573. uni.navigateTo({
  574. url: "/pages/start/Registration/Registration",
  575. });
  576. }
  577. function onPhoneInput(e) {
  578. // 确保只允许输入数字
  579. const value = e.detail.value;
  580. // 使用 isNaN 检查是否为有效数字
  581. if (isNaN(value)) {
  582. phone.value = "";
  583. } else {
  584. phone.value = value;
  585. }
  586. }
  587. // 发送验证码
  588. async function sendCode() {
  589. if (!VerCodeVerfifcation()) {
  590. return;
  591. }
  592. // 如果按钮已禁用,则不执行后续逻辑
  593. if (isCodeBtnDisabled.value) return;
  594. if (switchType.value === "Phone") {
  595. // 发送验证码
  596. const phoneAll = `${country.value}${phone.value}`;
  597. const res = await SendPhoneCodeApi({
  598. phone: phoneAll,
  599. });
  600. console.log("手机验证码:", res.message);
  601. const message = res.message;
  602. if (res.code === 200) {
  603. uni.showToast({
  604. title: message,
  605. icon: "none",
  606. });
  607. }
  608. }
  609. if (switchType.value === "Email") {
  610. // 发送验证码
  611. const res = await SendEmailCodeApi({
  612. email: email.value,
  613. });
  614. console.log("邮箱验证码:", res.message);
  615. const message = res.message;
  616. if (res.code === 200) {
  617. uni.showToast({
  618. title: message,
  619. icon: "none",
  620. });
  621. }
  622. }
  623. // 设置按钮为禁用状态
  624. isCodeBtnDisabled.value = true;
  625. codeBtnText.value = "重新发送";
  626. let time = 6;
  627. const timer = setInterval(() => {
  628. time--;
  629. codeBtnText.value = "重新发送 " + time + "s";
  630. if (time <= 0) {
  631. clearInterval(timer);
  632. codeBtnText.value = "重新发送";
  633. // 倒计时结束后启用按钮
  634. isCodeBtnDisabled.value = false;
  635. }
  636. }, 1000);
  637. return;
  638. }
  639. function openAgreement() {
  640. // 打开用户协议
  641. console.log("打开用户协议");
  642. uni.navigateTo({
  643. url: "/pages/start/agreement/agreement",
  644. });
  645. }
  646. function openPrivacy() {
  647. // 打开隐私政策
  648. console.log("打开隐私政策");
  649. uni.navigateTo({
  650. url: "/pages/start/privacy/privacy",
  651. });
  652. }
  653. function recoverPassword() {
  654. // 忘记密码
  655. // console.log("忘记密码");
  656. uni.navigateTo({
  657. url: "/pages/start/recoverPassword/recoverPassword",
  658. });
  659. }
  660. function changeCheckbox() {
  661. agreed.value = !agreed.value;
  662. checkboxUrl.value = agreed.value
  663. ? "../../../static/icons/Check-one-true.png"
  664. : "../../../static/icons/Check-one-false.png";
  665. }
  666. // 验证手机号是否正确
  667. function validatePhoneNumber(countryCode, phoneNumber) {
  668. // 检查是否为空
  669. if (!phoneNumber || phoneNumber.trim() === "") {
  670. uni.showToast({
  671. title: "手机号不能为空",
  672. icon: "none",
  673. });
  674. return false;
  675. }
  676. const bool = verificationPhone(countryCode, phoneNumber);
  677. console.log("验证是否成功", bool);
  678. // 检查格式是否正确
  679. if (!bool) {
  680. uni.showToast({
  681. title: "手机号格式不正确",
  682. icon: "none",
  683. });
  684. return false;
  685. }
  686. // 去掉+号后检查长度(手机号通常在7到15位之间)
  687. const cleanNumber = phoneNumber.replace(/^\+/, "");
  688. if (cleanNumber.length < 7 || cleanNumber.length > 15) {
  689. uni.showToast({
  690. title: "手机号长度不正确",
  691. icon: "none",
  692. });
  693. return false;
  694. }
  695. return true;
  696. }
  697. </script>
  698. <style scoped>
  699. .login-registration-container {
  700. display: flex;
  701. flex-direction: column;
  702. align-items: center;
  703. justify-content: center;
  704. padding: 0 70rpx;
  705. height: 100vh;
  706. background-color: #ffffff;
  707. }
  708. /* 自定义导航栏样式 */
  709. .custom-navbar {
  710. position: absolute;
  711. top: 0;
  712. left: 0;
  713. /* z-index: 999; */
  714. width: 90%;
  715. height: 80rpx;
  716. display: flex;
  717. justify-content: space-between;
  718. align-items: center;
  719. padding: 10rpx 40rpx;
  720. margin-bottom: 20rpx;
  721. }
  722. .nav-left,
  723. .nav-right {
  724. flex: 1;
  725. }
  726. .nav-right {
  727. display: flex;
  728. justify-content: flex-end;
  729. }
  730. .icons {
  731. margin: 20rpx;
  732. width: 40rpx;
  733. height: 40rpx;
  734. /* margin-right: 10rpx; */
  735. }
  736. .back-btn,
  737. .headphone-btn {
  738. font-size: 36rpx;
  739. font-weight: bold;
  740. color: #333333;
  741. padding: 10rpx;
  742. }
  743. .logo {
  744. width: 120rpx;
  745. height: 120rpx;
  746. margin-bottom: 60rpx;
  747. border-radius: 20%;
  748. }
  749. .welcome-text {
  750. font-size: 48rpx;
  751. font-weight: bold;
  752. color: #333333;
  753. margin-bottom: 60rpx;
  754. /* text-align: left; */
  755. /* align-self: flex-start; */
  756. }
  757. .switch-container {
  758. display: flex;
  759. margin-bottom: 40rpx;
  760. align-self: flex-start;
  761. }
  762. .switch-item {
  763. font-size: 28rpx;
  764. color: #999999;
  765. padding: 10rpx 20rpx;
  766. position: relative;
  767. }
  768. .switch-item::after {
  769. content: "";
  770. position: absolute;
  771. bottom: 0;
  772. left: 50%;
  773. transform: translateX(-50%);
  774. width: 60%;
  775. /* 控制边框宽度 */
  776. height: 2rpx;
  777. background-color: transparent;
  778. }
  779. .switch-item.active {
  780. color: #333333;
  781. font-weight: 700;
  782. }
  783. .switch-item.active::after {
  784. content: "";
  785. position: absolute;
  786. top: 60rpx;
  787. bottom: 0;
  788. left: 50%;
  789. transform: translateX(-50%);
  790. width: 30%;
  791. /* 控制边框宽度 */
  792. height: 7rpx;
  793. background-color: #333333;
  794. }
  795. .input-container {
  796. width: 100%;
  797. }
  798. /* 添加图标输入框样式 */
  799. .input-with-icon {
  800. display: flex;
  801. align-items: center;
  802. width: 100%;
  803. height: 80rpx;
  804. border-bottom: 2rpx solid #e5e5e5;
  805. margin-bottom: 20rpx;
  806. }
  807. .input-icon {
  808. width: 40rpx;
  809. height: 40rpx;
  810. margin: 0 20rpx;
  811. }
  812. .input-field {
  813. flex: 1;
  814. height: 80rpx;
  815. padding: 15rpx 0;
  816. font-size: 28rpx;
  817. color: #333333;
  818. border: none;
  819. background-color: transparent;
  820. }
  821. .phone-input-container {
  822. display: flex;
  823. align-items: center;
  824. width: 95.8%;
  825. height: 80rpx;
  826. /* border-radius: 20rpx; */
  827. /* border: 2rpx solid #e5e5e5; */
  828. /* background-color: #f5f5f5; */
  829. padding: 0 10rpx;
  830. border-bottom: 2rpx solid #e5e5e5;
  831. margin-bottom: 20rpx;
  832. }
  833. .country-code-selector {
  834. display: flex;
  835. align-items: center;
  836. padding: 0 10rpx;
  837. padding-bottom: 1rpx;
  838. height: 100%;
  839. /* border-right: 2rpx solid #e5e5e5; */
  840. /* background-color: #f5f5f5; */
  841. border-radius: 20rpx 0 0 20rpx;
  842. }
  843. .country-code {
  844. font-size: 28rpx;
  845. color: #333333;
  846. margin-right: 10rpx;
  847. }
  848. .country-flag-img {
  849. width: 40rpx;
  850. height: 40rpx;
  851. margin-right: 10rpx;
  852. }
  853. .arrow-down {
  854. font-size: 20rpx;
  855. color: #999999;
  856. }
  857. .phone-input {
  858. flex: 1;
  859. width: auto;
  860. height: 100%;
  861. border: none;
  862. background-color: transparent;
  863. padding: 0 0rpx;
  864. }
  865. .send-code-btn {
  866. width: 200rpx;
  867. height: 60rpx;
  868. display: inline-flex;
  869. padding: 0rpx 10rpx;
  870. justify-content: center;
  871. align-items: center;
  872. gap: 10px;
  873. border-radius: 4px;
  874. background: #000;
  875. }
  876. .send-code-btn-email {
  877. width: 200rpx;
  878. height: 60rpx;
  879. display: inline-flex;
  880. padding: 0rpx 10rpx;
  881. justify-content: center;
  882. align-items: center;
  883. gap: 10px;
  884. border-radius: 4px;
  885. background: #000;
  886. margin-right: 15rpx;
  887. }
  888. .send-code-btn-disabled {
  889. background: #e6e6e6;
  890. /* 禁用状态下的灰色背景 */
  891. }
  892. .send-code-btn-disabled-text {
  893. color: #999999 !important;
  894. }
  895. .send-code-text {
  896. color: #fff;
  897. font-size: 28rpx;
  898. }
  899. .agreement-container-one {
  900. display: flex;
  901. align-items: center;
  902. align-self: flex-start;
  903. margin-bottom: 80rpx;
  904. }
  905. .agreement-container {
  906. display: flex;
  907. align-items: center;
  908. margin-bottom: 30rpx;
  909. margin-top: -60rpx;
  910. align-self: flex-start;
  911. }
  912. .checkbox {
  913. width: 30rpx;
  914. height: 30rpx;
  915. margin-left: 20rpx;
  916. /* flex: content; */
  917. }
  918. .agreement-text-one {
  919. font-size: 22rpx;
  920. color: #666666;
  921. text-align: center;
  922. margin-left: 10rpx;
  923. }
  924. .agreement-text {
  925. margin-left: 20rpx;
  926. font-size: 24rpx;
  927. color: #666666;
  928. white-space: nowrap;
  929. }
  930. .link {
  931. color: #333333;
  932. font-weight: bold;
  933. text-decoration: underline;
  934. }
  935. .register-btn {
  936. width: 100%;
  937. height: 80rpx;
  938. background-color: #000000;
  939. color: white;
  940. font-size: 32rpx;
  941. font-weight: bold;
  942. border-radius: 40rpx;
  943. margin-bottom: 40rpx;
  944. }
  945. .or-text {
  946. font-size: 24rpx;
  947. color: #999999;
  948. margin-bottom: 40rpx;
  949. }
  950. .to-icon {
  951. width: 10rpx;
  952. height: 16rpx;
  953. }
  954. .third-party-login {
  955. width: 100%;
  956. margin-bottom: 60rpx;
  957. }
  958. .third-party-text {
  959. color: #ffffff;
  960. font-weight: bold;
  961. white-space: pre;
  962. }
  963. .third-party-btn {
  964. width: 100%;
  965. height: 80rpx;
  966. background-color: rgb(0, 0, 0);
  967. border: 2rpx solid #e5e5e5;
  968. border-radius: 40rpx;
  969. display: flex;
  970. align-items: center;
  971. justify-content: center;
  972. margin-bottom: 20rpx;
  973. font-size: 28rpx;
  974. color: #333333;
  975. }
  976. .google-icon,
  977. .apple-icon {
  978. width: 60rpx;
  979. height: 60rpx;
  980. margin-right: 20rpx;
  981. }
  982. .existing-account {
  983. display: flex;
  984. align-items: center;
  985. }
  986. .account-text {
  987. font-size: 24rpx;
  988. color: #666666;
  989. }
  990. .login-link {
  991. font-size: 24rpx;
  992. font-weight: bold;
  993. color: #333333;
  994. margin-left: 10rpx;
  995. text-decoration: underline;
  996. }
  997. .static-footer {
  998. position: fixed;
  999. bottom: 0;
  1000. }
  1001. /* 弹窗样式 */
  1002. .popup-content {
  1003. background-color: #ffffff;
  1004. padding: 40rpx;
  1005. text-align: center;
  1006. border-radius: 10rpx;
  1007. width: 550rpx;
  1008. }
  1009. .popup-message {
  1010. font-size: 28rpx;
  1011. color: #000000;
  1012. margin-bottom: 60rpx;
  1013. margin-top: 20rpx;
  1014. text-align: center; /* 水平居中 */
  1015. display: flex; /* 使用flex布局 */
  1016. justify-content: center; /* 水平居中 */
  1017. align-items: center; /* 垂直居中 */
  1018. font-weight: 300;
  1019. }
  1020. .popup-message-link {
  1021. font-weight: 700;
  1022. }
  1023. .button-group {
  1024. display: flex;
  1025. justify-content: space-around;
  1026. }
  1027. .agree-button {
  1028. width: 160rpx;
  1029. height: 56rpx;
  1030. background-color: #000000;
  1031. border-radius: 40rpx;
  1032. display: flex; /* 添加flex布局 */
  1033. align-items: center; /* 垂直居中 */
  1034. justify-content: center; /* 水平居中 */
  1035. }
  1036. .agree-text {
  1037. color: #ffffff;
  1038. font-size: 34rpx;
  1039. /* 添加垂直居中相关样式 */
  1040. display: flex;
  1041. align-items: center;
  1042. justify-content: center;
  1043. line-height: 1; /* 确保文字垂直居中 */
  1044. }
  1045. .cancel-button {
  1046. width: 160rpx;
  1047. height: 56rpx;
  1048. background-color: #e5e5e5;
  1049. border-radius: 40rpx;
  1050. display: flex; /* 添加flex布局 */
  1051. align-items: center; /* 垂直居中 */
  1052. justify-content: center; /* 水平居中 */
  1053. }
  1054. .cancel-text {
  1055. color: #333333;
  1056. font-size: 34rpx;
  1057. /* 添加垂直居中相关样式 */
  1058. display: flex;
  1059. align-items: center;
  1060. justify-content: center;
  1061. line-height: 1; /* 确保文字垂直居中 */
  1062. }
  1063. </style>