login.js 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. "use strict";
  2. const common_vendor = require("../../common/vendor.js");
  3. const utils_auth = require("../../utils/auth.js");
  4. require("../../utils/api.js");
  5. const UserInfoPopup = () => "../../components/UserInfoPopup.js";
  6. const _sfc_main = {
  7. components: {
  8. UserInfoPopup
  9. },
  10. data() {
  11. return {
  12. showOneClickLogin: true,
  13. // 是否显示一键登录按钮
  14. agreedToTerms: false,
  15. // 是否同意协议
  16. loginCode: "",
  17. // 微信登录code
  18. tempUserData: null
  19. // 临时存储的用户数据
  20. };
  21. },
  22. methods: {
  23. /**
  24. * 返回上一页
  25. */
  26. handleBack() {
  27. const pages = getCurrentPages();
  28. if (pages.length > 1) {
  29. common_vendor.index.navigateBack();
  30. } else {
  31. common_vendor.index.switchTab({
  32. url: "/pages/index/index"
  33. });
  34. }
  35. },
  36. /**
  37. * 第一步:微信一键登录(老用户静默登录)
  38. */
  39. async handleWxLogin() {
  40. if (!this.agreedToTerms) {
  41. common_vendor.index.showToast({
  42. title: "请先阅读并同意用户协议",
  43. icon: "none",
  44. duration: 2e3
  45. });
  46. return;
  47. }
  48. try {
  49. common_vendor.index.showLoading({ title: "登录中..." });
  50. const loginRes = await this.wxLoginAsync();
  51. this.loginCode = loginRes.code;
  52. console.log("[登录] 获取到微信code:", this.loginCode);
  53. const result = await utils_auth.wxSilentLogin(this.loginCode);
  54. common_vendor.index.hideLoading();
  55. if (result && result.isSign === "true") {
  56. console.log("[登录] 老用户登录成功");
  57. this.handleLoginSuccess();
  58. } else if (result && result.isSign === "false") {
  59. console.log("[登录] 新用户,需要授权手机号");
  60. this.showOneClickLogin = false;
  61. } else if (result && result.code === 103) {
  62. common_vendor.index.showModal({
  63. title: "账号异常",
  64. content: "您的账号已被禁用,如有疑问请联系客服",
  65. showCancel: false
  66. });
  67. } else {
  68. throw new Error("登录接口返回数据异常");
  69. }
  70. } catch (error) {
  71. common_vendor.index.hideLoading();
  72. console.error("[登录] 微信登录失败:", error);
  73. common_vendor.index.showToast({
  74. title: error.message || "登录失败,请重试",
  75. icon: "none",
  76. duration: 2e3
  77. });
  78. }
  79. },
  80. /**
  81. * 第二步:获取手机号授权(新用户)
  82. */
  83. async handleGetPhoneNumber(e) {
  84. console.log("[登录] 手机号授权回调:", e);
  85. if (e.detail.errMsg !== "getPhoneNumber:ok") {
  86. if (e.detail.errMsg.includes("no permission")) {
  87. common_vendor.index.showModal({
  88. title: "权限不足",
  89. content: '获取手机号功能需要:\n1. 小程序企业认证\n2. 开通"手机号快速验证组件"权限\n3. 在真机上测试',
  90. showCancel: false
  91. });
  92. } else {
  93. common_vendor.index.showToast({
  94. title: "授权失败,请重试",
  95. icon: "none"
  96. });
  97. }
  98. return;
  99. }
  100. try {
  101. common_vendor.index.showLoading({ title: "验证中..." });
  102. const loginRes = await this.wxLoginAsync();
  103. const newLoginCode = loginRes.code;
  104. const params = {
  105. loginCode: newLoginCode,
  106. phoneCode: e.detail.code,
  107. encryptedData: e.detail.encryptedData,
  108. iv: e.detail.iv
  109. };
  110. console.log("[登录] 发送手机号验证请求");
  111. const result = await utils_auth.wxPhoneLogin(params);
  112. common_vendor.index.hideLoading();
  113. if (result && result.isSign === "false") {
  114. console.log("[登录] 需要完善用户信息");
  115. this.tempUserData = result;
  116. this.$refs.userInfoPopup.open(result);
  117. } else if (result && result.isSign === "true") {
  118. console.log("[登录] 已注册用户,登录成功");
  119. this.handleLoginSuccess();
  120. } else {
  121. throw new Error("验证接口返回数据异常");
  122. }
  123. } catch (error) {
  124. common_vendor.index.hideLoading();
  125. console.error("[登录] 手机号验证失败:", error);
  126. let errorMsg = "验证失败,请重试";
  127. if (error.message) {
  128. if (error.message.includes("48001") || error.message.includes("未开通手机号快速验证组件")) {
  129. common_vendor.index.showModal({
  130. title: "权限未开通",
  131. content: '小程序未开通"手机号快速验证组件"权限\n\n请前往微信公众平台:\n开发 → 开发管理 → 接口设置\n开通"手机号快速验证组件"',
  132. showCancel: false
  133. });
  134. return;
  135. } else if (error.message.includes("40029") || error.message.includes("code无效")) {
  136. errorMsg = "phoneCode已失效,请重新授权";
  137. } else if (error.message.includes("40001") || error.message.includes("access_token")) {
  138. errorMsg = "access_token无效,请重试";
  139. } else if (error.message.includes("45011")) {
  140. errorMsg = "操作过于频繁,请稍后重试";
  141. } else {
  142. errorMsg = error.message;
  143. }
  144. }
  145. common_vendor.index.showToast({
  146. title: errorMsg,
  147. icon: "none",
  148. duration: 3e3
  149. });
  150. }
  151. },
  152. /**
  153. * 第三步:完善用户信息(首次登录)
  154. */
  155. async handleUserInfoConfirm(userInfo) {
  156. try {
  157. common_vendor.index.showLoading({ title: "注册中..." });
  158. const completeInfo = {
  159. openid: this.tempUserData.openid,
  160. unionid: this.tempUserData.unionid,
  161. phoneNumber: this.tempUserData.phoneNumber,
  162. nickname: userInfo.nickname,
  163. avatarUrl: userInfo.avatarUrl
  164. };
  165. console.log("[登录] 提交完整用户信息");
  166. await utils_auth.wxCompleteUserInfo(completeInfo);
  167. common_vendor.index.hideLoading();
  168. console.log("[登录] 注册成功");
  169. this.handleLoginSuccess();
  170. } catch (error) {
  171. common_vendor.index.hideLoading();
  172. console.error("[登录] 注册失败:", error);
  173. common_vendor.index.showToast({
  174. title: error.message || "注册失败,请重试",
  175. icon: "none",
  176. duration: 2e3
  177. });
  178. }
  179. },
  180. /**
  181. * 登录成功后的处理
  182. */
  183. handleLoginSuccess() {
  184. common_vendor.index.showToast({
  185. title: "登录成功",
  186. icon: "success",
  187. duration: 1500
  188. });
  189. setTimeout(() => {
  190. const pages = getCurrentPages();
  191. if (pages.length > 1) {
  192. common_vendor.index.navigateBack();
  193. } else {
  194. common_vendor.index.switchTab({
  195. url: "/pages/index/index"
  196. });
  197. }
  198. }, 1500);
  199. },
  200. /**
  201. * 协议勾选变化
  202. */
  203. handleAgreementChange(e) {
  204. this.agreedToTerms = e.detail.value.length > 0;
  205. },
  206. /**
  207. * 显示协议内容
  208. */
  209. showAgreement(type) {
  210. const title = type === "user" ? "用户协议" : "隐私政策";
  211. common_vendor.index.showModal({
  212. title,
  213. content: "这里显示协议内容...",
  214. showCancel: false
  215. });
  216. },
  217. /**
  218. * 封装 wx.login 为 Promise
  219. */
  220. wxLoginAsync() {
  221. return new Promise((resolve, reject) => {
  222. common_vendor.index.login({
  223. provider: "weixin",
  224. success: (res) => {
  225. resolve(res);
  226. },
  227. fail: (err) => {
  228. reject(err);
  229. }
  230. });
  231. });
  232. }
  233. }
  234. };
  235. if (!Array) {
  236. const _component_user_info_popup = common_vendor.resolveComponent("user-info-popup");
  237. _component_user_info_popup();
  238. }
  239. function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
  240. return common_vendor.e({
  241. a: common_vendor.o((...args) => $options.handleBack && $options.handleBack(...args)),
  242. b: $data.showOneClickLogin
  243. }, $data.showOneClickLogin ? {
  244. c: common_vendor.o((...args) => $options.handleWxLogin && $options.handleWxLogin(...args))
  245. } : {
  246. d: common_vendor.o((...args) => $options.handleGetPhoneNumber && $options.handleGetPhoneNumber(...args))
  247. }, {
  248. e: $data.agreedToTerms,
  249. f: common_vendor.o(($event) => $options.showAgreement("user")),
  250. g: common_vendor.o(($event) => $options.showAgreement("privacy")),
  251. h: common_vendor.o((...args) => $options.handleAgreementChange && $options.handleAgreementChange(...args)),
  252. i: common_vendor.sr("userInfoPopup", "cdfe2409-0"),
  253. j: common_vendor.o($options.handleUserInfoConfirm)
  254. });
  255. }
  256. const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-cdfe2409"], ["__file", "D:/program/gupiao-wx/src/pages/login/login.vue"]]);
  257. wx.createPage(MiniProgramPage);