Browse Source

Merge branch 'master' of https://git.cocorobo.cn/CocoRoboLabs/pbl-app

SanHQin 2 months ago
parent
commit
f33739245f
72 changed files with 1063 additions and 448 deletions
  1. 0 0
      dist/index.html
  2. 4 0
      dist/report.html
  3. 0 0
      dist/static/css/app.ba4eed89.css
  4. 0 1
      dist/static/css/chunk-17e66bfc.c94776c5.css
  5. 0 0
      dist/static/css/chunk-1aab73ec.881e8204.css
  6. 1 0
      dist/static/css/chunk-2ba95b61.2f601688.css
  7. 1 0
      dist/static/css/chunk-7f794d4e.ce137eb8.css
  8. 0 0
      dist/static/css/chunk-b40d50ca.56c23762.css
  9. 1 1
      dist/static/css/chunk-d4d28b52.5dd7065d.css
  10. 0 0
      dist/static/img/Union.953680c6.svg
  11. 0 0
      dist/static/img/delFile.b454d74e.svg
  12. 0 5
      dist/static/img/tel.747b262a.svg
  13. 0 0
      dist/static/img/videoFile.8b2406f2.svg
  14. 0 0
      dist/static/js/app.9adb1279.js
  15. 0 0
      dist/static/js/app.db776c4e.js
  16. 0 0
      dist/static/js/chunk-00b34a2c.c7e8b15a.js
  17. 0 0
      dist/static/js/chunk-01979dd3.c9735726.js
  18. 0 0
      dist/static/js/chunk-01979dd3.f3236b6c.js
  19. 0 0
      dist/static/js/chunk-01c5f272.14c996b9.js
  20. 0 0
      dist/static/js/chunk-03851ecf.9519877d.js
  21. 0 0
      dist/static/js/chunk-03851ecf.da18759c.js
  22. 0 0
      dist/static/js/chunk-07b980da.1b24e096.js
  23. 0 0
      dist/static/js/chunk-0e29728a.516dc24c.js
  24. 0 0
      dist/static/js/chunk-0e29728a.c1f229f5.js
  25. 0 0
      dist/static/js/chunk-1678db47.541df83d.js
  26. 0 0
      dist/static/js/chunk-1738a278.841c52f9.js
  27. 0 1
      dist/static/js/chunk-17e66bfc.e1127648.js
  28. 0 0
      dist/static/js/chunk-18ea3bfa.46cc7005.js
  29. 0 0
      dist/static/js/chunk-1a806098.e89ffabe.js
  30. 0 0
      dist/static/js/chunk-1aab73ec.b8834f63.js
  31. 0 0
      dist/static/js/chunk-1eb03832.48d36a1e.js
  32. 0 0
      dist/static/js/chunk-247d1cc7.0f517fcd.js
  33. 0 0
      dist/static/js/chunk-247d1cc7.415d5bfe.js
  34. 0 0
      dist/static/js/chunk-284ddcf3.41750d95.js
  35. 1 0
      dist/static/js/chunk-2ba95b61.ecd74c0b.js
  36. 0 0
      dist/static/js/chunk-2d0c7336.5464938b.js
  37. 0 0
      dist/static/js/chunk-2d0c7336.707392c1.js
  38. 0 0
      dist/static/js/chunk-2fc6aeae.23884e99.js
  39. 1 1
      dist/static/js/chunk-30b5de98.42d056b7.js
  40. 0 0
      dist/static/js/chunk-35d65314.96fda2ad.js
  41. 0 0
      dist/static/js/chunk-55e3fa90.0bb3afc5.js
  42. 0 0
      dist/static/js/chunk-55e3fa90.c8d9c3e3.js
  43. 0 0
      dist/static/js/chunk-5bb2a616.cb003f93.js
  44. 0 0
      dist/static/js/chunk-60b2ab15.bf31f0ff.js
  45. 0 0
      dist/static/js/chunk-61b307f8.76d3a8c6.js
  46. 0 0
      dist/static/js/chunk-67c4ee97.03123001.js
  47. 0 0
      dist/static/js/chunk-6ad98842.d4ffdd60.js
  48. 0 0
      dist/static/js/chunk-6e5f7eb4.1ad93511.js
  49. 0 0
      dist/static/js/chunk-793d7e56.57eb242b.js
  50. 0 0
      dist/static/js/chunk-7caf3a38.ed044c8f.js
  51. 0 0
      dist/static/js/chunk-7d4543c8.f800adaa.js
  52. 0 0
      dist/static/js/chunk-7f794d4e.da2e5d01.js
  53. 0 0
      dist/static/js/chunk-81a47c5e.f9e0b7c9.js
  54. 0 0
      dist/static/js/chunk-870f2882.2e55723f.js
  55. 0 0
      dist/static/js/chunk-970a3cc0.f9bacf9a.js
  56. 0 0
      dist/static/js/chunk-b265f6f8.5b14ed34.js
  57. 0 0
      dist/static/js/chunk-b40d50ca.95fb3681.js
  58. 0 0
      dist/static/js/chunk-c3be65e4.4e411d8f.js
  59. 0 0
      dist/static/js/chunk-d3f058fe.9bf03846.js
  60. 0 0
      dist/static/js/chunk-d3f058fe.a0ffef66.js
  61. 1 0
      dist/static/js/chunk-d4d28b52.94630a20.js
  62. 0 0
      dist/static/js/chunk-libs.4406bd5f.js
  63. 0 0
      dist/static/js/chunk-libs.d370c650.js
  64. 2 1
      public/index.html
  65. 70 0
      src/api/wechat.js
  66. 78 14
      src/permission.js
  67. 17 9
      src/router/router.config.js
  68. 4 4
      src/store/modules/user.js
  69. 101 101
      src/views/appStoreCopy/components/userInfoPage.vue
  70. 316 309
      src/views/appStoreCopy/index.vue
  71. 14 1
      src/views/login/index.vue
  72. 451 0
      src/views/wechatAuth/index.vue

File diff suppressed because it is too large
+ 0 - 0
dist/index.html


File diff suppressed because it is too large
+ 4 - 0
dist/report.html


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


+ 0 - 1
dist/static/css/chunk-17e66bfc.c94776c5.css

@@ -1 +0,0 @@
-.loginBox[data-v-02bea5b8]{position:relative;width:100vw;height:100vh;overflow:hidden}.loginBox>iframe[data-v-02bea5b8]{width:100%;height:100%;border:0}

File diff suppressed because it is too large
+ 0 - 0
dist/static/css/chunk-1aab73ec.881e8204.css


+ 1 - 0
dist/static/css/chunk-2ba95b61.2f601688.css

@@ -0,0 +1 @@
+.loginBox[data-v-c107d002]{position:relative;width:100vw;height:100vh;overflow:hidden}.loginBox>iframe[data-v-c107d002]{width:100%;height:100%;border:0}

+ 1 - 0
dist/static/css/chunk-7f794d4e.ce137eb8.css

