Browse Source

feat: 新增项目

lvkun996 1 year ago
parent
commit
e544fd1694
48 changed files with 1678 additions and 247 deletions
  1. 9 0
      README.md
  2. 1 0
      components.d.ts
  3. BIN
      dist.zip
  4. 164 162
      package-lock.json
  5. 3 2
      package.json
  6. 16 6
      src/api/common.ts
  7. 26 0
      src/api/course.ts
  8. 6 9
      src/api/learnPlan.ts
  9. 21 18
      src/components/OpenApp/index.vue
  10. 12 15
      src/hook/appHook.ts
  11. 6 0
      src/pages/Course/App.vue
  12. BIN
      src/pages/Course/assets/buy.png
  13. BIN
      src/pages/Course/assets/learn_count.png
  14. BIN
      src/pages/Course/assets/lock.png
  15. BIN
      src/pages/Course/assets/play.png
  16. BIN
      src/pages/Course/assets/time.png
  17. 14 0
      src/pages/Course/main.ts
  18. 17 0
      src/pages/Course/public/index.html
  19. 21 0
      src/pages/Course/router/index.ts
  20. 536 0
      src/pages/Course/views/index.vue
  21. 63 0
      src/pages/Course/views/mediaTypeTwo.vue
  22. 6 0
      src/pages/DownloadApp/App.vue
  23. BIN
      src/pages/DownloadApp/assets/guidance.png
  24. BIN
      src/pages/DownloadApp/assets/logo.png
  25. 1 0
      src/pages/DownloadApp/assets/redirect.html
  26. 14 0
      src/pages/DownloadApp/main.ts
  27. 17 0
      src/pages/DownloadApp/public/index.html
  28. 16 0
      src/pages/DownloadApp/router/index.ts
  29. 115 0
      src/pages/DownloadApp/views/index.vue
  30. 6 0
      src/pages/LearnPlanActive/App.vue
  31. BIN
      src/pages/LearnPlanActive/assets/course-1.png
  32. BIN
      src/pages/LearnPlanActive/assets/course-2.png
  33. BIN
      src/pages/LearnPlanActive/assets/course-3.png
  34. BIN
      src/pages/LearnPlanActive/assets/course-4.png
  35. BIN
      src/pages/LearnPlanActive/assets/light.png
  36. BIN
      src/pages/LearnPlanActive/assets/lock.png
  37. BIN
      src/pages/LearnPlanActive/assets/qrcode.png
  38. BIN
      src/pages/LearnPlanActive/assets/right.png
  39. BIN
      src/pages/LearnPlanActive/assets/video.mp4
  40. 85 0
      src/pages/LearnPlanActive/components/modal.vue
  41. 14 0
      src/pages/LearnPlanActive/main.ts
  42. 17 0
      src/pages/LearnPlanActive/public/index.html
  43. 21 0
      src/pages/LearnPlanActive/router/index.ts
  44. 172 0
      src/pages/LearnPlanActive/views/detail.vue
  45. 232 0
      src/pages/LearnPlanActive/views/index.vue
  46. 3 3
      src/service/request.ts
  47. 29 32
      src/utils/utils.ts
  48. 15 0
      vue.config.js

+ 9 - 0
README.md

@@ -3,9 +3,18 @@
 
 
 ## 访问url
+
   https://zaojiao.net/app_web/learn-plan.html#/blue-light-tip 学习计划
 
   https://zaojiao.net/app_web/section-audition.html#/et1WkdUu7ILvQFK 课程小节试听
 
+  https://zaojiao.net/app_web/lab.html#/ 蚂蚁抄丘与弗雷德一起探案
+
+  https://zaojiao.net/app_web/download-app.html#/  下载逻辑狗
+
+  https://zaojiao.net/app_web/course.html#/  家园共育app -> 园所端 -> 分享出来的课程详情页 
+
+  https://zaojiao.net/app_web/lp.html#/  动画课程试听试看
+
 ## NODE 版本
   14.19.0

+ 1 - 0
components.d.ts

@@ -11,6 +11,7 @@ declare module '@vue/runtime-core' {
     OpenApp: typeof import('./src/components/OpenApp/index.vue')['default']
     RouterLink: typeof import('vue-router')['RouterLink']
     RouterView: typeof import('vue-router')['RouterView']
+    VanIcon: typeof import('vant/es')['Icon']
     VanOverlay: typeof import('vant/es')['Overlay']
     VanProgress: typeof import('vant/es')['Progress']
   }

BIN
dist.zip


+ 164 - 162
package-lock.json

@@ -1077,123 +1077,6 @@
         "tslint": "^5.20.1",
         "webpack": "^4.0.0",
         "yorkie": "^2.0.0"
-      },
-      "dependencies": {
-        "chalk": {
-          "version": "4.1.2",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
-          "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "ansi-styles": "^4.1.0",
-            "supports-color": "^7.1.0"
-          }
-        },
-        "cosmiconfig": {
-          "version": "6.0.0",
-          "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz",
-          "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "@types/parse-json": "^4.0.0",
-            "import-fresh": "^3.1.0",
-            "parse-json": "^5.0.0",
-            "path-type": "^4.0.0",
-            "yaml": "^1.7.2"
-          }
-        },
-        "deepmerge": {
-          "version": "4.3.1",
-          "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
-          "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
-          "dev": true,
-          "optional": true
-        },
-        "fork-ts-checker-webpack-plugin-v5": {
-          "version": "npm:fork-ts-checker-webpack-plugin@5.2.1",
-          "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-5.2.1.tgz",
-          "integrity": "sha512-SVi+ZAQOGbtAsUWrZvGzz38ga2YqjWvca1pXQFUArIVXqli0lLoDQ8uS0wg0kSpcwpZmaW5jVCZXQebkyUQSsw==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "@babel/code-frame": "^7.8.3",
-            "@types/json-schema": "^7.0.5",
-            "chalk": "^4.1.0",
-            "cosmiconfig": "^6.0.0",
-            "deepmerge": "^4.2.2",
-            "fs-extra": "^9.0.0",
-            "memfs": "^3.1.2",
-            "minimatch": "^3.0.4",
-            "schema-utils": "2.7.0",
-            "semver": "^7.3.2",
-            "tapable": "^1.0.0"
-          }
-        },
-        "fs-extra": {
-          "version": "9.1.0",
-          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
-          "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "at-least-node": "^1.0.0",
-            "graceful-fs": "^4.2.0",
-            "jsonfile": "^6.0.1",
-            "universalify": "^2.0.0"
-          }
-        },
-        "jsonfile": {
-          "version": "6.1.0",
-          "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
-          "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "graceful-fs": "^4.1.6",
-            "universalify": "^2.0.0"
-          }
-        },
-        "lru-cache": {
-          "version": "6.0.0",
-          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
-          "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "yallist": "^4.0.0"
-          }
-        },
-        "schema-utils": {
-          "version": "2.7.0",
-          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz",
-          "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "@types/json-schema": "^7.0.4",
-            "ajv": "^6.12.2",
-            "ajv-keywords": "^3.4.1"
-          }
-        },
-        "semver": {
-          "version": "7.5.4",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
-          "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "lru-cache": "^6.0.0"
-          }
-        },
-        "universalify": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
-          "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
-          "dev": true,
-          "optional": true
-        }
       }
     },
     "@vue/cli-plugin-vuex": {
@@ -1266,17 +1149,6 @@
         "webpack-merge": "^4.2.2"
       },
       "dependencies": {
-        "chalk": {
-          "version": "4.1.2",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
-          "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "ansi-styles": "^4.1.0",
-            "supports-color": "^7.1.0"
-          }
-        },
         "cliui": {
           "version": "6.0.0",
           "resolved": "https://registry.npmmirror.com/cliui/-/cliui-6.0.0.tgz",
@@ -1288,37 +1160,6 @@
             "wrap-ansi": "^6.2.0"
           }
         },
