lsc há 3 dias atrás
pai
commit
1ff874eb6b
59 ficheiros alterados com 440 adições e 15 exclusões
  1. 0 0
      dist/index.html
  2. 1 1
      dist/report.html
  3. 0 0
      dist/static/css/app.ba4eed89.css
  4. 1 0
      dist/static/css/chunk-17f30775.2d489984.css
  5. 0 0
      dist/static/css/chunk-b40d50ca.56c23762.css
  6. 0 0
      dist/static/img/Union.953680c6.svg
  7. 0 0
      dist/static/img/delFile.b454d74e.svg
  8. 0 0
      dist/static/img/videoFile.8b2406f2.svg
  9. 0 0
      dist/static/js/app.5ca9adcc.js
  10. 0 0
      dist/static/js/chunk-00b34a2c.c7e8b15a.js
  11. 0 0
      dist/static/js/chunk-01979dd3.c9735726.js
  12. 0 0
      dist/static/js/chunk-01979dd3.f3236b6c.js
  13. 0 0
      dist/static/js/chunk-01c5f272.14c996b9.js
  14. 0 0
      dist/static/js/chunk-03851ecf.9519877d.js
  15. 0 0
      dist/static/js/chunk-03851ecf.da18759c.js
  16. 0 0
      dist/static/js/chunk-07b980da.1b24e096.js
  17. 0 0
      dist/static/js/chunk-0e29728a.516dc24c.js
  18. 0 0
      dist/static/js/chunk-0e29728a.c1f229f5.js
  19. 0 0
      dist/static/js/chunk-1678db47.541df83d.js
  20. 0 0
      dist/static/js/chunk-1738a278.841c52f9.js
  21. 0 0
      dist/static/js/chunk-17e66bfc.e3092c2f.js
  22. 0 0
      dist/static/js/chunk-17f30775.c2f388f7.js
  23. 0 0
      dist/static/js/chunk-18ea3bfa.46cc7005.js
  24. 0 0
      dist/static/js/chunk-1a806098.e89ffabe.js
  25. 0 0
      dist/static/js/chunk-1eb03832.7fa15c55.js
  26. 0 0
      dist/static/js/chunk-247d1cc7.0f517fcd.js
  27. 0 0
      dist/static/js/chunk-247d1cc7.415d5bfe.js
  28. 0 0
      dist/static/js/chunk-284ddcf3.41750d95.js
  29. 0 0
      dist/static/js/chunk-2d0c7336.5464938b.js
  30. 0 0
      dist/static/js/chunk-2d0c7336.707392c1.js
  31. 0 0
      dist/static/js/chunk-2fc6aeae.23884e99.js
  32. 1 1
      dist/static/js/chunk-30b5de98.42d056b7.js
  33. 0 0
      dist/static/js/chunk-55e3fa90.0bb3afc5.js
  34. 0 0
      dist/static/js/chunk-55e3fa90.c8d9c3e3.js
  35. 0 0
      dist/static/js/chunk-5bb2a616.cb003f93.js
  36. 0 0
      dist/static/js/chunk-60b2ab15.bf31f0ff.js
  37. 0 0
      dist/static/js/chunk-61b307f8.48e68204.js
  38. 0 0
      dist/static/js/chunk-61b307f8.76d3a8c6.js
  39. 0 0
      dist/static/js/chunk-67c4ee97.03123001.js
  40. 0 0
      dist/static/js/chunk-6ad98842.d4ffdd60.js
  41. 0 0
      dist/static/js/chunk-6e5f7eb4.1ad93511.js
  42. 0 0
      dist/static/js/chunk-793d7e56.57eb242b.js
  43. 0 0
      dist/static/js/chunk-7caf3a38.ed044c8f.js
  44. 0 0
      dist/static/js/chunk-7d4543c8.f800adaa.js
  45. 0 0
      dist/static/js/chunk-81a47c5e.f9e0b7c9.js
  46. 0 0
      dist/static/js/chunk-870f2882.2e55723f.js
  47. 0 0
      dist/static/js/chunk-970a3cc0.f9bacf9a.js
  48. 0 0
      dist/static/js/chunk-b265f6f8.5b14ed34.js
  49. 0 0
      dist/static/js/chunk-b40d50ca.95fb3681.js
  50. 0 0
      dist/static/js/chunk-b40d50ca.bf7f16f9.js
  51. 0 0
      dist/static/js/chunk-c3be65e4.4e411d8f.js
  52. 0 0
      dist/static/js/chunk-d3f058fe.9bf03846.js
  53. 0 0
      dist/static/js/chunk-d3f058fe.a0ffef66.js
  54. 0 0
      dist/static/js/chunk-libs.4406bd5f.js
  55. 0 0
      dist/static/js/chunk-libs.d370c650.js
  56. 70 0
      src/api/wechat.js
  57. 11 5
      src/permission.js
  58. 16 8
      src/router/router.config.js
  59. 340 0
      src/views/wechatAuth/index.vue

Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/index.html