@@ -0,0 +1 @@
+.wechat-auth-container[data-v-260bba66]{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-260bba66]{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-260bba66]{margin-bottom:.8rem}.wechat-auth-container .auth-content .logo img[data-v-260bba66]{width:2.13333rem;height:2.13333rem;border-radius:50%}.wechat-auth-container .auth-content .auth-status .van-icon[data-v-260bba66],.wechat-auth-container .auth-content .auth-status .van-loading[data-v-260bba66]{margin-bottom:.53333rem}.wechat-auth-container .auth-content .auth-status p[data-v-260bba66]{margin:.26667rem 0;font-size:.42667rem;color:#333}.wechat-auth-container .auth-content .auth-status p.user-info[data-v-260bba66]{font-size:.37333rem;color:#666;margin-top:.26667rem}.wechat-auth-container .auth-content .auth-status p.auth-desc[data-v-260bba66]{font-size:.37333rem;color:#999;margin:.4rem 0 .66667rem}.wechat-auth-container .auth-content .auth-status p.error-message[data-v-260bba66]{font-size:.37333rem;color:#ee0a24;margin:.4rem 0 .66667rem}.wechat-auth-container .auth-content .auth-status .van-button[data-v-260bba66]{margin-top:.53333rem;width:5.33333rem;height:1.17333rem;border-radius:.58667rem}@media (max-width:480px){.wechat-auth-container[data-v-260bba66]{padding:.26667rem}.wechat-auth-container .auth-content[data-v-260bba66]{padding:.8rem .53333rem}.wechat-auth-container .auth-content .auth-status .van-button[data-v-260bba66]{width:100%}}

File diff suppressed because it is too large
+ 0 - 0
dist/static/css/chunk-b40d50ca.56c23762.css


+ 1 - 1
dist/static/css/chunk-1eb03832.4e6bc751.css → dist/static/css/chunk-d4d28b52.5dd7065d.css

@@ -1 +1 @@
-.appStore[data-v-3536b7cc]{width:100vw;height:100vh;background-color:#f9f8f8;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;overflow:auto}.appStore[data-v-3536b7cc],.topC[data-v-3536b7cc]{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.topC[data-v-3536b7cc]{-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;width:100%;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;height:1.33333rem;padding:0 .32rem;position:relative;font-family:PingFang HK;font-weight:600;font-size:.4rem;line-height:.53333rem;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0}.topC img[data-v-3536b7cc]{position:absolute;top:50%;left:.26667rem;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);width:.61333rem}.infoCon[data-v-3536b7cc]{margin-top:.93333rem;padding:.4rem;box-sizing:border-box;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:.26667rem;font-family:PingFang HK;font-weight:400;font-size:.37333rem}.infoCon .Blo[data-v-3536b7cc],.infoCon[data-v-3536b7cc]{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.infoCon .Blo[data-v-3536b7cc]{-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;background:#fff;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;padding:.4rem .53333rem;border-radius:.26667rem}
+.appStore[data-v-6ef79dc2]{width:100vw;height:100vh;background-color:#f9f8f8;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;overflow:auto}.appStore[data-v-6ef79dc2],.topC[data-v-6ef79dc2]{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.topC[data-v-6ef79dc2]{-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;width:100%;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;height:1.33333rem;padding:0 .32rem;position:relative;font-family:PingFang HK;font-weight:600;font-size:.4rem;line-height:.53333rem;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0}.topC img[data-v-6ef79dc2]{position:absolute;top:50%;left:.26667rem;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);width:.61333rem}.infoCon[data-v-6ef79dc2]{margin-top:.93333rem;padding:.4rem;box-sizing:border-box;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:.26667rem;font-family:PingFang HK;font-weight:400;font-size:.37333rem}.infoCon .Blo[data-v-6ef79dc2],.infoCon[data-v-6ef79dc2]{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.infoCon .Blo[data-v-6ef79dc2]{-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;background:#fff;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;padding:.4rem .53333rem;border-radius:.26667rem}

+ 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 - 5
dist/static/img/tel.747b262a.svg

@@ -1,5 +0,0 @@
-<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
-<rect width="24" height="24" rx="12" fill="#D9D9D9"/>
-<path d="M15 5C15.2652 5 15.5196 5.10536 15.7071 5.29289C15.8946 5.48043 16 5.73478 16 6V18C16 18.2652 15.8946 18.5196 15.7071 18.7071C15.5196 18.8946 15.2652 19 15 19H9C8.73478 19 8.48043 18.8946 8.29289 18.7071C8.10536 18.5196 8 18.2652 8 18V6C8 5.73478 8.10536 5.48043 8.29289 5.29289C8.48043 5.10536 8.73478 5 9 5H15ZM9 4C8.46957 4 7.96086 4.21071 7.58579 4.58579C7.21071 4.96086 7 5.46957 7 6V18C7 18.5304 7.21071 19.0391 7.58579 19.4142C7.96086 19.7893 8.46957 20 9 20H15C15.5304 20 16.0391 19.7893 16.4142 19.4142C16.7893 19.0391 17 18.5304 17 18V6C17 5.46957 16.7893 4.96086 16.4142 4.58579C16.0391 4.21071 15.5304 4 15 4H9Z" fill="#0663FE"/>
-<path d="M12 18C12.2652 18 12.5196 17.8946 12.7071 17.7071C12.8946 17.5196 13 17.2652 13 17C13 16.7348 12.8946 16.4804 12.7071 16.2929C12.5196 16.1054 12.2652 16 12 16C11.7348 16 11.4804 16.1054 11.2929 16.2929C11.1054 16.4804 11 16.7348 11 17C11 17.2652 11.1054 17.5196 11.2929 17.7071C11.4804 17.8946 11.7348 18 12 18Z" fill="#0663FE"/>
-</svg>

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


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/app.9adb1279.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/app.db776c4e.js


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


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-01979dd3.c9735726.js


File diff suppressed because it is too large
+ 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


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-03851ecf.9519877d.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-03851ecf.da18759c.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-07b980da.1b24e096.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-0e29728a.516dc24c.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-0e29728a.c1f229f5.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-1678db47.541df83d.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-1738a278.841c52f9.js


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

@@ -1 +0,0 @@
-(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-17e66bfc"],{2915:function(t,e,n){},"9ed6":function(t,e,n){"use strict";n.r(e);var r=function(){var t=this;t._self._c;return t._m(0)},i=[function(){var t=this,e=t._self._c;return e("div",{staticClass:"loginBox"},[e("iframe",{attrs:{src:"//edu.cocorobo.cn/course/login?type=2",frameborder:"0"}})])}],c=n("c7eb"),o=n("1da1"),u=n("5530"),s=(n("14d9"),n("2f62")),a={data:function(){return{redirect:void 0,timer:null}},watch:{$route:{handler:function(t){this.redirect=t.query&&t.query.redirect},immediate:!0}},methods:Object(u["a"])(Object(u["a"])({},Object(s["b"])({login:"user/login"})),{},{handleLogin:function(){this.$router.push({path:this.redirect||"/"})},getLogin:function(){var t=this;return Object(o["a"])(Object(c["a"])().mark((function e(){var n;return Object(c["a"])().wrap((function(e){while(1)switch(e.prev=e.next){case 0:return e.next=2,t.login();case 2:n=e.sent,n&&t.$router.push({path:t.redirect||"/"});case 4:case"end":return e.stop()}}),e)})))()}}),beforeDestroy:function(){clearInterval(this.timer),this.timer=null},mounted:function(){var t=this;this.getLogin(),this.timer=setInterval((function(){t.getLogin()}),2e3)}},f=a,h=(n("9ff3"),n("2877")),l=Object(h["a"])(f,r,i,!1,null,"02bea5b8",null);e["default"]=l.exports},"9ff3":function(t,e,n){"use strict";n("2915")}}]);

File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-18ea3bfa.46cc7005.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-1a806098.e89ffabe.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-1aab73ec.b8834f63.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-1eb03832.48d36a1e.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-247d1cc7.0f517fcd.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-247d1cc7.415d5bfe.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-284ddcf3.41750d95.js


+ 1 - 0
dist/static/js/chunk-2ba95b61.ecd74c0b.js

@@ -0,0 +1 @@
+(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2ba95b61"],{3015:function(e,t,n){"use strict";n("d209")},"9ed6":function(e,t,n){"use strict";n.r(t);var r=function(){var e=this;e._self._c;return e._m(0)},i=[function(){var e=this,t=e._self._c;return t("div",{staticClass:"loginBox"},[t("iframe",{attrs:{src:"//edu.cocorobo.cn/course/login?type=2",frameborder:"0"}})])}],c=n("c7eb"),o=n("1da1"),a=n("5530"),s=(n("14d9"),n("2f62")),u=n("852e"),d=n.n(u),l={data:function(){return{redirect:void 0,timer:null}},watch:{$route:{handler:function(e){this.redirect=e.query&&e.query.redirect},immediate:!0}},methods:Object(a["a"])(Object(a["a"])({},Object(s["b"])({login:"user/login"})),{},{handleLogin:function(){this.$router.push({path:this.redirect||"/"})},getLogin:function(){var e=this;return Object(o["a"])(Object(c["a"])().mark((function t(){var n,r;return Object(c["a"])().wrap((function(t){while(1)switch(t.prev=t.next){case 0:return t.next=2,e.login();case 2:n=t.sent,r=d.a.get("redirectUri"),r&&"undefined"!==r||(r=""),console.log(r),n&&(r?window.location.href=r:e.$router.push({path:e.redirect||"/"}));case 7:case"end":return t.stop()}}),t)})))()}}),beforeDestroy:function(){clearInterval(this.timer),this.timer=null},mounted:function(){var e=this;d.a.set("isWeChat","1"),this.getLogin(),this.timer=setInterval((function(){e.getLogin()}),2e3)}},h=l,f=(n("3015"),n("2877")),b=Object(f["a"])(h,r,i,!1,null,"c107d002",null);t["default"]=b.exports},d209:function(e,t,n){}}]);

File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-2d0c7336.5464938b.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-2d0c7336.707392c1.js


File diff suppressed because it is too large
+ 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")}}]);

File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-35d65314.96fda2ad.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-55e3fa90.0bb3afc5.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-55e3fa90.c8d9c3e3.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-5bb2a616.cb003f93.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-60b2ab15.bf31f0ff.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-61b307f8.76d3a8c6.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-67c4ee97.03123001.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-6ad98842.d4ffdd60.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-6e5f7eb4.1ad93511.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-793d7e56.57eb242b.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-7caf3a38.ed044c8f.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-7d4543c8.f800adaa.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-7f794d4e.da2e5d01.js


File diff suppressed because it is too large
+ 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


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-b265f6f8.5b14ed34.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-b40d50ca.95fb3681.js


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


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-d3f058fe.9bf03846.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-d3f058fe.a0ffef66.js


+ 1 - 0
dist/static/js/chunk-d4d28b52.94630a20.js

@@ -0,0 +1 @@
+(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-d4d28b52"],{"1d10":function(t,s,c){"use strict";c("9b27")},"3e4a":function(t,s,c){t.exports=c.p+"static/img/backPage.1a3c5583.svg"},"61ba":function(t,s,c){t.exports=c.p+"static/img/sch.bc3dc09a.svg"},"9b27":function(t,s,c){},c928:function(t,s,c){t.exports=c.p+"static/img/logOut.c89838e6.svg"},fe96:function(t,s,c){"use strict";c.r(s);var i=function(){var t=this,s=t._self._c;return s("div",{staticClass:"appStore"},[s("div",{staticClass:"topC"},[s("img",{attrs:{src:c("3e4a"),alt:""},on:{click:t.backPage}}),s("div",[t._v(t._s(t.userinfo.username))])]),s("div",{staticClass:"infoCon"},[s("div",{staticStyle:{"font-size":"14px"}},[t._v("账户")]),s("div",{staticClass:"Blo"},[t._m(0),s("span",{staticStyle:{color:"#969BA3"}},[t._v(t._s(t.userinfo.schoolName))])]),s("div",{staticClass:"Blo",on:{click:t.exitLogin}},[t._m(1)])])])},e=[function(){var t=this,s=t._self._c;return s("div",{staticStyle:{display:"flex","align-items":"center",gap:"10px"}},[s("img",{attrs:{src:c("61ba"),alt:""}}),t._v(" 学校 ")])},function(){var t=this,s=t._self._c;return s("div",{staticStyle:{display:"flex","align-items":"center",gap:"10px"}},[s("img",{attrs:{src:c("c928"),alt:""}}),t._v(" 退出登录 ")])}],a=c("5530"),n=(c("14d9"),c("2f62")),o=c("c24f"),r={data:function(){return{}},computed:Object(a["a"])({},Object(n["c"])(["userinfo"])),methods:{backPage:function(){this.$router.push("/appStoreCopy")},exitLogin:function(){var t=this;this.$dialog({message:"是否现在退出登录?你将回到登录界面",showCancelButton:!0,beforeClose:function(s,c){"confirm"===s?Object(o["c"])().then((function(s){t.$toast({message:"退出成功",type:"success"}),t.$store.dispatch("user/logout"),window.location.reload(),c()})).catch((function(t){console.error(t),c()})):c()}})}}},l=r,u=(c("1d10"),c("2877")),f=Object(u["a"])(l,i,e,!1,null,"6ef79dc2",null);s["default"]=f.exports}}]);

File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-libs.4406bd5f.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-libs.d370c650.js


+ 2 - 1
public/index.html

@@ -43,5 +43,6 @@
 
 </html>
 <script>
-  document.domain = "cocorobo.cn"
+  // document.domain = "cocorobo.cn"
+  document.domain = document.domain.split(".").slice(-2).join(".");
 </script>

+ 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-get-user-info',
+    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
+  })
+}

+ 78 - 14
src/permission.js

@@ -3,10 +3,13 @@ import store from './store'
 import NProgress from 'nprogress' // progress bar
 import 'nprogress/nprogress.css' // progress bar style
 // import { getToken } from '@/utils/auth' // get token from cookie
+import Cookies from 'js-cookie'
+import { getToken } from '@/utils/auth'
+import { loginOut } from '@/api/user'
 
 NProgress.configure({ showSpinner: false }) // NProgress Configuration
 
-const whiteList = ['/login', '/resetpassword', '/help', '/echarts'] // no redirect whitelist
+const whiteList = ['/login', '/resetpassword', '/help', '/echarts', '/login2'] // no redirect whitelist
 
 // eslint-disable-next-line prettier/prettier
 router.beforeEach(async(to, from, next) => {
@@ -16,8 +19,8 @@ router.beforeEach(async(to, from, next) => {
 
   // determine whether the user has logged in
   // const hasToken = getToken()
-  const hasToken = store.getters.id
-
+  const hasToken = store.getters.id || getToken()
+  const isWeChat = Cookies.get('isWeChat')
   if (to.query.courseid !== '' && to.query.courseid !== undefined) {
     console.log(to.query.courseid)
     await store.commit('SET_COURSEID', to.query.courseid)
@@ -26,28 +29,70 @@ 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) {
     await store.commit('SET_SHARECOURSEID', shareCourseId)
   }
   if (hasToken) {
-    if (to.path === '/login') {
+    await store.commit('user/SET_ID', hasToken)
+    if (to.path === '/login' || to.path === '/login2') {
       // if is logged in, redirect to the home page
-
-      next({ path: '/' })
+      store.commit('user/SET_ID', hasToken)
+      if (isWeChat === '1') {
+        next({ path: '/' })
+      } else {
+        const queryParams = new URLSearchParams({
+          redirect_uri: to.query.url,
+          // 可以添加其他需要的参数
+          timestamp: Date.now().toString()
+        }).toString()
+        const redirect_uri = to.query.url ? encodeURIComponent(queryParams) : ''
+        const isApp = to.query.isApp ? to.query.isApp : '2'
+        if (isApp === '2' && redirect_uri) {
+          window.location.href = `weixin://dl/business/?appid=wxf8a72764a38a40b2&path=pages/index/index&query=${redirect_uri}`
+        } else if (redirect_uri) {
+          window.location.href = redirect_uri
+        } else {
+          next({ path: '/appStoreCopy' })
+        }
+      }
       NProgress.done()
     } else {
       const userinfo = store.getters.userinfo && Object.keys(store.getters.userinfo).length > 0
       console.log('store.getters', store.getters)
+      console.log('store.getters.userinfo', store.getters.userinfo)
+      console.log('isWeChat', isWeChat)
       console.log('userinfo', userinfo)
       // console.log('to', {...to} )
       if (userinfo) {
-        next()
+        console.log(store)
+        if (isWeChat === '1' || to.path === '/appStoreCopy' || to.path === '/searchL' || to.path === '/userInfoPage') {
+          next()
+        } else if (isWeChat === '2') {
+          const courseId = store.getters.courseId
+          const testId = store.getters.testId
+          const shareCourseId = store.getters.shareCourseId
+          if (courseId || testId || shareCourseId) {
+            Cookies.set('isWeChat', '1')
+            loginOut().then(async res => {
+              await store.dispatch('user/logout')
+              await store.commit('user/SET_ID', '')
+              next(`/login2?redirect=${to.path}`)
+            })
+          } else {
+            Cookies.set('isWeChat', '2')
+            next('/appStoreCopy')
+          }
+        } else {
+          next()
+        }
+        NProgress.done()
       } else {
         try {
           // 获取用户信息
+          console.log(store)
           const data = await store.dispatch('user/getInfo')
           await store.commit('user/SET_USERINFO', data)
           const courseId = store.getters.courseId
@@ -58,11 +103,15 @@ router.beforeEach(async(to, from, next) => {
           await store.commit('SET_SHARECOURSEID', '')
           // // 根据角色生成可访问的路线图
           if (courseId) {
-            next({ ...to, query: { courseid: courseId }, replace: true })
+            next({ ...to, query: { courseid: courseId, userid: hasToken }, replace: true })
           } else if (testId) {
-            next({ ...to, query: { courseid: testId }, replace: true })
+            next({ ...to, query: { courseid: testId, userid: hasToken }, replace: true })
           } else if (shareCourseId) {
-            next({ path: '/courseDetail', query: { courseid: shareCourseId, urlType: 1 }, replace: true })
+            next({
+              path: '/courseDetail',
+              query: { courseid: shareCourseId, urlType: 1, userid: hasToken },
+              replace: true
+            })
           } else {
             next({ ...to, replace: true })
           }
@@ -70,6 +119,7 @@ router.beforeEach(async(to, from, next) => {
           // remove token and go to login page to re-login
           // await store.dispatch('user/resetToken')
           // Notify({ type: 'danger', message: error || '发生异常' })
+          console.error(error)
           next(`/login?redirect=${to.path}`)
           NProgress.done()
         }
@@ -82,9 +132,23 @@ 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()
+      const courseId = store.getters.courseId
+      const testId = store.getters.testId
+      const shareCourseId = store.getters.shareCourseId
+
+      // 检查是否是微信授权回调
+      if (courseId || testId || shareCourseId) {
+        next(`/login2?redirect=${to.path}`)
+        NProgress.done()
+      } else if (window.location.href.indexOf('login') !== -1 && window.location.href.indexOf('login2') === -1) {
+        // 微信授权回调,允许访问
+        next('/login')
+        NProgress.done()
+      } else {
+        //   // other pages that do not have permission to access are redirected to the login page.
+        next(`/login`)
+        NProgress.done()
+      }
     }
   }
 })

+ 17 - 9
src/router/router.config.js

@@ -8,13 +8,21 @@ export const constantRouterMap = [
     redirect: '/home'
   },
   {
-    path: '/login',
+    path: '/login2',
     component: () => import('@/views/login/index'),
     meta: {
       title: '登录',
       keepAlive: false
     }
   },
+  {
+    path: '/login',
+    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',

+ 4 - 4
src/store/modules/user.js

@@ -76,10 +76,10 @@ const actions = {
           resolve(_user.userid)
         })
         .catch(error => {
-          //   var _user = { userid: '6c56ec0e-2c74-11ef-bee5-005056b86db5' }
-          //   commit('SET_ID', _user.userid)
-          //   setToken(_user.userid)
-          //   resolve(_user.userid)
+          // var _user = { userid: '6c56ec0e-2c74-11ef-bee5-005056b86db5' }
+          // commit('SET_ID', _user.userid)
+          // setToken(_user.userid)
+          // resolve(_user.userid)
           reject(error)
         })
     })

+ 101 - 101
src/views/appStoreCopy/components/userInfoPage.vue

@@ -1,83 +1,80 @@
 <template>
-    <div class="appStore">
-        <div class="topC">
-            <img  @click="backPage" src="../../../assets/images/appStoreCopy/backPage.svg" alt="">
-            <div>{{ userinfo.username }}</div>
+  <div class="appStore">
+    <div class="topC">
+      <img @click="backPage" src="../../../assets/images/appStoreCopy/backPage.svg" alt="" />
+      <div>{{ userinfo.username }}</div>
+    </div>
+    <div class="infoCon">
+      <div style="font-size: 14px;">账户</div>
+      <!-- <div class="Blo">
+        <div style="display: flex;align-items: center;gap: 10px;">
+          <img src="../../../assets/images/appStoreCopy/tel.svg" alt="" />
+          账号
         </div>
-        <div class="infoCon">
-            <div style="font-size: 14px;">账户</div>
-            <div class="Blo">
-                <div style="display: flex;align-items: center;gap: 10px;">
-                    <img src="../../../assets/images/appStoreCopy/tel.svg" alt="">
-                    账号
-                </div>
-                <span style="color: #969BA3;">{{ userinfo.accountNumber }}</span>
-            </div>
-            <div class="Blo">
-                <div style="display: flex;align-items: center;gap: 10px;">
-                    <img src="../../../assets/images/appStoreCopy/sch.svg" alt="">
-                    学校
-                </div>
-                <span style="color: #969BA3;">{{ userinfo.schoolName }}</span>
-            </div>
-            <div @click="exitLogin" class="Blo">
-                <div style="display: flex;align-items: center;gap: 10px;">
-                    <img src="../../../assets/images/appStoreCopy/logOut.svg" alt="">
-                    退出登录
-                </div>
-            </div>
+        <span style="color: #969BA3;">{{ userinfo.accountNumber }}</span>
+      </div> -->
+      <div class="Blo">
+        <div style="display: flex;align-items: center;gap: 10px;">
+          <img src="../../../assets/images/appStoreCopy/sch.svg" alt="" />
+          学校
         </div>
-
+        <span style="color: #969BA3;">{{ userinfo.schoolName }}</span>
+      </div>
+      <div @click="exitLogin" class="Blo">
+        <div style="display: flex;align-items: center;gap: 10px;">
+          <img src="../../../assets/images/appStoreCopy/logOut.svg" alt="" />
+          退出登录
+        </div>
+      </div>
     </div>
+  </div>
 </template>
 
 <script>
 import { mapGetters } from 'vuex'
 import { loginOut } from '@/api/user'
 
-    export default {
-        data(){
-            return{
-
-            }
-        },
-        computed: {
-            ...mapGetters(['userinfo']),
-        },
-        methods:{
-            backPage(){
-                this.$router.push('/appStoreCopy')
-            },
-            // 退出登录
-            exitLogin() {
-                this.$dialog({
-                    message: '是否现在退出登录?你将回到登录界面',
-                    showCancelButton: true,
-                    beforeClose: (action, done) => {
-                    if (action === 'confirm') {
-                        loginOut()
-                        .then(res => {
-                            this.$toast({
-                            message: '退出成功',
-                            type: 'success'
-                            })
-                            this.$store.dispatch('user/logout')
-                            window.location.reload()
-                            done()
-                        })
-                        .catch(err => {
-                            console.error(err)
-                            done()
-                        })
-                    } else {
-                        // 拦截取消操作
-                        done()
-                    }
-                    }
+export default {
+  data() {
+    return {}
+  },
+  computed: {
+    ...mapGetters(['userinfo'])
+  },
+  methods: {
+    backPage() {
+      this.$router.push('/appStoreCopy')
+    },
+    // 退出登录
+    exitLogin() {
+      this.$dialog({
+        message: '是否现在退出登录?你将回到登录界面',
+        showCancelButton: true,
+        beforeClose: (action, done) => {
+          if (action === 'confirm') {
+            loginOut()
+              .then(res => {
+                this.$toast({
+                  message: '退出成功',
+                  type: 'success'
                 })
-            },
+                this.$store.dispatch('user/logout')
+                window.location.reload()
+                done()
+              })
+              .catch(err => {
+                console.error(err)
+                done()
+              })
+          } else {
+            // 拦截取消操作
+            done()
+          }
         }
+      })
     }
+  }
+}
 </script>
 
 <style lang="scss" scoped>
@@ -92,42 +89,45 @@ import { loginOut } from '@/api/user'
   overflow: auto;
 }
 .topC {
-    display: flex;
-    justify-content: center;
-    width: 100%;
-    align-items: center;
-    height: 50px;
-    padding: 0px 12px;
-    box-sizing: border-box;
-    position: relative;
-    font-family: PingFang HK;
-    font-weight: 600;
-    font-size: 15px;
-    line-height: 20px;
-    flex-shrink: 0;
-  img{
-    position: absolute;top: 50%;left: 10px;transform: translate(0,-50%);
+  display: flex;
+  justify-content: center;
+  width: 100%;
+  align-items: center;
+  height: 50px;
+  padding: 0px 12px;
+  box-sizing: border-box;
+  position: relative;
+  font-family: PingFang HK;
+  font-weight: 600;
+  font-size: 15px;
+  line-height: 20px;
+  flex-shrink: 0;
+  img {
+    position: absolute;
+    top: 50%;
+    left: 10px;
+    transform: translate(0, -50%);
     width: 23px;
   }
 }
-.infoCon{
-    margin-top: 35px;
-    padding: 15px;
-    box-sizing: border-box;
-    display: flex;
-    flex-direction: column;
-    gap: 10px;
-    font-family: PingFang HK;
-    font-weight: 400;
-    font-size: 14px;
+.infoCon {
+  margin-top: 35px;
+  padding: 15px;
+  box-sizing: border-box;
+  display: flex;
+  flex-direction: column;
+  gap: 10px;
+  font-family: PingFang HK;
+  font-weight: 400;
+  font-size: 14px;
 
-    .Blo{
-        display: flex;
-        justify-content: space-between;
-        background: #fff;
-        align-items: center;
-        padding: 15px 20px;
-        border-radius: 10px;
-    }
+  .Blo {
+    display: flex;
+    justify-content: space-between;
+    background: #fff;
+    align-items: center;
+    padding: 15px 20px;
+    border-radius: 10px;
+  }
 }
-</style>
+</style>

+ 316 - 309
src/views/appStoreCopy/index.vue

@@ -23,7 +23,7 @@
         get-container="#appStoreCon"
         position="left"
         :overlay-style="{ opacity: 0 }"
-        :style="{ height: '92vh', transform: 'translate3d(0,0%, 0)', width: '45%', minWidth: '150px', opacity: .95}"
+        :style="{ height: '92vh', transform: 'translate3d(0,0%, 0)', width: '45%', minWidth: '150px', opacity: 0.95 }"
       >
         <div class="popupCon">
           <div class="popTop">
@@ -33,16 +33,20 @@
             <!-- <div>关注公众号</div> -->
           </div>
           <div class="popupBot" @click="goInfo">
-            <img style="width: 40px;height: 100%;object-fit: contain;color: #000;" src="../../assets/images/appStoreCopy/toux.png" alt="" />
+            <img
+              style="width: 40px;height: 100%;object-fit: contain;color: #000;"
+              src="../../assets/images/appStoreCopy/toux.png"
+              alt=""
+            />
             <div style="flex: 1;display: flex;flex-direction: column;gap: 5px;">
               <div style="font-size: 16px;font-weight: 600;">{{ userinfo.name }}</div>
-              <div style="overflow: hidden;text-overflow: ellipsis;white-space: nowrap;">{{ userSuffix() }}</div>
+              <!-- <div style="overflow: hidden;text-overflow: ellipsis;white-space: nowrap;">{{ userSuffix() }}</div> -->
             </div>
           </div>
         </div>
       </van-popup>
 
-        <van-tabs
+      <van-tabs
         @change="getData"
         @touchmove.stop="handleTouchMove"
         background="#F9F8F8"
@@ -51,76 +55,89 @@
         v-model="tabType"
         style="position: relative"
       >
-        <img @click="openSel" style="position: absolute;right: 10px;top: 15px;" src="../../assets/images/appStoreCopy/arrowup.svg" alt="">
+        <img
+          @click="openSel"
+          style="position: absolute;right: 10px;top: 15px;"
+          src="../../assets/images/appStoreCopy/arrowup.svg"
+          alt=""
+        />
         <div v-if="selXia" class="xiaH">
-          <div class="xiaHCon" @click="CutTab(i.id)" v-for="(i,index) in typeList" :key="index">
+          <div class="xiaHCon" @click="CutTab(i.id)" v-for="(i, index) in typeList" :key="index">
             {{ i.name }}
           </div>
         </div>
-          <van-tab v-for="(i, index) in typeList" class="appBlocks" :key="index" :name="i.id" :title="i.name">
-            <template v-if="dataList.length">
-              <div v-for="(i, ind) in dataList" @click="openUrl(i.url)" :key="ind + 'a'" class="appBlock">
-                <div class="appBlockTop">
-                  <div style="display: flex;justify-content: space-between;align-items: center;margin-bottom: 10px;">
-                    <img class="appBlockTopImg" :src="i.json.icon" alt="" />
-                    <!-- <img style="width: 16px;" src="../../assets/images/appStoreCopy/appde.svg" alt="" /> -->
-                  </div>
-                  <div class="appBlockTopTit">{{ i.name }}</div>
-                  <div style="display: flex;align-items: center;">
-                    <div style="display: flex;gap: 5px;">
-                      <span class="ATag">{{ i.label == 'workflow' ? '工作流' :'智能体' }}</span>
-                      <span class="ATag" v-if="i.tag">
-                        <img style="width: 30%;" :src="i.tag == 1 || !i.tag ?
-                              require('../../assets/images/appStoreCopy/dul.svg') 
-                              : require('../../assets/images/appStoreCopy/hz.svg')" 
-                              alt=""> {{ i.tag == '1' || !i.tag ? '官方' :'精选' }}
-                      </span>
-                      <span
-                       class="ATag"
-                        v-if="
-                          ['agent'].includes(i.label) ||
-                          (['workflow'].includes(i.label) && i.json.modes)
+        <van-tab v-for="(i, index) in typeList" class="appBlocks" :key="index" :name="i.id" :title="i.name">
+          <template v-if="dataList.length">
+            <div v-for="(i, ind) in dataList" @click="openUrl(i.url)" :key="ind + 'a'" class="appBlock">
+              <div class="appBlockTop">
+                <div style="display: flex;justify-content: space-between;align-items: center;margin-bottom: 10px;">
+                  <img class="appBlockTopImg" :src="i.json.icon" alt="" />
+                  <!-- <img style="width: 16px;" src="../../assets/images/appStoreCopy/appde.svg" alt="" /> -->
+                </div>
+                <div class="appBlockTopTit">{{ i.name }}</div>
+                <div style="display: flex;align-items: center;">
+                  <div style="display: flex;gap: 5px;">
+                    <span class="ATag">{{ i.label == 'workflow' ? '工作流' : '智能体' }}</span>
+                    <span class="ATag" v-if="i.tag">
+                      <img
+                        style="width: 30%;"
+                        :src="
+                          i.tag == 1 || !i.tag
+                            ? require('../../assets/images/appStoreCopy/dul.svg')
+                            : require('../../assets/images/appStoreCopy/hz.svg')
                         "
-                      >
-                        <template v-if="i.label === 'agent'">聊天式</template>
-                        <template v-else-if="i.json.modes">{{
-                          wayList[i.json.modes[0]]
-                        }}</template>
-                      </span>
-                    </div>
+                        alt=""
+                      />
+                      {{ i.tag == '1' || !i.tag ? '官方' : '精选' }}
+                    </span>
+                    <span
+                      class="ATag"
+                      v-if="['agent'].includes(i.label) || (['workflow'].includes(i.label) && i.json.modes)"
+                    >
+                      <template v-if="i.label === 'agent'">聊天式</template>
+                      <template v-else-if="i.json.modes">{{ wayList[i.json.modes[0]] }}</template>
+                    </span>
                   </div>
                 </div>
-                <div class="appBlockBot">
-                  <span>{{ i.username }}</span>
-                  <div class="appBlockBotCol">
-                    <div style="display: flex;align-items: center;">
-                      <img @click.stop="delAllOP(i.id,0)" v-if="collList.some(item => item.id === i.id)" src="../../assets/images/appStoreCopy/star1.svg" alt="" />
-                      <img @click.stop="addAllOP(i,0)" v-else src="../../assets/images/appStoreCopy/star.svg" alt="" />
-                      {{ i.collectCount }}
-                    </div>
-                    <div  style="display: flex;align-items: center;">
-                      <img @click.stop="delAllOP(i.id,2)" v-if="likeList.some(item => item.id === i.id)" src="../../assets/images/appStoreCopy/xin1.svg" alt="" />
-                      <img @click.stop="addAllOP(i,2)" v-else src="../../assets/images/appStoreCopy/xin.svg" alt="" />
-                      {{ i.likeCount }}
-                    </div>
-
+              </div>
+              <div class="appBlockBot">
+                <span>{{ i.username }}</span>
+                <div class="appBlockBotCol">
+                  <div style="display: flex;align-items: center;">
+                    <img
+                      @click.stop="delAllOP(i.id, 0)"
+                      v-if="collList.some(item => item.id === i.id)"
+                      src="../../assets/images/appStoreCopy/star1.svg"
+                      alt=""
+                    />
+                    <img @click.stop="addAllOP(i, 0)" v-else src="../../assets/images/appStoreCopy/star.svg" alt="" />
+                    {{ i.collectCount }}
+                  </div>
+                  <div style="display: flex;align-items: center;">
+                    <img
+                      @click.stop="delAllOP(i.id, 2)"
+                      v-if="likeList.some(item => item.id === i.id)"
+                      src="../../assets/images/appStoreCopy/xin1.svg"
+                      alt=""
+                    />
+                    <img @click.stop="addAllOP(i, 2)" v-else src="../../assets/images/appStoreCopy/xin.svg" alt="" />
+                    {{ i.likeCount }}
                   </div>
                 </div>
               </div>
-            </template>
-            <div v-else style="position: absolute;left: 50%;top: 30%;transform: translate(-50%,-50%);">
-              暂无数据哦~
             </div>
-            <!-- <div v-if="isShow" 
+          </template>
+          <div v-else style="position: absolute;left: 50%;top: 30%;transform: translate(-50%,-50%);">
+            暂无数据哦~
+          </div>
+          <!-- <div v-if="isShow"
               class="zzcl"
             >
                 加载中...
             </div> -->
-          </van-tab>
-        </van-tabs>
-        <div>
-        </div>
-      
+        </van-tab>
+      </van-tabs>
+      <div></div>
     </div>
 
     <!-- 侧边栏遮罩层 -->
@@ -130,34 +147,34 @@
       style="position: fixed;top: 0;left: 0;width: 100%;height: 100%;background-color: #000;opacity: 0"
     ></div>
 
-    <van-popup 
-    overlay-class="comCss" 
-    v-model="comShow" 
-    round 
-    :closeable="true"
-    position="bottom" 
-    class="Vpop"
-     >
-    <div class="comCssTit">
+    <van-popup overlay-class="comCss" v-model="comShow" round :closeable="true" position="bottom" class="Vpop">
+      <div class="comCssTit">
         电脑端开启更多高效体验
-    </div>
-    <img style="width: 170px;" src="../../assets/images/appStoreCopy/comp.svg" alt="">
-    <div class="cpmUrl"  @click="copyUrl">
-      <div>
-        https://cloud.cocorobo.cn/
       </div>
-      <img style="margin-left: 5px;height: 16.8px;" src="../../assets/images/appStoreCopy/copyIco.svg" alt="">
-    </div>
-    <div class="comBot">
-      复制网址,去电脑端浏览器访问吧
-    </div>
-  </van-popup>
+      <img style="width: 170px;" src="../../assets/images/appStoreCopy/comp.svg" alt="" />
+      <div class="cpmUrl" @click="copyUrl">
+        <div>
+          https://cloud.cocorobo.cn/
+        </div>
+        <img style="margin-left: 5px;height: 16.8px;" src="../../assets/images/appStoreCopy/copyIco.svg" alt="" />
+      </div>
+      <div class="comBot">
+        复制网址,去电脑端浏览器访问吧
+      </div>
+    </van-popup>
   </div>
 </template>
 
 <script>
 import { mapGetters } from 'vuex'
-import { getStoreType, getStoreCopy, insert_appStoreSave,select_appStoreSave,delete_appStoreSave,select_appStorJuri } from '@/api/appStore'
+import {
+  getStoreType,
+  getStoreCopy,
+  insert_appStoreSave,
+  select_appStoreSave,
+  delete_appStoreSave,
+  select_appStorJuri
+} from '@/api/appStore'
 import appStorePopup from './components/appStorePopup.vue'
 import { Dialog, Toast } from 'vant'
 const clickOutside = {
@@ -183,7 +200,7 @@ const clickOutside = {
 }
 
 export default {
-  name: 'appStore',
+  name: 'AppStore',
   components: {
     appStorePopup
   },
@@ -194,31 +211,27 @@ export default {
     return {
       tabType: 0,
       CeShow: false,
-      isShow: false, //loading
-      comShow:false, //电脑端链接
-      dataList: [], //应用列表
-      typeList: [], //tab栏
-      // showType: '', 
-      searchText: '', //查询框文字
-      selectJuri: 3, 
-      collList:[], //用户收藏
-      likeList:[], //用户喜欢
-      tabPage:'',
-      ZeShow:false,
-      selXia:false,
+      isShow: false, // loading
+      comShow: false, // 电脑端链接
+      dataList: [], // 应用列表
+      typeList: [], // tab栏
+      // showType: '',
+      searchText: '', // 查询框文字
+      selectJuri: 3,
+      collList: [], // 用户收藏
+      likeList: [], // 用户喜欢
+      tabPage: '',
+      ZeShow: false,
+      selXia: false,
       // selectList: [
       //   { index: 1, label: '我的' },
       //   { index: 2, label: '组织' },
       //   { index: 3, label: '所有人' }
       // ],
-      wayList: [
-				'聊天室',
-				'卡片式',
-				'沉浸式',
-			],
+      wayList: ['聊天室', '卡片式', '沉浸式'],
       // 权限标签
-      juriListData:[],
-      tagList:[],
+      juriListData: [],
+      tagList: [],
       showCardId: null
     }
   },
@@ -237,55 +250,52 @@ export default {
       }
     },
     userSuffix() {
-			let yym = "";
-			return function () {
-				// this.userinfo.role == 1 && this.userinfo.rrole == 1 && this.userinfo.type == 1 &&
-				yym = this.userinfo;
-
-				let val = yym.accountNumber;
-
-				let userName = JSON.parse(JSON.stringify(val));
-
-				const regEmail = new RegExp(
-					"^[A-Za-z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$"
-				);
-
-				// // 判断用户输入账户带不带后缀
-				if (!regEmail.test(userName)) {
-					console.log("111");
-				} else {
-					const parts = userName.split("@");
-					userName = parts[0];
-				}
-
-				return userName;
-			};
-		}
+      let yym = ''
+      return function() {
+        // this.userinfo.role == 1 && this.userinfo.rrole == 1 && this.userinfo.type == 1 &&
+        yym = this.userinfo
+
+        const val = yym.accountNumber
+
+        let userName = JSON.parse(JSON.stringify(val))
+
+        const regEmail = new RegExp('^[A-Za-z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$')
+
+        // // 判断用户输入账户带不带后缀
+        if (!regEmail.test(userName)) {
+          console.log('111')
+        } else {
+          const parts = userName.split('@')
+          userName = parts[0]
+        }
+
+        return userName
+      }
+    }
   },
   methods: {
-    
     async copyUrl() {
-      const url = "https://cloud.cocorobo.cn/";
+      const url = 'https://cloud.cocorobo.cn/'
       try {
-        await navigator.clipboard.writeText(url);
+        await navigator.clipboard.writeText(url)
         Toast({
           message: '链接已复制!',
-          position: 'top',
-        });
+          position: 'top'
+        })
       } catch (err) {
-        console.error("复制失败:", err);
+        console.error('复制失败:', err)
         Toast({
           message: '复制失败,请手动复制',
-          position: 'top',
-        });
+          position: 'top'
+        })
       }
     },
     // 跳转个人信息页
-    goInfo(){
+    goInfo() {
       this.$router.push('/userInfoPage')
     },
     // 跳转查询页面
-    searchPage(){
+    searchPage() {
       this.$router.push('/searchL')
     },
     // 阻止触摸移动事件的默认行为
@@ -315,21 +325,21 @@ export default {
       }
       this.tabPage = val
       this.isShow = true
-      let params = {
+      const params = {
         uid: this.userinfo.userid,
         name: this.searchText,
         label: '',
         type: val == 'k11' ? '' : val,
         juri: selectJuri,
         stand: this.userinfo.schoolArea,
-        status:'',
-        model:'',
-        exportType:''
+        status: '',
+        model: '',
+        exportType: ''
       }
 
       getStoreCopy(params)
         .then(res => {
-          let _data = res[0]
+          const _data = res[0]
           if (_data.length > 0) {
             _data.forEach(i => {
               if (i.json) {
@@ -351,116 +361,115 @@ export default {
         })
     },
     // 添加收藏0 喜欢2
-    addAllOP(val,typeL){
-      console.log(val,typeL);
-
-      let params = [
-          {
-            uid: this.userinfo.userid, 
-            type: typeL, 
-            aid: val.id, 
-            json: '',
+    addAllOP(val, typeL) {
+      console.log(val, typeL)
+
+      const params = [
+        {
+          uid: this.userinfo.userid,
+          type: typeL,
+          aid: val.id,
+          json: ''
+        }
+      ]
+      insert_appStoreSave(params)
+        .then(res => {
+          // console.log(res);
+          // this.getData(this.tabPage)
+          if (typeL == 0) {
+            this.dataList.forEach(e => {
+              if (e.id == val.id) {
+                e.collectCount = e.collectCount + 1
+              }
+            })
+          } else {
+            this.dataList.forEach(e => {
+              if (e.id == val.id) {
+                e.likeCount = e.likeCount + 1
+              }
+            })
           }
-        ]
-        insert_appStoreSave(params)
-          .then(res => {
-            // console.log(res);
-            // this.getData(this.tabPage)
-            if (typeL == 0) {
-                this.dataList.forEach(e=>{
-                  if (e.id == val.id) {
-                    e.collectCount = e.collectCount + 1
-                  }
-                })
-            }else{
-                this.dataList.forEach(e=>{
-                  if (e.id == val.id) {
-                    e.likeCount = e.likeCount+1
-                  }
-                })
-            }
-            this.getAllOP(typeL)
-          })
-          .catch(err => {
-            console.log(err)
-            this.$message.error('添加失败')
-          })
+          this.getAllOP(typeL)
+        })
+        .catch(err => {
+          console.log(err)
+          this.$message.error('添加失败')
+        })
     },
     // 删除收藏0 喜欢2
-    delAllOP(val,type){
-      console.log(val,type);
-      
-        let kD = ''
-        if (type == 0) {
-           kD = this.collList.find(e => val === e.id )
-        } else {
-           kD = this.likeList.find(e => val === e.id )
+    delAllOP(val, type) {
+      console.log(val, type)
+
+      let kD = ''
+      if (type == 0) {
+        kD = this.collList.find(e => val === e.id)
+      } else {
+        kD = this.likeList.find(e => val === e.id)
+      }
+
+      const params = [
+        {
+          sid: kD.sid
         }
-      
-        
-        let params = [
-          {
-            sid: kD.sid
-          }
-        ]
-        
-        delete_appStoreSave(params)
-          .then(res => {
-            console.log(res);
-              // this.getData(this.tabPage)
-
-              if (type == 0) {
-                  this.dataList.forEach(e=>{
-                    if (e.id == val) {
-                      e.collectCount = e.collectCount-1
-                    }
-                  })
-              }else{
-                  this.dataList.forEach(e=>{
-                    if (e.id == val) {
-                      e.likeCount = e.likeCount-1
-                    }
-                  })
+      ]
+
+      delete_appStoreSave(params)
+        .then(res => {
+          console.log(res)
+          // this.getData(this.tabPage)
+
+          if (type == 0) {
+            this.dataList.forEach(e => {
+              if (e.id == val) {
+                e.collectCount = e.collectCount - 1
+              }
+            })
+          } else {
+            this.dataList.forEach(e => {
+              if (e.id == val) {
+                e.likeCount = e.likeCount - 1
               }
-              this.getAllOP(type)
-          })
-          .catch(err => {
-            console.log(err)
-            this.$message.error('操作失败')
-          })
+            })
+          }
+          this.getAllOP(type)
+        })
+        .catch(err => {
+          console.log(err)
+          this.$message.error('操作失败')
+        })
     },
     // 获取2点赞 与0收藏
-    getAllOP(val){
-        let params = {
-            uid: this.userinfo.userid,
-            type: val,
-				    limit: 0,
-        }
-        select_appStoreSave(params)
-          .then(res => {
-            if (val == 0) {
-              this.collList = res[0];
-            }else{
-              this.likeList = res[0];
-            }
-          })
-          .catch(err => {
-            console.log(err)
-            this.$toast.error('获取用户点赞应用失败')
-          })
+    getAllOP(val) {
+      const params = {
+        uid: this.userinfo.userid,
+        type: val,
+        limit: 0
+      }
+      select_appStoreSave(params)
+        .then(res => {
+          if (val == 0) {
+            this.collList = res[0]
+          } else {
+            this.likeList = res[0]
+          }
+        })
+        .catch(err => {
+          console.log(err)
+          this.$toast.error('获取用户点赞应用失败')
+        })
     },
     getAllStoreType() {
-      let params = {
+      const params = {
         suserid: this.userinfo.userid,
         sorg: this.userinfo.org,
         soid: this.userinfo.organizeid,
         sstand: this.userinfo.schoolArea,
-        exportType:''
+        exportType: ''
       }
 
       getStoreType(params)
         .then(res => {
-          let _data = res[0]
+          const _data = res[0]
           if (_data.length > 0) {
             this.typeList = _data
             this.typeList.unshift({ id: 'k11', name: '我的' })
@@ -478,58 +487,47 @@ export default {
       window.open(url, '_blank')
     },
     setDataTag(_list) {
-			let _result = _list;
-			_result.forEach((item) => {
-				if (
-					this.juriListData.find(
-						(i) => i.jid === item[i.type] && i.utype === "1"
-					) &&
-					item.juri == "3"
-				) {
-					item.tag = "1"; //官方
-				} else if (
-					this.juriListData.find(
-						(i) => i.jid === item[i.type] && i.utype === "2"
-					) &&
-					item.juri == "3"
-				) {
-					item.tag = "2"; //精选
-				} else if (item.role === 1 && item.juri == "2") {
-					item.tag = "3"; //专属
-				} else if (item.juri === "2") {
-					item.tag = "4"; //组织
-				} else if (item.userid === this.userinfo.userid && item.juri === "1") {
-					item.tag = "5"; //个人
-				}
-			});
-      
-			return _result;
-		},
-    openSel(){
+      const _result = _list
+      _result.forEach(item => {
+        if (this.juriListData.find(i => i.jid === item[i.type] && i.utype === '1') && item.juri == '3') {
+          item.tag = '1' // 官方
+        } else if (this.juriListData.find(i => i.jid === item[i.type] && i.utype === '2') && item.juri == '3') {
+          item.tag = '2' // 精选
+        } else if (item.role === 1 && item.juri == '2') {
+          item.tag = '3' // 专属
+        } else if (item.juri === '2') {
+          item.tag = '4' // 组织
+        } else if (item.userid === this.userinfo.userid && item.juri === '1') {
+          item.tag = '5' // 个人
+        }
+      })
+
+      return _result
+    },
+    openSel() {
       this.selXia = true
       this.ZeShow = true
     },
-    CutTab(val){
+    CutTab(val) {
       this.tabType = val
       this.selXia = false
       this.ZeShow = false
       this.getData(val)
     },
 
-   	//获取显示标权限
-		getAppStoreJuri() {
-        select_appStorJuri({})
-          .then(res => {
-            this.juriListData = res[0];
-           	if (this.dataList.length > 0) {
-							this.dataList = JSON.parse(JSON.stringify(this.setDataTag(this.dataList)));
-						}
-          })
-          .catch(err => {
-            console.log(err)
-          })
-		},
-    
+    // 获取显示标权限
+    getAppStoreJuri() {
+      select_appStorJuri({})
+        .then(res => {
+          this.juriListData = res[0]
+          if (this.dataList.length > 0) {
+            this.dataList = JSON.parse(JSON.stringify(this.setDataTag(this.dataList)))
+          }
+        })
+        .catch(err => {
+          console.log(err)
+        })
+    }
   },
   mounted() {
     this.getData()
@@ -587,14 +585,14 @@ export default {
     display: flex;
     align-items: center;
     gap: 10px;
-    background: #F3F3F3;
+    background: #f3f3f3;
     border-radius: 8px;
     padding: 5px 8px;
   }
 }
 .appBlocks {
   position: relative;
- 
+
   display: grid;
   grid-template-columns: repeat(auto-fill, minmax(40%, 1fr)); /* 自适应列 */
   align-items: start;
@@ -652,7 +650,7 @@ export default {
         display: flex;
         align-items: center;
         flex-shrink: 0;
-        img{
+        img {
           margin-right: 2px;
         }
       }
@@ -666,12 +664,12 @@ export default {
       justify-content: space-between;
       font-size: 14px !important;
       box-sizing: border-box;
-      color: rgba(40,47,60,0.8) !important;
+      color: rgba(40, 47, 60, 0.8) !important;
       .appBlockBotCol {
         display: flex;
         align-items: center;
         gap: 8px;
-        img{
+        img {
           width: 20px;
         }
       }
@@ -696,31 +694,31 @@ export default {
   overflow-x: hidden;
   width: 100%;
 }
-/deep/ .comCss{
-    background: rgba(158, 152, 152, 0.4);
-    backdrop-filter: blur(3px);
+/deep/ .comCss {
+  background: rgba(158, 152, 152, 0.4);
+  backdrop-filter: blur(3px);
 }
-/deep/ .van-tabs__wrap{
+/deep/ .van-tabs__wrap {
   padding-right: 30px !important;
 }
-.Vpop{
-      padding: 20px 30px;
-      box-sizing: border-box;
-      height: 350px;
-      display: flex;
-      flex-direction: column;
-      align-items: center;
+.Vpop {
+  padding: 20px 30px;
+  box-sizing: border-box;
+  height: 350px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
 }
-.comCssTit{
+.comCssTit {
   font-family: PingFang HK;
   font-weight: 600;
   font-size: 20px;
   line-height: 20px;
-  color: #0663FE;
+  color: #0663fe;
   margin-bottom: 20px;
 }
-.cpmUrl{
-  background: #3681FC;
+.cpmUrl {
+  background: #3681fc;
   border-radius: 12px;
   padding: 10px 20px;
   box-sizing: border-box;
@@ -733,25 +731,33 @@ export default {
   font-size: 12px;
   margin: 10px 0 20px;
 }
-.comBot{
+.comBot {
   font-family: PingFang HK;
   font-weight: 400;
   font-size: 14px;
   line-height: 20px;
   color: #000;
 }
-.zzcl{
-      position: absolute;
-      left: 0%;top: 0%;
-      background: #fff;
-      width: 100%;height: 100%;opacity: .6;
-      display: flex;justify-content: center;line-height: 350px;
-      font-size: 16px;
-      color: #000;
+.zzcl {
+  position: absolute;
+  left: 0%;
+  top: 0%;
+  background: #fff;
+  width: 100%;
+  height: 100%;
+  opacity: 0.6;
+  display: flex;
+  justify-content: center;
+  line-height: 350px;
+  font-size: 16px;
+  color: #000;
 }
-.xiaH{
-  position: absolute;left: 0;top: 44px;
-  z-index: 999;width: 100%;
+.xiaH {
+  position: absolute;
+  left: 0;
+  top: 44px;
+  z-index: 999;
+  width: 100%;
   background-color: rgb(232, 232, 233);
   border-radius: 0 0 15px 15px;
   box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
@@ -761,11 +767,12 @@ export default {
   flex-wrap: wrap;
   gap: 10px;
   min-height: 100px;
-  .xiaHCon{
+  .xiaHCon {
     // flex-shrink: 0;
     width: auto;
     height: 30px;
-    background: #fff;display: flex;
+    background: #fff;
+    display: flex;
     align-items: center;
     border-radius: 5px;
     padding: 0 10px;

+ 14 - 1
src/views/login/index.vue

@@ -7,6 +7,8 @@
 
 <script>
 import { mapActions } from 'vuex'
+import Cookies from 'js-cookie'
+
 export default {
   data() {
     return {
@@ -31,8 +33,18 @@ export default {
     },
     async getLogin() {
       const userid = await this.login()
+      let redirect_uri = Cookies.get('redirectUri')
+      if (!redirect_uri || redirect_uri === 'undefined') {
+        redirect_uri = ''
+      }
+      console.log(redirect_uri)
       if (userid) {
-        this.$router.push({ path: this.redirect || '/' })
+        if (redirect_uri) {
+          // Cookies.remove('redirectUri')
+          window.location.href = redirect_uri
+        } else {
+          this.$router.push({ path: this.redirect || '/' })
+        }
       }
       // eduGet().then(res => {})
     }
@@ -42,6 +54,7 @@ export default {
     this.timer = null
   },
   mounted() {
+    Cookies.set('isWeChat', '1')
     this.getLogin()
     this.timer = setInterval(() => {
       this.getLogin()

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

@@ -0,0 +1,451 @@
+<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">{{ Loading ? '授权中...' : '开始授权' }}</van-button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapActions } from 'vuex'
+import { wechatAuth, wechatRegister } from '@/api/wechat'
+import Cookies from 'js-cookie'
+
+export default {
+  name: 'WechatAuth',
+  data() {
+    return {
+      authStatus: 'init', // init, loading, success, error
+      userInfo: {},
+      errorMessage: '',
+      redirect: '',
+      code: '',
+      Loading: false
+    }
+  },
+  computed: {
+    // 微信授权配置
+    wechatConfig() {
+      // 直接返回对象,不需要再返回函数
+      const redirectUri = this.$route.query.url ? decodeURIComponent(this.$route.query.url) : null
+      const isApp = this.$route.query.isApp ? this.$route.query.isApp : '2'
+      Cookies.set('isApp', isApp)
+      console.log('redirectUri from query:', redirectUri)
+      if (redirectUri && redirectUri !== 'undefined') {
+        Cookies.set('redirectUri', redirectUri)
+      }
+      return {
+        appId: 'wx2d69589899b7ecd6',
+        // appId: 'wx3a8dd28881c2c41f',
+        scope: 'snsapi_userinfo', // snsapi_base 或 snsapi_userinfo
+        redirectUri: encodeURIComponent(window.location.origin + '/login'),
+        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() {
+      if (this.Loading) {
+        return
+      }
+      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'
+        this.Loading = true
+        // 调用后端接口,用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.userInfo.nickname,
+            mail: result.openid + '@wechat.com',
+            openid: result.openid + '-wechat'
+          })
+          console.log(res)
+
+          // console.log(res)
+          const loginData = JSON.stringify({
+            openid: result.openid + '-wechat',
+            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(async() => {
+              // this.$router.replace('/login')
+              await this.login()
+              let redirect_uri = Cookies.get('redirectUri')
+              const isApp = Cookies.get('isApp')
+
+              if (!redirect_uri || redirect_uri === 'undefined') {
+                redirect_uri = ''
+              }
+              this.Loading = false
+              console.log(redirect_uri)
+              if (redirect_uri) {
+                // Cookies.remove('redirectUri')
+                if (isApp === '2') {
+                  // 构建查询参数
+                  const queryParams = new URLSearchParams({
+                    redirect_uri: redirect_uri,
+                    // 可以添加其他需要的参数
+                    timestamp: Date.now().toString()
+                  }).toString()
+
+                  window.location.href = `weixin://dl/business/?appid=wxf8a72764a38a40b2&path=pages/index/index&query=${encodeURIComponent(
+                    queryParams
+                  )}`
+                } else {
+                  window.location.href = redirect_uri
+                }
+              } else {
+                this.$router.replace('/appStoreCopy')
+              }
+            })
+            .catch(error => {
+              this.Loading = false
+              console.log('error', error)
+              setTimeout(() => {
+                this.$router.replace('/login2')
+              }, 2000)
+            })
+        } else {
+          this.Loading = false
+          throw new Error(result.message || '授权失败')
+        }
+      } catch (error) {
+        console.error('微信授权失败:', error)
+        this.authStatus = 'error'
+        this.Loading = false
+        this.errorMessage = error.message || '授权失败,请重试'
+        this.$message.error(this.errorMessage)
+        // 如果授权失败,跳转到登录页面
+        // setTimeout( async () => {
+        await this.getLogin()
+        setTimeout(async () => {
+          this.$router.replace('/login2')
+        }, 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
+    },
+    async getLogin() {
+      this.loading = true
+      try {
+        const userid = await this.login()
+        let redirect_uri = Cookies.get('redirectUri')
+        const isApp = Cookies.get('isApp')
+        if (!redirect_uri || redirect_uri === 'undefined') {
+          redirect_uri = ''
+        }
+        this.Loading = false
+        console.log(redirect_uri)
+        const courseId = this.$store.getters.courseId
+        const testId = this.$store.getters.testId
+        const shareCourseId = this.$store.getters.shareCourseId
+
+        if (userid) {
+          if (redirect_uri) {
+            // Cookies.remove('redirectUri')
+            if (isApp === '2') {
+              // 构建查询参数
+              const queryParams = new URLSearchParams({
+                redirect_uri: redirect_uri,
+                // 可以添加其他需要的参数
+                timestamp: Date.now().toString()
+              }).toString()
+
+              window.location.href = `weixin://dl/business/?appid=wxf8a72764a38a40b2&path=pages/index/index&query=${encodeURIComponent(
+                queryParams
+              )}`
+            } else {
+              window.location.href = redirect_uri
+            }
+          } else if (courseId) {
+            this.$router.replace({
+              path: '/courseDetail',
+              query: { courseid: courseId, userid: userid },
+              replace: true
+            })
+          } else if (testId) {
+            this.$router.replace({
+              path: '/testDetail',
+              query: { courseid: testId, userid: userid },
+              replace: true
+            })
+          } else if (shareCourseId) {
+            this.$router.replace({
+              path: '/courseDetail',
+              query: { courseid: shareCourseId, urlType: 1, userid: userid },
+              replace: true
+            })
+          } else {
+            this.$router.replace('/appStoreCopy')
+          }
+        }
+      } catch (e) {
+        console.log(e)
+      }
+      // eduGet().then(res => {})
+    }
+  },
+
+  async mounted() {
+    // 检查是否在微信浏览器中
+    if (!this.isWechatBrowser()) {
+      // this.authStatus = 'error'
+      // this.errorMessage = '请在微信中打开此页面'
+      Cookies.set('isWeChat', '1')
+      this.$router.replace('/login2')
+      return
+    } else {
+      Cookies.set('isWeChat', '2')
+    }
+    await this.getLogin()
+
+    // 如果有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>

Some files were not shown because too many files changed in this diff