s-auth-modal.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. <template>
  2. <!-- 规格弹窗 -->
  3. <su-popup :show="authType !== ''" round="10" :showClose="true" @close="closeAuthModal">
  4. <view class="login-wrap">
  5. <!-- 标题栏 -->
  6. <view class="head-box " v-if="['smsLogin', 'accountLogin','register'].includes(authType)">
  7. <view class="ss-flex ss-m-b-20">
  8. <view
  9. :class="[isActive=='accountLogin' ?`head-title ss-m-r-40 head-title-animation`:`head-title-active ss-m-r-40`]
  10. "
  11. @tap="isActive='accountLogin';showAuthModal('accountLogin','accountLogin')">
  12. 账号登录
  13. </view>
  14. <view
  15. :class="[isActive=='smsLogin'?`head-title head-title-line head-title-animation ss-m-r-40`:` ss-m-r-40 head-title-active head-title-line`]"
  16. @tap="isActive='smsLogin';showAuthModal('smsLogin','smsLogin')">
  17. 短信登录
  18. </view>
  19. <!-- v-if="linkId" -->
  20. <view
  21. :class="[isActive=='register' ?`head-title head-title-line head-title-animation`:`head-title-active head-title-line`]"
  22. @tap="isActive='register';showAuthModal('register','register')">
  23. 注册
  24. </view>
  25. </view>
  26. </view>
  27. <!-- 用户协议的勾选 -->
  28. <view v-if="[ 'smsLogin','accountLogin','register'].includes(authType)" class="agreement-box ss-flex ss-row-center"
  29. :class="{ shake: currentProtocol }">
  30. <label class="radio ss-flex ss-col-center" @tap="onChange">
  31. <radio :checked="state.protocol" color="var(--ui-BG-Main)" style="transform: scale(0.8)"
  32. @tap.stop="onChange" />
  33. <view class="agreement-text ss-flex ss-col-center ss-m-l-8">
  34. 我已阅读并遵守
  35. <view class="tcp-text" @tap.stop="onProtocol('用户协议')">
  36. 《用户协议》
  37. </view>
  38. <view class="agreement-text">与</view>
  39. <view class="tcp-text" @tap.stop="onProtocol('隐私协议')">
  40. 《隐私协议》
  41. </view>
  42. </view>
  43. </label>
  44. </view>
  45. <!-- 微信公众号授权登陆 在验证码登录 账号登录中显示-->
  46. <view v-if="['accountLogin', 'smsLogin'].includes(authType)"
  47. class="auto-login-box ss-flex ss-flex-col ss-row-center ss-col-center">
  48. <view class="wx-login-btn " @tap="thirdLogin('wechat')" v-if=" ['WechatOfficialAccount', 'WechatMiniProgram', 'App'].includes(sheep.$platform.name) && sheep.$platform.isWechatInstalled
  49. ">
  50. <image class=" auto-login-img" :src="sheep.$url.static('/static/images/wechat.png')" />
  51. <text>微信授权登录</text>
  52. </view>
  53. </view>
  54. <!-- 微信公众号授权登陆 在账号注册中显示 -->
  55. <view v-if="['register'].includes(authType)"
  56. class="auto-login-box ss-flex ss-flex-col ss-row-center ss-col-center">
  57. <view class="wx-login-btn " @tap="thirdRegister('wechat')" v-if=" ['WechatOfficialAccount', 'WechatMiniProgram', 'App'].includes(sheep.$platform.name) && sheep.$platform.isWechatInstalled
  58. ">
  59. <image class=" auto-login-img" :src="sheep.$url.static('/static/images/wechat.png')" />
  60. <text>微信授权注册</text>
  61. </view>
  62. </view>
  63. <!-- 1. 微信公众号授权登录 第一次登陆时弹窗绑定手机号 accountLogin -->
  64. <officialAccountFirstLogin v-if="authType === 'officialAccountFirstLogin'" :agreeStatus="state.protocol" @onConfirm="onConfirm" />
  65. <!-- 1. 账号密码登录 accountLogin -->
  66. <account-login v-if="authType === 'accountLogin'" :agreeStatus="state.protocol" @onConfirm="onConfirm" />
  67. <!-- 2. 短信登录 smsLogin -->
  68. <sms-login v-if="authType === 'smsLogin'" :agreeStatus="state.protocol" @onConfirm="onConfirm" />
  69. <!-- 注册 -->
  70. <register v-if="authType === 'register'" :agreeStatus="state.protocol" @onConfirm="onConfirm" />
  71. <!-- 3. 忘记密码 resetPassword-->
  72. <reset-password v-if="authType === 'resetPassword'" />
  73. <!-- 4. 绑定手机号 changeMobile -->
  74. <change-mobile v-if="authType === 'changeMobile'" />
  75. <!-- 5. 修改密码 changePassword-->
  76. <changePassword v-if="authType === 'changePassword'" />
  77. <!-- 6. 微信小程序授权 -->
  78. <mp-authorization v-if="authType === 'mpAuthorization'" />
  79. <!-- 7. 第三方登录 -->
  80. <view v-if="['accountLogin', 'smsLogin'].includes(authType)"
  81. class="auto-login-box ss-flex ss-flex-col ss-row-center ss-col-center">
  82. <!-- 7.1 微信小程序的快捷登录 -->
  83. <view v-if="sheep.$platform.name === 'WechatMiniProgram'" class="ss-flex register-box">
  84. <view class="register-title">还没有账号?</view>
  85. <button class="ss-reset-button login-btn" open-type="getPhoneNumber"
  86. @getphonenumber="getPhoneNumber">
  87. 快捷登录
  88. </button>
  89. <view class="circle" />
  90. </view>
  91. <!-- 7.2 微信的公众号、App、小程序的登录,基于 openid + code -->
  92. <!-- <button
  93. v-if="
  94. ['WechatOfficialAccount', 'WechatMiniProgram', 'App'].includes(sheep.$platform.name) &&
  95. sheep.$platform.isWechatInstalled
  96. "
  97. @tap="thirdLogin('wechat')"
  98. class="ss-reset-button auto-login-btn"
  99. >
  100. <image
  101. class="auto-login-img"
  102. :src="sheep.$url.static('/static/images/wechat.png')"
  103. />
  104. </button> -->
  105. <!-- 7.3 iOS 登录 TODO 非繁人:等后面搞 App 再弄 -->
  106. <button v-if="sheep.$platform.os === 'ios' && sheep.$platform.name === 'App'" @tap="thirdLogin('apple')"
  107. class="ss-reset-button auto-login-btn">
  108. <image class="auto-login-img" :src="sheep.$url.static('/static/images/apple.png')" />
  109. </button>
  110. </view>
  111. <view class="safe-box" />
  112. </view>
  113. </su-popup>
  114. </template>
  115. <script setup>
  116. import {
  117. computed,
  118. reactive,
  119. ref
  120. } from 'vue';
  121. import sheep from '@/sheep';
  122. import accountLogin from './components/account-login.vue';
  123. import smsLogin from './components/sms-login.vue';
  124. import register from './components/register.vue'
  125. import resetPassword from './components/reset-password.vue';
  126. import changeMobile from './components/change-mobile.vue';
  127. import changePassword from './components/change-password.vue';
  128. import mpAuthorization from './components/mp-authorization.vue';
  129. import officialAccountFirstLogin from './components/officialAccountFirstLogin'
  130. import {
  131. closeAuthModal,
  132. showAuthModal
  133. } from '@/sheep/hooks/useModal';
  134. const appInfo = computed(() => sheep.$store('app').info);
  135. const linkId = uni.getStorageSync("linkId");
  136. const modalStore = sheep.$store('modal');
  137. // 授权弹窗类型
  138. const authType = computed(() => modalStore.auth);
  139. const isActive = computed(() => modalStore.isActive)
  140. const state = reactive({
  141. protocol: false,
  142. });
  143. const currentProtocol = ref(false);
  144. // 勾选协议
  145. function onChange() {
  146. state.protocol = !state.protocol;
  147. }
  148. // 查看协议
  149. function onProtocol(title) {
  150. closeAuthModal();
  151. sheep.$router.go('/pages/public/richtext', {
  152. title,
  153. });
  154. }
  155. // 点击登录 / 注册事件
  156. function onConfirm(e) {
  157. currentProtocol.value = e;
  158. setTimeout(() => {
  159. currentProtocol.value = false;
  160. }, 1000);
  161. }
  162. // 第三方授权登陆(微信小程序、Apple)
  163. const thirdLogin = async (provider) => {
  164. if (!state.protocol) {
  165. currentProtocol.value = true;
  166. setTimeout(() => {
  167. currentProtocol.value = false;
  168. }, 1000);
  169. sheep.$helper.toast('请勾选同意');
  170. return;
  171. }
  172. const loginRes = await sheep.$platform.useProvider(provider).login();
  173. if (loginRes) {
  174. closeAuthModal();
  175. // 触发小程序授权信息弹框
  176. // #ifdef MP-WEIXIN
  177. showAuthModal('mpAuthorization');
  178. // #endif
  179. }
  180. };
  181. // 第三方授权注册
  182. const thirdRegister = async (provider) => {
  183. if (!state.protocol) {
  184. currentProtocol.value = true;
  185. setTimeout(() => {
  186. currentProtocol.value = false;
  187. }, 1000);
  188. sheep.$helper.toast('请勾选同意');
  189. return;
  190. }
  191. const linkId = uni.getStorageSync("linkId");
  192. if (!linkId) {
  193. sheep.$helper.toast('您只能通过分享注册');
  194. return false;
  195. }
  196. const loginRes = await sheep.$platform.useProvider(provider).register();
  197. if (loginRes) {
  198. closeAuthModal();
  199. // 触发小程序授权信息弹框
  200. // #ifdef MP-WEIXIN
  201. showAuthModal('mpAuthorization');
  202. // #endif
  203. }
  204. };
  205. // 微信小程序的“手机号快速验证”:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getPhoneNumber.html
  206. const getPhoneNumber = async (e) => {
  207. if (e.detail.errMsg !== 'getPhoneNumber:ok') {
  208. sheep.$helper.toast('快捷登录失败');
  209. return;
  210. }
  211. let result = await sheep.$platform.useProvider().mobileLogin(e.detail);
  212. if (result) {
  213. closeAuthModal();
  214. }
  215. };
  216. </script>
  217. <style lang="scss" scoped>
  218. @import './index.scss';
  219. .shake {
  220. animation: shake 0.05s linear 4 alternate;
  221. }
  222. @keyframes shake {
  223. from {
  224. transform: translateX(-10rpx);
  225. }
  226. to {
  227. transform: translateX(10rpx);
  228. }
  229. }
  230. .register-box {
  231. position: relative;
  232. justify-content: center;
  233. .register-btn {
  234. color: #999999;
  235. font-size: 30rpx;
  236. font-weight: 500;
  237. }
  238. .register-title {
  239. color: #999999;
  240. font-size: 30rpx;
  241. font-weight: 400;
  242. margin-right: 24rpx;
  243. }
  244. .or-title {
  245. margin: 0 16rpx;
  246. color: #999999;
  247. font-size: 30rpx;
  248. font-weight: 400;
  249. }
  250. .login-btn {
  251. color: var(--ui-BG-Main);
  252. font-size: 30rpx;
  253. font-weight: 500;
  254. }
  255. .circle {
  256. position: absolute;
  257. right: 0rpx;
  258. top: 18rpx;
  259. width: 8rpx;
  260. height: 8rpx;
  261. border-radius: 8rpx;
  262. background: var(--ui-BG-Main);
  263. }
  264. }
  265. .safe-box {
  266. height: calc(constant(safe-area-inset-bottom) / 5 * 3);
  267. height: calc(env(safe-area-inset-bottom) / 5 * 3);
  268. }
  269. .tcp-text {
  270. color: var(--ui-BG-Main);
  271. }
  272. .agreement-text {
  273. color: $dark-9;
  274. }
  275. .wx-login-btn {
  276. width: 100%;
  277. border: 1rpx solid #55b774;
  278. border-radius: 10rpx;
  279. padding: 10rpx 0;
  280. color: #333333;
  281. display: flex;
  282. align-items: center;
  283. justify-content: center;
  284. font-size: 32rpx;
  285. margin: 0 0 0.625rem 0;
  286. box-sizing: border-box;
  287. text {
  288. margin-left: 20rpx
  289. }
  290. }
  291. .agreement-box {
  292. margin: 40rpx;
  293. }
  294. </style>