-        "json5": {
-          "version": "2.2.3",
-          "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
-          "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
-          "dev": true,
-          "optional": true
-        },
-        "loader-utils": {
-          "version": "2.0.4",
-          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
-          "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "big.js": "^5.2.2",
-            "emojis-list": "^3.0.0",
-            "json5": "^2.1.2"
-          }
-        },
-        "vue-loader-v16": {
-          "version": "npm:vue-loader@16.8.3",
-          "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.8.3.tgz",
-          "integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "chalk": "^4.1.0",
-            "hash-sum": "^2.0.0",
-            "loader-utils": "^2.0.0"
-          }
-        },
         "wrap-ansi": {
           "version": "6.2.0",
           "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
@@ -5927,6 +5768,123 @@
         }
       }
     },
+    "fork-ts-checker-webpack-plugin-v5": {
+      "version": "npm:fork-ts-checker-webpack-plugin@5.2.1",
+      "resolved": "https://registry.npmmirror.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-5.2.1.tgz",
+      "integrity": "sha512-SVi+ZAQOGbtAsUWrZvGzz38ga2YqjWvca1pXQFUArIVXqli0lLoDQ8uS0wg0kSpcwpZmaW5jVCZXQebkyUQSsw==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "@babel/code-frame": "^7.8.3",
+        "@types/json-schema": "^7.0.5",
+        "chalk": "^4.1.0",
+        "cosmiconfig": "^6.0.0",
+        "deepmerge": "^4.2.2",
+        "fs-extra": "^9.0.0",
+        "memfs": "^3.1.2",
+        "minimatch": "^3.0.4",
+        "schema-utils": "2.7.0",
+        "semver": "^7.3.2",
+        "tapable": "^1.0.0"
+      },
+      "dependencies": {
+        "chalk": {
+          "version": "4.1.2",
+          "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
+          "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "cosmiconfig": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmmirror.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz",
+          "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "@types/parse-json": "^4.0.0",
+            "import-fresh": "^3.1.0",
+            "parse-json": "^5.0.0",
+            "path-type": "^4.0.0",
+            "yaml": "^1.7.2"
+          }
+        },
+        "deepmerge": {
+          "version": "4.3.1",
+          "resolved": "https://registry.npmmirror.com/deepmerge/-/deepmerge-4.3.1.tgz",
+          "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+          "dev": true,
+          "optional": true
+        },
+        "fs-extra": {
+          "version": "9.1.0",
+          "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-9.1.0.tgz",
+          "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "at-least-node": "^1.0.0",
+            "graceful-fs": "^4.2.0",
+            "jsonfile": "^6.0.1",
+            "universalify": "^2.0.0"
+          }
+        },
+        "jsonfile": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.1.0.tgz",
+          "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "graceful-fs": "^4.1.6",
+            "universalify": "^2.0.0"
+          }
+        },
+        "lru-cache": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz",
+          "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "yallist": "^4.0.0"
+          }
+        },
+        "schema-utils": {
+          "version": "2.7.0",
+          "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-2.7.0.tgz",
+          "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "@types/json-schema": "^7.0.4",
+            "ajv": "^6.12.2",
+            "ajv-keywords": "^3.4.1"
+          }
+        },
+        "semver": {
+          "version": "7.6.0",
+          "resolved": "https://registry.npmmirror.com/semver/-/semver-7.6.0.tgz",
+          "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "lru-cache": "^6.0.0"
+          }
+        },
+        "universalify": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz",
+          "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+          "dev": true,
+          "optional": true
+        }
+      }
+    },
     "form-data": {
       "version": "2.3.3",
       "resolved": "https://registry.npmmirror.com/form-data/-/form-data-2.3.3.tgz",
@@ -13326,6 +13284,50 @@
         }
       }
     },
+    "vue-loader-v16": {
+      "version": "npm:vue-loader@16.8.3",
+      "resolved": "https://registry.npmmirror.com/vue-loader/-/vue-loader-16.8.3.tgz",
+      "integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "chalk": "^4.1.0",
+        "hash-sum": "^2.0.0",
+        "loader-utils": "^2.0.0"
+      },
+      "dependencies": {
+        "chalk": {
+          "version": "4.1.2",
+          "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
+          "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "json5": {
+          "version": "2.2.3",
+          "resolved": "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz",
+          "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+          "dev": true,
+          "optional": true
+        },
+        "loader-utils": {
+          "version": "2.0.4",
+          "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz",
+          "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "big.js": "^5.2.2",
+            "emojis-list": "^3.0.0",
+            "json5": "^2.1.2"
+          }
+        }
+      }
+    },
     "vue-router": {
       "version": "4.1.6",
       "resolved": "https://registry.npmmirror.com/vue-router/-/vue-router-4.1.6.tgz",
@@ -13752,9 +13754,9 @@
       "dev": true
     },
     "weixin-js-sdk": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmmirror.com/weixin-js-sdk/-/weixin-js-sdk-1.6.0.tgz",
-      "integrity": "sha512-3IYQH7aalJGFJrwdT3epvTdR1MboMiH7vIZ5BRL2eYOJ12BNah7csoMkmSZzkq1+l92sSq29XdTCVjCJoK2sBQ=="
+      "version": "1.6.5",
+      "resolved": "https://registry.npmmirror.com/weixin-js-sdk/-/weixin-js-sdk-1.6.5.tgz",
+      "integrity": "sha512-Gph1WAWB2YN/lMOFB/ymb+hbU/wYazzJgu6PMMktCy9cSCeW5wA6Zwt0dpahJbJ+RJEwtTv2x9iIu0U4enuVSQ=="
     },
     "which": {
       "version": "1.3.1",

+ 3 - 2
package.json

@@ -6,7 +6,8 @@
     "serve": "vue-cli-service serve",
     "build": "vue-cli-service build",
     "lint": "vue-cli-service lint",
-    "upload:pro": "python upload.py /usr/share/nginx/html/zaojiao/ app_web pro",
+    "upload:zaojiao": "python upload.py /usr/share/nginx/html/zaojiao/ app_web pro",
+    "upload:luojigou": "python upload.py /usr/share/nginx/html/luojigou/ app_web pro",
     "upload:dev": "python upload.py /usr/share/nginx/html/ app_web dev"
   },
   "dependencies": {
@@ -27,7 +28,7 @@
     "vue": "^3.0.0",
     "vue-class-component": "^8.0.0-0",
     "vue-router": "^4.0.0-0",
-    "weixin-js-sdk": "^1.6.0"
+    "weixin-js-sdk": "^1.6.5"
   },
   "devDependencies": {
     "@typescript-eslint/eslint-plugin": "^4.18.0",

+ 16 - 6
src/api/common.ts

@@ -1,12 +1,22 @@
 import request from '@/service/index'
 
 // 获取c端微信签名
-export function getWXSignature() {
-  let url = window.location.href.split('#')[0];
+export function getCWXSignature () {
+  const url = window.location.href.split('#')[0]
   // let url = `https://luojigou.vip/app_web`;
   return request({
-    url: `app/wx/sign`,
+    url: 'app/wx/sign',
     method: 'GET',
-    params: {url},
-  });
-}
+    params: { url }
+  })
+}
+
+// 获取家长端微信签名
+export function getParentWXSignature () {
+  const url = window.location.href.split('#')[0]
+  return request({
+    url: 'app/wx/sign/parent',
+    method: 'GET',
+    params: { url }
+  })
+}

+ 26 - 0
src/api/course.ts

@@ -0,0 +1,26 @@
+import request from '@/service/index'
+
+/**
+ * 获取分享出来的课程资料详情
+ * @param params
+ * @returns
+ */
+export const getAICourse = (params: {skuId: string, hasWork: 1 | any}) => {
+  return request({
+    url: '/teach/v1/AICourse/item',
+    method: 'GET',
+    params
+  })
+}
+
+/**
+ * 获取分享出来的课程 类型是图文时的详情
+ * @param params
+ * @returns
+ */
+export const getAICoursePictureById = (id: string) => {
+  return request({
+    url: '/teach/v1/AICourse/item/' + id,
+    method: 'GET'
+  })
+}

+ 6 - 9
src/api/learnPlan.ts

@@ -1,13 +1,11 @@
 import request from '@/service/index'
 
-
-
 /**
  * 根据用户id获取用户学习报告情况
- * @param data 
- * @returns 
+ * @param data
+ * @returns
  */
- export const getReportByUser = (data: any) => {
+export const getReportByUser = (data: any) => {
   return request<API.LearnPlan.Task>({
     url: '/app/game-course/data/task4',
     method: 'post',
@@ -15,11 +13,10 @@ import request from '@/service/index'
   })
 }
 
-
 /**
  * 分享用户的学习报告
- * @param data 
- * @returns 
+ * @param data
+ * @returns
  */
 export const shareUserReport = (data: any) => {
   return request<API.LearnPlan.Task>({
@@ -27,4 +24,4 @@ export const shareUserReport = (data: any) => {
     method: 'post',
     data
   })
-}
+}

+ 21 - 18
src/components/OpenApp/index.vue

@@ -11,21 +11,9 @@
         <slot>
           <div
             class="btn"
-            style="
-            width: 334px;
-            height: 52px;
-            background: #ff8024;
-            border-radius: 26px;
-            display: flex;
-            justify-content: center;
-            align-items: center;
-            font-size: 18px;
-            font-family: PingFangSC-Regular, PingFang SC;
-            font-weight: 400;
-            color: #ffffff;
-          "
+            :style="styles + props.style"
           >
-            打开APP
+            {{props.text}}
           </div>
         </slot>
       </div>
@@ -39,8 +27,22 @@ import { defineProps, withDefaults, ref } from 'vue'
 interface IProps {
   appid?: string;
   extinfo?: string;
+  text: string
+  style: string
 }
 
+const styles = `width: 334px;
+            height: 52px;
+            background: #ff8024;
+            border-radius: 26px;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            font-size: 18px;
+            font-family: PingFangSC-Regular, PingFang SC;
+            font-weight: 400;
+            color: #ffffff;`
+
 const props = withDefaults(defineProps<IProps>(), {
   // wxe87236d542cd0f94 逻辑狗思维教育公众号
   // wxd61f929a1c72280a 思维魔法学堂公众号
@@ -49,7 +51,9 @@ const props = withDefaults(defineProps<IProps>(), {
   // wxf6e96c65ba6116d4 luojigou.vip
 
   appid: 'wxeb44a864bdd935be',
-  extinfo: ''
+  extinfo: '',
+  text: '打开APP',
+  style: ''
 })
 
 const launchBtnRef = ref()
@@ -61,13 +65,12 @@ const handleReadyFn = () => {
 
   launchBtnRef.value.addEventListener('error', function (e: any) {
     console.log('error:', e.detail)
-    window.location.href =
-      'https://sj.qq.com/myapp/detail.htm?apkName=com.zaojiao.app'
+    // window.location.href = 'https://sj.qq.com/myapp/detail.htm?apkName=com.zaojiao.app'
   })
 }
 
 setTimeout(() => {
-  console.log(props.extinfo, 'props.extinfo')
+  console.log(props, 'props')
 }, 3000)
 </script>
 

+ 12 - 15
src/hook/appHook.ts

@@ -3,55 +3,54 @@
  * @description 点击调用app方法
  */
 
-import { useTokenStore } from "@/store";
+import { useTokenStore } from '@/store'
 
 const push = (path: string) => {
   switch (path) {
     case 'navigateExercise':
       window.navigateExercise.postMessage(JSON.stringify({}))
-      break;
+      break
     case 'navigateRecord':
       window.navigateRecord.postMessage(JSON.stringify({}))
-      break;
+      break
     case 'reloadGame':
       window.reloadGame.postMessage(JSON.stringify({}))
-      break;
+      break
   }
 }
 
 const back = (path = '') => {
+  console.log('path:', path)
+
   window.popPage.postMessage(path)
 }
 
-
 const getToken = () => {
   try {
     window.getToken.postMessage(JSON.stringify({}))
   } catch (error) {
-    
+
   }
 
-  return new Promise( (resolve) => {
+  return new Promise((resolve) => {
     window.returnToken = token => {
-      useTokenStore().set(token) 
+      useTokenStore().set(token)
       resolve(token)
     }
   })
 }
 
-
 const shareWx = (url: string) => {
-  const prams = JSON.stringify({callname: url})
+  const prams = JSON.stringify({ callname: url })
   window.sharePoster.postMessage(prams)
 }
 
 const savePoster = (url: string) => {
-  const prams = JSON.stringify({callname: url})
+  const prams = JSON.stringify({ callname: url })
   window.savePoster.postMessage(prams)
 }
 
 export const useAppRouter = () => {
-  
   const router = {
     push: push,
     back: back,
@@ -62,10 +61,8 @@ export const useAppRouter = () => {
 }
 
 export const useAppFunc = () => {
-
   return {
     shareWx,
     savePoster
   }
-
-}
+}

+ 6 - 0
src/pages/Course/App.vue

@@ -0,0 +1,6 @@
+<script setup lang="ts">
+</script>
+
+<template>
+  <router-view/>
+</template>

BIN
src/pages/Course/assets/buy.png


BIN
src/pages/Course/assets/learn_count.png


BIN
src/pages/Course/assets/lock.png


BIN
src/pages/Course/assets/play.png


BIN
src/pages/Course/assets/time.png


+ 14 - 0
src/pages/Course/main.ts

@@ -0,0 +1,14 @@
+import { createApp } from 'vue'
+import App from './App.vue'
+import router from './router'
+import 'lib-flexible'
+import 'normalize.css'
+import * as Pinia from 'pinia'
+import VConsole from 'vconsole'
+import '@/utils/vant'
+
+// const vconsole = new VConsole()
+
+// import store from './store'
+
+createApp(App).use(router).use(Pinia.createPinia()).mount('#course')

+ 17 - 0
src/pages/Course/public/index.html

@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html lang="">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width,initial-scale=1.0">
+    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
+    <title>逻辑狗</title>
+  </head>
+  <body>
+    <noscript>
+      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
+    </noscript>
+    <div id="course"></div>
+    <!-- built files will be auto injected -->
+  </body>
+</html>

+ 21 - 0
src/pages/Course/router/index.ts

@@ -0,0 +1,21 @@
+import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
+
+const routes: Array<RouteRecordRaw> = [
+  {
+    path: '/',
+    name: 'page',
+    component: () => import('../views/index.vue')
+  },
+  {
+    path: '/media',
+    name: 'media',
+    component: () => import('../views/mediaTypeTwo.vue')
+  }
+]
+
+const router = createRouter({
+  history: createWebHashHistory(),
+  routes
+})
+
+export default router

+ 536 - 0
src/pages/Course/views/index.vue

@@ -0,0 +1,536 @@
+<template>
+  <div calss="course-detail" >
+    <!-- 课程详情 -->
+    <div class="course" >
+    <div class="cover">
+      <img :src="state.imgCover" alt="">
+    </div>
+    <div class="desc" >
+      <div class="price" >
+        <div class="current-price" >{{state.price}}</div>
+        <div class="discount-price" >原价:¥{{state.markingPrice}}</div>
+      </div>
+      <div class="title" >{{state.name}}</div>
+      <div class="subtitle" >{{state.simpleDescription}}</div>
+      <div class="sub-desc" >
+        <div class="tag" >
+          <div class="tag-item" >{{state.suitAge}}岁</div>
+          <div class="tag-item" >{{state.chapterList.length}}讲</div>
+        </div>
+        <div class="buy" >
+          <img :src="require('@/pages/Course/assets/learn_count.png')" alt="">
+          <div>{{state.courseCount}}人学过</div>
+        </div>
+      </div>
+    </div>
+    </div>
+    <!-- 目录 -->
+    <div class='meun-section' >
+      <div class="tabs" :style="{top: currentVideo ? '210px' : '0px' }">
+        <div
+          :class="['tabs-item', curTabRef === item.id ? 'tabs-item-active' : '']"
+          v-for="item in tabs"
+          :key="item.id"
+          @click="changeTabs(item.id)"
+        >
+          {{item.name}}
+        </div>
+        <div class="line" :style="{left: curTabRef === 0 ? '80px' : '268px'}" ></div>
+      </div>
+      <div class="course-desc"  v-if="curTabRef === 0" >
+        <div v-html="state.description" ></div>
+      </div>
+      <div class="course-meun" v-if="curTabRef === 1"  >
+        <!-- 小分类 -->
+        <div class='course-meun-tabs'  >
+          <div :class="['course-meun-tabs-item', chapterIdRef === item.id ? 'course-meun-tabs-item-active' : '']" @click="changeChapter(index, item.id)" v-for="(item, index) in state.chapterList" :key="item.id">
+            {{item.name}}
+          </div>
+        </div>
+        <div
+          class="course-meun-item"
+          v-for="_ in  currentMediaList"
+          :key="_.id"
+        >
+          <div class='cover' @click="playCourse(_)">
+            <div class="overlay" v-if="_.payType === 0" >
+              <img class="lock" :src="require('@/pages/Course/assets/lock.png')" alt="">
+            </div>
+            <img  :src="_.imgCover" alt="">
+          </div>
+          <div class="course-meun-item-intro"  >
+            <div class="title-container" >
+              <div class="title">{{_.name}}</div>
+              <div class="try-see" v-if="_.payType !== 0" >试看</div>
+            </div>
+            <div class="intro" >
+              <div class="intro-item" v-if="mediaType === 0" ><img :src="require('@/pages/Course/assets/time.png')" alt=""><div>{{getDuration(_.video.duration)}}</div></div>
+              <div class="intro-item" ><img :src="require('@/pages/Course/assets/play.png')" alt=""><div>{{_.readCountStr}}</div></div>
+              <div class="intro-item" @click="openTeachingMaterial(_)" ><van-icon name="description" style="margin-right: 5px;margin-top: 2px;" /><div>资料</div></div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+
+  <video
+    v-if="currentVideo"
+    :style="{zIndex: currentVideo? 30 : 1}"
+    :src="currentVideo"
+    controls
+    autoplay
+    playsinline
+  >
+  </video>
+
+  <!-- 打开app的按钮 如果没有app,就去应用市场 -->
+  <div class="btn" >
+    <!-- <div class="open-app-btn" >
+      加入学习解锁全部课程
+    </div> -->
+    <!-- <OpenApp appid='wxe87236d542cd0f94'   /> -->
+    <OpenApp appid='wxf6e96c65ba6116d4' text="加入学习解锁全部课程" :extinfo="'/course/pipeline?course_id=' + skuId"  />
+  </div>
+</template>
+
+<script setup lang="ts">
+import { getAICourse } from '@/api/course'
+import { getParentWXSignature } from '@/api/common'
+import { onMounted, ref } from 'vue'
+import OpenApp from '@/components/OpenApp/index.vue'
+import { registerWxopenButton } from '@/utils/utils'
+import { useRoute, useRouter } from 'vue-router'
+
+const userAgent = navigator.userAgent
+
+// 判断是否在微信中
+// var isInWeChat = /MicroMessenger/.test(userAgent)
+
+const route = useRoute()
+
+const router = useRouter()
+
+const skuId = route.query.skuId
+
+const tabs = [
+  {
+    name: '详情',
+    id: 0
+  },
+  {
+    name: '目录',
+    id: 1
+  }
+]
+
+const curTabRef = ref(0)
+
+const state = ref({
+  chapterList: []
+})
+
+const currentVideo = ref('')
+
+const currentMediaList = ref([])
+
+const chapterIdRef = ref('')
+
+const openTeachingMaterial = (record: any) => {
+  if (record.payType == 0) return
+  window.open(record.teachingMaterial.fileUrl)
+}
+
+const changeChapter = (index: number, id: string) => {
+  currentMediaList.value = state.value.chapterList[index].itemList
+  chapterIdRef.value = id
+}
+
+const getDuration = (count: any) => {
+  const m = Math.floor(Number(count).toFixed(0) / 60)
+  const s = Number(count).toFixed(0) % 60
+  return (m > 10 ? m : '0' + m) + ':' + (s > 10 ? s : '0' + s)
+}
+
+// 0  视频  2 图文 1 音频
+const mediaType = ref(0)
+
+const playCourse = (record) => {
+  if (record.payType === 0) return
+  if (mediaType.value === 0) {
+    currentVideo.value = record.video.videoUrl
+  } else if (mediaType.value === 2) {
+    router.push({
+      path: '/media',
+      query: { id: record.id }
+    })
+  }
+}
+
+const changeTabs = (id: number) => {
+  curTabRef.value = id
+}
+
+// 获取课程
+const _getAICourse = async () => {
+  const { data } = await getAICourse({ skuId: skuId as string, hasWork: '' })
+  state.value = data
+  mediaType.value = data.mediaType
+  currentMediaList.value = data.chapterList[0].itemList
+  chapterIdRef.value = data.chapterList[0].id
+}
+
+onMounted(() => {
+  _getAICourse()
+  registerWxopenButton(getParentWXSignature)
+})
+
+</script>
+
+<style lang="scss" scoped >
+.course-detail {
+  width: 100vw;
+  min-height: 100vh;
+  background-color: #F6F6F6;
+}
+.course {
+  .cover {
+    width: 375px;
+    height: 231px;
+    background-color: deepskyblue;
+    position: relative;
+    z-index: 1;
+
+    img {
+      width: 100%;
+      height: 100%;
+      display: block;
+      object-fit: cover;
+      position: absolute;
+      top: 0;
+      left: 0;
+      z-index: 2;
+    }
+  }
+  .desc {
+    width: 375px;
+    height: 185px;
+    background: #FFFFFF;
+    box-shadow: 0px 6px 11px 4px rgba(231,237,241,0.6);
+    border-radius: 22px 22px 0px 0px;
+    margin-top: -22px;
+    padding: 16px;
+    box-sizing: border-box;
+    position: relative;
+    z-index: 2;
+    .price {
+      display: flex;
+      align-items: center;
+      .current-price {
+        font-family: PingFangSC, PingFang SC;
+        font-weight: 600;
+        font-size: 26px;
+        color: #FF1F1F;
+        line-height: 37px;
+        text-align: left;
+        font-style: normal;
+        margin-right: 12px;
+      }
+      .discount-price {
+        font-family: PingFangSC, PingFang SC;
+        font-weight: 400;
+        font-size: 12px;
+        color: #999999;
+        line-height: 17px;
+        text-align: left;
+        font-style: normal;
+        text-decoration-line: line-through;
+      }
+    }
+    .title {
+      font-family: PingFangSC, PingFang SC;
+      font-weight: 600;
+      font-size: 18px;
+      color: #333333;
+      line-height: 25px;
+      text-align: left;
+      font-style: normal;
+      margin-top: 6px;
+    }
+    .subtitle {
+      font-family: PingFangSC, PingFang SC;
+      font-weight: 400;
+      font-size: 13px;
+      color: #797979;
+      line-height: 20px;
+      text-align: justify;
+      font-style: normal;
+      margin-top: 5px;
+    }
+    .sub-desc {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      margin-top: 16px;
+      .tag {
+        display: flex;
+        .tag-item {
+          width: 60px;
+          height: 23px;
+          background: #FFF2E8;
+          margin-right: 14px;
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          font-family: PingFangSC, PingFang SC;
+          font-weight: 400;
+          font-size: 11px;
+          color: #FF7422;
+          font-style: normal;
+        }
+      }
+      .buy {
+        font-family: PingFangSC, PingFang SC;
+        font-weight: 400;
+        font-size: 12px;
+        color: #999999;
+        line-height: 23px;
+        text-align: left;
+        font-style: normal;
+        display: flex;
+        align-items: center;
+        img {
+          width: 11px;
+          height: 11px;
+          margin-right: 4px;
+        }
+      }
+    }
+  }
+}
+
+.meun-section {
+  margin-top: 20px;
+  background-color: #F6F6F6;
+
+    .tabs {
+      width: 100vw;
+      height: 58px;
+      display: flex;
+      align-items: center;
+      justify-content: space-around;
+      background-color: #fff;
+      position: sticky;
+      top: 210px;
+      z-index: 4;
+      .tabs-item {
+        font-family: PingFangSC, PingFang SC;
+        font-weight: 500;
+        font-size: 16px;
+        color: #999999;
+        line-height: 22px;
+        text-align: left;
+        font-style: normal;
+      }
+      .tabs-item-active {
+        font-weight: 600;
+        font-size: 17px;
+        color: #333333;
+        line-height: 24px;
+      }
+      .line {
+        width: 30px;
+        height: 6px;
+        background-color: #0B57C7;
+        border-radius: 10px;
+        position: absolute;
+        top: 44px;
+        left: 80px;
+      }
+    }
+    .course-desc {
+      width: 100vw;
+      height: 42vh;
+      padding: 16px;
+      box-sizing: border-box;
+      font-weight: 600;
+      font-size: 16px;
+      color: #636161;
+      line-height: 18px;
+    }
+    .course-meun {
+      width: 100vw;
+      padding: 16px;
+      padding-left: 26px;
+      box-sizing: border-box;
+      padding-bottom: 100px;
+      .course-meun-tabs {
+        margin-bottom: 20px;
+        width: calc(100vw - 32px);
+        overflow: hidden;
+        overflow-x: scroll;
+        display: flex;
+        align-items: center;
+        .course-meun-tabs-item {
+          background: #F6F6F6;
+          border-radius: 18px;
+          padding: 8px 20px;
+          box-sizing: border-box;
+          font-family: PingFangSC, PingFang SC;
+          font-weight: 500;
+          font-size: 15px;
+          color: #9B9B9B;
+          line-height: 21px;
+          height: 36px;
+          margin-right: 20px;
+          background-color: #fff;
+        }
+        .course-meun-tabs-item-active {
+          border: 1px solid #0B57C7;
+          color: #0B57C7
+        }
+      }
+      .course-meun-item {
+        display: flex;
+        align-items: center;
+        margin-bottom: 20px;
+        .cover {
+          width: 107px;
+          height: 60px;
+          margin-right: 14px;
+          position: relative;
+          .overlay {
+            width: 107px;
+            height: 60px;
+            background-color: rgba( 0, 0, 0, 0.6);
+            position: absolute;
+            top: 0;
+            left: 0;
+            z-index: 3;
+            display: flex;
+            justify-content: center;
+            align-items: start;
+            border-radius: 20px;
+            .lock {
+              width: 17px;
+              height: 16px;
+              display: block;
+              position: absolute;
+              top: 50%;
+              left: 50%;
+              transform: translate(-50%, -50%);
+            }
+          }
+          img {
+            width: 107px;
+            height: 60px;
+            border-radius: 20px;
+            display: block;
+            object-fit: cover;
+            position: absolute;
+            top: 0;
+            left: 0;
+            z-index: 2;
+          }
+        }
+        .course-meun-item-intro {
+          .title-container {
+            display: flex;
+            align-items: center;
+            width: 220px;
+            .title {
+              max-width: 180px;
+              font-family: PingFangSC, PingFang SC;
+              font-weight: 500;
+              font-size: 15px;
+              color: #333333;
+              line-height: 21px;
+              text-align: left;
+              font-style: normal;
+              white-space: nowrap;
+              overflow: hidden;
+              text-overflow: ellipsis;
+              margin-right: 6px;
+            }
+            .try-see {
+              width: 39px;
+              height: 18px;
+              background: linear-gradient( 279deg, #FF9055 0%, #FFB856 100%);
+              border-radius: 9px;
+              display: flex;
+              justify-content: center;
+              align-items: center;
+              font-size: 12px;
+              line-height: 18px;
+            }
+          }
+
+          .intro {
+            display: flex;
+            font-family: PingFangSC, PingFang SC;
+            font-weight: 400;
+            font-size: 12px;
+            color: #BEBEBE;
+            line-height: 17px;
+            text-align: left;
+            font-style: normal;
+            margin-top: 10px;
+            .intro-item {
+              margin-right: 16px;
+              display: flex;
+              align-items: center;
+              img {
+                width: 13px;
+                height: 13px;
+                display: block;
+                margin-right: 2px;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  video {
+      width: 100%;
+      height: 210px;
+      display: block;
+      object-fit: cover;
+      position: fixed;
+      top: 0;
+      left: 0;
+      z-index: 1;
+    }
+
+.btn {
+  width: 375px;
+  height: 87px;
+  background: #FFFFFF;
+  box-shadow: 0px -4px 34px 0px rgba(0,0,0,0.06);
+  position: fixed;
+  bottom: -2px;
+  left: 0%;
+  z-index: 100;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  .open-app-btn {
+    width: 343px;
+    height: 46px;
+    background: linear-gradient( 306deg, #FF9A59 0%, #FF4747 100%);
+    border-radius: 23px;
+    font-family: PingFangSC, PingFang SC;
+    font-weight: 500;
+    font-size: 18px;
+    color: #FFFFFF;
+    line-height: 25px;
+    text-align: left;
+    font-style: normal;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+  }
+}
+
+</style>

+ 63 - 0
src/pages/Course/views/mediaTypeTwo.vue

@@ -0,0 +1,63 @@
+<template>
+  <div class="media-type" >
+    <div class="cover" >
+      <img :src="state.imgCover" alt="">
+    </div>
+    <div class="title" >{{state.name}}</div>
+    <div class="content" v-html="state.richText" ></div>
+  </div>
+</template>
+<script lang='ts' setup >
+import { defineProps, onMounted, ref } from 'vue'
+import { getAICoursePictureById } from '@/api/course'
+import { useRoute } from 'vue-router'
+
+const route = useRoute()
+
+const id = route.query.id
+
+console.log('id:', id)
+
+const state = ref({})
+
+const GetAICoursePictureById = async () => {
+  const { data } = await getAICoursePictureById(id as string)
+  state.value = data
+}
+
+onMounted(() => {
+  GetAICoursePictureById()
+})
+
+</script>
+<style lang='scss' scoped >
+.media-type {
+  height: 100vh;
+  transform-origin: 0 0;
+  scale: 0.5;
+  // translate: ;
+  .cover {
+    width: 200vw;
+    height: 462px;
+    display: block;
+    object-fit: cover;
+    img {
+      width: 100%;
+      height: 100%;
+      object-fit: cover;
+      display: block;
+    }
+  }
+  .title {
+    width: 200vw;
+    font-size: 36px;
+    font-weight: 600;
+    margin: 40px 0;
+    padding: 0 40px;
+    box-sizing: border-box;
+  }
+  .content {
+    width: 100vw;
+  }
+}
+</style>

+ 6 - 0
src/pages/DownloadApp/App.vue

@@ -0,0 +1,6 @@
+<script setup lang="ts">
+</script>
+
+<template>
+  <router-view/>
+</template>

BIN
src/pages/DownloadApp/assets/guidance.png


BIN
src/pages/DownloadApp/assets/logo.png


+ 1 - 0
src/pages/DownloadApp/assets/redirect.html

@@ -0,0 +1 @@
+No Content: https://itunes.apple.com/cn/app/id741292507

+ 14 - 0
src/pages/DownloadApp/main.ts

@@ -0,0 +1,14 @@
+import { createApp } from 'vue'
+import App from './App.vue'
+import router from './router'
+import 'lib-flexible'
+import 'normalize.css'
+import * as Pinia from 'pinia'
+// import VConsole from 'vconsole'
+import '@/utils/vant'
+
+// const vconsole = new VConsole()
+
+// import store from './store'
+
+createApp(App).use(router).use(Pinia.createPinia()).mount('#DownloadApp')

+ 17 - 0
src/pages/DownloadApp/public/index.html

@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html lang="">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width,initial-scale=1.0">
+    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
+    <title>逻辑狗</title>
+  </head>
+  <body>
+    <noscript>
+      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
+    </noscript>
+    <div id="DownloadApp"></div>
+    <!-- built files will be auto injected -->
+  </body>
+</html>

+ 16 - 0
src/pages/DownloadApp/router/index.ts

@@ -0,0 +1,16 @@
+import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
+
+const routes: Array<RouteRecordRaw> = [
+  {
+    path: '/',
+    name: 'page',
+    component: () => import('../views/index.vue')
+  }
+]
+
+const router = createRouter({
+  history: createWebHashHistory(),
+  routes
+})
+
+export default router

+ 115 - 0
src/pages/DownloadApp/views/index.vue

@@ -0,0 +1,115 @@
+<template>
+  <div class="download-app" >
+    <div class="app" >
+      <img class="logo" :src="require('@/pages/DownloadApp/assets/logo.png')" alt="">
+      <div class="logo-desc" >
+        逻辑狗·与千万逻辑狗宝贝一起成长
+      </div>
+      <div class="download-btn" @click="downloadApp" >
+        立即下载逻辑狗
+      </div>
+    </div>
+
+    <div class="guidance-overlay" v-if="isInWeChat" >
+      <img class="guidance" :src="require('@/pages/DownloadApp/assets/guidance.png')" alt="">
+      <div class="desc" >
+        请使用其他浏览器打开
+      </div>
+    </div>
+
+  </div>
+
+</template>
+
+<script setup lang="ts">
+import { onMounted } from 'vue'
+
+const userAgent = navigator.userAgent
+
+const isAndroid = /Android/.test(userAgent)
+
+const isIOS = /(iPhone|iPad|iPod)/.test(userAgent)
+
+// 判断是否在微信中
+var isInWeChat = /MicroMessenger/.test(userAgent)
+
+onMounted(() => {
+  console.log('isIOS:', isIOS)
+  console.log('isAndroid:', isAndroid)
+  console.log('userAgent:', userAgent)
+  downloadApp()
+})
+
+const downloadApp = () => {
+  if (isIOS) {
+    window.location.href = 'https://apps.apple.com/cn/app/%E9%80%BB%E8%BE%91%E7%8B%97/id1486738676'
+  } else {
+    window.location.href = 'market://details?id=com.zaojiao.app'
+  }
+}
+</script>
+
+<style>
+.download-app {
+  width: 100vw;
+  height: 100vh;
+}
+
+.app {
+  position: fixed;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+  display: flex;
+  flex-direction: column;
+  flex-wrap: wrap;
+  align-items: center;
+  width: 100vw;
+}
+
+.logo {
+  width: 86px;
+  height: 86px;
+  border-radius: 10px;
+  z-index: 1;
+  margin: 0 auto;
+}
+
+.logo-desc {
+  margin-top: 20px;
+  font-size: 16px;
+}
+
+.download-btn {
+  border: 1px solid #2f9f3e;
+  padding: 10px 30px;
+  margin-top: 20px;
+  border-radius: 20px;
+  color: #2f9f3e;
+  letter-spacing: 2px;
+}
+
+.guidance-overlay {
+  width: 100vw;
+  height: 100vh;
+  background-color: rgba(0, 0, 0, 0.7);
+  position: fixed;
+  z-index: 2;
+}
+
+.guidance {
+  width: 135px;
+  position: fixed;
+  top: 20px;
+  right: 20px;
+}
+
+.desc {
+  font-size: 20px;
+  color: #fff;
+  position: fixed;
+  top: 170px;
+  right: 20px;
+}
+
+</style>

+ 6 - 0
src/pages/LearnPlanActive/App.vue

@@ -0,0 +1,6 @@
+<script setup lang="ts">
+</script>
+
+<template>
+  <router-view/>
+</template>

BIN
src/pages/LearnPlanActive/assets/course-1.png


BIN
src/pages/LearnPlanActive/assets/course-2.png


BIN
src/pages/LearnPlanActive/assets/course-3.png


BIN
src/pages/LearnPlanActive/assets/course-4.png


BIN
src/pages/LearnPlanActive/assets/light.png


BIN
src/pages/LearnPlanActive/assets/lock.png


BIN
src/pages/LearnPlanActive/assets/qrcode.png


BIN
src/pages/LearnPlanActive/assets/right.png


BIN
src/pages/LearnPlanActive/assets/video.mp4


+ 85 - 0
src/pages/LearnPlanActive/components/modal.vue

@@ -0,0 +1,85 @@
+<template>
+  <van-overlay :show="show" @click="closeModal" >
+    <div class="wrapper" @click.stop>
+      <div class="qrcode" >
+        <img :src="require('@/pages/LearnPlanActive/assets/qrcode.png')" alt="">
+        <div class="tip" > {{isInWeChat ? '长按' : ''}}添加老师 解锁全部内容</div>
+      </div>
+      <div class="btn" >
+        <!-- <OpenApp appid='wxe87236d542cd0f94'   /> -->
+        <div class="cancel-btn" @click="closeModal">关闭</div>
+        <!-- <OpenApp appid='wxeb44a864bdd935be' style="width: 100px;height: 40px" text="打开APP" extinfo="/course/pipeline"  /> -->
+      </div>
+    </div>
+  </van-overlay>
+</template>
+<script lang='ts'  setup >
+import { ref, defineExpose } from 'vue'
+import OpenApp from '@/components/OpenApp/index.vue'
+const userAgent = navigator.userAgent
+var isInWeChat = /MicroMessenger/.test(userAgent)
+const show = ref(false)
+
+const closeModal = () => {
+  show.value = false
+}
+
+const openModal = () => {
+  show.value = true
+}
+
+defineExpose({
+  openModal
+})
+
+</script>
+<style lang='scss' scoped >
+.wrapper {
+  width: 300px;
+  height: 350px;
+  background: #fff;
+  border-radius: 20px;
+  box-shadow: 0px -4px 34px 0px rgba(0,0,0,0.06);
+  position: fixed;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+  z-index: 100;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  .qrcode {
+    margin-top: -60px;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    img {
+      width: 200px;
+      height: 200px;
+    }
+    .tip {
+      margin-top: 10px;
+      font-size: 16px;
+    }
+  }
+  .btn {
+    position: absolute;
+    left: 0;
+    bottom: 20px;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    width: 100%;
+    .cancel-btn {
+      width: 200px;
+      height: 40px;
+      border-radius: 30px;
+      background-color: #2d59ec;
+      color: #fff;
+      line-height: 40px;
+      text-align: center;
+      font-size: 18px;
+    }
+  }
+}
+</style>

+ 14 - 0
src/pages/LearnPlanActive/main.ts

@@ -0,0 +1,14 @@
+import { createApp } from 'vue'
+import App from './App.vue'
+import router from './router'
+import 'lib-flexible'
+import 'normalize.css'
+import * as Pinia from 'pinia'
+import VConsole from 'vconsole'
+import '@/utils/vant'
+
+// const vconsole = new VConsole()
+
+// import store from './store'
+
+createApp(App).use(router).use(Pinia.createPinia()).mount('#LearnPlanActive')

+ 17 - 0
src/pages/LearnPlanActive/public/index.html

@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html lang="">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width,initial-scale=1.0">
+    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
+    <title>逻辑狗</title>
+  </head>
+  <body>
+    <noscript>
+      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
+    </noscript>
+    <div id="LearnPlanActive"></div>
+    <!-- built files will be auto injected -->
+  </body>
+</html>

+ 21 - 0
src/pages/LearnPlanActive/router/index.ts

@@ -0,0 +1,21 @@
+import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
+
+const routes: Array<RouteRecordRaw> = [
+  {
+    path: '/',
+    name: 'page',
+    component: () => import('../views/index.vue')
+  },
+  {
+    path: '/detail',
+    name: 'detail',
+    component: () => import('../views/detail.vue')
+  }
+]
+
+const router = createRouter({
+  history: createWebHashHistory(),
+  routes
+})
+
+export default router

+ 172 - 0
src/pages/LearnPlanActive/views/detail.vue

@@ -0,0 +1,172 @@
+<template>
+  <div class="detail" >
+    <div class="desc" >
+      <div class="cover" >
+        <img :src="cover" alt="">
+      </div>
+      <div class="title" >
+        {{name}}
+      </div>
+    </div>
+
+    <div class="course-meun" >
+      <div
+        :class="['course-meun-item', 'course-meun-item-active']"
+        v-for="(item, index) in meun"
+        :key="item.icon"
+        @click="openCourse(item)"
+      >
+        <div class="left" >
+          <img class="icon" :src="item.icon" alt="">
+          <div class="title" >{{item.title}}</div>
+        </div>
+        <div class="right" > <img :src="require('@/pages/LearnPlanActive/assets/right.png')" alt=""> </div>
+      </div>
+    </div>
+  </div>
+
+  <van-overlay :show="show" @click="closeModal" >
+    <div class="wrapper" @click.stop>
+      <video ref="videoRef" :muted="true"  style="width: 360px" autoplay controls :src="require('@/pages/LearnPlanActive/assets/video.mp4')" />
+    </div>
+  </van-overlay>
+
+  <modal ref="ModalDom" />
+</template>
+<script lang='ts'  setup >
+
+import { ref } from 'vue'
+import { useRoute } from 'vue-router'
+import modal from '../components/modal.vue'
+
+const meun = [
+  {
+    title: '学一学',
+    icon: require('@/pages/LearnPlanActive/assets/course-1.png'),
+    id: 0
+  },
+  {
+    title: '练一练 (试看版)',
+    icon: require('@/pages/LearnPlanActive/assets/course-2.png'),
+    id: 1
+  },
+  {
+    title: '小小讲师',
+    icon: require('@/pages/LearnPlanActive/assets/course-3.png'),
+    id: 2
+  },
+  {
+    title: '学习报告',
+    icon: require('@/pages/LearnPlanActive/assets/course-4.png'),
+    id: 3
+  }
+]
+
+const ModalDom = ref()
+const show = ref(false)
+
+const route = useRoute()
+
+const videoRef = ref()
+
+const { index, name, cover } = route.query
+
+const openCourse = (record: any) => {
+  if (record.id === 0) {
+    window.open('https://luojigou.vip/lp-active-' + index + '?to=learnPlan&isActive=1')
+  } else if (record.id === 1) {
+    show.value = true
+  } else {
+    ModalDom.value.openModal()
+  }
+}
+
+const closeModal = () => {
+  show.value = false
+  videoRef.value.pause()
+}
+
+</script>
+<style lang='scss' scoped >
+
+.detail {
+  padding: 0 20px;
+  padding-top: 40px;
+  .desc {
+    display: flex;
+    align-items: center;
+    .cover {
+      margin-right: 20px;
+      width: 96px;
+      height: 127px;
+      border-radius: 20px;
+      overflow: hidden;
+      img {
+        width: 100%;
+        height: 100%;
+      }
+    }
+    .title {
+      font-family: PingFangSC, PingFang SC;
+      font-weight: 600;
+      font-size: 22px;
+      color: #000000;
+      line-height: 16px;
+      text-align: left;
+      font-style: normal;
+    }
+  }
+  .course-meun {
+    margin-top: 32px;
+    .course-meun-item {
+      width: 335px;
+      height: 82px;
+      background: #F7F8FA;
+      border-radius: 20px;
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      padding-left: 8px;
+      padding-right: 30px;
+      box-sizing: border-box;
+      margin-bottom: 16px;
+      .left {
+        display: flex;
+        align-items: center;
+        .icon {
+          width: 70px;
+          height: 82px;
+          display: block;
+        }
+        .title {
+          font-family: PingFangSC, PingFang SC;
+          font-weight: 600;
+          font-size: 20px;
+          color: #FFFFFF;
+          line-height: 16px;
+          text-shadow: 0px 0px 30px rgba(255,128,36,0.31);
+          text-align: center;
+          font-style: normal;
+        }
+      }
+      .right {
+        img {
+          width: 18px;
+          height: 20px;
+        }
+      }
+    }
+    .course-meun-item-active {
+      background: #FF8024;
+      box-shadow: 0px 0px 30px 0px rgba(255,128,36,0.31);
+    }
+  }
+}
+
+.wrapper {
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+}
+</style>

+ 232 - 0
src/pages/LearnPlanActive/views/index.vue

@@ -0,0 +1,232 @@
+<template>
+  <div class="course" >
+    <div
+      class="course-item"
+      v-for="(item, index) in meun"
+      :key="item"
+      @click="pushCourseDetailPage(item, index)"
+    >
+      <div class="overlay" v-if="index >= 5" >
+        <img class="lock" :src="require('@/pages/LearnPlanActive/assets/lock.png')" alt="">
+      </div>
+      <div class="cover" >
+        <img :src="item.imgCover" alt="">
+      </div>
+      <div class="desc" >
+        <div class="course-title" >第{{index + 1}}节</div>
+        <div class="title" >{{item.name.split(' ')[1]}}</div>
+        <div class="level" ><img v-for="item in 3" :key="item" :src="require('@/pages/LearnPlanActive/assets/light.png')" alt=""></div>
+      </div>
+    </div>
+  </div>
+
+  <Modal ref="ModalDom" />
+</template>
+<script lang='ts'  setup >
+import { useRouter } from 'vue-router'
+import { registerWxopenButton } from '@/utils/utils'
+import { getCWXSignature } from '@/api/common'
+import { onMounted, ref } from 'vue'
+import Modal from '../components/modal.vue'
+
+const router = useRouter()
+
+const meun = [
+  {
+    id: '1645619635348258817',
+    imgCover: 'https://img.luojigou.vip/Fs777MWT4wUc6yv8vXC4Is_82HTZ?imageView2/0/q/50|imageslim',
+    name: '第1节 房间大作战',
+    payType: 1,
+    type: 3
+  },
+  {
+    id: '1645619635436339202',
+    imgCover: 'https://img.luojigou.vip/FryqW_OKCBJI65E2v5fqEjNHTOUU?imageView2/0/q/50|imageslim',
+    name: '第2节 玩具派对',
+    payType: 1,
+    type: 3
+  },
+  {
+    id: '1645619635532808193',
+    imgCover: 'https://img.luojigou.vip/FgCVZ0bDBzNNV6JI1bgvI8QnOSwo?imageView2/0/q/50|imageslim',
+    name: '第3节 美味奇趣蛋',
+    payType: 1,
+    type: 3
+  },
+  {
+    id: '1645619635612499970',
+    imgCover: 'https://img.luojigou.vip/FmGwXvAAt5xtkbgpNaGmtqsdYAZG?imageView2/0/q/50|imageslim',
+    name: '第4节 开心游乐场',
+    payType: 1,
+    type: 3
+  },
+  {
+    id: '1645619635692191746',
+    imgCover: 'https://img.luojigou.vip/FpxYWf3020sdGrGNSrH0Z1QJOmnD?imageView2/0/q/50|imageslim',
+    name: '第5节 积木城堡',
+    payType: 1,
+    type: 3
+  },
+  {
+    id: '1645619635776077826',
+    imgCover: 'https://img.luojigou.vip/Fhj2XUpHwvIzgsQqpkQpLRJxQCUU?imageView2/0/q/50|imageslim',
+    name: '第6节 去海滩玩',
+    payType: 1,
+    type: 3
+  },
+  {
+    id: '1645619635859963906',
+    imgCover: 'https://img.luojigou.vip/FgeO_AMU-kYVIyHjvuy02A-WxoZW?imageView2/0/q/50|imageslim',
+    name: '第7节 神奇的书',
+    payType: 1,
+    type: 3
+  },
+  {
+    id: '1645619635960627201',
+    imgCover: 'https://img.luojigou.vip/FqgVL09gd8IPwqY_KOdK8Sa-u0K_?imageView2/0/q/50|imageslim',
+    name: '第8节 好饿的一天',
+    payType: 1,
+    type: 3
+  },
+  {
+    id: '1645619636036124674',
+    imgCover: 'https://img.luojigou.vip/ForsHyPsj8FaUNWr45YB0nKCZ5K7?imageView2/0/q/50|imageslim',
+    name: '第9节 调皮的青蛙',
+    payType: 1,
+    type: 3
+  },
+  {
+    id: '1645619636166148098',
+    imgCover: 'https://img.luojigou.vip/FnVe8GjonXFM9k9FjJg4wxD1EhN8?imageView2/0/q/50|imageslim',
+    name: '第10节 一起画画',
+    payType: 1,
+    type: 3
+  },
+  {
+    id: '1645619636250034177',
+    imgCover: 'https://img.luojigou.vip/FpEXWsrkaQvy614J2yWEk7aF6Q4T?imageView2/0/q/50|imageslim',
+    name: '第11节 一起学拍照',
+    payType: 1,
+    type: 3
+  },
+  {
+    id: '1645619636325531650',
+    imgCover: 'https://img.luojigou.vip/FgOmIY2YztbrBGRgtiTnpm6GHQQL?imageView2/0/q/50|imageslim',
+    name: '第12节 一起看电视',
+    payType: 1,
+    type: 3
+  },
+  {
+    id: '1645619636405223426',
+    imgCover: 'https://img.luojigou.vip/FgepQOcvHGbkVGfWfx90sHddyJVe?imageView2/0/q/50|imageslim',
+    name: '第13节 下雨啦',
+    payType: 1,
+    type: 3
+  },
+  {
+    id: '1645619636484915201',
+    imgCover: 'https://img.luojigou.vip/FtntGhOxr5EPFEJ6h7QWRTGLR2wl?imageView2/0/q/50|imageslim',
+    name: '第14节 影子配对棋',
+    payType: 1,
+    type: 3
+  },
+  {
+    id: '1645619636598161410',
+    imgCover: 'https://img.luojigou.vip/Fu_obJiGD5WDoN8eJRfgiuGjtaTj?imageView2/0/q/50|imageslim',
+    name: '第15节 星星能量',
+    payType: 1,
+    type: 3
+  }
+]
+
+const ModalDom = ref()
+
+const pushCourseDetailPage = (record: any, index: number) => {
+  if (index <= 4) {
+    router.push({
+      path: '/detail',
+      query: { index: index, name: record.name.split(' ')[1], cover: record.imgCover }
+    })
+  } else {
+    ModalDom.value.openModal()
+  }
+}
+
+onMounted(() => {
+  // registerWxopenButton(getCWXSignature)
+})
+
+</script>
+<style lang='scss' scoped >
+.course {
+  padding: 40px 16px;
+  background: #F9F9F9;
+  .course-item {
+    width: 343px;
+    height: 151px;
+    background: #FFFFFF;
+    box-shadow: 0px 2px 10px 5px rgba(0,0,0,0.03);
+    border-radius: 20px;
+    padding: 12px;
+    box-sizing: border-box;
+    display: flex;
+    margin-bottom: 12px;
+    position: relative;
+    overflow: hidden;
+    .overlay {
+      width: 100%;
+      height: 100%;
+      background-color: rgba(0, 0, 0, 0.4);
+      position: absolute;
+      top: 0;
+      left: 0;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      .lock {
+
+      }
+    }
+    .cover {
+      width: 96px;
+      height: 127px;
+      margin-right: 12px;
+      border-radius: 20px;
+      overflow: hidden;
+      img {
+        width: 100%;
+        height: 100%;
+        display: block;
+      }
+    }
+    .desc {
+      font-family: PingFangSC, PingFang SC;
+      margin-top: 16px;
+      .course-title {
+        font-weight: 400;
+        font-size: 14px;
+        color: #666666;
+        line-height: 12px;
+        text-align: left;
+        font-style: normal;
+      }
+      .title {
+        font-weight: 500;
+        font-size: 18px;
+        color: #333333;
+        line-height: 21px;
+        margin-top: 10px;
+      }
+      .level  {
+        display: flex;
+        margin-top: 12px;
+        img {
+          width: 17px;
+          height: 22px;
+          margin-right: 6px;
+        }
+      }
+    }
+  }
+}
+</style>

+ 3 - 3
src/service/request.ts

@@ -1,10 +1,10 @@
 import { useTokenStore } from '@/store'
 import axios, { AxiosResponse } from 'axios'
 
-// const baseURL = process.env.NODE_ENV === 'development' ? '/api' : '/zd-api'
-// const baseURL = process.env.NODE_ENV === 'development' ? 'https://open.api.luojigou.vip/' : '/zd-api'
+const baseURL = process.env.NODE_ENV === 'development' ? '/api' : '/zd-api'
+// const baseURL = process.env.NODE_EN === 'development' ? 'https://open.api.luojigou.vip/' : '/zd-api'
 // const baseURL = process.env.NODE_ENV === 'development' ? '/https://open.api.luojigou.vip/' : '/zd-api'
-const baseURL = '/zd-api'
+// const baseURL = '/zd-api'
 
 // 'https://open.api.luojigou.vip/'
 

+ 29 - 32
src/utils/utils.ts

@@ -1,7 +1,7 @@
 import html2canvas from 'html2canvas'
 import QRCode from 'qrcode'
 import { ScreenShot } from './typing'
-import { getWXSignature } from '@/api/common'
+import { getCWXSignature } from '@/api/common'
 import wx from 'weixin-js-sdk'
 
 /**
@@ -11,14 +11,14 @@ import wx from 'weixin-js-sdk'
  */
 export const screenShot: ScreenShot = async (el) => {
   const _el = typeof el === 'string' ? document.getElementById(el) : el
-  const scale = window.devicePixelRatio;
-    // canvas.width = 1000 * scale;
-    // canvas.height = 1000 * scale;
-    // ctx.scale(scale, scale);
+  const scale = window.devicePixelRatio
+  // canvas.width = 1000 * scale;
+  // canvas.height = 1000 * scale;
+  // ctx.scale(scale, scale);
   return new Promise((resolve) => {
     html2canvas(_el!, {
       useCORS: true,
-      scale,
+      scale
     }).then(canvas => {
       const img = document.createElement('img')
       img.src = canvas.toDataURL('image/png')
@@ -29,8 +29,8 @@ export const screenShot: ScreenShot = async (el) => {
 }
 
 export const createQrcode = (text: string): Promise<string> => {
-  console.log('text:', text);
-  
+  console.log('text:', text)
+
   return new Promise((resolve) => {
     QRCode.toDataURL(text, { errorCorrectionLevel: 'H' }, function (err, url) {
       if (err) {
@@ -42,34 +42,31 @@ export const createQrcode = (text: string): Promise<string> => {
   })
 }
 
-
 /**
  * @description 注册wx-open-launch-app
  */
 
-export async function registerWxopenButton() {
+export async function registerWxopenButton (request: () => any) {
   return new Promise(async resolve => {
-    const {data} = await getWXSignature();
-    console.log('register: wxopenButto:', data);
-    
- 
-      const {signature, appId, nonceStr, timestamp} = data;
-      wx.config({
-        debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印
-        appId, // 必填,公众号的唯一标识
-        timestamp, // 必填,生成签名的时间戳
-        nonceStr, // 必填,生成签名的随机串
-        signature,// 必填,签名
-        jsApiList: ['openLocation', 'getLocation'], // 必填,需要使用的JS接口列表
-        openTagList: ['wx-open-launch-app'] // 可选,需要使用的开放标签列表,例如['wx-open-launch-app']
-      });
-      wx.error((res: any) => {
-        console.log(res);
-      });
+    const { data } = await request()
+    console.log('register: wxopenButto:', data)
 
-      wx.ready(() => {
-        resolve(true);
-      });
-   
-  });
+    const { signature, appId, nonceStr, timestamp } = data
+    wx.config({
+      debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印
+      appId, // 必填,公众号的唯一标识
+      timestamp, // 必填,生成签名的时间戳
+      nonceStr, // 必填,生成签名的随机串
+      signature, // 必填,签名
+      jsApiList: ['openLocation', 'getLocation'], // 必填,需要使用的JS接口列表
+      openTagList: ['wx-open-launch-app'] // 可选,需要使用的开放标签列表,例如['wx-open-launch-app']
+    })
+    wx.error((res: any) => {
+      console.log(res)
+    })
+
+    wx.ready(() => {
+      resolve(true)
+    })
+  })
 }

+ 15 - 0
vue.config.js

@@ -25,6 +25,21 @@ module.exports = {
       entry: 'src/pages/SectionAudition/main.ts',
       template: 'src/pages/SectionAudition/public/index.html',
       filename: 'section-audition.html'
+    },
+    DownloadApp: {
+      entry: 'src/pages/DownloadApp/main.ts',
+      template: 'src/pages/DownloadApp/public/index.html',
+      filename: 'download-app.html'
+    },
+    Course: {
+      entry: 'src/pages/Course/main.ts',
+      template: 'src/pages/Course/public/index.html',
+      filename: 'course.html'
+    },
+    LP: {
+      entry: 'src/pages/LearnPlanActive/main.ts',
+      template: 'src/pages/LearnPlanActive/public/index.html',
+      filename: 'lp.html'
     }
   },
   chainWebpack: config => {