Diff do ficheiro suprimidas por serem muito extensas
+ 1 - 1
dist/report.html


+ 0 - 0
dist/static/css/app.970aed35.css → dist/static/css/app.ba4eed89.css


+ 1 - 0
dist/static/css/chunk-17f30775.2d489984.css

@@ -0,0 +1 @@
+.wechat-auth-container[data-v-1b8780b6]{min-height:100vh;background:-webkit-linear-gradient(315deg,#667eea,#764ba2);background:linear-gradient(135deg,#667eea,#764ba2);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;padding:.53333rem}.wechat-auth-container .auth-content[data-v-1b8780b6]{background:#fff;border-radius:.42667rem;padding:1.06667rem .8rem;text-align:center;box-shadow:0 .26667rem .8rem rgba(0,0,0,.1);max-width:10.66667rem;width:100%}.wechat-auth-container .auth-content .logo[data-v-1b8780b6]{margin-bottom:.8rem}.wechat-auth-container .auth-content .logo img[data-v-1b8780b6]{width:2.13333rem;height:2.13333rem;border-radius:50%}.wechat-auth-container .auth-content .auth-status .van-icon[data-v-1b8780b6],.wechat-auth-container .auth-content .auth-status .van-loading[data-v-1b8780b6]{margin-bottom:.53333rem}.wechat-auth-container .auth-content .auth-status p[data-v-1b8780b6]{margin:.26667rem 0;font-size:.42667rem;color:#333}.wechat-auth-container .auth-content .auth-status p.user-info[data-v-1b8780b6]{font-size:.37333rem;color:#666;margin-top:.26667rem}.wechat-auth-container .auth-content .auth-status p.auth-desc[data-v-1b8780b6]{font-size:.37333rem;color:#999;margin:.4rem 0 .66667rem}.wechat-auth-container .auth-content .auth-status p.error-message[data-v-1b8780b6]{font-size:.37333rem;color:#ee0a24;margin:.4rem 0 .66667rem}.wechat-auth-container .auth-content .auth-status .van-button[data-v-1b8780b6]{margin-top:.53333rem;width:5.33333rem;height:1.17333rem;border-radius:.58667rem}@media (max-width:480px){.wechat-auth-container[data-v-1b8780b6]{padding:.26667rem}.wechat-auth-container .auth-content[data-v-1b8780b6]{padding:.8rem .53333rem}.wechat-auth-container .auth-content .auth-status .van-button[data-v-1b8780b6]{width:100%}}

+ 0 - 0
dist/static/css/chunk-b40d50ca.cf12ca03.css → dist/static/css/chunk-b40d50ca.56c23762.css


+ 0 - 0
dist/static/img/Union.b0ea0f49.svg → dist/static/img/Union.953680c6.svg


+ 0 - 0
dist/static/img/delFile.ec8981b7.svg → dist/static/img/delFile.b454d74e.svg


+ 0 - 0
dist/static/img/videoFile.22737868.svg → dist/static/img/videoFile.8b2406f2.svg


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/app.5ca9adcc.js


+ 0 - 0
dist/static/js/chunk-00b34a2c.b40f08bf.js → dist/static/js/chunk-00b34a2c.c7e8b15a.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-01979dd3.c9735726.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-01979dd3.f3236b6c.js


+ 0 - 0
dist/static/js/chunk-01c5f272.834e483b.js → dist/static/js/chunk-01c5f272.14c996b9.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-03851ecf.9519877d.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-03851ecf.da18759c.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-07b980da.1b24e096.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-0e29728a.516dc24c.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-0e29728a.c1f229f5.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-1678db47.541df83d.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-1738a278.841c52f9.js


+ 0 - 0
dist/static/js/chunk-17e66bfc.e1127648.js → dist/static/js/chunk-17e66bfc.e3092c2f.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-17f30775.c2f388f7.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-18ea3bfa.46cc7005.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-1a806098.e89ffabe.js


+ 0 - 0
dist/static/js/chunk-1eb03832.48d36a1e.js → dist/static/js/chunk-1eb03832.7fa15c55.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-247d1cc7.0f517fcd.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-247d1cc7.415d5bfe.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-284ddcf3.41750d95.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-2d0c7336.5464938b.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-2d0c7336.707392c1.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-2fc6aeae.23884e99.js


+ 1 - 1
dist/static/js/chunk-30b5de98.aa4fc6f0.js → dist/static/js/chunk-30b5de98.42d056b7.js

@@ -1 +1 @@
-(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-30b5de98"],{"6f03":function(t,e,i){},"730a":function(t,e,i){"use strict";i.r(e);i("b0c0");var s=function(){var t=this,e=t._self._c;return e("div",{staticClass:"home-container"},[e("head-bar",{on:{back:t.back},scopedSlots:t._u([{key:"title",fn:function(){return[e("div",{staticClass:"navTitle"},[t._v("查看问卷")])]},proxy:!0}])}),e("div",{staticClass:"step_box"},[e("topicVue",{attrs:{cJson:t.cJson,title:t.name,brief:t.brief,checktype:2,see:t.see}})],1)],1)},c=[],n=i("5530"),o=(i("14d9"),i("b64b"),i("e9c4"),i("98e5")),r=i("71ed"),a=i("2f62"),u=i("bf3a"),d={components:{headBar:r["a"],topicVue:u["a"]},data:function(){return{courseid:this.$route.query.courseid,tid:this.$route.query.tid,name:this.$route.query.name,title:"",brief:"",cJson:[],see:!1}},computed:Object(n["a"])({},Object(a["c"])(["userinfo"])),methods:{back:function(){this.$router.push({path:"/test"})},getData:function(){var t=this,e={cid:this.courseid,tid:this.tid};Object(o["g"])(e).then((function(e){e[1].length&&(t.cJson=JSON.parse(e[1][0].courseJson)),t.title=e[0][0].title,t.brief=e[0][0].brief,t.see=1==e[0][0].open,t.$forceUpdate()})).catch((function(t){console.error(t)}))},publish:function(){var t=this,e=this.$refs["topicVue"].checkArray,i=[{uid:this.userinfo.userid,cid:this.courseid,cjson:JSON.stringify(e),type:2}];Object(o["a"])(i).then((function(e){t.$message.success("提交成功"),t.back()})).catch((function(t){console.error(t)}))}},mounted:function(){this.getData()}},f=d,h=(i("a998"),i("2877")),b=Object(h["a"])(f,s,c,!1,null,"55bd9d6e",null);e["default"]=b.exports},a998:function(t,e,i){"use strict";i("6f03")}}]);
+(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-30b5de98"],{"6f03":function(t,e,i){},"730a":function(t,e,i){"use strict";i.r(e);i("b0c0");var s=function(){var t=this,e=t._self._c;return e("div",{staticClass:"home-container"},[e("head-bar",{on:{back:t.back},scopedSlots:t._u([{key:"title",fn:function(){return[e("div",{staticClass:"navTitle"},[t._v("查看问卷")])]},proxy:!0}])}),e("div",{staticClass:"step_box"},[e("topicVue",{attrs:{cJson:t.cJson,title:t.name,brief:t.brief,checktype:2,see:t.see}})],1)],1)},c=[],n=i("5530"),o=(i("14d9"),i("e9c4"),i("b64b"),i("98e5")),r=i("71ed"),a=i("2f62"),u=i("bf3a"),d={components:{headBar:r["a"],topicVue:u["a"]},data:function(){return{courseid:this.$route.query.courseid,tid:this.$route.query.tid,name:this.$route.query.name,title:"",brief:"",cJson:[],see:!1}},computed:Object(n["a"])({},Object(a["c"])(["userinfo"])),methods:{back:function(){this.$router.push({path:"/test"})},getData:function(){var t=this,e={cid:this.courseid,tid:this.tid};Object(o["g"])(e).then((function(e){e[1].length&&(t.cJson=JSON.parse(e[1][0].courseJson)),t.title=e[0][0].title,t.brief=e[0][0].brief,t.see=1==e[0][0].open,t.$forceUpdate()})).catch((function(t){console.error(t)}))},publish:function(){var t=this,e=this.$refs["topicVue"].checkArray,i=[{uid:this.userinfo.userid,cid:this.courseid,cjson:JSON.stringify(e),type:2}];Object(o["a"])(i).then((function(e){t.$message.success("提交成功"),t.back()})).catch((function(t){console.error(t)}))}},mounted:function(){this.getData()}},f=d,h=(i("a998"),i("2877")),b=Object(h["a"])(f,s,c,!1,null,"55bd9d6e",null);e["default"]=b.exports},a998:function(t,e,i){"use strict";i("6f03")}}]);

Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-55e3fa90.0bb3afc5.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-55e3fa90.c8d9c3e3.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-5bb2a616.cb003f93.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-60b2ab15.bf31f0ff.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-61b307f8.48e68204.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-61b307f8.76d3a8c6.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-67c4ee97.03123001.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-6ad98842.d4ffdd60.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-6e5f7eb4.1ad93511.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-793d7e56.57eb242b.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-7caf3a38.ed044c8f.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-7d4543c8.f800adaa.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-81a47c5e.f9e0b7c9.js


+ 0 - 0
dist/static/js/chunk-870f2882.42b8e484.js → dist/static/js/chunk-870f2882.2e55723f.js


+ 0 - 0
dist/static/js/chunk-970a3cc0.dd258de8.js → dist/static/js/chunk-970a3cc0.f9bacf9a.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-b265f6f8.5b14ed34.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-b40d50ca.95fb3681.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-b40d50ca.bf7f16f9.js


+ 0 - 0
dist/static/js/chunk-c3be65e4.0f153444.js → dist/static/js/chunk-c3be65e4.4e411d8f.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-d3f058fe.9bf03846.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-d3f058fe.a0ffef66.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-libs.4406bd5f.js


Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-libs.d370c650.js


+ 70 - 0
src/api/wechat.js

@@ -0,0 +1,70 @@
+import request from '@/utils/request'
+const api = 'https://pbl.cocorobo.cn/api/cocoflow/'
+// const api = 'http://localhost:7003/api/cocoflow/'
+
+// 微信授权 - 用code换取access_token和用户信息
+export function wechatAuth(data) {
+  return request({
+    url: api + 'wechat-callback',
+    method: 'POST',
+    data,
+    hideloading: false
+  })
+}
+
+export function wechatRegister(data) {
+  return request({
+    url: api + 'wechat-register',
+    method: 'POST',
+    data,
+    hideloading: false
+  })
+}
+
+// 获取微信用户信息
+export function getWechatUserInfo(openid) {
+  return request({
+    url: `/api/wechat/userinfo/${openid}`,
+    method: 'GET',
+    hideloading: true
+  })
+}
+
+// 微信JS-SDK配置
+export function getWechatJsConfig(url) {
+  return request({
+    url: api + 'api/wechat/jsconfig',
+    method: 'POST',
+    data: { url },
+    hideloading: true
+  })
+}
+
+// 微信分享配置
+export function getWechatShareConfig(data) {
+  return request({
+    url: api + 'api/wechat/share',
+    method: 'POST',
+    data,
+    hideloading: true
+  })
+}
+
+// 微信支付
+export function wechatPay(data) {
+  return request({
+    url: api + 'api/wechat/pay',
+    method: 'POST',
+    data,
+    hideloading: false
+  })
+}
+
+// 检查微信授权状态
+export function checkWechatAuth(openid) {
+  return request({
+    url: api + `api/wechat/check-auth/${openid}`,
+    method: 'GET',
+    hideloading: true
+  })
+}

+ 11 - 5
src/permission.js

@@ -6,7 +6,7 @@ import 'nprogress/nprogress.css' // progress bar style
 
 NProgress.configure({ showSpinner: false }) // NProgress Configuration
 
-const whiteList = ['/login', '/resetpassword', '/help', '/echarts'] // no redirect whitelist
+const whiteList = ['/login', '/resetpassword', '/help', '/echarts', '/wechat-auth'] // no redirect whitelist
 
 // eslint-disable-next-line prettier/prettier
 router.beforeEach(async(to, from, next) => {
@@ -26,7 +26,7 @@ router.beforeEach(async(to, from, next) => {
     await store.commit('SET_TESTID', to.query.testid)
   }
   const shareCourseId =
-    window.location.href.indexOf('?shareCourseId=') != -1
+    window.location.href.indexOf('?shareCourseId=') !== -1
       ? window.location.href.split('?shareCourseId=')[1].toString()
       : ''
   if (shareCourseId) {
@@ -82,9 +82,15 @@ router.beforeEach(async(to, from, next) => {
       // in the free login whitelist, go directly
       next()
     } else {
-      //   // other pages that do not have permission to access are redirected to the login page.
-      next(`/login?redirect=${to.path}`)
-      NProgress.done()
+      // 检查是否是微信授权回调
+      if (window.location.href.indexOf('wechat-auth') != -1) {
+        // 微信授权回调,允许访问
+        next('/wechat-auth')
+      } else {
+        //   // other pages that do not have permission to access are redirected to the login page.
+        next(`/login?redirect=${to.path}`)
+        NProgress.done()
+      }
     }
   }
 })

+ 16 - 8
src/router/router.config.js

@@ -15,6 +15,14 @@ export const constantRouterMap = [
       keepAlive: false
     }
   },
+  {
+    path: '/wechat-auth',
+    component: () => import('@/views/wechatAuth/index'),
+    meta: {
+      title: '微信授权',
+      keepAlive: false
+    }
+  },
   {
     path: '/course',
     component: () => import('@/views/course/index'),
@@ -42,7 +50,7 @@ export const constantRouterMap = [
   {
     path: '/appStoreCopy',
     component: () => import('@/views/appStoreCopy/index'),
-    meta: {title: '应用管理',keepAlive: false}
+    meta: { title: '应用管理', keepAlive: false }
   },
   {
     path: '/',
@@ -67,15 +75,15 @@ export const constantRouterMap = [
         component: () => import('@/views/eva/index'),
         meta: { title: '观察记录', keepAlive: false }
       },
-			{
-				path: 'appStore',
-				name: 'appStore',
-				component: () => import('@/views/appStore/index'),
-				meta: { title: '应用管理', keepAlive: false }
-			},
+      {
+        path: 'appStore',
+        name: 'appStore',
+        component: () => import('@/views/appStore/index'),
+        meta: { title: '应用管理', keepAlive: false }
+      }
     ]
   },
-	
+
   {
     path: '/classObserve',
     name: 'classObserve',

+ 340 - 0
src/views/wechatAuth/index.vue

@@ -0,0 +1,340 @@
+<template>
+  <div class="wechat-auth-container">
+    <div class="auth-content">
+      <!-- <div class="logo">
+        <img src="@/assets/images/logo.png" alt="Logo" />
+      </div> -->
+
+      <div class="auth-status" v-if="authStatus === 'loading'">
+        <van-loading type="spinner" color="#1989fa" />
+        <p>正在授权中...</p>
+      </div>
+      <!--
+      <div class="auth-status" v-else-if="authStatus === 'success'">
+        <van-icon name="success" color="#07c160" size="48" />
+        <p>授权成功</p>
+        <p class="user-info">{{ userInfo.nickname }}</p>
+      </div> -->
+
+      <div class="auth-status" v-else-if="authStatus === 'error'">
+        <van-icon name="cross" color="#ee0a24" size="48" />
+        <p>授权失败</p>
+        <p class="error-message">{{ errorMessage }}</p>
+        <van-button type="primary" @click="retryAuth">重新授权</van-button>
+      </div>
+
+      <div class="auth-status" v-else>
+        <van-icon name="wechat" color="#07c160" size="48" />
+        <p>微信授权</p>
+        <p class="auth-desc">请点击下方按钮进行微信授权</p>
+        <van-button type="primary" @click="startAuth">开始授权</van-button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapActions } from 'vuex'
+import { wechatAuth, wechatRegister } from '@/api/wechat'
+
+export default {
+  name: 'WechatAuth',
+  data() {
+    return {
+      authStatus: 'init', // init, loading, success, error
+      userInfo: {},
+      errorMessage: '',
+      redirect: '',
+      code: ''
+    }
+  },
+  computed: {
+    // 微信授权配置
+    wechatConfig() {
+      return {
+        appId: 'wxf8a72764a38a40b2',
+        // appId: 'wx3a8dd28881c2c41f',
+        scope: 'snsapi_userinfo', // snsapi_base 或 snsapi_userinfo
+        redirectUri: encodeURIComponent(window.location.origin + '/wechat-auth'),
+        state: 'wechat_auth'
+      }
+    }
+  },
+  watch: {
+    $route: {
+      handler: function(route) {
+        // 从URL中提取参数,包括#之前的参数
+        const url = window.location.href
+        const urlParams = new URLSearchParams(url.split('?')[1]?.split('#')[0] || '')
+
+        this.code = urlParams.get('code') || route.query.code
+        this.state = urlParams.get('state') || route.query.state
+
+        // redirect参数可能在#之后
+        this.redirect = route.query.redirect || this.extractRedirectFromHash()
+
+        console.log('URL参数解析:', {
+          url: url,
+          code: this.code,
+          state: this.state,
+          redirect: this.redirect,
+          routeQuery: route.query
+        })
+      },
+      immediate: true
+    }
+  },
+  methods: {
+    ...mapActions({
+      login: 'user/login',
+      getInfo: 'user/getInfo'
+    }),
+
+    // 开始微信授权
+    startAuth() {
+      this.authStatus = 'loading'
+
+      // 构建微信授权URL
+      const authUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${this.wechatConfig.appId}&redirect_uri=${this.wechatConfig.redirectUri}&response_type=code&scope=${this.wechatConfig.scope}&state=${this.wechatConfig.state}#wechat_redirect`
+
+      // 跳转到微信授权页面
+      window.location.href = authUrl
+    },
+
+    // 处理微信授权回调
+    async handleAuthCallback() {
+      if (!this.code) {
+        this.authStatus = 'error'
+        this.errorMessage = '未获取到授权码'
+        return
+      }
+
+      try {
+        this.authStatus = 'loading'
+
+        // 调用后端接口,用code换取access_token和用户信息
+        const result = await this.exchangeCodeForToken(this.code)
+        console.log(result)
+
+        if (result.openid) {
+          this.userInfo = result
+          this.authStatus = 'success'
+          const res = await wechatRegister({
+            username: result.openid,
+            mail: result.openid + '@wechat.com'
+          })
+          console.log(res)
+
+          // console.log(res)
+          const loginData = JSON.stringify({
+            openid: result.openid,
+            edu: true
+          })
+          const myHeaders = new Headers()
+          myHeaders.append('Content-Type', 'application/json')
+          const requestOptionsLogin = {
+            method: 'POST',
+            headers: myHeaders,
+            body: loginData,
+            redirect: 'follow',
+            credentials: 'include'
+          }
+
+          fetch('https://beta.api.cocorobo.cn/api/user', requestOptionsLogin)
+            .then(response => response.text())
+            .then(() => {
+              this.$router.replace('/login')
+            })
+            .catch(error => {
+              console.log('error', error)
+              setTimeout(() => {
+                this.$router.replace('/login')
+              }, 2000)
+            })
+        } else {
+          throw new Error(result.message || '授权失败')
+        }
+      } catch (error) {
+        console.error('微信授权失败:', error)
+        this.authStatus = 'error'
+        this.errorMessage = error.message || '授权失败,请重试'
+
+        // 如果授权失败,跳转到登录页面
+        setTimeout(() => {
+          this.$router.replace('/login')
+        }, 2000)
+      }
+    },
+
+    // 用code换取access_token和用户信息
+    async exchangeCodeForToken(code) {
+      try {
+        const response = await wechatAuth({
+          code: code,
+          state: this.state
+        })
+
+        // 根据实际API响应格式调整
+        if (response && response.data) {
+          return response.data
+        } else if (response && response.success !== undefined) {
+          return response
+        } else {
+          // 如果API还没有实现,模拟成功响应
+          return {
+            success: true,
+            userInfo: {
+              openid: 'test_openid_' + Date.now(),
+              nickname: '微信用户',
+              headimgurl: '',
+              unionid: 'test_unionid_' + Date.now()
+            }
+          }
+        }
+      } catch (error) {
+        console.error('API调用失败:', error)
+      }
+    },
+    // 跳转到目标页面
+    redirectToTarget() {
+      let targetPath = '/'
+
+      // 使用已解析的redirect参数
+      if (this.redirect) {
+        targetPath = this.redirect
+      }
+
+      console.log('跳转到目标页面:', targetPath)
+      this.$router.replace(targetPath)
+    },
+
+    // 重试授权
+    retryAuth() {
+      this.authStatus = 'init'
+      this.errorMessage = ''
+      this.startAuth()
+    },
+
+    // 检查是否在微信浏览器中
+    isWechatBrowser() {
+      const ua = navigator.userAgent.toLowerCase()
+      return ua.indexOf('micromessenger') !== -1
+    },
+
+    // 从URL hash中提取redirect参数
+    extractRedirectFromHash() {
+      const hash = window.location.hash
+      if (hash && hash.includes('redirect=')) {
+        const match = hash.match(/redirect=([^&]+)/)
+        if (match) {
+          return decodeURIComponent(match[1])
+        }
+      }
+      return null
+    }
+  },
+
+  mounted() {
+    // 检查是否在微信浏览器中
+    if (!this.isWechatBrowser()) {
+      this.authStatus = 'error'
+      this.errorMessage = '请在微信中打开此页面'
+      return
+    }
+
+    // 如果有code参数,说明是从微信授权回调过来的
+    if (this.code) {
+      this.handleAuthCallback()
+    } else {
+      // 没有code参数,开始授权流程
+      this.startAuth()
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.wechat-auth-container {
+  min-height: 100vh;
+  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  padding: 20px;
+
+  .auth-content {
+    background: white;
+    border-radius: 16px;
+    padding: 40px 30px;
+    text-align: center;
+    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
+    max-width: 400px;
+    width: 100%;
+
+    .logo {
+      margin-bottom: 30px;
+
+      img {
+        width: 80px;
+        height: 80px;
+        border-radius: 50%;
+      }
+    }
+
+    .auth-status {
+      .van-loading,
+      .van-icon {
+        margin-bottom: 20px;
+      }
+
+      p {
+        margin: 10px 0;
+        font-size: 16px;
+        color: #333;
+
+        &.user-info {
+          font-size: 14px;
+          color: #666;
+          margin-top: 10px;
+        }
+
+        &.auth-desc {
+          font-size: 14px;
+          color: #999;
+          margin: 15px 0 25px;
+        }
+
+        &.error-message {
+          font-size: 14px;
+          color: #ee0a24;
+          margin: 15px 0 25px;
+        }
+      }
+
+      .van-button {
+        margin-top: 20px;
+        width: 200px;
+        height: 44px;
+        border-radius: 22px;
+      }
+    }
+  }
+}
+
+// 响应式设计
+@media (max-width: 480px) {
+  .wechat-auth-container {
+    padding: 10px;
+
+    .auth-content {
+      padding: 30px 20px;
+
+      .auth-status {
+        .van-button {
+          width: 100%;
+        }
+      }
+    }
+  }
+}
+</style>

Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff