소스 검색

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

SanHQin 20 시간 전
부모
커밋
f33739245f
72개의 변경된 파일1063개의 추가작업 그리고 448개의 파일을 삭제
  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

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/index.html


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 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}

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 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%}}

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 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


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/app.9adb1279.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/app.db776c4e.js


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


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/chunk-01979dd3.c9735726.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 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


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/chunk-03851ecf.9519877d.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/chunk-03851ecf.da18759c.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/chunk-07b980da.1b24e096.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/chunk-0e29728a.516dc24c.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/chunk-0e29728a.c1f229f5.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/chunk-1678db47.541df83d.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 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")}}]);

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/chunk-18ea3bfa.46cc7005.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/chunk-1a806098.e89ffabe.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/chunk-1aab73ec.b8834f63.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/chunk-1eb03832.48d36a1e.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/chunk-247d1cc7.0f517fcd.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/chunk-247d1cc7.415d5bfe.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 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){}}]);

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/chunk-2d0c7336.5464938b.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/chunk-2d0c7336.707392c1.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 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")}}]);

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/chunk-35d65314.96fda2ad.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/chunk-55e3fa90.0bb3afc5.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/chunk-55e3fa90.c8d9c3e3.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/chunk-5bb2a616.cb003f93.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/chunk-60b2ab15.bf31f0ff.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/chunk-61b307f8.76d3a8c6.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/chunk-67c4ee97.03123001.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/chunk-6ad98842.d4ffdd60.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/chunk-6e5f7eb4.1ad93511.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/chunk-793d7e56.57eb242b.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/chunk-7caf3a38.ed044c8f.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/chunk-7d4543c8.f800adaa.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/chunk-7f794d4e.da2e5d01.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 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


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/chunk-b265f6f8.5b14ed34.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 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


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/chunk-d3f058fe.9bf03846.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 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}}]);

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/static/js/chunk-libs.4406bd5f.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 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>

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.