index.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667
  1. <template>
  2. <mobile-frame>
  3. <view class="main">
  4. <view class="one" v-if="platform.uniPlatform=='app'">
  5. <view class="one_2">
  6. <uni-data-checkbox mode="tag" v-model="loginType" :localdata="loginTypeList" @change="logintypeChange"></uni-data-checkbox>
  7. </view>
  8. <view class="one_3" v-if="loginType==0">
  9. <uni-forms ref="codeForm" :rules="codeRules" :model="codeForm" label-width="auto">
  10. <uni-forms-item label="手机号" name="phone">
  11. <uni-easyinput type="number" v-model="codeForm.phone" placeholder="请输入手机号" />
  12. </uni-forms-item>
  13. <uni-forms-item label="验证码" name="code">
  14. <view class="yzm">
  15. <view class="l">
  16. <uni-easyinput type="text" v-model="codeForm.code" placeholder="请输入手机验证码" />
  17. </view>
  18. <view class="r">
  19. <button type="default" size="mini" @tap.stop="appsendCount">{{time_count==0?'验证码':time_count}}</button>
  20. </view>
  21. </view>
  22. </uni-forms-item>
  23. <view class="btn">
  24. <button type="default" size="mini" @click="codeSubmit('codeForm')">提交登录</button>
  25. </view>
  26. </uni-forms>
  27. </view>
  28. <view class="one_4" v-else-if="loginType==1">
  29. <uni-forms ref="accountForm" :rules="accountRules" :model="accountForm" label-width="auto">
  30. <uni-forms-item label="手机号" name="phone">
  31. <uni-easyinput type="number" v-model="accountForm.phone" placeholder="请输入手机号" />
  32. </uni-forms-item>
  33. <uni-forms-item label="登录密码" name="password">
  34. <uni-easyinput type="number" v-model="accountForm.password" placeholder="请输入登录密码" />
  35. </uni-forms-item>
  36. <view class="btn">
  37. <button type="default" size="mini" @click="accountSubmit('accountForm')">提交登录</button>
  38. </view>
  39. </uni-forms>
  40. </view>
  41. </view>
  42. <view class="two" v-else-if="platform.uniPlatform=='mp-weixin'">
  43. <view class="icon">
  44. <text class="iconfont icon-weixin"></text>
  45. </view>
  46. <view class="btn">
  47. <button type="default" size="mini" @tap="wxLogin()">微信信任登录</button>
  48. </view>
  49. </view>
  50. <view class="thr">
  51. <view class="thr_1">
  52. <checkbox-group @change="changeAgree">
  53. <label>
  54. <checkbox :checked="agree" />
  55. <text @tap="toAgree()">我已阅读并同意“用户协议”和“隐私政策”</text>
  56. </label>
  57. </checkbox-group>
  58. </view>
  59. </view>
  60. </view>
  61. <uni-popup ref="dialogShow" type="dialog">
  62. <uni-popup-dialog :title="dialog.title" mode="base" :before-close="true" @confirm="diaSubmit(dialog)" @close="diaReset(dialog)">
  63. <view class="dialog dialog_1" v-if="dialog.type=='1'">
  64. <uni-forms ref="phoneForm" :model="phoneForm" label-width="auto">
  65. <uni-forms-item label="方式">
  66. <uni-data-checkbox v-model="phoneForm.type" :localdata="typeList" />
  67. </uni-forms-item>
  68. <uni-forms-item label="微信" v-if="phoneForm.type==0">
  69. <button type="default" size="mini" open-type="getPhoneNumber" @getphonenumber="getUserPhone">获取微信绑定手机</button>
  70. </uni-forms-item>
  71. <uni-forms-item label="手机号" v-if="phoneForm.type==0">
  72. <uni-easyinput type="number" v-model="phoneForm.phone" disabled />
  73. </uni-forms-item>
  74. <uni-forms-item label="手机号" v-if="phoneForm.type==1">
  75. <view class="yzm">
  76. <view class="l">
  77. <uni-easyinput type="number" v-model="phoneForm.phone" placeholder="请输入手机号" />
  78. </view>
  79. <view class="r">
  80. <button type="default" size="mini" @tap="sendCount">{{time_count==0?'验证码':time_count}}</button>
  81. </view>
  82. </view>
  83. </uni-forms-item>
  84. <uni-forms-item label="验证码" v-if="phoneForm.type==1">
  85. <uni-easyinput type="number" v-model="phoneForm.code" placeholder="请输入验证码" />
  86. </uni-forms-item>
  87. </uni-forms>
  88. </view>
  89. </uni-popup-dialog>
  90. </uni-popup>
  91. </mobile-frame>
  92. </template>
  93. <script>
  94. export default {
  95. data() {
  96. return {
  97. // 平台信息
  98. platform: {},
  99. //openid
  100. openid: '',
  101. // 隐私协议
  102. agree: false,
  103. // app-start
  104. loginType: 0,
  105. // 短信登录
  106. loginTypeList: [ //
  107. {
  108. "value": 0,
  109. "text": "短信登录"
  110. }, {
  111. "value": 1,
  112. "text": "密码登录"
  113. },
  114. ],
  115. // 验证码登录
  116. codeForm: {},
  117. codeRules: {
  118. phone: {
  119. rules: [ //
  120. {
  121. required: true,
  122. errorMessage: '请输入手机号',
  123. },
  124. {
  125. minLength: 11,
  126. maxLength: 11,
  127. errorMessage: '账号长度在{maxLength}个字符',
  128. }
  129. ]
  130. },
  131. code: {
  132. rules: [ //
  133. {
  134. required: true,
  135. errorMessage: '请输入短信验证码',
  136. }
  137. ]
  138. }
  139. },
  140. // 密码登录
  141. accountForm: {},
  142. accountRules: {
  143. phone: {
  144. rules: [ //
  145. {
  146. required: true,
  147. errorMessage: '请输入手机号',
  148. },
  149. {
  150. minLength: 11,
  151. maxLength: 11,
  152. errorMessage: '账号长度在{maxLength}个字符',
  153. }
  154. ]
  155. },
  156. password: {
  157. rules: [ //
  158. {
  159. required: true,
  160. errorMessage: '请输入登录密码',
  161. }
  162. ]
  163. }
  164. },
  165. // app-end
  166. // 微信登陆
  167. // 无账号
  168. is_user: false,
  169. user: {},
  170. // 弹框
  171. dialog: {
  172. title: '绑定手机号',
  173. type: '1'
  174. },
  175. // 绑定手机号
  176. phoneForm: {
  177. type: 0,
  178. },
  179. typeList: [ //
  180. {
  181. text: '微信',
  182. value: 0
  183. },
  184. {
  185. text: '短信验证',
  186. value: 1
  187. }
  188. ],
  189. // 倒计时
  190. time_count: 0
  191. };
  192. },
  193. onShow: function() {
  194. const that = this;
  195. that.search();
  196. },
  197. methods: {
  198. search() {
  199. const that = this;
  200. uni.getStorage({
  201. key: 'system',
  202. success: function(res) {
  203. if (res.data) that.$set(that, `platform`, res.data);
  204. // 获取openid
  205. that.searchOpenid()
  206. }
  207. })
  208. },
  209. // 查询openid
  210. searchOpenid() {
  211. const that = this;
  212. if (that.platform.uniPlatform == 'mp-weixin') {
  213. uni.login({
  214. provider: 'weixin',
  215. success: async function(res) {
  216. const aee = await that.$api(`/wechat/api/login/app`, 'GET', {
  217. config: that.$config.wx_projectkey,
  218. js_code: res.code
  219. })
  220. if (aee.errcode == '0') {
  221. that.$set(that, `openid`, aee.data.openid);
  222. // 微信登录
  223. that.openidLogin(aee.data.openid);
  224. }
  225. },
  226. fail: function(err) {
  227. console.log(err);
  228. }
  229. })
  230. } else if (that.platform.uniPlatform == 'app') {
  231. console.log('to do');
  232. }
  233. },
  234. // 有账号,微信登录,直接返回上一页
  235. async openidLogin(e) {
  236. const that = this;
  237. let res = await that.$api(`/user/wxLogin`, 'POST', {
  238. openid: e
  239. })
  240. if (res.errcode == '0') {
  241. uni.setStorage({
  242. data: res.data,
  243. key: 'token',
  244. success: function() {
  245. uni.navigateBack({
  246. delta: 1
  247. })
  248. }
  249. })
  250. } else {
  251. if (res.errcode == '-5') {
  252. console.log('无账号');
  253. that.$set(that, `is_user`, false)
  254. }
  255. }
  256. },
  257. // 微信信任登录
  258. async wxLogin() {
  259. const that = this;
  260. if (that.agree) {
  261. uni.getUserProfile({
  262. desc: '用于展示',
  263. success: async function(res) {
  264. let parmas = {
  265. openid: that.openid,
  266. icon: [{
  267. url: res.userInfo.avatarUrl
  268. }],
  269. name: res.userInfo.nickName,
  270. }
  271. const arr = await that.$api(`/user`, 'POST', parmas);
  272. if (arr.errcode == '0') {
  273. that.$set(that, `user`, arr.data);
  274. // 打开弹框
  275. that.diaShow();
  276. } else {
  277. uni.showToast({
  278. title: arr.errmsg,
  279. icon: 'none'
  280. });
  281. }
  282. },
  283. fail: function(err) {
  284. console.log(err);
  285. }
  286. })
  287. } else {
  288. uni.showToast({
  289. title: '请阅读并同意用户协议和隐私政策',
  290. icon: 'none'
  291. })
  292. }
  293. },
  294. // 微信信任登录-1
  295. async wxLogins() {
  296. const that = this;
  297. const agg = await that.$api(`/user/wxLogin`, 'POST', {
  298. openid: that.openid
  299. })
  300. if (agg.errcode == '0') {
  301. uni.setStorage({
  302. data: agg.data,
  303. key: 'token',
  304. success: function() {
  305. uni.navigateBack({
  306. delta: 1
  307. })
  308. }
  309. })
  310. } else {
  311. uni.showToast({
  312. title: agg.errmsg,
  313. icon: 'none'
  314. });
  315. }
  316. },
  317. // 打开弹框,绑定手机号
  318. diaShow() {
  319. const that = this;
  320. that.$refs.dialogShow.open();
  321. },
  322. // 获取手机号
  323. async getUserPhone(e) {
  324. const that = this;
  325. let user = that.user;
  326. let detail = e.detail;
  327. let res = await that.$api(`/wechat/api/login/getPhone`, 'GET', {
  328. config: that.$config.wx_projectkey,
  329. code: detail.code
  330. })
  331. if (res.errcode == '0') {
  332. let phone = res.data && res.data.phone_info && res.data.phone_info.purePhoneNumber || '';
  333. that.$set(that.phoneForm, `phone`, phone);
  334. } else {
  335. uni.showToast({
  336. title: res.errmsg,
  337. icon: 'none'
  338. })
  339. }
  340. },
  341. // 短信验证
  342. // 获取验证码
  343. async sendCount() {
  344. const that = this;
  345. let user = this.user;
  346. let form = that.form && that.form.phone ? that.form : that.phoneForm;
  347. if (form && form.phone) {
  348. let res = await that.$api(`/user/toBindPhone`, 'POST', {
  349. id: user._id,
  350. phone: form.phone
  351. })
  352. if (res.errcode == '0') {
  353. uni.showToast({
  354. title: '发送成功'
  355. })
  356. that.$set(that, `time_count`, 60);
  357. that.timeDown();
  358. } else {
  359. uni.showToast({
  360. title: res.errmsg,
  361. icon: 'none'
  362. })
  363. }
  364. } else {
  365. uni.showToast({
  366. title: '输入错误,请重新输入!',
  367. icon: 'none'
  368. })
  369. }
  370. },
  371. // 倒计时
  372. timeDown() {
  373. const that = this;
  374. var times = setInterval(() => {
  375. that.time_count--;
  376. if (that.time_count <= 0) {
  377. clearInterval(times);
  378. }
  379. }, 1000);
  380. },
  381. // 弹框确认(关闭)
  382. async diaSubmit(e) {
  383. const that = this;
  384. let user = this.user;
  385. if (e.type == '1') {
  386. const that = this;
  387. let form = that.phoneForm;
  388. if (form.type == '0') {
  389. if (form && form.phone) that.updatePhone(form.phone);
  390. } else if (form.type == '1') {
  391. const res = await that.$api(`/user/checkBindPhone`, 'POST', {
  392. id: user._id,
  393. code: form.code,
  394. phone: form.phone
  395. });
  396. if (res.errcode == '0') {
  397. const arr = await that.$api(`/user/${user._id}`, 'POST', {
  398. phone: form.phone
  399. });
  400. if (arr.errcode == '0') {
  401. uni.showToast({
  402. title: '绑定手机号成功',
  403. icon: 'none'
  404. })
  405. that.wxLogins();
  406. } else {
  407. uni.showToast({
  408. title: arr.errmsg,
  409. icon: 'none'
  410. })
  411. }
  412. } else {
  413. uni.showToast({
  414. title: res.errmsg,
  415. icon: 'none'
  416. })
  417. }
  418. }
  419. }
  420. },
  421. async updatePhone(e) {
  422. const that = this;
  423. let user = that.user;
  424. let arr = await that.$api(`/user/${user._id}`, 'POST', {
  425. phone: e
  426. })
  427. if (arr.errcode == '0') {
  428. that.wxLogins();
  429. } else {
  430. uni.showToast({
  431. title: res.errmsg,
  432. icon: 'none'
  433. })
  434. }
  435. },
  436. // 弹框取消(关闭)
  437. diaReset(e) {
  438. const that = this;
  439. if (e.type == '1') {
  440. that.wxLogins();
  441. }
  442. },
  443. // 账号登录-start
  444. // 选择登录类型
  445. logintypeChange(e) {
  446. const that = this;
  447. that.$set(that, `loginType`, e.detail.value)
  448. },
  449. // 验证码登录
  450. async appsendCount() {
  451. const that = this;
  452. let form = that.codeForm;
  453. if (form && form.phone) {
  454. let res = await that.$api(`/user/toLoginByCode`, 'POST', {
  455. phone: form.phone
  456. })
  457. console.log(res);
  458. if (res.errcode == '0') {
  459. uni.showToast({
  460. title: '发送成功'
  461. })
  462. that.$set(that, `time_count`, 60);
  463. that.timeDown();
  464. } else {
  465. uni.showToast({
  466. title: res.errmsg,
  467. icon: 'none'
  468. })
  469. }
  470. } else {
  471. uni.showToast({
  472. title: '输入错误,请重新输入!',
  473. icon: 'none'
  474. })
  475. }
  476. },
  477. codeSubmit(ref) {
  478. const that = this;
  479. let agree = that.agree;
  480. that.$refs[ref].validate().then(async params => {
  481. if (agree) {
  482. const res = await that.$api(`/user/checkLoginCode`, 'POST', params);
  483. if (res.errcode == '0') {
  484. uni.setStorage({
  485. key: 'token',
  486. data: res.data,
  487. success: function() {
  488. uni.navigateBack({
  489. delta: 1
  490. })
  491. }
  492. });
  493. } else {
  494. uni.showToast({
  495. title: res.errmsg,
  496. icon: 'none'
  497. })
  498. }
  499. } else {
  500. uni.showToast({
  501. title: '请阅读并同意用户协议和隐私政策',
  502. icon: 'none'
  503. })
  504. }
  505. }).catch(err => {
  506. console.log(err);
  507. })
  508. },
  509. // 账号登录
  510. accountSubmit(ref) {
  511. const that = this;
  512. let agree = that.agree;
  513. that.$refs[ref].validate().then(async params => {
  514. if (agree) {
  515. const res = await that.$api(`/user/login`, 'POST', {
  516. ...params
  517. })
  518. if (res.errcode == '0') {
  519. uni.setStorage({
  520. key: 'token',
  521. data: res.data,
  522. success: function() {
  523. uni.navigateBack({
  524. delta: 1
  525. })
  526. }
  527. });
  528. } else {
  529. uni.showToast({
  530. title: res.errmsg,
  531. icon: 'none'
  532. })
  533. }
  534. } else {
  535. uni.showToast({
  536. title: '请阅读并同意用户协议和隐私政策',
  537. icon: 'none'
  538. })
  539. }
  540. }).catch(err => {
  541. console.log(err);
  542. })
  543. },
  544. // 账号登录-end
  545. // 同意隐私协议
  546. changeAgree() {
  547. const that = this;
  548. if (that.agree) that.$set(that, `agree`, false)
  549. else that.$set(that, `agree`, true);
  550. },
  551. // 查看隐私协议
  552. toAgree() {
  553. uni.navigateTo({
  554. url: `/pages/other/agree`
  555. })
  556. },
  557. }
  558. }
  559. </script>
  560. <style lang="scss">
  561. .main {
  562. .one {
  563. padding: 2vw;
  564. .one_2 {
  565. margin: 4vw 22vw;
  566. text-align: center;
  567. }
  568. .btn {
  569. text-align: center;
  570. margin: 0 0 2vw 0;
  571. width: 96vw;
  572. button {
  573. width: 40%;
  574. padding: 1vw 2vw;
  575. background-color: var(--f35BColor);
  576. color: var(--fffColor);
  577. font-size: var(--font20Size);
  578. }
  579. }
  580. }
  581. .two {
  582. text-align: center;
  583. margin: 20vw 0;
  584. .icon {
  585. margin: 0 0 5vw 0;
  586. text {
  587. font-size: 60px;
  588. }
  589. }
  590. .btn {
  591. button {
  592. background-color: var(--f35BColor);
  593. color: var(--fffColor);
  594. }
  595. }
  596. }
  597. .thr {
  598. .thr_1 {
  599. padding: 0 2vw;
  600. font-size: 14px;
  601. text-align: center;
  602. position: absolute;
  603. width: 96vw;
  604. bottom: 25vw;
  605. }
  606. }
  607. }
  608. .dialog {
  609. width: 100vw;
  610. }
  611. .dialog_1 {
  612. .uni-forms {
  613. display: flex;
  614. form {
  615. width: 100%;
  616. }
  617. }
  618. .uni-data-checklist {
  619. border: 1px solid #E5E5E5;
  620. padding: 1vw;
  621. border-radius: 5px;
  622. }
  623. .uni-forms-item {
  624. margin-bottom: 2vw !important;
  625. }
  626. }
  627. .yzm {
  628. display: flex;
  629. flex-direction: row;
  630. justify-content: space-between;
  631. .l {
  632. flex-grow: 1;
  633. }
  634. .r {
  635. width: 18vw;
  636. button {
  637. width: 100%;
  638. line-height: 2.8;
  639. padding: 0 1vw;
  640. }
  641. }
  642. }
  643. </style>