login.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. <!-- 微信公众号的登录回调页 -->
  2. <template>
  3. <view />
  4. <!-- 积分确权 -->
  5. <su-popup :show="selectSocialUsers" type="center" round="10" :isMaskClick="false" showClose @close="close">
  6. <view class="head-nav">
  7. <view class="head-box">
  8. <view class="ss-flex ss-m-b-20">
  9. <view class="isActive head-title">
  10. 请选择账号登录
  11. </view>
  12. </view>
  13. </view>
  14. </view>
  15. <view>
  16. <view v-for="user in state.socialUsers" :key="user.username" class="ss-flex" style="padding: 20rpx;margin: 0 auto;width: 520rpx;" @click="selectUser(user.username)">
  17. <image :src="user.avatar" style="width:100rpx;height:100rpx;border-radius: 50%;margin-right:20rpx" />
  18. <view>{{user.username}}</view>
  19. </view>
  20. </view>
  21. </su-popup>
  22. <su-popup :show="isPopup" round="10" :showClose="false" @close="closeAuthModal">
  23. <view>
  24. <view class="head-box">
  25. <view class="ss-flex ss-m-b-20">
  26. <view class="isActive head-title">
  27. 微信注册
  28. </view>
  29. </view>
  30. </view>
  31. <!-- 表单项 -->
  32. <uni-forms ref="smsLoginRef" v-model="state.model" :rules="state.rules" validateTrigger="bind"
  33. labelWidth="140" labelAlign="center" class="loginUniForm">
  34. <uni-forms-item name="username" label="用户名" class="loginUniFormItem">
  35. <uni-easyinput placeholder="请输入用户名" v-model="state.username" :inputBorder="false" :clearable="false" @blur="verifyUsername">
  36. <template v-slot:right>
  37. <view v-if="!state.verifyUsername" class="icon"><image style :src="sheep.$url.static('/static/images/shibai.png')" /></view>
  38. <view v-else class="icon"> <image :src="sheep.$url.static('/static/images/chenggong.png')" /></view>
  39. </template>
  40. </uni-easyinput>
  41. </uni-forms-item>
  42. <uni-forms-item name="mobile" label="手机号" class="loginUniFormItem ss-p-t-10">
  43. <uni-easyinput placeholder="请输入手机号" v-model="state.model.mobile" :inputBorder="false" type="number">
  44. <template v-slot:right>
  45. <button class="ss-reset-button code-btn code-btn-start" :disabled="!state.verifyUsername"
  46. :class="{ 'disabled': !state.verifyUsername }" @tap="getSmsCode('smsLogin', state.model.mobile)">
  47. {{ getSmsTimer('smsLogin') }}
  48. </button>
  49. </template>
  50. </uni-easyinput>
  51. </uni-forms-item>
  52. <uni-forms-item name="code" label="验证码" class="loginUniFormItem">
  53. <uni-easyinput placeholder="请输入验证码" v-model="state.model.code" :inputBorder="false" type="number"
  54. maxlength="4">
  55. </uni-easyinput>
  56. </uni-forms-item>
  57. </uni-forms>
  58. <view style="display: flex;justify-content: space-between;padding: 40rpx;padding-bottom: 0rpx;padding-bottom: 40rpx">
  59. <button class="ss-reset-button login-btn-start" @tap="officialRegister"> 注册 </button>
  60. </view>
  61. </view>
  62. </su-popup>
  63. </template>
  64. <script setup>
  65. import {
  66. ref,
  67. reactive,
  68. unref,
  69. computed,
  70. onBeforeMount
  71. } from 'vue';
  72. import sheep from '@/sheep';
  73. import {
  74. onLoad
  75. } from '@dcloudio/uni-app';
  76. import {
  77. showAuthModal,
  78. closeAuthModal,
  79. getSmsCode,
  80. getSmsTimer
  81. } from '@/sheep/hooks/useModal';
  82. import {
  83. code,
  84. mobile
  85. } from '@/sheep/validate/form';
  86. import AuthUtil from '@/sheep/api/member/auth';
  87. const smsLoginRef = ref(null);
  88. // 数据
  89. const state = reactive({
  90. verifyUsername: false ,
  91. username:'',
  92. openid:'',
  93. socialUsers:[],
  94. loginReqVO: {
  95. type: 31,
  96. code: "",
  97. state: "",
  98. },
  99. isMobileEnd: false, // 手机号输入完毕
  100. codeText: '获取验证码',
  101. model: {
  102. mobile: '', // 手机号
  103. code: '', // 验证码
  104. scene: 1
  105. },
  106. rules: {
  107. code,
  108. mobile,
  109. },
  110. });
  111. const isPopup = ref(false);
  112. const selectSocialUsers = ref(false);
  113. // 定义修改状态的方法
  114. function updateIsPopup() {
  115. isPopup.value = true;
  116. }
  117. function updateSocialUsers(openid,socialUsers){
  118. selectSocialUsers.value = true;
  119. state.openid = openid;
  120. state.socialUsers = socialUsers;
  121. console.log("updateSocialUsers条用了,这时state.socialUsers是",state.socialUsers)
  122. }
  123. // 选了登录的用户
  124. async function selectUser(username){
  125. console.log(username)
  126. // 提交数据
  127. const { code } = await AuthUtil.selectUsernameLogin({openId:state.openid ,username});
  128. if (code === 0) {
  129. // closeAuthModal();
  130. // 检测 H5 登录回调
  131. let returnUrl = uni.getStorageSync('returnUrl');
  132. if (returnUrl) {
  133. uni.removeStorage('returnUrl');
  134. location.replace(returnUrl);
  135. } else {
  136. uni.switchTab({
  137. url: '/',
  138. });
  139. }
  140. }
  141. }
  142. let lastUsername = ref('')
  143. async function verifyUsername(e){
  144. const username = e.detail.value;
  145. if(username == '' || username == lastUsername.value){
  146. // 为空或者没改东西,不调校验
  147. return false;
  148. }
  149. lastUsername.value = username
  150. // 提交数据
  151. const { data } = await AuthUtil.verifyUsername(username);
  152. // false就是已经有这个用户名,不可以用。true是没有,可以改
  153. console.log(data)
  154. if(data){
  155. state.verifyUsername = data
  156. }else {
  157. state.verifyUsername = data
  158. }
  159. }
  160. async function officialRegister(){
  161. uni.setStorageSync("linkId",1)
  162. const linkId = uni.getStorageSync("linkId");
  163. if(!linkId){
  164. return false;
  165. }
  166. const { code } = await sheep.$platform.useProvider().register(code,state.loginReqVO.state,linkId,state.username)
  167. // 提交数据
  168. if (code === 0) {
  169. closeAuthModal();
  170. // 检测 H5 登录回调
  171. let returnUrl = uni.getStorageSync('returnUrl');
  172. if (returnUrl) {
  173. uni.removeStorage('returnUrl');
  174. location.replace(returnUrl);
  175. } else {
  176. uni.switchTab({
  177. url: '/',
  178. });
  179. }
  180. }
  181. }
  182. onBeforeMount(async () => {
  183. const options = {}
  184. new URLSearchParams(location.search).forEach((value, key) => {
  185. options[key] = value;
  186. });
  187. state.loginReqVO.code = options.code
  188. state.loginReqVO.state = options.state
  189. })
  190. onLoad(async (options) => {
  191. // #ifdef H5
  192. // 将 search 参数赋值到 options 中,方便下面解析
  193. new URLSearchParams(location.search).forEach((value, key) => {
  194. options[key] = value;
  195. });
  196. const event = options.event;
  197. const code = options.code;
  198. const state = options.state;
  199. if (event === 'login') { // 场景一:登录
  200. const res = await sheep.$platform.useProvider().login(code, state)
  201. console.log("login.vue的res",res)
  202. if (res.data.socialUsers != null){
  203. updateSocialUsers(res.data.openid,res.data.socialUsers)
  204. return false
  205. }
  206. } else if (event === 'register') {
  207. updateIsPopup()
  208. return false
  209. } else if (event === 'bind') { // 场景二:绑定
  210. sheep.$platform.useProvider().bind(code, state);
  211. }
  212. // 检测 H5 登录回调
  213. let returnUrl = uni.getStorageSync('returnUrl');
  214. if (returnUrl) {
  215. uni.removeStorage('returnUrl');
  216. location.replace(returnUrl);
  217. } else {
  218. uni.switchTab({
  219. url: '/',
  220. });
  221. }
  222. // #endif
  223. });
  224. </script>
  225. <style lang="scss" scoped>
  226. .icon{
  227. display:flex;
  228. align-items: center;
  229. margin-right:7rpx
  230. }
  231. .icon image{
  232. width:35rpx;
  233. height:35rpx;
  234. }
  235. @keyframes title-animation {
  236. 0% {
  237. font-size: 32rpx;
  238. }
  239. 100% {
  240. font-size: 36rpx;
  241. }
  242. }
  243. .login-wrap {
  244. padding: 50rpx 34rpx;
  245. min-height: 500rpx;
  246. background-color: #fff;
  247. border-radius: 20rpx 20rpx 0 0;
  248. }
  249. .head-box {
  250. padding: 40rpx 40rpx 0;
  251. .head-title {
  252. min-width: 160rpx;
  253. font-size: 36rpx;
  254. font-weight: bold;
  255. color: #333333;
  256. line-height: 36rpx;
  257. }
  258. .head-title-active {
  259. width: 160rpx;
  260. font-size: 32rpx;
  261. font-weight: 600;
  262. color: #999;
  263. line-height: 36rpx;
  264. }
  265. .head-title-animation {
  266. animation-name: title-animation;
  267. animation-duration: 0.1s;
  268. animation-timing-function: ease-out;
  269. animation-fill-mode: forwards;
  270. }
  271. .head-title-line {
  272. position: relative;
  273. &::before {
  274. content: '';
  275. width: 1rpx;
  276. height: 34rpx;
  277. background-color: #e4e7ed;
  278. position: absolute;
  279. left: -30rpx;
  280. top: 50%;
  281. transform: translateY(-50%);
  282. }
  283. }
  284. .head-subtitle {
  285. font-size: 26rpx;
  286. font-weight: 400;
  287. color: #afb6c0;
  288. text-align: left;
  289. display: flex;
  290. }
  291. }
  292. // .code-btn[disabled] {
  293. // background-color: #fff;
  294. // }
  295. .code-btn-start {
  296. width: 160rpx;
  297. height: 56rpx;
  298. line-height: normal;
  299. border: 2rpx solid var(--ui-BG-Main);
  300. border-radius: 28rpx;
  301. font-size: 26rpx;
  302. font-weight: 400;
  303. color: var(--ui-BG-Main);
  304. opacity: 1;
  305. }
  306. .forgot-btn {
  307. width: 160rpx;
  308. line-height: 56rpx;
  309. font-size: 30rpx;
  310. font-weight: 500;
  311. color: #999;
  312. }
  313. .login-btn-start {
  314. width: 158rpx;
  315. height: 56rpx;
  316. line-height: normal;
  317. background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
  318. border-radius: 28rpx;
  319. font-size: 26rpx;
  320. font-weight: 500;
  321. color: #fff;
  322. }
  323. .type-btn {
  324. padding: 20rpx;
  325. margin: 40rpx auto;
  326. width: 200rpx;
  327. font-size: 30rpx;
  328. font-weight: 500;
  329. color: #999999;
  330. }
  331. .auto-login-box {
  332. width: 100%;
  333. .auto-login-btn {
  334. width: 68rpx;
  335. height: 68rpx;
  336. border-radius: 50%;
  337. margin: 0 30rpx;
  338. }
  339. .auto-login-img {
  340. width: 68rpx;
  341. height: 68rpx;
  342. border-radius: 50%;
  343. }
  344. }
  345. .agreement-box {
  346. margin: 80rpx auto 0;
  347. .protocol-check {
  348. transform: scale(0.7);
  349. }
  350. .agreement-text {
  351. font-size: 26rpx;
  352. font-weight: 500;
  353. color: #999999;
  354. .tcp-text {
  355. color: var(--ui-BG-Main);
  356. }
  357. }
  358. }
  359. // 修改密码
  360. .editPwd-btn-box {
  361. .save-btn {
  362. width: 690rpx;
  363. line-height: 70rpx;
  364. background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
  365. border-radius: 35rpx;
  366. font-size: 28rpx;
  367. font-weight: 500;
  368. color: #ffffff;
  369. }
  370. .forgot-btn {
  371. width: 690rpx;
  372. line-height: 70rpx;
  373. font-size: 28rpx;
  374. font-weight: 500;
  375. color: #999999;
  376. }
  377. }
  378. .code-btn-start {
  379. color: #55b774;
  380. border: 1px solid #55b774;
  381. }
  382. .agreement-box {
  383. margin: 20rpx 0;
  384. }
  385. .login-btn-start {
  386. background: rgb(14, 147, 46);
  387. width: 100%;
  388. height: 80rpx;
  389. font-size: 32rpx;
  390. }
  391. .loginUniForm {
  392. margin: 40rpx;
  393. border: 1rpx solid #d6d6d6;
  394. padding: 10rpx 15rpx;
  395. border-radius: 10rpx;
  396. }
  397. .loginUniFormItem:first-child {
  398. border-bottom: 1rpx solid #d6d6d6;
  399. padding-bottom: 10rpx;
  400. }
  401. .loginUniFormItem:last-child {
  402. border-bottom: none;
  403. padding-top: 10rpx;
  404. }
  405. ::v-deep .loginUniFormItem .uni-forms-item__inner {
  406. padding-bottom: 0;
  407. }
  408. ::v-deep .loginUniFormItem .uni-error-message {
  409. bottom: -20rpx;
  410. }
  411. </style>