index.vue 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. <template>
  2. <view class="login-container">
  3. <!-- 登录标题 -->
  4. <text class="title">智能医疗问诊系统</text>
  5. <!-- 账号输入框 -->
  6. <input class="input-box" v-model="account" placeholder="请输入账号" />
  7. <!-- 密码输入框 -->
  8. <input class="input-box" v-model="password" type="password" password placeholder="请输入密码" />
  9. <!-- 登录和注册按钮 -->
  10. <view class="btn-group">
  11. <button class="login-btn" @tap="handleLogin">登录</button>
  12. <button class="register-btn" @tap="handleRegister">注册</button>
  13. </view>
  14. <!-- 微信登录按钮 -->
  15. <button
  16. class="wechat-btn"
  17. open-type="getPhoneNumber"
  18. @getphonenumber="handleGetPhoneNumber"
  19. @tap="handleGetUserProfile"
  20. >
  21. <text class="btn-text">微信一键登录</text>
  22. </button>
  23. <!-- 加载状态 -->
  24. <view v-if="loading" class="loading-mask">
  25. <uni-spinner type="circular" color="#07c160" size="40"></uni-spinner>
  26. </view>
  27. </view>
  28. </template>
  29. <script>
  30. export default {
  31. data() {
  32. return {
  33. loading: false,
  34. userInfo: null,
  35. rawData: null,
  36. account: 'patient',
  37. password: '123456'
  38. };
  39. },
  40. mounted() {
  41. this.initWechat();
  42. },
  43. methods: {
  44. initWechat() {
  45. // 移除依赖 WeixinJSBridge 的代码,因为小程序环境没有该对象
  46. console.log('跳过依赖 WeixinJSBridge 的初始化');
  47. },
  48. handleGetUserProfile() {
  49. uni.showLoading({
  50. title: '获取信息中...',
  51. mask: true
  52. });
  53. uni.getUserProfile({
  54. desc: '用于完善会员资料',
  55. success: (res) => {
  56. this.userInfo = res.userInfo;
  57. this.rawData = res.rawData;
  58. console.log('获取到的 rawData:', this.rawData);
  59. uni.hideLoading();
  60. },
  61. fail: (err) => {
  62. console.error('获取用户信息失败:', err);
  63. // 针对不同错误类型给出不同提示
  64. if (err.errMsg.includes('getUserAvatarInfo fail')) {
  65. uni.showToast({
  66. title: '获取用户头像信息失败,请检查网络或更新微信版本',
  67. icon: 'none'
  68. });
  69. } else {
  70. uni.showToast({
  71. title: '请授权后再登录',
  72. icon: 'none'
  73. });
  74. }
  75. uni.hideLoading();
  76. }
  77. });
  78. },
  79. // 处理获取手机号事件
  80. handleGetPhoneNumber: async function(e) {
  81. if (e.detail.errMsg === 'getPhoneNumber:ok') {
  82. if (!this.rawData) {
  83. console.error('请先授权获取用户信息');
  84. uni.showToast({ title: '请先授权获取用户信息', icon: 'none' });
  85. return;
  86. }
  87. try {
  88. uni.showLoading({
  89. title: '登录中...',
  90. mask: true
  91. });
  92. this.loading = true;
  93. const encryptedData = e.detail.encryptedData;
  94. const iv = e.detail.iv;
  95. const { code } = await new Promise((resolve, reject) => {
  96. uni.login({
  97. success: (res) => resolve(res),
  98. fail: (err) => reject(err)
  99. });
  100. });
  101. const response = await new Promise((resolve, reject) => {
  102. uni.request({
  103. url: 'http://localhost:8080/api/auth/wechat/login',
  104. method: 'POST',
  105. data: {
  106. code,
  107. encryptedData,
  108. iv,
  109. rawData: this.rawData
  110. },
  111. success: (res) => resolve(res),
  112. fail: (err) => {
  113. console.error('网络请求失败:', err);
  114. reject(err);
  115. }
  116. });
  117. });
  118. console.log('后端返回的完整数据:', response.data);
  119. if (response.data) {
  120. if (response.data.wxNickname && response.data.wxAvatarUrl) {
  121. wx.setStorageSync('userToken', response.data.token);
  122. wx.setStorageSync('userInfo', {
  123. userId: response.data.userId,
  124. wxNickname: response.data.wxNickname,
  125. wxAvatarUrl: response.data.wxAvatarUrl
  126. });
  127. // 跳转逻辑
  128. wx.switchTab({
  129. url: '/pages/home/index'
  130. });
  131. } else {
  132. console.error('后端未返回微信昵称或头像信息:', response.data);
  133. wx.showToast({ title: '获取用户信息失败,请重试', icon: 'none' });
  134. }
  135. } else {
  136. console.error('登录响应数据为空:', response);
  137. wx.showToast({ title: '登录失败,请重试', icon: 'none' });
  138. }
  139. } catch (error) {
  140. console.error('登录过程出错:', error);
  141. wx.showToast({ title: '登录失败,请重试', icon: 'none' });
  142. } finally {
  143. this.loading = false;
  144. wx.hideLoading();
  145. }
  146. } else {
  147. // 优化错误提示
  148. if (e.detail.errMsg.includes('getPhoneNumber:fail')) {
  149. wx.showToast({
  150. title: '获取手机号失败,请重试或检查授权',
  151. icon: 'none'
  152. });
  153. } else {
  154. console.error('用户拒绝授权', e.detail.errMsg);
  155. wx.showToast({ title: '请授权后再登录', icon: 'none' });
  156. }
  157. }
  158. },
  159. // 登录点击方法
  160. handleLogin() {
  161. uni.request({
  162. url: 'http://localhost:8080/user/login',
  163. method: 'POST',
  164. data: {
  165. username: this.account,
  166. password: this.password
  167. },
  168. success: (res) => {
  169. console.log('登录响应:', res.data);
  170. if (res.data.code == 200) {
  171. uni.showToast({
  172. title: '登录成功',
  173. icon: 'success'
  174. });
  175. // 清空输入框数据
  176. this.account = '';
  177. this.password = '';
  178. uni.switchTab({
  179. url: '/pages/home/index'
  180. });
  181. } else {
  182. uni.showToast({
  183. title: res.data.message || '登录失败,请重试',
  184. icon: 'none'
  185. });
  186. }
  187. },
  188. fail: (err) => {
  189. console.error('登录请求失败:', err);
  190. uni.showToast({
  191. title: '网络错误,请重试',
  192. icon: 'none'
  193. });
  194. },
  195. complete: () => {
  196. uni.hideLoading();
  197. }
  198. });
  199. },
  200. // 注册点击方法
  201. handleRegister() {
  202. uni.request({
  203. url: 'http://localhost:8080/user/register',
  204. method: 'POST',
  205. data: {
  206. username: this.account,
  207. password: this.password
  208. },
  209. success: (res) => {
  210. console.log('注册响应:', res.data);
  211. if (res.data.code == 200) {
  212. uni.showToast({
  213. title: '注册成功',
  214. icon: 'success'
  215. });
  216. // 清空输入框数据
  217. this.account = '';
  218. this.password = '';
  219. // 可以在这里添加注册成功后的逻辑,如跳转到登录页
  220. } else {
  221. uni.showToast({
  222. title: res.data.message || '注册失败,请重试',
  223. icon: 'none'
  224. });
  225. }
  226. },
  227. fail: (err) => {
  228. console.error('注册请求失败:', err);
  229. uni.showToast({
  230. title: '网络错误,请重试',
  231. icon: 'none'
  232. });
  233. },
  234. complete: () => {
  235. uni.hideLoading();
  236. }
  237. });
  238. }
  239. }
  240. };
  241. </script>
  242. <style scoped lang="scss">
  243. .login-container {
  244. display: flex;
  245. flex-direction: column;
  246. align-items: center;
  247. justify-content: center;
  248. height: 100vh;
  249. background-color: #f0f2f5;
  250. }
  251. .title {
  252. font-size: 36rpx;
  253. color: #1a73e8;
  254. margin-bottom: 80rpx;
  255. font-weight: bold;
  256. }
  257. .input-box {
  258. width: 600rpx;
  259. height: 120rpx;
  260. margin-bottom: 40rpx;
  261. padding: 0 20rpx;
  262. border: 2rpx solid #d9d9d9;
  263. border-radius: 12rpx;
  264. font-size: 32rpx;
  265. background-color: white;
  266. }
  267. .login-btn, .register-btn, .wechat-btn {
  268. display: flex;
  269. align-items: center;
  270. justify-content: center;
  271. width: 280rpx;
  272. height: 120rpx;
  273. color: white;
  274. border-radius: 60rpx;
  275. box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.15);
  276. font-size: 32rpx;
  277. }
  278. .login-btn {
  279. background-color: #1a73e8;
  280. }
  281. .register-btn {
  282. background-color: #ff9500;
  283. }
  284. .wechat-btn {
  285. background-color: #07c160;
  286. margin-top: 40rpx;
  287. }
  288. .wechat-btn .wechat-icon {
  289. width: 60rpx;
  290. height: 60rpx;
  291. margin-right: 20rpx;
  292. }
  293. .btn-group {
  294. display: flex;
  295. justify-content: space-between;
  296. width: 600rpx;
  297. }
  298. .loading-mask {
  299. position: fixed;
  300. top: 0;
  301. left: 0;
  302. width: 100%;
  303. height: 100%;
  304. background-color: rgba(0, 0, 0, 0.3);
  305. display: flex;
  306. align-items: center;
  307. justify-content: center;
  308. z-index: 9999;
  309. }
  310. </style>